diff --git a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID.h b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID.h index 3454d47113745..c8ee861e530b4 100644 --- a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID.h +++ b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID.h @@ -58,7 +58,7 @@ class DetID static constexpr ID MCH = 9; static constexpr ID MID = 10; static constexpr ID ZDC = 11; - static constexpr ID FIT = 12; + static constexpr ID T0 = 12; static constexpr ID ACO = 13; static constexpr ID First = ITS; static constexpr ID Last = ACO; ///< if extra detectors added, update this !!! @@ -105,13 +105,13 @@ class DetID ID mID = First; ///< detector ID static constexpr const char* sDetNames[nDetectors + 1] = ///< defined detector names - { "ITS", "TPC", "TRD", "TOF", "PHS", "CPV", "EMC", "HMP", "MFT", "MCH", "MID", "ZDC", "FIT", "ACO", nullptr }; + { "ITS", "TPC", "TRD", "TOF", "PHS", "CPV", "EMC", "HMP", "MFT", "MCH", "MID", "ZDC", "T0", "ACO", nullptr }; // detector names, will be defined in DataSources static constexpr std::array sMasks = ///< detectot masks { utils::bit2Mask(ITS), utils::bit2Mask(TPC), utils::bit2Mask(TRD), utils::bit2Mask(TOF), utils::bit2Mask(PHS), utils::bit2Mask(CPV), utils::bit2Mask(EMC), utils::bit2Mask(HMP), utils::bit2Mask(MFT), utils::bit2Mask(MCH), - utils::bit2Mask(MID), utils::bit2Mask(ZDC), utils::bit2Mask(FIT), utils::bit2Mask(ACO) }; + utils::bit2Mask(MID), utils::bit2Mask(ZDC), utils::bit2Mask(T0), utils::bit2Mask(ACO) }; ClassDefNV(DetID, 1); }; diff --git a/DataFormats/Detectors/Common/src/DetID.cxx b/DataFormats/Detectors/Common/src/DetID.cxx index 649bca757e3a2..961593b4c870f 100644 --- a/DataFormats/Detectors/Common/src/DetID.cxx +++ b/DataFormats/Detectors/Common/src/DetID.cxx @@ -25,7 +25,7 @@ constexpr std::array DetID::sMasks; // redundant declarations constexpr DetID::ID DetID::ITS, DetID::TPC, DetID::TRD, DetID::TOF, DetID::PHS, DetID::CPV, DetID::EMC, - DetID::HMP, DetID::MFT, DetID::MCH, DetID::MID, DetID::ZDC, DetID::FIT, DetID::ACO, DetID::First, DetID::Last; + DetID::HMP, DetID::MFT, DetID::MCH, DetID::MID, DetID::ZDC, DetID::T0, DetID::ACO, DetID::First, DetID::Last; constexpr int DetID::nDetectors; diff --git a/DataFormats/Headers/include/Headers/DataHeader.h b/DataFormats/Headers/include/Headers/DataHeader.h index d748a009f479a..4b743139427ab 100644 --- a/DataFormats/Headers/include/Headers/DataHeader.h +++ b/DataFormats/Headers/include/Headers/DataHeader.h @@ -589,7 +589,7 @@ constexpr o2::header::DataOrigin gDataOriginACO{ "ACO" }; constexpr o2::header::DataOrigin gDataOriginCPV{ "CPV" }; constexpr o2::header::DataOrigin gDataOriginCTP{ "CTP" }; constexpr o2::header::DataOrigin gDataOriginEMC{ "EMC" }; -constexpr o2::header::DataOrigin gDataOriginFIT{ "FIT" }; +constexpr o2::header::DataOrigin gDataOriginT0{ "T0" }; constexpr o2::header::DataOrigin gDataOriginHMP{ "HMP" }; constexpr o2::header::DataOrigin gDataOriginITS{ "ITS" }; constexpr o2::header::DataOrigin gDataOriginMCH{ "MCH" }; diff --git a/Detectors/FIT/CMakeLists.txt b/Detectors/FIT/CMakeLists.txt index 7153b888b9502..c8c3ba0078283 100644 --- a/Detectors/FIT/CMakeLists.txt +++ b/Detectors/FIT/CMakeLists.txt @@ -1,4 +1,4 @@ # Libraries -add_subdirectory(base) -add_subdirectory(simulation) -add_subdirectory(reconstruction) +add_subdirectory(common) +add_subdirectory(T0) +#add_subdirectory(V0) diff --git a/Detectors/FIT/T0/CMakeLists.txt b/Detectors/FIT/T0/CMakeLists.txt new file mode 100644 index 0000000000000..7153b888b9502 --- /dev/null +++ b/Detectors/FIT/T0/CMakeLists.txt @@ -0,0 +1,4 @@ +# Libraries +add_subdirectory(base) +add_subdirectory(simulation) +add_subdirectory(reconstruction) diff --git a/Detectors/FIT/T0/base/CMakeLists.txt b/Detectors/FIT/T0/base/CMakeLists.txt new file mode 100644 index 0000000000000..f4ce749ff13cd --- /dev/null +++ b/Detectors/FIT/T0/base/CMakeLists.txt @@ -0,0 +1,22 @@ +set(MODULE_NAME "T0Base") + +O2_SETUP(NAME ${MODULE_NAME}) + +set(SRCS + src/Geometry.cxx + ) + +set(HEADERS + include/${MODULE_NAME}/Geometry.h + ) + +Set(LINKDEF src/T0BaseLinkDef.h) +Set(LIBRARY_NAME ${MODULE_NAME}) +set(BUCKET_NAME fit_base_bucket) + +O2_GENERATE_LIBRARY() + +install( + DIRECTORY files + DESTINATION share/Detectors/T0/ +) diff --git a/Detectors/FIT/base/files/quartzOptProperties.txt b/Detectors/FIT/T0/base/files/quartzOptProperties.txt similarity index 100% rename from Detectors/FIT/base/files/quartzOptProperties.txt rename to Detectors/FIT/T0/base/files/quartzOptProperties.txt diff --git a/Detectors/FIT/base/include/FITBase/Geometry.h b/Detectors/FIT/T0/base/include/T0Base/Geometry.h similarity index 98% rename from Detectors/FIT/base/include/FITBase/Geometry.h rename to Detectors/FIT/T0/base/include/T0Base/Geometry.h index d07065a00185b..71580b4a20e6a 100644 --- a/Detectors/FIT/base/include/FITBase/Geometry.h +++ b/Detectors/FIT/T0/base/include/T0Base/Geometry.h @@ -18,7 +18,7 @@ #include namespace o2 { -namespace fit +namespace t0 { // FIT is not tracking detector, Geometry could be used in future but not now. So just simple settings class Geometry @@ -52,6 +52,6 @@ class Geometry ClassDefNV(Geometry, 1); }; -} // namespace fit +} // namespace t0 } // namespace o2 #endif diff --git a/Detectors/FIT/base/src/Geometry.cxx b/Detectors/FIT/T0/base/src/Geometry.cxx similarity index 97% rename from Detectors/FIT/base/src/Geometry.cxx rename to Detectors/FIT/T0/base/src/Geometry.cxx index 0c31ea91587a9..46084df237544 100644 --- a/Detectors/FIT/base/src/Geometry.cxx +++ b/Detectors/FIT/T0/base/src/Geometry.cxx @@ -9,14 +9,14 @@ // or submit itself to any jurisdiction. #include //#include -#include "FITBase/Geometry.h" +#include "T0Base/Geometry.h" #include #include -ClassImp(o2::fit::Geometry); +ClassImp(o2::t0::Geometry); -using namespace o2::fit; +using namespace o2::t0; Geometry::Geometry() : mMCP{ { 0, 0, 0 } } { diff --git a/Detectors/FIT/reconstruction/src/FITReconstructionLinkDef.h b/Detectors/FIT/T0/base/src/T0BaseLinkDef.h similarity index 80% rename from Detectors/FIT/reconstruction/src/FITReconstructionLinkDef.h rename to Detectors/FIT/T0/base/src/T0BaseLinkDef.h index 9b9f866b49c00..4be48bd4b2466 100644 --- a/Detectors/FIT/reconstruction/src/FITReconstructionLinkDef.h +++ b/Detectors/FIT/T0/base/src/T0BaseLinkDef.h @@ -14,8 +14,6 @@ #pragma link off all classes; #pragma link off all functions; -#pragma link C++ class o2::fit::CollisionTimeRecoTask+; -#pragma link C++ class o2::fit::RecPoints+; -#pragma link C++ class o2::fit::Channel+; +#pragma link C++ class o2::t0::Geometry + ; #endif diff --git a/Detectors/FIT/T0/base/src/T0BaseLinkDef.h~HEAD b/Detectors/FIT/T0/base/src/T0BaseLinkDef.h~HEAD new file mode 100644 index 0000000000000..4be48bd4b2466 --- /dev/null +++ b/Detectors/FIT/T0/base/src/T0BaseLinkDef.h~HEAD @@ -0,0 +1,19 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifdef __CLING__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class o2::t0::Geometry + ; + +#endif diff --git a/Detectors/FIT/T0/base/src/T0BaseLinkDef.h~first separation T0 V0 b/Detectors/FIT/T0/base/src/T0BaseLinkDef.h~first separation T0 V0 new file mode 100644 index 0000000000000..4be48bd4b2466 --- /dev/null +++ b/Detectors/FIT/T0/base/src/T0BaseLinkDef.h~first separation T0 V0 @@ -0,0 +1,19 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifdef __CLING__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class o2::t0::Geometry + ; + +#endif diff --git a/Detectors/FIT/T0/macros/readHitsDigits.C b/Detectors/FIT/T0/macros/readHitsDigits.C new file mode 100644 index 0000000000000..8d1886387b0f1 --- /dev/null +++ b/Detectors/FIT/T0/macros/readHitsDigits.C @@ -0,0 +1,87 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "FITSimulation/Detector.h" +#include "FITBase/Digit.h" +#include +#endif + +void readHitsDigits() +{ + using namespace o2::fit; + // using namespace o2::fit::Digit; + + // Create histograms + TDirectory* cwd = gDirectory; + gDirectory = 0x0; + + TH2F* hMultHit = new TH2F("hMultHits", "photons Hits ", 210, 0, 210, 500, 0, 5000); + TH2F* hTimeHit = new TH2F("hTimeAChit", "Time Hits", 210, 0, 210, 1000, 0, 15); + TH2F* hMultDig = new TH2F("hMultDig", "photons Digits ", 210, 0, 210, 500, 0, 20); + TH2F* hTimeDig = new TH2F("hTimeDig", "Time Digits", 210, 0, 210, 300, 0, 15); + + gDirectory = cwd; + + TFile* fhit = new TFile("o2sim.root"); + TTree* hitTree = (TTree*)fhit->Get("o2sim"); + std::vector* hitArray = nullptr; + hitTree->SetBranchAddress("FITHit", &hitArray); + Int_t nevH = hitTree->GetEntries(); // hits are stored as one event per entry + std::cout << "Found " << nevH << " events with hits " << std::endl; + + Double_t hit_time[240]; + Int_t countE[240]; + // Event ------------------------- LOOP + for (Int_t ievent = 0; ievent < nevH; ievent++) { + hitTree->GetEntry(ievent); + for (int ii = 0; ii < 240; ii++) { + countE[ii] = 0; + hit_time[ii] = 0; + } + for (auto& hit : *hitArray) { + Int_t detID = hit.GetDetectorID(); + hit_time[detID] = hit.GetTime(); + hTimeHit->Fill(detID, hit_time[detID]); + if (hit_time[detID] < 10 && detID < 96) + std::cout << ievent << " " << detID << " time " << hit_time[detID] << endl; + + countE[detID]++; + } + for (int ii = 0; ii < 208; ii++) { + if (countE[ii] > 100) { + hMultHit->Fill(ii, countE[ii]); + // std::cout<Get("o2sim"); + o2::fit::Digit* digArr = new Digit; + digTree->SetBranchAddress("FITDigit", &digArr); + Int_t nevD = digTree->GetEntries(); // digits in cont. readout may be grouped as few events per entry + std::cout << "Found " << nevD << " events with digits " << std::endl; + Float_t cfd[208], amp[208]; + for (Int_t iev = 0; iev < nevD; iev++) { + digTree->GetEvent(iev); + for (int ii = 0; ii < 208; ii++) { + cfd[ii] = amp[ii] = 0; + } + for (const auto& d : digArr->getChDgData()) { + Int_t mcp = d.ChId; + cfd[mcp] = d.CFDTime; + amp[mcp] = d.QTCAmpl; + // cout<Fill(Float_t(mcp), amp[mcp]); + hTimeDig->Fill(Float_t(mcp), cfd[mcp]); + } + } + TFile* Hfile = new TFile("FigFit_dig_pp.root", "RECREATE"); + printf("Writting histograms to root file \n"); + Hfile->cd(); + //Create a canvas, set the view range, show histograms + // TCanvas *c1 = new TCanvas("c1","Alice T0 Time ",400,10,600,600); + hTimeHit->Write(); + hMultHit->Write(); + hTimeDig->Write(); + hMultDig->Write(); + +} // end of macro diff --git a/Detectors/FIT/T0/macros/readRecPoints.C b/Detectors/FIT/T0/macros/readRecPoints.C new file mode 100644 index 0000000000000..941d2a241fd60 --- /dev/null +++ b/Detectors/FIT/T0/macros/readRecPoints.C @@ -0,0 +1,58 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "FITSimulation/Detector.h" +#include "FITBase/Digit.h" +#include "FITReconstruction/RecPoints.h" +#include +#endif +void readRecPoints() +{ + using namespace o2::fit; + // using namespace o2::fit::Digit; + + // Create histograms + TDirectory* cwd = gDirectory; + gDirectory = 0x0; + + TH2F* hMultRec = new TH2F("hMultRec", "photons Recits ", 210, 0, 210, 500, 0, 1000); + TH2F* hTimeRec = new TH2F("hTimeRec", "Time Recits", 210, 0, 210, 1000, 1, 13); + TH1F* ht0AC = new TH1F("hT0AC", "T0AC", 100, -1, 1); + + gDirectory = cwd; + + TFile* frec = TFile::Open("o2reco_fit.root"); + std::cout << " Open rec file " << std::endl; + TTree* recTree = (TTree*)frec->Get("o2sim"); + o2::fit::RecPoints* recArr = new RecPoints; + recTree->SetBranchAddress("FITRecPoints", &recArr); + Int_t nevD = recTree->GetEntries(); // recits in cont. readout may be grouped as few events per entry + std::cout << "Found " << nevD << " events with recits " << std::endl; + Float_t cfd[208], amp[208]; + for (Int_t iev = 0; iev < nevD; iev++) { + recTree->GetEvent(iev); + + Float_t t0AC = recArr->GetCollisionTime(0); + Float_t eventtime = recArr->GetTimeFromDigit(); + ht0AC->Fill(t0AC - eventtime); + std::cout << iev << " AC " << recArr->GetCollisionTime(0) << " " << eventtime << std::endl; + for (int ii = 0; ii < 208; ii++) { + cfd[ii] = amp[ii] = 0; + } + for (const auto& d : recArr->getChDgData()) { + Int_t mcp = d.ChId; + cfd[mcp] = d.CFDTime; + amp[mcp] = d.QTCAmpl; + // cout<Fill(Float_t(mcp), amp[mcp]); + hTimeRec->Fill(Float_t(mcp), cfd[mcp]); + } + } + TFile* Hfile = new TFile("FigFit_rec_pp.root", "RECREATE"); + printf("Writting histograms to root file \n"); + Hfile->cd(); + //Create a canvas, set the view range, show histograms + // TCanvas *c1 = new TCanvas("c1","Alice T0 Time ",400,10,600,600); + hTimeRec->Write(); + hMultRec->Write(); + ht0AC->Write(); + +} // end of macro diff --git a/Detectors/FIT/T0/macros/run_digi_fit.C b/Detectors/FIT/T0/macros/run_digi_fit.C new file mode 100644 index 0000000000000..8c9f513087903 --- /dev/null +++ b/Detectors/FIT/T0/macros/run_digi_fit.C @@ -0,0 +1,96 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include + +#include + +#include "FairLogger.h" +#include "FairRunAna.h" +#include "FairFileSource.h" +#include "FairRuntimeDb.h" +#include "FairParRootFileIo.h" +#include "FairSystemInfo.h" + +#include "FITSimulation/DigitizerTask.h" +#endif + +void run_digi_fit(Int_t nEvents = 10, Float_t rate = 50.e3) +{ + // if rate>0 then continuous simulation for this rate will be performed + + // Initialize logger + FairLogger* logger = FairLogger::GetLogger(); + logger->SetLogVerbosityLevel("LOW"); + logger->SetLogScreenLevel("DEBUG"); + + // Input and output file name + std::stringstream inputfile, outputfile, paramfile; + inputfile << "o2sim.root"; + paramfile << "o2sim_par.root"; + outputfile << "o2sim_digi.root"; + + // Setup timer + TStopwatch timer; + + // Setup FairRoot analysis manager + FairRunAna* fRun = new FairRunAna(); + FairFileSource* fFileSource = new FairFileSource(inputfile.str().c_str()); + fRun->SetSource(fFileSource); + std::cout << "@@@@ input " << inputfile.str().c_str() << std::endl; + fRun->SetOutputFile(outputfile.str().c_str()); + std::cout << "@@@@ output " << outputfile.str().c_str() << std::endl; + + if (rate > 0) { + fFileSource->SetEventMeanTime(1.e9 / rate); // is in us + } + + // Setup Runtime DB + + FairRuntimeDb* rtdb = fRun->GetRuntimeDb(); + std::cout << "@@@@ param " << paramfile.str().c_str() << std::endl; + FairParRootFileIo* parInput1 = new FairParRootFileIo(); + parInput1->open(paramfile.str().c_str()); + rtdb->setFirstInput(parInput1); + + // Setup digitizer + o2::fit::DigitizerTask* digi = new o2::fit::DigitizerTask(); + // digi->setContinuous(rate > 0); + // digi->setFairTimeUnitInNS(1.0); // tell in which units (wrt nanosecond) FAIT timestamps are + fRun->AddTask(digi); + + std::cout << "@@@@ Add task " << std::endl; + fRun->Init(); + std::cout << "@@@@ Run Init " << std::endl; + + timer.Start(); + fRun->Run(); + + std::cout << std::endl + << std::endl; + + // Extract the maximal used memory an add is as Dart measurement + // This line is filtered by CTest and the value send to CDash + FairSystemInfo sysInfo; + Float_t maxMemory = sysInfo.GetMaxMemory(); + std::cout << ""; + std::cout << maxMemory; + std::cout << "" << std::endl; + + timer.Stop(); + Double_t rtime = timer.RealTime(); + Double_t ctime = timer.CpuTime(); + + Float_t cpuUsage = ctime / rtime; + cout << ""; + cout << cpuUsage; + cout << "" << endl; + cout << endl + << endl; + std::cout << "Macro finished succesfully" << std::endl; + + std::cout << endl + << std::endl; + std::cout << "Output file is " << outputfile.str() << std::endl; + // std::cout << "Parameter file is " << parFile << std::endl; + std::cout << "Real time " << rtime << " s, CPU time " << ctime << "s" << endl + << endl; +} diff --git a/Detectors/FIT/T0/macros/test/run_test.sh b/Detectors/FIT/T0/macros/test/run_test.sh new file mode 100755 index 0000000000000..9e1f69e98dc2c --- /dev/null +++ b/Detectors/FIT/T0/macros/test/run_test.sh @@ -0,0 +1,5 @@ +# +nEvents=10 +mcEngine=\"TGeant3\" +# +# will be fill later diff --git a/Detectors/FIT/reconstruction/CMakeLists.txt b/Detectors/FIT/T0/reconstruction/CMakeLists.txt similarity index 79% rename from Detectors/FIT/reconstruction/CMakeLists.txt rename to Detectors/FIT/T0/reconstruction/CMakeLists.txt index 38d1f821e51ec..66bddb7503563 100644 --- a/Detectors/FIT/reconstruction/CMakeLists.txt +++ b/Detectors/FIT/T0/reconstruction/CMakeLists.txt @@ -1,4 +1,4 @@ -set(MODULE_NAME "FITReconstruction") +set(MODULE_NAME "T0Reconstruction") O2_SETUP(NAME ${MODULE_NAME}) @@ -13,7 +13,7 @@ set(HEADERS ) -Set(LINKDEF src/FITReconstructionLinkDef.h) +Set(LINKDEF src/T0ReconstructionLinkDef.h) Set(LIBRARY_NAME ${MODULE_NAME}) set(BUCKET_NAME fit_reconstruction_bucket) diff --git a/Detectors/FIT/reconstruction/include/FITReconstruction/CollisionTimeRecoTask.h b/Detectors/FIT/T0/reconstruction/include/T0Reconstruction/CollisionTimeRecoTask.h similarity index 86% rename from Detectors/FIT/reconstruction/include/FITReconstruction/CollisionTimeRecoTask.h rename to Detectors/FIT/T0/reconstruction/include/T0Reconstruction/CollisionTimeRecoTask.h index df9f2f0f2242a..717977c7c1707 100644 --- a/Detectors/FIT/reconstruction/include/FITReconstruction/CollisionTimeRecoTask.h +++ b/Detectors/FIT/T0/reconstruction/include/T0Reconstruction/CollisionTimeRecoTask.h @@ -15,22 +15,22 @@ #include #include "FITBase/Digit.h" -#include "FITReconstruction/RecPoints.h" +#include "T0Reconstruction/RecPoints.h" namespace o2 { -namespace fit +namespace t0 { class CollisionTimeRecoTask { public: CollisionTimeRecoTask() = default; ~CollisionTimeRecoTask() = default; - void Process(const Digit& digits, RecPoints& recPoints) const; + void Process(const o2::fit::Digit& digits, RecPoints& recPoints) const; void FinishTask(); private: ClassDefNV(CollisionTimeRecoTask, 1); }; -} // namespace fit +} // namespace t0 } // namespace o2 #endif diff --git a/Detectors/FIT/reconstruction/include/FITReconstruction/RecPoints.h b/Detectors/FIT/T0/reconstruction/include/T0Reconstruction/RecPoints.h similarity index 80% rename from Detectors/FIT/reconstruction/include/FITReconstruction/RecPoints.h rename to Detectors/FIT/T0/reconstruction/include/T0Reconstruction/RecPoints.h index b61266b27d17e..324b199387a3f 100644 --- a/Detectors/FIT/reconstruction/include/FITReconstruction/RecPoints.h +++ b/Detectors/FIT/T0/reconstruction/include/T0Reconstruction/RecPoints.h @@ -21,7 +21,7 @@ namespace o2 { -namespace fit +namespace t0 { struct Channel { Int_t index; @@ -34,7 +34,7 @@ class RecPoints RecPoints() = default; RecPoints(const std::array& collisiontime, Float_t vertex, - std::vector timeamp) + std::vector timeamp) : mCollisionTime(collisiontime), mVertex(vertex), mTimeAmp(std::move(timeamp)) @@ -42,7 +42,7 @@ class RecPoints } ~RecPoints() = default; - void FillFromDigits(const Digit& digit); + void FillFromDigits(const o2::fit::Digit& digit); Float_t GetCollisionTime(int side) const { return mCollisionTime[side]; } void setCollisionTime(Float_t time, int side) { mCollisionTime[side] = time; } @@ -56,20 +56,20 @@ class RecPoints void setBC(Int_t bc) { mBC = bc; } void setOrbit(Int_t orbit) { mOrbit = orbit; } - const std::vector& getChDgData() const { return mTimeAmp; } - void setChDgData(const std::vector& TimeAmp) { mTimeAmp = TimeAmp; } - void setChDgData(std::vector&& TimeAmp) { mTimeAmp = std::move(TimeAmp); } + const std::vector& getChDgData() const { return mTimeAmp; } + void setChDgData(const std::vector& TimeAmp) { mTimeAmp = TimeAmp; } + void setChDgData(std::vector&& TimeAmp) { mTimeAmp = std::move(TimeAmp); } private: std::array mCollisionTime; Float_t mVertex = 0; Double_t mEventTime; //event time from Fair for continuous - std::vector mTimeAmp; + std::vector mTimeAmp; Int_t mBC = 0; // BC from digits Int_t mOrbit = 0; // orbit from digits ClassDefNV(RecPoints, 1); }; -} // namespace fit +} // namespace t0 } // namespace o2 #endif diff --git a/Detectors/FIT/reconstruction/src/CollisionTimeRecoTask.cxx b/Detectors/FIT/T0/reconstruction/src/CollisionTimeRecoTask.cxx similarity index 86% rename from Detectors/FIT/reconstruction/src/CollisionTimeRecoTask.cxx rename to Detectors/FIT/T0/reconstruction/src/CollisionTimeRecoTask.cxx index 97bcad7286348..db42d06de8cab 100644 --- a/Detectors/FIT/reconstruction/src/CollisionTimeRecoTask.cxx +++ b/Detectors/FIT/T0/reconstruction/src/CollisionTimeRecoTask.cxx @@ -11,10 +11,10 @@ /// \file CollisionTimeRecoTask.cxx /// \brief Implementation of the FIT reconstruction task -#include "FITReconstruction/CollisionTimeRecoTask.h" -#include "FairLogger.h" // for LOG - +#include "T0Reconstruction/CollisionTimeRecoTask.h" +#include "FairLogger.h" // for LOG +using namespace o2::t0; using namespace o2::fit; /* //_____________________________________________________________________ @@ -29,7 +29,7 @@ CollisionTimeRecoTask::CollisionTimeRecoTask() void CollisionTimeRecoTask::Process(const Digit& digits, RecPoints& recPoints) const { - LOG(INFO) << "Running reconstruction on new event" << FairLogger::endl; + // LOG(INFO) << "Running reconstruction on new event" << FairLogger::endl; recPoints.FillFromDigits(digits); } //________________________________________________________ diff --git a/Detectors/FIT/T0/reconstruction/src/RecPoints.cxx b/Detectors/FIT/T0/reconstruction/src/RecPoints.cxx new file mode 100644 index 0000000000000..be86dd75bd00f --- /dev/null +++ b/Detectors/FIT/T0/reconstruction/src/RecPoints.cxx @@ -0,0 +1,62 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "T0Reconstruction/RecPoints.h" +#include "T0Base/Geometry.h" +#include +#include +#include + +using namespace o2::t0; +using namespace o2::fit; + +ClassImp(o2::t0::RecPoints); + +void RecPoints::FillFromDigits(const o2::fit::Digit& digit) +{ + mCollisionTime = {}; + + Int_t ndigitsC = 0, ndigitsA = 0; + constexpr Int_t nMCPsA = 4 * o2::t0::Geometry::NCellsA; + constexpr Int_t nMCPsC = 4 * o2::t0::Geometry::NCellsC; + constexpr Int_t nMCPs = nMCPsA + nMCPsC; + Float_t sideAtime = 0, sideCtime = 0; + + mBC = digit.getBC(); + mOrbit = digit.getOrbit(); + mEventTime = o2::InteractionRecord::bc2ns(mBC, mOrbit); + + Float_t BCEventTime = 12.5; + + mTimeAmp = digit.getChDgData(); + for (auto& d : mTimeAmp) { + d.CFDTime -= mEventTime /*- BCEventTime*/; + if (abs(d.CFDTime - BCEventTime) < 2) { + if (d.ChId < nMCPsA) { + sideAtime += d.CFDTime; + ndigitsA++; + } else { + sideCtime += d.CFDTime; + ndigitsC++; + } + } + } + + if (ndigitsA > 0) + mCollisionTime[1] = sideAtime / Float_t(ndigitsA); + + if (ndigitsC > 0) + mCollisionTime[2] = sideCtime / Float_t(ndigitsC); + + if (ndigitsA > 0 && ndigitsC > 0) { + mVertex = (mCollisionTime[1] - mCollisionTime[2]) / 2.; + mCollisionTime[0] = (mCollisionTime[1] + mCollisionTime[2]) / 2.; + } +} diff --git a/Detectors/FIT/T0/reconstruction/src/T0ReconstructionLinkDef.h b/Detectors/FIT/T0/reconstruction/src/T0ReconstructionLinkDef.h new file mode 100644 index 0000000000000..a8d4cc4b2a857 --- /dev/null +++ b/Detectors/FIT/T0/reconstruction/src/T0ReconstructionLinkDef.h @@ -0,0 +1,23 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifdef __CLING__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class o2::t0::CollisionTimeRecoTask + ; +#pragma link C++ class o2::t0::RecPoints + ; +#pragma link C++ class std::vector < o2::t0::RecPoints > +; + +#pragma link C++ class o2::t0::Channel + ; + +#endif diff --git a/Detectors/FIT/T0/simulation/CMakeLists.txt b/Detectors/FIT/T0/simulation/CMakeLists.txt new file mode 100644 index 0000000000000..e70cf0c0ae85a --- /dev/null +++ b/Detectors/FIT/T0/simulation/CMakeLists.txt @@ -0,0 +1,19 @@ +set(MODULE_NAME "T0Simulation") + +O2_SETUP(NAME ${MODULE_NAME}) + +set(SRCS + src/Detector.cxx + #src/DigitizerTask.cxx + ) + +set(HEADERS + include/${MODULE_NAME}/Detector.h + #include/${MODULE_NAME}/DigitizerTask.h + ) + +Set(LINKDEF src/T0SimulationLinkDef.h) +Set(LIBRARY_NAME ${MODULE_NAME}) +set(BUCKET_NAME fit_simulation_bucket) + +O2_GENERATE_LIBRARY() diff --git a/Detectors/FIT/simulation/include/FITSimulation/Detector.h b/Detectors/FIT/T0/simulation/include/T0Simulation/Detector.h similarity index 84% rename from Detectors/FIT/simulation/include/FITSimulation/Detector.h rename to Detectors/FIT/T0/simulation/include/T0Simulation/Detector.h index 7651614ae2800..8a935f4a8c6be 100644 --- a/Detectors/FIT/simulation/include/FITSimulation/Detector.h +++ b/Detectors/FIT/T0/simulation/include/T0Simulation/Detector.h @@ -11,13 +11,13 @@ /// \file Detector.h /// \brief Definition of the Detector class -#ifndef ALICEO2_FIT_DETECTOR_H_ -#define ALICEO2_FIT_DETECTOR_H_ +#ifndef ALICEO2_T0_DETECTOR_H_ +#define ALICEO2_T0_DETECTOR_H_ #include "SimulationDataFormat/BaseHits.h" #include "DetectorsBase/Detector.h" // for Detector -#include "FITBase/Geometry.h" -#include "CommonUtils/ShmAllocator.h" +#include "T0Base/Geometry.h" +#include "FITSimulation/HitType.h" class FairModule; @@ -27,29 +27,7 @@ class TGraph; namespace o2 { -namespace fit -{ -class HitType : public o2::BasicXYZEHit -{ - public: - using BasicXYZEHit::BasicXYZEHit; -}; -} // namespace fit -} // namespace o2 - -#ifdef USESHM -namespace std -{ -template <> -class allocator : public o2::utils::ShmAllocator -{ -}; -} // namespace std -#endif - -namespace o2 -{ -namespace fit +namespace t0 { class Geometry; } @@ -57,7 +35,7 @@ class Geometry; namespace o2 { -namespace fit +namespace t0 { // using HitType = o2::BasicXYZEHit; class Geometry; @@ -91,11 +69,11 @@ class Detector : public o2::Base::DetImpl /// This method is called for each step during simulation (see FairMCApplication::Stepping()) Bool_t ProcessHits(FairVolume* v) override; - HitType* AddHit(float x, float y, float z, float time, float energy, Int_t trackId, Int_t detId); + o2::fit::HitType* AddHit(float x, float y, float z, float time, float energy, Int_t trackId, Int_t detId); void Register() override; - std::vector* getHits(Int_t iColl) + std::vector* getHits(Int_t iColl) { if (iColl == 0) { return mHits; @@ -151,7 +129,7 @@ class Detector : public o2::Base::DetImpl std::vector mReflMet; /// Container for data points - std::vector* mHits = nullptr; + std::vector* mHits = nullptr; /// Define the sensitive volumes of the geometry void defineSensitiveVolumes(); @@ -169,7 +147,7 @@ class Detector : public o2::Base::DetImpl std::ostream& operator<<(std::ostream& os, Detector& source); std::istream& operator>>(std::istream& os, Detector& source); -} // namespace fit +} // namespace t0 } // namespace o2 #ifdef USESHM @@ -178,7 +156,7 @@ namespace o2 namespace Base { template <> -struct UseShm { +struct UseShm { static constexpr bool value = true; }; } // namespace Base diff --git a/Detectors/FIT/T0/simulation/include/T0Simulation/DigitizationParameters.h b/Detectors/FIT/T0/simulation/include/T0Simulation/DigitizationParameters.h new file mode 100644 index 0000000000000..631164a592bdb --- /dev/null +++ b/Detectors/FIT/T0/simulation/include/T0Simulation/DigitizationParameters.h @@ -0,0 +1,27 @@ +#ifndef ALICEO2_T0_DIGITIZATION_PARAMETERS +#define ALICEO2_T0_DIGITIZATION_PARAMETERS +#include +#include + +namespace o2::t0 +{ +inline o2::fit::DigitizationParameters T0DigitizationParameters() +{ + o2::fit::DigitizationParameters result; + result.NCellsA = Geometry::NCellsA; + result.NCellsC = Geometry::NCellsC; + result.ZdetA = Geometry::ZdetA; + result.ZdetC = Geometry::ZdetC; + result.ChannelWidth = Geometry::ChannelWidth; + result.mBC_clk_center = 12.5; // clk center + result.mMCPs = (Geometry::NCellsA + Geometry::NCellsC) * 4; //number of MCPs + result.mCFD_trsh_mip = 0.4; // = 4[mV] / 10[mV/mip] + result.mTime_trg_gate = 4.; // ns + result.mAmpThreshold = 100; // number of photoelectrons + result.mTimeDiffAC = (Geometry::ZdetA - Geometry::ZdetC) * TMath::C(); + result.mIsT0 = true; + + return result; +} +} // namespace o2::t0 +#endif diff --git a/Detectors/FIT/simulation/include/FITSimulation/DigitizerTask.h b/Detectors/FIT/T0/simulation/include/T0Simulation/DigitizerTask.h similarity index 85% rename from Detectors/FIT/simulation/include/FITSimulation/DigitizerTask.h rename to Detectors/FIT/T0/simulation/include/T0Simulation/DigitizerTask.h index 5dcc1e00c98d0..2d0f13fcdecb9 100644 --- a/Detectors/FIT/simulation/include/FITSimulation/DigitizerTask.h +++ b/Detectors/FIT/T0/simulation/include/T0Simulation/DigitizerTask.h @@ -18,7 +18,7 @@ #include "Rtypes.h" // for DigitizerTask::Class, ClassDef, etc #include "FITBase/Digit.h" -#include "FITSimulation/Detector.h" // for HitType +#include "T0Simulation/Detector.h" // for HitType #include "FITSimulation/Digitizer.h" #include "SimulationDataFormat/MCTruthContainer.h" #include "SimulationDataFormat/MCCompLabel.h" @@ -26,7 +26,7 @@ namespace o2 { -namespace fit +namespace t0 { class DigitizerTask : public FairTask @@ -54,10 +54,10 @@ class DigitizerTask : public FairTask Bool_t mContinuous = kFALSE; ///< flag to do continuous simulation double mFairTimeUnitInNS = 1; ///< Fair time unit in ns - Int_t mSourceID = 0; ///< current source - Int_t mEventID = 0; ///< current event id from the source - Digitizer mDigitizer; ///< Digitizer - const std::vector* mHitsArray = nullptr; ///< Array of MC hits + Int_t mSourceID = 0; ///< current source + Int_t mEventID = 0; ///< current event id from the source + Digitizer mDigitizer; ///< Digitizer + const std::vector* mHitsArray = nullptr; ///< Array of MC hits TBranch* mQEDBranch = nullptr; //! optional special branch of hits from QED collitions const std::vector* mHitsArrayQED = nullptr; //! array of MC hits from ED @@ -66,13 +66,13 @@ class DigitizerTask : public FairTask int mLastQEDEntry = -1; ///< last used QED entry UChar_t mQEDSourceID = 0; ///< MC ID source of the QED (stored in the labels) - Digit* mEventDigit = nullptr; + o2::fit::Digit* mEventDigit = nullptr; o2::dataformats::MCTruthContainer mMCTruthArray; //! Labels containter o2::dataformats::MCTruthContainer* mMCTruthArrayPtr = &mMCTruthArray; //! Labels containter pointer ClassDefOverride(DigitizerTask, 1); }; -} // namespace fit +} // namespace t0 } // namespace o2 #endif /* ALICEO2_TOF_DIGITIZERTASK_H */ diff --git a/Detectors/FIT/simulation/src/Detector.cxx b/Detectors/FIT/T0/simulation/src/Detector.cxx similarity index 97% rename from Detectors/FIT/simulation/src/Detector.cxx rename to Detectors/FIT/T0/simulation/src/Detector.cxx index 9bd812cda3de0..6c7ec8bb9bc26 100644 --- a/Detectors/FIT/simulation/src/Detector.cxx +++ b/Detectors/FIT/T0/simulation/src/Detector.cxx @@ -24,17 +24,17 @@ #include "FairVolume.h" #include -#include "FITBase/Geometry.h" -#include "FITSimulation/Detector.h" +#include "T0Base/Geometry.h" +#include "T0Simulation/Detector.h" #include "SimulationDataFormat/Stack.h" -using namespace o2::fit; -using o2::fit::Geometry; +using namespace o2::t0; +using o2::t0::Geometry; ClassImp(Detector); Detector::Detector(Bool_t Active) - : o2::Base::DetImpl("FIT", Active), mIdSens1(0), mPMTeff(nullptr), mHits(o2::utils::createSimVector()) + : o2::Base::DetImpl("T0", Active), mIdSens1(0), mPMTeff(nullptr), mHits(o2::utils::createSimVector()) { // Gegeo = GetGeometry() ; @@ -43,7 +43,7 @@ Detector::Detector(Bool_t Active) } Detector::Detector(const Detector& rhs) - : o2::Base::DetImpl(rhs), mIdSens1(rhs.mIdSens1), mPMTeff(rhs.mPMTeff), mHits(o2::utils::createSimVector()) + : o2::Base::DetImpl(rhs), mIdSens1(rhs.mIdSens1), mPMTeff(rhs.mPMTeff), mHits(o2::utils::createSimVector()) { } @@ -66,7 +66,7 @@ void Detector::InitializeO2Detector() void Detector::ConstructGeometry() { - LOG(DEBUG) << "Creating FIT geometry\n"; + LOG(DEBUG) << "Creating FIT T0 geometry\n"; CreateMaterials(); Float_t zdetA = 333; @@ -309,7 +309,7 @@ Bool_t Detector::ProcessHits(FairVolume* v) return kFALSE; } -HitType* Detector::AddHit(float x, float y, float z, float time, float energy, Int_t trackId, Int_t detId) +o2::fit::HitType* Detector::AddHit(float x, float y, float z, float time, float energy, Int_t trackId, Int_t detId) { mHits->emplace_back(x, y, z, time, energy, trackId, detId); auto stack = (o2::Data::Stack*)fMC->GetStack(); @@ -384,7 +384,7 @@ void Detector::DefineOpticalProperties() const char* aliceO2env = std::getenv("O2_ROOT"); if (aliceO2env) inputDir = aliceO2env; - inputDir += "/share/Detectors/FIT/files/"; + inputDir += "/share/Detectors/T0/files/"; TString optPropPath = inputDir + "quartzOptProperties.txt"; optPropPath = gSystem->ExpandPathName(optPropPath.Data()); // Expand $(ALICE_ROOT) into real system path diff --git a/Detectors/FIT/simulation/src/DigitizerTask.cxx b/Detectors/FIT/T0/simulation/src/DigitizerTask.cxx similarity index 94% rename from Detectors/FIT/simulation/src/DigitizerTask.cxx rename to Detectors/FIT/T0/simulation/src/DigitizerTask.cxx index 938b0c8148cfe..7492dc367ab6f 100644 --- a/Detectors/FIT/simulation/src/DigitizerTask.cxx +++ b/Detectors/FIT/T0/simulation/src/DigitizerTask.cxx @@ -11,17 +11,18 @@ /// \file DigitizerTask.cxx /// \brief Implementation of the TOF digitizer task -#include "FITSimulation/DigitizerTask.h" +#include "T0Simulation/DigitizerTask.h" #include "MathUtils/Utils.h" #include "FairLogger.h" // for LOG #include "FairRootManager.h" // for FairRootManager -ClassImp(o2::fit::DigitizerTask); +ClassImp(o2::t0::DigitizerTask); using namespace o2::fit; +using namespace o2::t0; -DigitizerTask::DigitizerTask() : FairTask("FITDigitizerTask"), mDigitizer() {} +DigitizerTask::DigitizerTask() : FairTask("T0DigitizerTask"), mDigitizer() {} DigitizerTask::~DigitizerTask() { if (mEventDigit) @@ -49,7 +50,7 @@ InitStatus DigitizerTask::Init() mDigitizer.setMCLabels(mMCTruthArrayPtr); // Register output container - mgr->RegisterAny("FITDigit", mEventDigit, kTRUE); + mgr->RegisterAny("FITT0Digit", mEventDigit, kTRUE); // mMCTruthArray = new typename std::remove_pointer::type; mgr->RegisterAny("FITDigitMCTruth", mMCTruthArrayPtr, kTRUE); mDigitizer.init(); @@ -96,7 +97,6 @@ void DigitizerTask::FinishTask() mgr->SetLastFill(kTRUE); /// necessary, otherwise the data is not written out mDigitizer.finish(); - } //________________________________________________________ void DigitizerTask::processQEDBackground(double tMax) diff --git a/Detectors/FIT/T0/simulation/src/T0SimulationLinkDef.h b/Detectors/FIT/T0/simulation/src/T0SimulationLinkDef.h new file mode 100644 index 0000000000000..57f5c478301ad --- /dev/null +++ b/Detectors/FIT/T0/simulation/src/T0SimulationLinkDef.h @@ -0,0 +1,20 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifdef __CLING__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class o2::t0::Detector + ; +#pragma link C++ class o2::Base::DetImpl < o2::t0::Detector > +; + +#endif diff --git a/Detectors/FIT/common/CMakeLists.txt b/Detectors/FIT/common/CMakeLists.txt new file mode 100644 index 0000000000000..32a36ff118835 --- /dev/null +++ b/Detectors/FIT/common/CMakeLists.txt @@ -0,0 +1,4 @@ +# Libraries +add_subdirectory(base) +add_subdirectory(simulation) +#add_subdirectory(reconstruction) diff --git a/Detectors/FIT/base/CMakeLists.txt b/Detectors/FIT/common/base/CMakeLists.txt similarity index 69% rename from Detectors/FIT/base/CMakeLists.txt rename to Detectors/FIT/common/base/CMakeLists.txt index 2c41f4b4ed87f..e0ad1e42cafff 100644 --- a/Detectors/FIT/base/CMakeLists.txt +++ b/Detectors/FIT/common/base/CMakeLists.txt @@ -3,23 +3,18 @@ set(MODULE_NAME "FITBase") O2_SETUP(NAME ${MODULE_NAME}) set(SRCS - src/Geometry.cxx src/Digit.cxx ) set(HEADERS - include/${MODULE_NAME}/Geometry.h include/${MODULE_NAME}/Digit.h + include/${MODULE_NAME}/MCLabel.h ) - Set(LINKDEF src/FITBaseLinkDef.h) Set(LIBRARY_NAME ${MODULE_NAME}) set(BUCKET_NAME fit_base_bucket) O2_GENERATE_LIBRARY() -install( - DIRECTORY files - DESTINATION share/Detectors/FIT/ -) + diff --git a/Detectors/FIT/base/include/FITBase/Digit.h b/Detectors/FIT/common/base/include/FITBase/Digit.h similarity index 95% rename from Detectors/FIT/base/include/FITBase/Digit.h rename to Detectors/FIT/common/base/include/FITBase/Digit.h index f2e17419a4b36..430371fd41dff 100644 --- a/Detectors/FIT/base/include/FITBase/Digit.h +++ b/Detectors/FIT/common/base/include/FITBase/Digit.h @@ -24,7 +24,8 @@ struct ChannelData { Int_t ChId; //channel Id Double_t CFDTime; //time in ns, 0 at lhc clk center Double_t QTCAmpl; // Amplitude in mips - ClassDefNV(ChannelData, 1); + int numberOfParticles; + ClassDefNV(ChannelData, 2); }; /// \class Digit @@ -71,6 +72,7 @@ class Digit : public DigitBase } const std::vector& getChDgData() const { return mChDgDataArr; } + std::vector& getChDgData() { return mChDgDataArr; } void setChDgData(const std::vector& ChDgDataArr) { mChDgDataArr = ChDgDataArr; } void setChDgData(std::vector&& ChDgDataArr) { mChDgDataArr = std::move(ChDgDataArr); } diff --git a/Detectors/FIT/simulation/include/FITSimulation/MCLabel.h b/Detectors/FIT/common/base/include/FITBase/MCLabel.h similarity index 100% rename from Detectors/FIT/simulation/include/FITSimulation/MCLabel.h rename to Detectors/FIT/common/base/include/FITBase/MCLabel.h diff --git a/Detectors/FIT/base/src/Digit.cxx b/Detectors/FIT/common/base/src/Digit.cxx similarity index 100% rename from Detectors/FIT/base/src/Digit.cxx rename to Detectors/FIT/common/base/src/Digit.cxx diff --git a/Detectors/FIT/base/src/FITBaseLinkDef.h b/Detectors/FIT/common/base/src/FITBaseLinkDef.h similarity index 90% rename from Detectors/FIT/base/src/FITBaseLinkDef.h rename to Detectors/FIT/common/base/src/FITBaseLinkDef.h index 0953222bedcae..6f296f68a0a68 100644 --- a/Detectors/FIT/base/src/FITBaseLinkDef.h +++ b/Detectors/FIT/common/base/src/FITBaseLinkDef.h @@ -14,8 +14,7 @@ #pragma link off all classes; #pragma link off all functions; -#pragma link C++ class o2::fit::Geometry+; -#pragma link C++ class o2::fit::Digit+; +#pragma link C++ class o2::fit::Digit + ; #pragma link C++ class o2::fit::ChannelData + ; #pragma link C++ class vector < o2::fit::ChannelData > +; #pragma link C++ class vector < o2::fit::Digit > +; diff --git a/Detectors/FIT/simulation/CMakeLists.txt b/Detectors/FIT/common/simulation/CMakeLists.txt similarity index 63% rename from Detectors/FIT/simulation/CMakeLists.txt rename to Detectors/FIT/common/simulation/CMakeLists.txt index d62bdd9ff067c..5bd07c681e44e 100644 --- a/Detectors/FIT/simulation/CMakeLists.txt +++ b/Detectors/FIT/common/simulation/CMakeLists.txt @@ -3,20 +3,19 @@ set(MODULE_NAME "FITSimulation") O2_SETUP(NAME ${MODULE_NAME}) set(SRCS - src/Detector.cxx src/Digitizer.cxx - src/DigitizerTask.cxx - ) + ) set(HEADERS - include/${MODULE_NAME}/Detector.h include/${MODULE_NAME}/Digitizer.h - include/${MODULE_NAME}/DigitizerTask.h - include/${MODULE_NAME}/MCLabel.h + include/${MODULE_NAME}/DigitizationParameters.h ) + Set(LINKDEF src/FITSimulationLinkDef.h) Set(LIBRARY_NAME ${MODULE_NAME}) set(BUCKET_NAME fit_simulation_bucket) O2_GENERATE_LIBRARY() + + diff --git a/Detectors/FIT/common/simulation/include/FITSimulation/DigitizationParameters.h b/Detectors/FIT/common/simulation/include/FITSimulation/DigitizationParameters.h new file mode 100644 index 0000000000000..7f2a08144144f --- /dev/null +++ b/Detectors/FIT/common/simulation/include/FITSimulation/DigitizationParameters.h @@ -0,0 +1,23 @@ +#ifndef ALICEO2_FIT_DIGITIZATION_PARAMETERS +#define ALICEO2_FIT_DIGITIZATION_PARAMETERS + +namespace o2::fit +{ +struct DigitizationParameters { + int NCellsA; // number of radiatiors on A side + int NCellsC; // number of radiatiors on C side + float ZdetA; // number of radiatiors on A side + float ZdetC; // number of radiatiors on C side + float ChannelWidth; // channel width in ps + + Float_t mBC_clk_center; // clk center + Int_t mMCPs; //number of MCPs + Float_t mCFD_trsh_mip; // = 4[mV] / 10[mV/mip] + Float_t mTime_trg_gate; // ns + Int_t mAmpThreshold; // number of photoelectrons + Float_t mTimeDiffAC; + bool mIsT0; //amplitude T0(true) or V0 (false) + +}; +} // namespace o2::fit +#endif diff --git a/Detectors/FIT/simulation/include/FITSimulation/Digitizer.h b/Detectors/FIT/common/simulation/include/FITSimulation/Digitizer.h similarity index 73% rename from Detectors/FIT/simulation/include/FITSimulation/Digitizer.h rename to Detectors/FIT/common/simulation/include/FITSimulation/Digitizer.h index 1b8815a1ba2b3..7f8c4f7d3add0 100644 --- a/Detectors/FIT/simulation/include/FITSimulation/Digitizer.h +++ b/Detectors/FIT/common/simulation/include/FITSimulation/Digitizer.h @@ -12,10 +12,11 @@ #define ALICEO2_FIT_DIGITIZER_H #include "FITBase/Digit.h" -#include "FITSimulation/Detector.h" +#include "T0Simulation/Detector.h" #include "SimulationDataFormat/MCTruthContainer.h" #include "SimulationDataFormat/MCCompLabel.h" #include "FITSimulation/MCLabel.h" +#include "FITSimulation/DigitizationParameters.h" namespace o2 { @@ -24,11 +25,12 @@ namespace fit class Digitizer { public: - Digitizer(Int_t mode = 0) : mMode(mode) { initParameters(); }; + Digitizer(const DigitizationParameters& params, Int_t mode = 0) : mMode(mode), parameters(params) { initParameters(); }; ~Digitizer() = default; //void process(const std::vector* hits, std::vector* digits); - void process(const std::vector* hits, Digit* digit); + void process(const std::vector* hits, Digit* digit); + void computeAverage(Digit& digit); void initParameters(); // void printParameters(); @@ -56,12 +58,7 @@ class Digitizer Int_t mSrcID; // signal, background or QED Double_t mEventTime; // timestamp - Float_t mBC_clk_center = 12.5; // clk center - Int_t mMCPs = (Geometry::NCellsA + Geometry::NCellsC) * 4; //number of MCPs - Float_t mCFD_trsh_mip = 0.4; // = 4[mV] / 10[mV/mip] - Float_t mTime_trg_gate = 4.; // ns - Int_t mAmpThreshold = 100; // number of photoelectrons - Float_t mTimeDiffAC = (Geometry::ZdetA - Geometry::ZdetC) * TMath::C(); + DigitizationParameters parameters; o2::dataformats::MCTruthContainer* mMCLabels = nullptr; diff --git a/Detectors/FIT/common/simulation/include/FITSimulation/HitType.h b/Detectors/FIT/common/simulation/include/FITSimulation/HitType.h new file mode 100644 index 0000000000000..94f166f188a88 --- /dev/null +++ b/Detectors/FIT/common/simulation/include/FITSimulation/HitType.h @@ -0,0 +1,31 @@ +#ifndef ALICEO2_FIT_HITTYPE_H_ +#define ALICEO2_FIT_HITTYPE_H_ + +#include "SimulationDataFormat/BaseHits.h" +#include "SimulationDataFormat/Stack.h" +#include "CommonUtils/ShmAllocator.h" + +namespace o2 +{ +namespace fit +{ +class HitType : public o2::BasicXYZEHit +{ + public: + using BasicXYZEHit::BasicXYZEHit; +}; +} // namespace fit + +} // namespace o2 + +#endif + +#ifdef USESHM +namespace std +{ +template <> +class allocator : public o2::utils::ShmAllocator +{ +}; +} // namespace std +#endif diff --git a/Detectors/FIT/simulation/src/Digitizer.cxx b/Detectors/FIT/common/simulation/src/Digitizer.cxx similarity index 65% rename from Detectors/FIT/simulation/src/Digitizer.cxx rename to Detectors/FIT/common/simulation/src/Digitizer.cxx index 3820a6527a4f5..bf067050b01bd 100644 --- a/Detectors/FIT/simulation/src/Digitizer.cxx +++ b/Detectors/FIT/common/simulation/src/Digitizer.cxx @@ -9,7 +9,7 @@ // or submit itself to any jurisdiction. #include "FITSimulation/Digitizer.h" -#include "FITSimulation/MCLabel.h" +#include "FITBase/MCLabel.h" #include "SimulationDataFormat/MCTruthContainer.h" #include @@ -20,18 +20,18 @@ #include using namespace o2::fit; -using o2::fit::Geometry; +//using o2::fit::Geometry; ClassImp(Digitizer); -void Digitizer::process(const std::vector* hits, Digit* digit) +void Digitizer::process(const std::vector* hits, Digit* digit) + { //parameters constants TO DO: move to class - constexpr Float_t C_side_cable_cmps = 2.8; //ns - constexpr Float_t A_side_cable_cmps = 11.; //ns - constexpr Float_t signal_width = 5.; // time gate for signal, ns - constexpr Float_t nPe_in_mip = 250.; // n ph. e. in one mip + constexpr Float_t C_side_cable_cmps = 2.877; //ns + constexpr Float_t A_side_cable_cmps = 11.08; //ns + constexpr Float_t signal_width = 5.; // time gate for signal, ns Int_t nlbl = 0; //number of MCtrues @@ -40,15 +40,17 @@ void Digitizer::process(const std::vector* hits, Digit* digit) digit->setOrbit(mOrbit); //Calculating signal time, amplitude in mean_time +- time_gate -------------- - Double_t cfd[300] = {}; - Float_t amp[300] = {}; - Int_t ch_signal_nPe[300] = {}; - Double_t ch_signal_MIP[300] = {}; - Double_t ch_signal_time[300] = {}; + std::vector& channel_data = digit->getChDgData(); + if (channel_data.size() == 0) { + channel_data.reserve(parameters.mMCPs); + for (int i = 0; i < parameters.mMCPs; ++i) + channel_data.emplace_back(ChannelData{ i, 0, 0, 0 }); + } + assert(digit->getChDgData().size() == parameters.mMCPs); for (auto& hit : *hits) { Int_t hit_ch = hit.GetDetectorID(); Double_t hit_time = hit.GetTime(); - Bool_t is_A_side = (hit_ch <= 4 * Geometry::NCellsA); + Bool_t is_A_side = (hit_ch <= 4 * parameters.NCellsA); Float_t time_compensate = is_A_side ? A_side_cable_cmps : C_side_cable_cmps; Bool_t is_hit_in_signal_gate = (hit_time > time_compensate - signal_width * .5) && @@ -56,9 +58,10 @@ void Digitizer::process(const std::vector* hits, Digit* digit) Double_t hit_time_corr = hit_time - time_compensate /* + mBC_clk_center + mEventTime*/; - if (/*is_time_in_gate &&*/ is_hit_in_signal_gate) { - ch_signal_nPe[hit_ch]++; - ch_signal_time[hit_ch] += hit_time_corr; + if (is_hit_in_signal_gate) { + channel_data[hit_ch].numberOfParticles++; + channel_data[hit_ch].QTCAmpl += hit.GetEnergyLoss(); + channel_data[hit_ch].CFDTime += hit_time_corr; } //charge particles in MCLabel @@ -72,37 +75,24 @@ void Digitizer::process(const std::vector* hits, Digit* digit) } } } +} - // sum different sources - std::vector mChDgDataArr; - for (const auto& d : digit->getChDgData()) { - Int_t mcp = d.ChId; - cfd[mcp] = d.CFDTime; - amp[mcp] = d.QTCAmpl; - } - - for (Int_t ch_iter = 0; ch_iter < mMCPs; ch_iter++) { - if (ch_signal_nPe[ch_iter] != 0) { - ch_signal_MIP[ch_iter] = amp[ch_iter] + ch_signal_nPe[ch_iter] / nPe_in_mip; - if (cfd[ch_iter] > 0) { - cfd[ch_iter] = cfd[ch_iter] - mBC_clk_center - mEventTime; - ch_signal_time[ch_iter] = ((cfd[ch_iter] + ch_signal_time[ch_iter] / (float)ch_signal_nPe[ch_iter]) / 2.) + mBC_clk_center + mEventTime; - } else - ch_signal_time[ch_iter] = (ch_signal_time[ch_iter] / (float)ch_signal_nPe[ch_iter]) + mBC_clk_center + mEventTime; - - if (ch_signal_MIP[ch_iter] > mCFD_trsh_mip) { - LOG(DEBUG) << ch_iter << " : " - << " : " << ch_signal_time[ch_iter] - mBC_clk_center - mEventTime << " : " - << ch_signal_MIP[ch_iter] << " : " << mEventTime << " cfd " << cfd[ch_iter] << FairLogger::endl; - mChDgDataArr.emplace_back(ChannelData{ ch_iter, ch_signal_time[ch_iter], ch_signal_MIP[ch_iter] }); - } else { - ch_signal_MIP[ch_iter] = 0; - ch_signal_time[ch_iter] = 0; - } - } +void Digitizer::computeAverage(Digit& digit) +{ + constexpr Float_t nPe_in_mip = 250.; // n ph. e. in one mip + auto& channel_data = digit.getChDgData(); + for (auto& ch_data : channel_data) { + if (ch_data.numberOfParticles == 0) + continue; + ch_data.CFDTime /= ch_data.numberOfParticles; + if (parameters.mIsT0) + ch_data.QTCAmpl = ch_data.numberOfParticles / nPe_in_mip; } - - digit->setChDgData(std::move(mChDgDataArr)); + channel_data.erase(std::remove_if(channel_data.begin(), channel_data.end(), + [this](ChannelData const& ch_data) { + return ch_data.QTCAmpl < parameters.mCFD_trsh_mip; + }), + channel_data.end()); } //------------------------------------------------------------------------ @@ -112,11 +102,12 @@ void Digitizer::smearCFDtime(Digit* digit) std::vector mChDgDataArr; for (const auto& d : digit->getChDgData()) { Int_t mcp = d.ChId; - Double_t cfd = d.CFDTime - mBC_clk_center - mEventTime; + Double_t cfd = d.CFDTime; Float_t amp = d.QTCAmpl; - if (amp > mCFD_trsh_mip) { - Double_t smeared_time = gRandom->Gaus(cfd, 0.050) + mBC_clk_center + mEventTime; - mChDgDataArr.emplace_back(ChannelData{ mcp, smeared_time, amp }); + int numpart = d.numberOfParticles; + if (amp > parameters.mCFD_trsh_mip) { + Double_t smeared_time = gRandom->Gaus(cfd, 0.050) + parameters.mBC_clk_center + mEventTime; + mChDgDataArr.emplace_back(ChannelData{ mcp, smeared_time, amp, numpart }); } } digit->setChDgData(std::move(mChDgDataArr)); @@ -143,14 +134,14 @@ void Digitizer::setTriggers(Digit* digit) Float_t amp[300] = {}; for (const auto& d : digit->getChDgData()) { Int_t mcp = d.ChId; - cfd[mcp] = d.CFDTime - mBC_clk_center - mEventTime; + cfd[mcp] = d.CFDTime; amp[mcp] = d.QTCAmpl; - if (amp[mcp] < mCFD_trsh_mip) + if (amp[mcp] < parameters.mCFD_trsh_mip) continue; - if (cfd[mcp] < -mTime_trg_gate / 2. || cfd[mcp] > mTime_trg_gate / 2.) + if (cfd[mcp] < -parameters.mTime_trg_gate / 2. || cfd[mcp] > parameters.mTime_trg_gate / 2.) continue; - Bool_t is_A_side = (mcp <= 4 * Geometry::NCellsA); + Bool_t is_A_side = (mcp <= 4 * parameters.NCellsA); if (is_A_side) { n_hit_A++; summ_ampl_A += amp[mcp]; @@ -193,17 +184,21 @@ void Digitizer::setTriggers(Digit* digit) void Digitizer::initParameters() { - mBC_clk_center = 12.5; // clk center - mMCPs = (Geometry::NCellsA + Geometry::NCellsC) * 4; - mCFD_trsh_mip = 0.4; // = 4[mV] / 10[mV/mip] - mTime_trg_gate = 4.; // ns - mAmpThreshold = 100; + /* + parameters.mBC_clk_center = 12.5; // clk center + parameters.mMCPs = (parameters.NCellsA + parameters.NCellsC) * 4; + parameters.mCFD_trsh_mip = 0.4; // = 4[mV] / 10[mV/mip] + parameters.mTime_trg_gate = 4.; // ns + parameters.mAmpThreshold = 100; + */ mEventTime = 0; // murmur } //_______________________________________________________________________ -void Digitizer::init() {} - +void Digitizer::init() +{ + std::cout << " @@@ Digitizer::init " << std::endl; +} //_______________________________________________________________________ void Digitizer::finish() {} /* diff --git a/Detectors/FIT/simulation/src/FITSimulationLinkDef.h b/Detectors/FIT/common/simulation/src/FITSimulationLinkDef.h similarity index 79% rename from Detectors/FIT/simulation/src/FITSimulationLinkDef.h rename to Detectors/FIT/common/simulation/src/FITSimulationLinkDef.h index 21d1780df2b38..16f71c6f7ff3d 100644 --- a/Detectors/FIT/simulation/src/FITSimulationLinkDef.h +++ b/Detectors/FIT/common/simulation/src/FITSimulationLinkDef.h @@ -14,14 +14,12 @@ #pragma link off all classes; #pragma link off all functions; -#pragma link C++ class o2::fit::Detector+; #pragma link C++ class o2::fit::Digitizer + ; -#pragma link C++ class o2::fit::DigitizerTask + ; +#pragma link C++ class o2::fit::DigitizationParameters + ; +#pragma link C++ class o2::fit::HitType + ; +#pragma link C++ class vector < o2::fit::HitType > +; #pragma link C++ class o2::fit::MCLabel + ; #pragma link C++ class o2::dataformats::MCTruthContainer < o2::fit::MCLabel > +; -#pragma link C++ class o2::fit::HitType + ; -#pragma link C++ class vector < o2::fit::HitType> + ; - -#pragma link C++ class o2::Base::DetImpl+; +#pragma link C++ class o2::Base::DetImpl < o2::fit::Detector > +; #endif diff --git a/Detectors/FIT/macros/run_reco_t0.C b/Detectors/FIT/macros/run_reco_t0.C new file mode 100644 index 0000000000000..0091998fdc53b --- /dev/null +++ b/Detectors/FIT/macros/run_reco_t0.C @@ -0,0 +1,72 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include +#include +#include +#include +#include +#include +#include + +#include "FairLogger.h" + +#include "T0Reconstruction/CollisionTimeRecoTask.h" +#include "T0Reconstruction/RecPoints.h" +#include "FITBase/Digit.h" +#endif + +void run_reco_t0(std::string inpudDig = "t0digits.root", + std::string outName = "o2reco_t0.root", + std::string inputGRP = "o2sim_grp.root") +{ + + // Initialize logger + FairLogger* logger = FairLogger::GetLogger(); + logger->SetLogVerbosityLevel("LOW"); + logger->SetLogScreenLevel("DEBUG"); + + // Setup timer + TStopwatch timer; + + TFile* fdig = TFile::Open("t0digits.root"); + std::cout << " Open digits file " << std::endl; + TTree* digTree = (TTree*)fdig->Get("o2sim"); + digTree->Print(); + std::vector* digits = new std::vector; + digTree->SetBranchAddress("T0Digit", &digits); + Int_t nevD = digTree->GetEntries(); // digits in cont. readout may be grouped as few events per entry + std::cout << "Found " << nevD << " events with digits " << std::endl; + + //std::vector recPoints; + std::vector* recPointsP = new std::vector; + + TFile outFile(outName.c_str(), "recreate"); + TTree outTree("o2sim", "T0RecPoints"); + outTree.Branch("T0Cluster", &recPointsP); + + o2::t0::CollisionTimeRecoTask recoFIT; + timer.Start(); + for (int iEv = 0; iEv < nevD; iEv++) { + digTree->GetEntry(iEv); + recPointsP->resize(digits->size()); + for (size_t collID = 0; collID < digits->size(); ++collID) + recoFIT.Process((*digits)[collID], (*recPointsP)[collID]); + outTree.Fill(); + } + + outTree.Print(); + outFile.ls(); + timer.Stop(); + outTree.Write(); + Double_t rtime = timer.RealTime(); + Double_t ctime = timer.CpuTime(); + + Float_t cpuUsage = ctime / rtime; + std::cout << ""; + std::cout << cpuUsage; + std::cout << "" << std::endl; + std::cout << "Macro finished succesfully." << std::endl; + + std::cout << "Real time " << rtime << " s, CPU time " << ctime + << "s" << std::endl + << std::endl; +} diff --git a/Detectors/FIT/reconstruction/src/RecPoints.cxx b/Detectors/FIT/reconstruction/src/RecPoints.cxx deleted file mode 100644 index 50aa761dc5991..0000000000000 --- a/Detectors/FIT/reconstruction/src/RecPoints.cxx +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright CERN and copyright holders of ALICE O2. This software is -// distributed under the terms of the GNU General Public License v3 (GPL -// Version 3), copied verbatim in the file "COPYING". -// -// See http://alice-o2.web.cern.ch/license for full licensing information. -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include "FITReconstruction/RecPoints.h" -#include "FITBase/Geometry.h" -#include -#include -#include - -using namespace o2::fit; - -ClassImp(o2::fit::RecPoints); - -void RecPoints::FillFromDigits(const Digit& digit) -{ - mTimeAmp.clear(); - mCollisionTime = {}; - - Int_t ndigitsC = 0, ndigitsA = 0; - constexpr Int_t nMCPsA = 4 * o2::fit::Geometry::NCellsA; - constexpr Int_t nMCPsC = 4 * o2::fit::Geometry::NCellsC; - constexpr Int_t nMCPs = nMCPsA + nMCPsC; - Float_t cfd[nMCPs] = {}, amp[nMCPs] = {}; - Float_t sideAtime = 0, sideCtime = 0; - - mBC = digit.getBC(); - mOrbit = digit.getOrbit(); - mEventTime = o2::InteractionRecord::bc2ns(mBC, mOrbit); - - Float_t BCEventTime = 12.5; - - for (const auto& d : digit.getChDgData()) { - Int_t mcp = d.ChId; - cfd[mcp] = d.CFDTime - mEventTime - BCEventTime; - amp[mcp] = d.QTCAmpl; - mTimeAmp.push_back(ChannelData{ mcp, cfd[mcp], amp[mcp] }); - // LOG(DEBUG) << " mcp " << mcp<<" time "<< cfd[mcp]<<" amplitude "<< amp[mcp] << FairLogger::endl; - } - - for (Int_t imcp = 0; imcp < nMCPsA; imcp++) { - if (cfd[imcp] > -2 && cfd[imcp] < 2) { - sideAtime += (cfd[imcp]); - ndigitsA++; - } - } - for (Int_t imcp = 0; imcp < nMCPsC; imcp++) { - if (cfd[imcp + nMCPsA] > 0) { - sideCtime += (cfd[imcp + nMCPsA]); - ndigitsC++; - } - } - if (ndigitsA > 0) - sideAtime = sideAtime / Float_t(ndigitsA); - if (ndigitsC > 0) - sideCtime = sideCtime / Float_t(ndigitsC); - - if (sideAtime > 0 && sideCtime > 0) { - mVertex = (sideAtime - sideCtime) / 2.; - mCollisionTime[0] = (sideAtime + sideCtime) / 2.; - } - if (sideAtime > 0) { - mCollisionTime[1] = sideAtime; - } - if (sideCtime > 0) { - mCollisionTime[2] = sideCtime; - } -} diff --git a/Detectors/FIT/simulation/include/FITSimulation/MCLabel.h~HEAD b/Detectors/FIT/simulation/include/FITSimulation/MCLabel.h~HEAD new file mode 100644 index 0000000000000..7a82415ec5e08 --- /dev/null +++ b/Detectors/FIT/simulation/include/FITSimulation/MCLabel.h~HEAD @@ -0,0 +1,39 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// Declaration of a transient MC label class for FIT + +#ifndef ALICEO2_FIT_MCLABEL_H_ +#define ALICEO2_FIT_MCLABEL_H_ + +#include "SimulationDataFormat/MCCompLabel.h" + +namespace o2 +{ +namespace fit +{ +class MCLabel : public o2::MCCompLabel +{ + private: + Int_t mDetID = -1; + + public: + MCLabel() = default; + MCLabel(Int_t trackID, Int_t eventID, Int_t srcID, Int_t qID) + : o2::MCCompLabel(trackID, eventID, srcID), mDetID(qID) {} + + Int_t getDetID() const { return mDetID; } + + ClassDefNV(MCLabel, 1); +}; +} // namespace fit +} // namespace o2 + +#endif diff --git a/Detectors/FIT/simulation/include/FITSimulation/MCLabel.h~e6c90292b4ea1ca164bf869789a6c1755aac715a b/Detectors/FIT/simulation/include/FITSimulation/MCLabel.h~e6c90292b4ea1ca164bf869789a6c1755aac715a new file mode 100644 index 0000000000000..7a82415ec5e08 --- /dev/null +++ b/Detectors/FIT/simulation/include/FITSimulation/MCLabel.h~e6c90292b4ea1ca164bf869789a6c1755aac715a @@ -0,0 +1,39 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// Declaration of a transient MC label class for FIT + +#ifndef ALICEO2_FIT_MCLABEL_H_ +#define ALICEO2_FIT_MCLABEL_H_ + +#include "SimulationDataFormat/MCCompLabel.h" + +namespace o2 +{ +namespace fit +{ +class MCLabel : public o2::MCCompLabel +{ + private: + Int_t mDetID = -1; + + public: + MCLabel() = default; + MCLabel(Int_t trackID, Int_t eventID, Int_t srcID, Int_t qID) + : o2::MCCompLabel(trackID, eventID, srcID), mDetID(qID) {} + + Int_t getDetID() const { return mDetID; } + + ClassDefNV(MCLabel, 1); +}; +} // namespace fit +} // namespace o2 + +#endif diff --git a/Steer/DigitizerWorkflow/src/FITDigitWriterSpec.cxx b/Steer/DigitizerWorkflow/src/FITDigitWriterSpec.cxx index fd16a3329e6d6..20b15710e4d46 100644 --- a/Steer/DigitizerWorkflow/src/FITDigitWriterSpec.cxx +++ b/Steer/DigitizerWorkflow/src/FITDigitWriterSpec.cxx @@ -8,19 +8,24 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// @brief Processor spec for a ROOT file writer for TOF digits +/// @brief Processor spec for a ROOT file writer for FIT T0&V0 digits #include "FITDigitWriterSpec.h" #include "Framework/CallbackService.h" #include "Framework/ControlService.h" -#include -#include -#include "TTree.h" -#include "TBranch.h" -#include "TFile.h" +#include "Framework/Task.h" #include "FITBase/Digit.h" +#include "Headers/DataHeader.h" +#include "DetectorsCommonDataFormats/DetID.h" +#include "SimulationDataFormat/MCTruthContainer.h" +#include "SimulationDataFormat/MCCompLabel.h" +#include +#include +#include #include // for make_shared, make_unique, unique_ptr #include +#include +#include using namespace o2::framework; using SubSpecificationType = o2::framework::DataAllocator::SubSpecificationType; @@ -30,88 +35,124 @@ namespace o2 namespace fit { -template -TBranch* getOrMakeBranch(TTree& tree, std::string brname, T* ptr) +class FITDPLDigitWriter { - if (auto br = tree.GetBranch(brname.c_str())) { - br->SetAddress(static_cast(&ptr)); - return br; + + using MCCont = o2::dataformats::MCTruthContainer; + + public: + void init(framework::InitContext& ic) + { + std::string detStrL = mID.getName(); + std::transform(detStrL.begin(), detStrL.end(), detStrL.begin(), ::tolower); + + auto filename = ic.options().get((detStrL + "-digit-outfile").c_str()); + auto treename = ic.options().get("treename"); + std::cout << " @@@ FITDPLDigitWriter " << detStrL << " file " << filename << " tree " << treename << std::endl; + + mOutFile = std::make_unique(filename.c_str(), "RECREATE"); + if (!mOutFile || mOutFile->IsZombie()) { + LOG(ERROR) << "Failed to open " << filename << " output file"; + } else { + LOG(INFO) << "Opened " << filename << " output file"; + } + mOutTree = std::make_unique(treename.c_str(), treename.c_str()); } - // otherwise make it - return tree.Branch(brname.c_str(), ptr); -} + void run(framework::ProcessingContext& pc) + { + if (mFinished) { + return; + } + std::string detStr = mID.getName(); + std::string detStrL = mID.getName(); + std::transform(detStrL.begin(), detStrL.end(), detStrL.begin(), ::tolower); + + // retrieve the digits from the input + auto inDigits = pc.inputs().get>((detStr + "digits").c_str()); + // auto inROFs = pc.inputs().get>((detStr + "digitsROF").c_str()); + // auto inMC2ROFs = pc.inputs().get>((detStr + "digitsMC2ROF").c_str()); + // auto inLabels = pc.inputs().get((detStr + "digitsMCTR").c_str()); + LOG(INFO) << "RECEIVED DIGITS SIZE " << inDigits.size(); + + auto digitsP = &inDigits; + // auto labelsRaw = inLabels.get(); + // connect this to a particular branch + + auto brDig = getOrMakeBranch(*mOutTree.get(), (detStr + "Digit").c_str(), &digitsP); + // auto brLbl = getOrMakeBranch(*mOutTree.get(), (detStr + "DigitMCTruth").c_str(), &labelsRaw); + mOutTree->Fill(); + + mOutFile->cd(); + mOutTree->Write(); + mOutTree.reset(); // delete the tree before closing the file + mOutFile->Close(); + mFinished = true; + pc.services().get().readyToQuit(false); + } + + protected: + FITDPLDigitWriter() {} + template + TBranch* getOrMakeBranch(TTree& tree, std::string brname, T* ptr) + { + if (auto br = tree.GetBranch(brname.c_str())) { + br->SetAddress(static_cast(ptr)); + return br; + } + // otherwise make it + return tree.Branch(brname.c_str(), ptr); + } + + bool mFinished = false; + o2::detectors::DetID mID; + o2::header::DataOrigin mOrigin = o2::header::gDataOriginInvalid; + std::vector mDigits; // input digits + std::unique_ptr mOutFile; + std::unique_ptr mOutTree; +}; + +//_______________________________________________ +class T0DPLDigitWriter : public FITDPLDigitWriter +{ + public: + // FIXME: origina should be extractable from the DetID, the problem is 3d party header dependencies + static constexpr o2::detectors::DetID::ID DETID = o2::detectors::DetID::T0; + static constexpr o2::header::DataOrigin DETOR = o2::header::gDataOriginT0; + T0DPLDigitWriter() + { + mID = DETID; + mOrigin = DETOR; + } +}; + +constexpr o2::detectors::DetID::ID T0DPLDigitWriter::DETID; +constexpr o2::header::DataOrigin T0DPLDigitWriter::DETOR; + +//_______________________________________________ /// create the processor spec -/// TODO: replace by generic processor once this is working -DataProcessorSpec getFITDigitWriterSpec() +/// describing a processor receiving digits for ITS/MFT and writing them to file +DataProcessorSpec getT0DigitWriterSpec() { - auto initFunction = [](InitContext& ic) { - // get the option from the init context - auto filename = ic.options().get("fit-digit-outfile"); - auto treename = ic.options().get("treename"); + std::string detStr = o2::detectors::DetID::getName(T0DPLDigitWriter::DETID); + std::string detStrL = detStr; + std::transform(detStrL.begin(), detStrL.end(), detStrL.begin(), ::tolower); + auto detOrig = T0DPLDigitWriter::DETOR; - auto outputfile = std::make_shared(filename.c_str(), "RECREATE"); - auto outputtree = std::make_shared(treename.c_str(), treename.c_str()); - - // container for incoming digits - auto digits = std::make_shared>(); - - // the callback to be set as hook at stop of processing for the framework - auto finishWriting = [outputfile, outputtree]() { - outputtree->SetEntries(1); - outputtree->Write(); - outputfile->Close(); - }; - ic.services().get().set(CallbackService::Id::Stop, finishWriting); - - // setup the processing function - // using by-copy capture of the worker instance shared pointer - // the shared pointer makes sure to clean up the instance when the processing - // function gets out of scope - auto processingFct = [outputfile, outputtree, digits](ProcessingContext& pc) { - static bool finished = false; - if (finished) { - // avoid being executed again when marked as finished; - return; - } - - // retrieve the digits from the input - auto indata = pc.inputs().get>("fitdigits"); - LOG(INFO) << "RECEIVED DIGITS SIZE " << indata.size(); - *digits.get() = std::move(indata); - - // connect this to a particular branch - auto br = getOrMakeBranch(*outputtree.get(), "FITDigit", digits.get()); - br->Fill(); - - // retrieve labels from the input - //auto labeldata = pc.inputs().get*>("tofdigitlabels"); - //LOG(INFO) << "TOF GOT " << labeldata->getNElements() << " LABELS "; - //auto labeldataraw = labeldata.get(); - // connect this to a particular branch - //auto labelbr = getOrMakeBranch(*outputtree.get(), "TOFDigitMCTruth", &labeldataraw); - //labelbr->Fill(); - - finished = true; - pc.services().get().readyToQuit(false); - }; - - // return the actual processing function as a lambda function using variables - // of the init function - return processingFct; - }; + std::vector inputs; + inputs.emplace_back(InputSpec{ (detStr + "digits").c_str(), detOrig, "DIGITS", 0, Lifetime::Timeframe }); return DataProcessorSpec{ - "FITDigitWriter", - Inputs{ InputSpec{ "fitdigits", "FIT", "DIGITS", 0, Lifetime::Timeframe }, - /* InputSpec{ "tofdigitlabels", "TOF", "DIGITSMCTR", 0, Lifetime::Timeframe } */ }, + (detStr + "DigitWriter").c_str(), + inputs, {}, // no output - AlgorithmSpec(initFunction), + AlgorithmSpec(adaptFromTask()), Options{ - { "fit-digit-outfile", VariantType::String, "fitdigits.root", { "Name of the input file" } }, + { (detStrL + "-digit-outfile").c_str(), VariantType::String, (detStrL + "digits.root").c_str(), { "Name of the input file" } }, { "treename", VariantType::String, "o2sim", { "Name of top-level TTree" } }, } }; } + } // end namespace fit } // end namespace o2 diff --git a/Steer/DigitizerWorkflow/src/FITDigitWriterSpec.h b/Steer/DigitizerWorkflow/src/FITDigitWriterSpec.h index 8f828e5bfd40c..4f07f79d6c028 100644 --- a/Steer/DigitizerWorkflow/src/FITDigitWriterSpec.h +++ b/Steer/DigitizerWorkflow/src/FITDigitWriterSpec.h @@ -18,9 +18,9 @@ namespace o2 namespace fit { -o2::framework::DataProcessorSpec getFITDigitWriterSpec(); +o2::framework::DataProcessorSpec getT0DigitWriterSpec(); -} // end namespace tof +} // namespace fit } // end namespace o2 -#endif /* STEER_DIGITIZERWORKFLOW_FITDIGITWRITER_H_ */ +#endif /* STEER_DIGITIZERWORKFLOW_ITSMFTDIGITWRITER_H_ */ diff --git a/Steer/DigitizerWorkflow/src/FITDigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/FITDigitizerSpec.cxx index 4c2a37ea28dee..b29815737553d 100644 --- a/Steer/DigitizerWorkflow/src/FITDigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/FITDigitizerSpec.cxx @@ -14,15 +14,18 @@ #include "Framework/DataRefUtils.h" #include "Framework/Lifetime.h" #include "Headers/DataHeader.h" -#include "TStopwatch.h" #include "Steer/HitProcessingManager.h" // for RunContext -#include "TChain.h" #include "FITSimulation/Digitizer.h" -#include -#include +#include "T0Simulation/DigitizationParameters.h" +#include "FITBase/Digit.h" +#include "FITSimulation/MCLabel.h" +#include "SimulationDataFormat/MCCompLabel.h" +#include "SimulationDataFormat/MCTruthContainer.h" #include "Framework/Task.h" -#include #include "DataFormatsParameters/GRPObject.h" +#include +#include +#include using namespace o2::framework; using SubSpecificationType = o2::framework::DataAllocator::SubSpecificationType; @@ -31,57 +34,52 @@ namespace o2 { namespace fit { - // helper function which will be offered as a service -template -void retrieveHits(std::vector const& chains, - const char* brname, - int sourceID, - int entryID, - std::vector* hits) -{ - auto br = chains[sourceID]->GetBranch(brname); - if (!br) { - LOG(ERROR) << "No branch found"; - return; - } - br->SetAddress(&hits); - br->GetEntry(entryID); -} +//template class FITDPLDigitizerTask { + public: - FITDPLDigitizerTask() = default; + FITDPLDigitizerTask(o2::fit::DigitizationParameters const& parameters) + : mDigitizer(parameters) {} ~FITDPLDigitizerTask() = default; void init(framework::InitContext& ic) { + std::cout << " @@@@ init " << std::endl; // setup the input chain for the hits mSimChains.emplace_back(new TChain("o2sim")); // add the main (background) file mSimChains.back()->AddFile(ic.options().get("simFile").c_str()); - + std::cout << " @@@@@ sim file " << ic.options().get("simFile").c_str() << std::endl; // maybe add a particular signal file auto signalfilename = ic.options().get("simFileS"); if (signalfilename.size() > 0) { mSimChains.emplace_back(new TChain("o2sim")); mSimChains.back()->AddFile(signalfilename.c_str()); } - - mDigitizer.init(); + static constexpr o2::detectors::DetID::ID DETID = o2::detectors::DetID::T0; + std::cout << " o2::detectors::DetID::T0 " << mID.getName() << std::endl; + if (mID == o2::detectors::DetID::T0) { + mDigitizer.init(); + std::cout << " @@@@ mT0Digitizer.init" << std::endl; + } const bool isContinuous = ic.options().get("pileup"); - // mDigitizer.setContinuous(isContinuous); - // mDigitizer.setMCTruthContainer(labels.get()); + // mT0Digitizer.setContinuous(isContinuous); + // mT0Digitizer.setMCTruthContainer(labels.get()); } void run(framework::ProcessingContext& pc) { + static bool finished = false; if (finished) { return; } + std::string detStr = mID.getName(); + std::cout << " @@@@ run !!!!!!! " << detStr << std::endl; // read collision context from input auto context = pc.inputs().get("collisioncontext"); @@ -110,31 +108,35 @@ class FITDPLDigitizerTask mDigitizer.setEventTime(timesview[collID].timeNS); mDigitizer.setOrbit(timesview[collID].orbit); mDigitizer.setBC(timesview[collID].bc); + mDigitizer.setMCLabels(&mLabels); digit.cleardigits(); // for each collision, loop over the constituents event and source IDs // (background signal merging is basically taking place here) + std::cout << " @@@@ mOrigin " << mOrigin << " mID " << mID.getName() << std::endl; for (auto& part : eventParts[collID]) { // get the hits for this event and this source hits.clear(); - retrieveHits(mSimChains, "FITHit", part.sourceID, part.entryID, &hits); + retrieveHits(mSimChains, part.sourceID, part.entryID, &hits); LOG(INFO) << "For collision " << collID << " eventID " << part.entryID << " found " << hits.size() << " hits "; // call actual digitization procedure labels.clear(); // digits.clear(); + mDigitizer.setSrcID(part.sourceID); mDigitizer.process(&hits, &digit); - auto data = digit.getChDgData(); + const auto& data = digit.getChDgData(); LOG(INFO) << "Have " << data.size() << " fired channels "; // copy digits into accumulator // labelAccum.mergeAtBack(*labels); } + mDigitizer.computeAverage(digit); mDigitizer.setTriggers(&digit); mDigitizer.smearCFDtime(&digit); digitAccum.push_back(digit); // we should move it there actually LOG(INFO) << "Have " << digitAccum.back().getChDgData().size() << " fired channels "; digit.printStream(std::cout); } - // if (mDigitizer.isContinuous()) { + // if (mT0Digitizer.isContinuous()) { // digits->clear(); // labels->clear(); // digitizer->flushOutputContainer(*digits.get()); @@ -146,10 +148,11 @@ class FITDPLDigitizerTask // LOG(INFO) << "Have " << labelAccum.getNElements() << " TOF labels "; // here we have all digits and we can send them to consumer (aka snapshot it onto output) - pc.outputs().snapshot(Output{ "FIT", "DIGITS", 0, Lifetime::Timeframe }, digitAccum); + pc.outputs().snapshot(Output{ mOrigin, "DIGITS", 0, Lifetime::Timeframe }, digitAccum); // pc.outputs().snapshot(Output{ "FIT", "DIGITSMCTR", 0, Lifetime::Timeframe }, labelAccum); + LOG(INFO) << "FIT: Sending ROMode= " << mROMode << " to GRPUpdater"; - pc.outputs().snapshot(Output{ "FIT", "ROMode", 0, Lifetime::Timeframe }, mROMode); + pc.outputs().snapshot(Output{ mOrigin, "ROMode", 0, Lifetime::Timeframe }, mROMode); timer.Stop(); LOG(INFO) << "Digitization took " << timer.CpuTime() << "s"; @@ -158,33 +161,76 @@ class FITDPLDigitizerTask finished = true; } - private: + // private: + protected: Bool_t mContinuous = kFALSE; ///< flag to do continuous simulation double mFairTimeUnitInNS = 1; ///< Fair time unit in ns - - Digitizer mDigitizer; ///< Digitizer + o2::detectors::DetID mID; + o2::header::DataOrigin mOrigin = o2::header::gDataOriginInvalid; + o2::fit::Digitizer mDigitizer; ///< Digitizer + //Digitizer mV0Digitizer; ///< Digitizer // RS: at the moment using hardcoded flag for continuos readout o2::parameters::GRPObject::ROMode mROMode = o2::parameters::GRPObject::CONTINUOUS; // readout mode std::vector mSimChains; + + void retrieveHits(std::vector const& chains, + int sourceID, + int entryID, + std::vector* hits) + { + std::string detStr = mID.getName(); + std::cout << "@@@@ retrieveHit " << detStr << std::endl; + auto br = mSimChains[sourceID]->GetBranch((detStr + "Hit").c_str()); + // auto br = chains[sourceID]->GetBranch(brname); + if (!br) { + LOG(ERROR) << "No branch found"; + return; + } + br->SetAddress(&hits); + br->GetEntry(entryID); + } }; -o2::framework::DataProcessorSpec getFITDigitizerSpec(int channel) +class FITT0DPLDigitizerTask : public FITDPLDigitizerTask +{ + public: + // FIXME: origina should be extractable from the DetID, the problem is 3d party header dependencies + static constexpr o2::detectors::DetID::ID DETID = o2::detectors::DetID::T0; + static constexpr o2::header::DataOrigin DETOR = o2::header::gDataOriginT0; + FITT0DPLDigitizerTask() : FITDPLDigitizerTask{ o2::t0::T0DigitizationParameters() } + { + mID = DETID; + mOrigin = DETOR; + std::cout << " @@@@ DETOR FITT0DPLDigitizerTask " << mOrigin << " " << mID.getName() << std::endl; + } +}; + +constexpr o2::detectors::DetID::ID FITT0DPLDigitizerTask::DETID; +constexpr o2::header::DataOrigin FITT0DPLDigitizerTask::DETOR; + +o2::framework::DataProcessorSpec getFITT0DigitizerSpec(int channel) { // create the full data processor spec using // a name identifier // input description // algorithmic description (here a lambda getting called once to setup the actual processing function) // options that can be used for this processor (here: input file names where to take the hits) + std::string detStr = o2::detectors::DetID::getName(FITT0DPLDigitizerTask::DETID); + auto detOrig = FITT0DPLDigitizerTask::DETOR; + std::cout << "@@@@ getFITT0DigitizerSpec " << detStr << " dteOrig " << detOrig << std::endl; + return DataProcessorSpec{ - "FITDigitizer", Inputs{ InputSpec{ "collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast(channel), Lifetime::Timeframe } }, - Outputs{ OutputSpec{ "FIT", "DIGITS", 0, Lifetime::Timeframe }, - /*OutputSpec{ "FIT", "DIGITSMCTR", 0, Lifetime::Timeframe }*/ - OutputSpec{ "FIT", "ROMode", 0, Lifetime::Timeframe } }, - AlgorithmSpec{ adaptFromTask() }, + (detStr + "Digitizer").c_str(), + Inputs{ InputSpec{ "collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast(channel), Lifetime::Timeframe } }, + Outputs{ OutputSpec{ detOrig, "DIGITS", 0, Lifetime::Timeframe }, + /*OutputSpec{ detOrig "FIT", "DIGITSMCTR", 0, Lifetime::Timeframe }*/ + OutputSpec{ detOrig, "ROMode", 0, Lifetime::Timeframe } }, + AlgorithmSpec{ adaptFromTask() }, Options{ { "simFile", VariantType::String, "o2sim.root", { "Sim (background) input filename" } }, { "simFileS", VariantType::String, "", { "Sim (signal) input filename" } }, { "pileup", VariantType::Int, 1, { "whether to run in continuous time mode" } } } + // I can't use VariantType::Bool as it seems to have a problem }; } diff --git a/Steer/DigitizerWorkflow/src/FITDigitizerSpec.h b/Steer/DigitizerWorkflow/src/FITDigitizerSpec.h index bcf4c4eabde02..b47d0148ebab1 100644 --- a/Steer/DigitizerWorkflow/src/FITDigitizerSpec.h +++ b/Steer/DigitizerWorkflow/src/FITDigitizerSpec.h @@ -18,7 +18,8 @@ namespace o2 namespace fit { -o2::framework::DataProcessorSpec getFITDigitizerSpec(int channel); +o2::framework::DataProcessorSpec getFITT0DigitizerSpec(int channel); +//o2::framework::DataProcessorSpec getFITV0DigitizerSpec(int channel); } // end namespace fit } // end namespace o2 diff --git a/Steer/DigitizerWorkflow/src/GRPUpdaterSpec.cxx b/Steer/DigitizerWorkflow/src/GRPUpdaterSpec.cxx index 5c6c93b01dba2..55d87e7b49079 100644 --- a/Steer/DigitizerWorkflow/src/GRPUpdaterSpec.cxx +++ b/Steer/DigitizerWorkflow/src/GRPUpdaterSpec.cxx @@ -87,7 +87,7 @@ o2::framework::DataProcessorSpec getGRPUpdaterSpec(const std::vector #include #include -#include +#include #include #include #include @@ -183,9 +183,9 @@ void build_geometry(FairRunSim* run = nullptr) run->AddModule(new o2::phos::Detector(true)); } - if (isActivated("FIT")) { + if (isActivated("T0")) { // FIT - run->AddModule(new o2::fit::Detector(true)); + run->AddModule(new o2::t0::Detector(true)); } if (isActivated("HMP")) { diff --git a/run/O2HitMerger.h b/run/O2HitMerger.h index 2d69e70b4835c..84b48fc5d7da8 100644 --- a/run/O2HitMerger.h +++ b/run/O2HitMerger.h @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include #include #include @@ -466,8 +466,8 @@ void O2HitMerger::initDetInstances() mDetectorInstances[i] = std::move(std::make_unique(true)); counter++; } - if (i == DetID::FIT) { - mDetectorInstances[i] = std::move(std::make_unique(true)); + if (i == DetID::T0) { + mDetectorInstances[i] = std::move(std::make_unique(true)); counter++; } if (i == DetID::MCH) {