diff --git a/macro/beamtime/mcbm2022/data/.gitignore b/macro/beamtime/mcbm2022/data/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..4ea40f8315d27f24d50e2c0f6ac12ea00b5542f6 --- /dev/null +++ b/macro/beamtime/mcbm2022/data/.gitignore @@ -0,0 +1 @@ +*.root diff --git a/macro/beamtime/mcbm2022/mTofCriParIron_withBmon.par b/macro/beamtime/mcbm2022/mTofCriParIron_withBmon.par new file mode 100644 index 0000000000000000000000000000000000000000..7a8f08b4d362a3fda47e2a34bfb5ab59950ceda5 --- /dev/null +++ b/macro/beamtime/mcbm2022/mTofCriParIron_withBmon.par @@ -0,0 +1,34 @@ +#################################################################################################### +[CbmMcbm2018TofPar] +//---------------------------------------------------------------------------- +NrOfGdpbs: Int_t 12 +GdpbIdArray: Int_t \ +0xabc0 0xabc1 0xabc2 0xabc3 0xabc4 0xabc5 0xabc6 0xabc7 0xabf3 0xabf2 0xabf0 0xabf1 +NrOfFeesPerGdpb: Int_t 10 +NrOfGet4PerFee: Int_t 8 +NrOfChannelsPerGet4: Int_t 4 +NrOfGbtx: Int_t 24 +NrOfModule: Int_t 0 +NrOfRpc: Int_t \ + 5 5 5 5 5 5 5 5 5 5 5 5 2 2 2 2 1 1 1 1 1 1 1 1 +RpcType: Int_t \ + 0 0 0 0 2 2 0 0 0 0 0 0 9 9 6 9 99 -1 99 -1 99 -1 99 -1 +RpcSide: Int_t \ + 0 1 0 1 0 1 0 1 0 1 0 1 2 2 2 0 0 0 0 0 1 0 1 0 +ModuleId: Int_t \ + 0 0 1 1 0 0 2 2 3 3 4 4 0 -1 0 1 0 -1 0 -1 0 -1 0 -1 +NbMsTot: Int_t 100 +NbMsOverlap: Int_t 1 +SizeMsInNs: Double_t 102400.0 +//SizeMsInNs: Double_t 1638400 +StarTriggerDeadtime: Double_t \ + 1000.0 1000.0 1000.0 1000.0 1000.0 +StarTriggerDelay: Double_t \ + 2000.0 2000.0 2000.0 2000.0 2000.0 +// 2000.0 2000.0 2000.0 2000.0 2000.0 +//-23000.0 -23000.0 -23000.0 -23000.0 -23000.0 +StarTriggerWinSize: Double_t \ + 2000.0 2000.0 2000.0 2000.0 2000.0 +TsDeadtimePeriod: Double_t 62.5 + +#################################################################################################### diff --git a/macro/beamtime/mcbm2022/mcbm_unp_event.C b/macro/beamtime/mcbm2022/mcbm_unp_event.C new file mode 100644 index 0000000000000000000000000000000000000000..e0ffb52fe12c1b51dfe3b22fc437249644714c19 --- /dev/null +++ b/macro/beamtime/mcbm2022/mcbm_unp_event.C @@ -0,0 +1,722 @@ +/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Jan de Cuveland, Volker Friese, Pierre-Alain Loizeau, Pascal Raisig [committer], Dominik Smith, Adrian A. Weber */ + + +// --- Includes needed for IDE +#include <RtypesCore.h> + +#include <cstdint> +#include <memory> +#include <string> +#include <vector> + +#include <math.h> +#include <stdio.h> +#if !defined(__CLING__) +#include "CbmTrdRawMessageSpadic.h" +#include "CbmTrdSpadic.h" + +#include <FairLogger.h> +#include <FairRootFileSink.h> +#include <FairRunOnline.h> +#include <Logger.h> + +#include <TStopwatch.h> +#include <TSystem.h> +#endif + +std::shared_ptr<CbmTrdUnpackMonitor> GetTrdMonitor(std::string treefilename, bool fasp = false); +std::shared_ptr<CbmTrdSpadic> GetTrdSpadic(bool useAvgBaseline = false); +std::shared_ptr<CbmStsUnpackMonitor> GetStsMonitor(std::string treefilename, bool bDebugMode = false); +std::shared_ptr<CbmMuchUnpackMonitor> GetMuchMonitor(std::string treefilename, bool bDebugMode = false); +std::shared_ptr<CbmRichUnpackMonitor> GetRichMonitor(std::string treefilename, bool bDebugMode = false); +std::shared_ptr<CbmTofUnpackMonitor> GetTofMonitor(std::string treefilename, bool bBmonMode = false); +const char* defaultSetupName = "mcbm_beam_2021_07_surveyed"; + +/// FIXME: Disable clang formatting to keep easy parameters overview +/* clang-format off */ +Bool_t mcbm_unp_event(bool bBmoninTof = false, + std::int32_t nTimeslices = -1, + std::string infile = "/scratch/mcbm_data/2022_iron/2160_node8_0000.tsa;/scratch/mcbm_data/2022_iron/2160_node9_0000.tsa", + UInt_t uRunId = 2160, + const char* setupName = defaultSetupName, + std::string sOutDir = "data/") +{ + /// FIXME: Re-enable clang formatting after parameters initial values setting + /* clang-format on */ + + std::vector<std::string> vInFile = {infile}; + + + // --- Logger settings ---------------------------------------------------- + TString logLevel = "INFO"; + TString logVerbosity = "LOW"; + // ------------------------------------------------------------------------ + + // ----- Environment -------------------------------------------------- + TString myName = "mcbm_eventmcbm_unp_event_reco"; // this macro's name for screen output + TString srcDir = gSystem->Getenv("VMCWORKDIR"); // top source directory + // ------------------------------------------------------------------------ + + + // ----- EventBuilder Settings---------------- + /// FIXME: Disable clang formatting to keep easy parameters overview + /* clang-format off */ + const UInt_t eb_TriggerMinNumberBmon { 0 }; + const UInt_t eb_TriggerMinNumberSts { 0 }; + const UInt_t eb_TriggerMinNumberMuch { 0 }; + const UInt_t eb_TriggerMinNumberTof { 4 }; + const UInt_t eb_TriggerMinNumberRich { 0 }; + + const Int_t eb_TriggerMaxNumberBMon { -1 }; + const Int_t eb_TriggerMaxNumberSts { -1 }; + const Int_t eb_TriggerMaxNumberMuch { -1 }; + const Int_t eb_TriggerMaxNumberTof { -1 }; + const Int_t eb_TriggerMaxNumberRich { -1 }; + /// FIXME: Re-enable clang formatting after parameters initial values setting + /* clang-format on */ + // ------------------------------------------------------------------------ + + + // ----- Output filename ---------------------------------------------- + std::string filename = Form("%d_%s.digi.root", uRunId, (bBmoninTof ? "BmonInTof" : "BmonSepar")); + std::string outfilename = sOutDir + "/" + filename; + std::cout << "-I- " << myName << ": Output file will be " << outfilename << std::endl; + std::string histosfilename = sOutDir + "/" + filename; + histosfilename.replace(histosfilename.find(".digi.root"), 10, ".hist.root"); + std::cout << "-I- " << myName << ": Histos file will be " << histosfilename << std::endl; + // ------------------------------------------------------------------------ + + + // ----- Performance profiling ---------------------------------------- + // Set to true if you want some minimal performance profiling output + bool doPerfProfiling = true; + // Define if you want a special path and name for the performance profiling output file + std::string perfProfFileName = sOutDir + "/" + filename; + perfProfFileName.replace(perfProfFileName.find(".digi.root"), 10, ".perf.root"); + // ------------------------------------------------------------------------ + + // ----- CbmSetup ----------------------------------------------------- + if (2060 <= uRunId && defaultSetupName == setupName) { + /// Setup changed multiple times between the 2022 carbon and uranium runs + if (uRunId <= 2065) { + /// Carbon runs: 2060 - 2065 = 10/03/2022 + setupName = "mcbm_beam_2022_03_09_carbon"; + } + else if (2150 <= uRunId && uRunId <= 2160) { + /// Iron runs: 2150 - 2160 = 24-25/03/2022 + setupName = "mcbm_beam_2022_03_22_iron"; + } + else if (2176 <= uRunId && uRunId <= 2310) { + /// Uranium runs: 2176 - 2310 = 30/03/2022 - 01/04/2022 + setupName = "mcbm_beam_2022_03_28_uranium"; + } + } + auto cbmGeoSetup = CbmSetup::Instance(); + cbmGeoSetup->LoadSetup(setupName); + // ------------------------------------------------------------------------ + + // ----- UnpackerConfigs ---------------------------------------------- + + // ---- BMON ---- + std::shared_ptr<CbmBmonUnpackConfig> bmonconfig = nullptr; + + if (!bBmoninTof) { + bmonconfig = std::make_shared<CbmBmonUnpackConfig>("", uRunId); + if (bmonconfig) { + // bmonconfig->SetDebugState(); + bmonconfig->SetDoWriteOutput(); + // bmonconfig->SetDoWriteOptOutA("CbmBmonErrors"); + std::string parfilesbasepathBmon = Form("%s/macro/beamtime/mcbm2022/", srcDir.Data()); + bmonconfig->SetParFilesBasePath(parfilesbasepathBmon); + bmonconfig->SetParFileName("mBmonCriPar.par"); + bmonconfig->SetSystemTimeOffset(-1220); // [ns] value to be updated + if (2160 <= uRunId) { + bmonconfig->SetSystemTimeOffset(-80); // [ns] value to be updated + } + /// Enable Monitor plots + // bmonconfig->SetMonitor(GetTofMonitor(outfilename, true)); + } + } + // ------------- + + // ---- STS ---- + std::shared_ptr<CbmStsUnpackConfig> stsconfig = nullptr; + + stsconfig = std::make_shared<CbmStsUnpackConfig>(std::string(setupName), uRunId); + if (stsconfig) { + // stsconfig->SetDebugState(); + stsconfig->SetDoWriteOutput(); + stsconfig->SetDoWriteOptOutA("StsDigiPulser"); + std::string parfilesbasepathSts = Form("%s/macro/beamtime/mcbm2021/", srcDir.Data()); + if (2060 <= uRunId) { + /// Starting to readout the U3 since 10/03/2022 Carbon run + parfilesbasepathSts = Form("%s/macro/beamtime/mcbm2022/", srcDir.Data()); + } + stsconfig->SetParFilesBasePath(parfilesbasepathSts); + /// Enable duplicates rejection, Ignores the ADC for duplicates check + stsconfig->SetDuplicatesRejection(true, true); + /// Enable Monitor plots + //stsconfig->SetMonitor(GetStsMonitor(outfilename, true)); + stsconfig->SetSystemTimeOffset(-2221); // [ns] value to be updated + if (2160 <= uRunId) { + stsconfig->SetSystemTimeOffset(-1075); // [ns] value to be updated + } + + stsconfig->SetMinAdcCut(1, 1); + stsconfig->SetMinAdcCut(2, 1); + stsconfig->SetMinAdcCut(3, 1); + stsconfig->SetMinAdcCut(4, 1); + + stsconfig->MaskNoisyChannel(3, 56); + stsconfig->MaskNoisyChannel(3, 75); + stsconfig->MaskNoisyChannel(3, 79); + stsconfig->MaskNoisyChannel(3, 85); + stsconfig->MaskNoisyChannel(7, 123); + stsconfig->MaskNoisyChannel(7, 124); + stsconfig->MaskNoisyChannel(7, 125); + stsconfig->MaskNoisyChannel(7, 158); + stsconfig->MaskNoisyChannel(7, 159); + stsconfig->MaskNoisyChannel(7, 162); + stsconfig->MaskNoisyChannel(7, 715); + stsconfig->MaskNoisyChannel(9, 709); + stsconfig->MaskNoisyChannel(12, 119); + + // Time Walk correction + std::map<uint32_t, CbmStsParModule> walkMap; + auto parAsic = new CbmStsParAsic(128, 31, 31., 1., 5., 800., 1000., 3.9789e-3); + + // Module params: number of channels, number of channels per ASIC + auto parMod = new CbmStsParModule(2048, 128); + + // default + double p0 = 0, p1 = 0, p2 = 0, p3 = 0; + parAsic->SetWalkCoef({p0, p1, p2, p3}); + parMod->SetAllAsics(*parAsic); + + walkMap[0x10107C02] = CbmStsParModule(*parMod); // Make a copy for storage + walkMap[0x101FFC02] = CbmStsParModule(*parMod); // Make a copy for storage + + /// To be replaced by a storage in a new parameter class later + int sensor, asic; + std::ifstream asicTimeWalk_par(Form("%s/mStsAsicTimeWalk.par", parfilesbasepathSts.data())); + while (asicTimeWalk_par >> std::hex >> sensor >> std::dec >> asic >> p0 >> p1 >> p2 >> p3) { + std::cout << Form("Setting time-walk parametersfor: module %x, ASIC %u\n", sensor, asic); + parAsic->SetWalkCoef({p0, p1, p2, p3}); + + if (walkMap.find(sensor) == walkMap.end()) { walkMap[sensor] = CbmStsParModule(*parMod); } + walkMap[sensor].SetAsic(asic, *parAsic); + } + + stsconfig->SetWalkMap(walkMap); + } + // ------------- + + // ---- MUCH ---- + std::shared_ptr<CbmMuchUnpackConfig> muchconfig = nullptr; + + muchconfig = std::make_shared<CbmMuchUnpackConfig>(std::string(setupName), uRunId); + if (muchconfig) { + // muchconfig->SetDebugState(); + muchconfig->SetDoWriteOutput(); + muchconfig->SetDoWriteOptOutA("MuchDigiPulser"); + std::string parfilesbasepathMuch = Form("%s/macro/beamtime/mcbm2022/", srcDir.Data()); + muchconfig->SetParFilesBasePath(parfilesbasepathMuch); + if (2060 <= uRunId && uRunId <= 2162) { + /// Starting to use CRI Based MUCH setup with 2GEM and 1 RPC since 09/03/2022 Carbon run + muchconfig->SetParFileName("mMuchParUpto26032022.par"); + } + /// Enable duplicates rejection, Ignores the ADC for duplicates check + muchconfig->SetDuplicatesRejection(true, true); + /// Enable Monitor plots + //muchconfig->SetMonitor(GetMuchMonitor(outfilename, true)); + muchconfig->SetSystemTimeOffset(-2221); // [ns] value to be updated + if (2160 <= uRunId) { + muchconfig->SetSystemTimeOffset(-1020); // [ns] value to be updated + } + + // muchconfig->SetMinAdcCut(1, 1); + + // muchconfig->MaskNoisyChannel(3, 56); + } + // ------------- + + // ---- TRD ---- + std::shared_ptr<CbmTrdUnpackConfig> trd1Dconfig = nullptr; + + TString trdsetuptag = ""; + cbmGeoSetup->GetGeoTag(ECbmModuleId::kTrd, trdsetuptag); + // trd1Dconfig = std::make_shared<CbmTrdUnpackConfig>(trdsetuptag.Data(), uRunId); + trd1Dconfig = std::make_shared<CbmTrdUnpackConfig>(trdsetuptag.Data()); + if (trd1Dconfig) { + trd1Dconfig->SetDoWriteOutput(); + // Activate the line below to write Trd1D digis to a separate "TrdSpadicDigi" branch. Can be used to separate between Fasp and Spadic digis + // trd1Dconfig->SetOutputBranchName("TrdSpadicDigi"); + // trd1Dconfig->SetDoWriteOptOutA(CbmTrdRawMessageSpadic::GetBranchName()); + // trd1Dconfig->SetDoWriteOptOutB("SpadicInfoMessages"); // SpadicInfoMessages + + std::string parfilesbasepathTrd = Form("%s/parameters/trd", srcDir.Data()); + trd1Dconfig->SetParFilesBasePath(parfilesbasepathTrd); + // trd1Dconfig->SetMonitor(GetTrdMonitor(outfilename)); + // Get the spadic configuration true = avg baseline active / false plain sample 0 + trd1Dconfig->SetSpadicObject(GetTrdSpadic(true)); + trd1Dconfig->SetSystemTimeOffset(0); // [ns] value to be updated + if (2160 <= uRunId) { + trd1Dconfig->SetSystemTimeOffset(1140); // [ns] value to be updated + } + } + // ------------- + + // ---- TRDFASP2D ---- + std::shared_ptr<CbmTrdUnpackFaspConfig> trdfasp2dconfig = nullptr; + + trdfasp2dconfig = std::make_shared<CbmTrdUnpackFaspConfig>(trdsetuptag.Data()); + if (trdfasp2dconfig) { + // trdfasp2dconfig->SetDebugState(); + trdfasp2dconfig->SetDoWriteOutput(); + // Activate the line below to write Trd1D digis to a separate "TrdFaspDigi" branch. Can be used to separate between Fasp and Spadic digis + // trdfasp2dconfig->SetOutputBranchName("TrdFaspDigi"); + uint8_t map[NFASPMOD]; + if (uRunId <= 1588) { + uint8_t map21[] = {9, 2, 3, 11, 10, 7, 8, 0, 1, 4, 6, 5}; + for (int i(0); i < NFASPMOD; i++) + map[i] = (i < 12 ? map21[i] : i); + } + else + for (int i(0); i < NFASPMOD; i++) + map[i] = i; + trdfasp2dconfig->SetFaspMapping(5, map); + std::string parfilesbasepathTrdfasp2d = Form("%s/parameters/trd", srcDir.Data()); + trdfasp2dconfig->SetParFilesBasePath(parfilesbasepathTrdfasp2d); + trdfasp2dconfig->SetSystemTimeOffset(-1800); // [ns] value to be updated + if (2160 <= uRunId) { + trdfasp2dconfig->SetSystemTimeOffset(-570); // [ns] value to be updated + } + // trdfasp2dconfig->SetMonitor(dynamic_pointer_cast<CbmTrdUnpackFaspMonitor>(GetTrdMonitor(outfilename, 1))); + } + // ------------- + + // ---- TOF ---- + std::shared_ptr<CbmTofUnpackConfig> tofconfig = nullptr; + + tofconfig = std::make_shared<CbmTofUnpackConfig>("", uRunId); + if (tofconfig) { + // tofconfig->SetDebugState(); + tofconfig->SetDoWriteOutput(); + // tofconfig->SetDoWriteOptOutA("CbmTofErrors"); + std::string parfilesbasepathTof = Form("%s/macro/beamtime/mcbm2021/", srcDir.Data()); + std::string parFileNameTof = "mTofCriPar.par"; + if (2060 <= uRunId) { + /// Additional modules added just before the 10/03/2022 Carbon run + parfilesbasepathTof = Form("%s/macro/beamtime/mcbm2022/", srcDir.Data()); + /// Setup changed multiple times between the 2022 carbon and uranium runs + if (uRunId <= 2065) { + /// Carbon runs: 2060 - 2065 + parFileNameTof = "mTofCriParCarbon.par"; + } + else if (2150 <= uRunId && uRunId <= 2160) { + /// Iron runs: 2150 - 2160 + parFileNameTof = "mTofCriParIron.par"; + if (bBmoninTof) { parFileNameTof = "mTofCriParIron_withBmon.par"; } + } + else if (2176 <= uRunId && uRunId <= 2310) { + /// Uranium runs: 2176 - 2310 + parFileNameTof = "mTofCriParUranium.par"; + } + } + tofconfig->SetParFilesBasePath(parfilesbasepathTof); + tofconfig->SetParFileName(parFileNameTof); + tofconfig->SetSystemTimeOffset(-1220); // [ns] value to be updated + if (2160 <= uRunId) { + tofconfig->SetSystemTimeOffset(0); // [ns] value to be updated + } + if (uRunId <= 1659) { + /// Switch ON the -4 offset in epoch count (hack for Spring-Summer 2021) + tofconfig->SetFlagEpochCountHack2021(); + } + /// Enable Monitor plots + // tofconfig->SetMonitor(GetTofMonitor(outfilename, false)); + } + // ------------- + + // ---- RICH ---- + std::shared_ptr<CbmRichUnpackConfig> richconfig = nullptr; + + richconfig = std::make_shared<CbmRichUnpackConfig>("", uRunId); + if (richconfig) { + if (1904 < uRunId) { + /// Switch to new unpacking algo starting from first combined cosmics run in 2022 + richconfig->SetUnpackerVersion(CbmRichUnpackerVersion::v03); + richconfig->SetMonitor(GetRichMonitor(outfilename, true)); + } + + richconfig->DoTotOffsetCorrection(); // correct ToT offset + richconfig->SetDebugState(); + richconfig->SetDoWriteOutput(); + std::string parfilesbasepathRich = Form("%s/macro/beamtime/mcbm2021/", srcDir.Data()); + richconfig->SetParFilesBasePath(parfilesbasepathRich); + richconfig->SetSystemTimeOffset(256000 - 1200); // [ns] 1 MS and additional correction + if (1904 < uRunId) richconfig->SetSystemTimeOffset(-1200); + if (2160 <= uRunId) { + richconfig->SetSystemTimeOffset(50); // [ns] value to be updated + } + if (uRunId == 1588) richconfig->MaskDiRICH(0x7150); + } + // ------------- + + // ------------------------------------------------------------------------ + + // --------------------event builder--------------------------------------- + CbmTaskBuildRawEvents* evBuildRaw = new CbmTaskBuildRawEvents(); + + //Choose between NoOverlap, MergeOverlap, AllowOverlap + evBuildRaw->SetEventOverlapMode(EOverlapModeRaw::AllowOverlap); + + // Set TOF as reference detector + evBuildRaw->SetReferenceDetector(kRawEventBuilderDetTof); + + // Add all 2022 detectors not enable by default + evBuildRaw->AddDetector(kRawEventBuilderDetT0); + evBuildRaw->AddDetector(kRawEventBuilderDetMuch); + + // Remove detectors not there in 2022 + evBuildRaw->RemoveDetector(kRawEventBuilderDetPsd); + + // void SetTsParameters(double TsStartTime, double TsLength, double TsOverLength): TsStartTime=0, TsLength=256ms in 2021, TsOverLength=TS overlap, not used in mCBM2021 + //evBuildRaw->SetTsParameters(0.0, 2.56e8, 0.0);, 0.0); + // void SetTsParameters(double TsStartTime, double TsLength, double TsOverLength): TsStartTime=0, TsLength=102.4ms in 2022, TsOverLength=TS overlap not used in mCBM202? + evBuildRaw->SetTsParameters(0.0, 1.28e8, 1.12928e8); + + evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kTof, eb_TriggerMinNumberTof); + evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kTof, eb_TriggerMaxNumberTof); + + evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kT0, eb_TriggerMinNumberBmon); + evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kT0, eb_TriggerMaxNumberBMon); + + evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kSts, eb_TriggerMinNumberSts); + evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kSts, eb_TriggerMaxNumberSts); + + evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kMuch, eb_TriggerMinNumberMuch); + evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kMuch, eb_TriggerMaxNumberMuch); + + evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kRich, eb_TriggerMinNumberRich); + evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kRich, eb_TriggerMaxNumberRich); + + if (bBmoninTof) { evBuildRaw->SetTriggerWindow(ECbmModuleId::kT0, -180, 20); } + else { + evBuildRaw->SetTriggerWindow(ECbmModuleId::kT0, -100, 100); + } + evBuildRaw->SetTriggerWindow(ECbmModuleId::kSts, -60, 60); + evBuildRaw->SetTriggerWindow(ECbmModuleId::kMuch, -100, 500); + evBuildRaw->SetTriggerWindow(ECbmModuleId::kTrd, -100, 350); + evBuildRaw->SetTriggerWindow(ECbmModuleId::kTrd2d, -200, 200); + evBuildRaw->SetTriggerWindow(ECbmModuleId::kTof, -60, 60); + evBuildRaw->SetTriggerWindow(ECbmModuleId::kRich, -60, 60); + + // Use standard MUCH digis + evBuildRaw->ChangeMuchBeamtimeDigiFlag(); + + // Set Det type to find T0 in TOF digis = Select storage of BMon digis + if (bBmoninTof) { evBuildRaw->SetT0InTofDetType(); } + + evBuildRaw->SetOutFilename(histosfilename); + // ------------------------------------------------------------------------ + + // In general, the following parts need not be touched + // ======================================================================== + + // ----- Timer -------------------------------------------------------- + TStopwatch timer; + timer.Start(); + // ------------------------------------------------------------------------ + + // ----- CbmSourceTsArchive ------------------------------------------- + auto source = new CbmSourceTsArchive(vInFile); + auto unpack = source->GetRecoUnpack(); + unpack->SetDoPerfProfiling(doPerfProfiling); + unpack->SetOutputFilename(perfProfFileName); + // Enable full time sorting instead sorting per FLIM link + unpack->SetTimeSorting(true); + + if (bmonconfig) unpack->SetUnpackConfig(bmonconfig); + if (stsconfig) unpack->SetUnpackConfig(stsconfig); + if (muchconfig) unpack->SetUnpackConfig(muchconfig); + if (trd1Dconfig) unpack->SetUnpackConfig(trd1Dconfig); + if (trdfasp2dconfig) unpack->SetUnpackConfig(trdfasp2dconfig); + if (tofconfig) unpack->SetUnpackConfig(tofconfig); + if (richconfig) unpack->SetUnpackConfig(richconfig); + // ------------------------------------------------------------------------ + + + // ----- FairRunAna --------------------------------------------------- + auto run = new FairRunOnline(source); + auto sink = new FairRootFileSink(outfilename.data()); + run->SetSink(sink); + auto eventheader = new CbmTsEventHeader(); + run->SetRunId(uRunId); + run->SetEventHeader(eventheader); + + run->AddTask(evBuildRaw); + // ------------------------------------------------------------------------ + + + // ----- Logger settings ---------------------------------------------- + FairLogger::GetLogger()->SetLogScreenLevel(logLevel.Data()); + FairLogger::GetLogger()->SetLogVerbosityLevel(logVerbosity.Data()); + // ------------------------------------------------------------------------ + + + // ----- Run initialisation ------------------------------------------- + std::cout << std::endl; + std::cout << "-I- " << myName << ": Initialise run" << std::endl; + run->Init(); + // ------------------------------------------------------------------------ + + + // ----- Start run ---------------------------------------------------- + std::cout << std::endl << std::endl; + std::cout << "-I- " << myName << ": Starting run" << std::endl; + if (nTimeslices < 0) run->Run(-1, 0); + else + run->Run(0, nTimeslices); + // ------------------------------------------------------------------------ + + + // ----- Finish ------------------------------------------------------- + timer.Stop(); + std::cout << "Macro finished successfully." << std::endl; + std::cout << "After CpuTime = " << timer.CpuTime() << " s RealTime = " << timer.RealTime() << " s." << std::endl; + // ------------------------------------------------------------------------ + + return kTRUE; +} // End of main macro function + + +/** + * @brief Get the Trd Monitor. Extra function to keep default macro part more silent. + * @return std::shared_ptr<CbmTrdUnpackMonitor> +*/ +std::shared_ptr<CbmTrdUnpackMonitor> GetTrdMonitor(std::string treefilename, bool fasp = false) +{ + // ----- Output filename and path ------------------------------------- + std::string sOutDir = ""; + std::string filename = ""; + auto filenamepos = treefilename.find_last_of("/"); + if (filenamepos != treefilename.npos) { + sOutDir = treefilename.substr(0, filenamepos); + filename = treefilename.substr(filenamepos++); + } + if (sOutDir.empty()) sOutDir = gSystem->GetWorkingDirectory(); + std::string mydir = "/qa"; + sOutDir += mydir; + + auto currentdir = gSystem->GetWorkingDirectory(); + + if (!gSystem->cd(sOutDir.data())) gSystem->MakeDirectory(sOutDir.data()); + else + gSystem->cd(currentdir.data()); + + std::string outfilename = sOutDir + filename; + auto filetypepos = outfilename.find(".digi.root"); + if (filetypepos != outfilename.npos) outfilename.replace(filetypepos, 10, ".mon.trd.root"); + else + outfilename += ".mon.trd.root"; + // ------------------------------------------------------------------------ + + std::vector<CbmTrdUnpackMonitor::eDigiHistos> digihistovec = { + CbmTrdUnpackMonitor::eDigiHistos::kMap, CbmTrdUnpackMonitor::eDigiHistos::kMap_St, + CbmTrdUnpackMonitor::eDigiHistos::kMap_Nt, CbmTrdUnpackMonitor::eDigiHistos::kCharge, + CbmTrdUnpackMonitor::eDigiHistos::kCharge_St, CbmTrdUnpackMonitor::eDigiHistos::kCharge_Nt, + CbmTrdUnpackMonitor::eDigiHistos::kChannel, CbmTrdUnpackMonitor::eDigiHistos::kChannel_St, + CbmTrdUnpackMonitor::eDigiHistos::kChannel_Nt, CbmTrdUnpackMonitor::eDigiHistos::kTriggerType, + CbmTrdUnpackMonitor::eDigiHistos::kDigiDeltaT}; + + std::vector<CbmTrdUnpackMonitor::eRawHistos> rawhistovec = { + CbmTrdUnpackMonitor::eRawHistos::kSignalshape, CbmTrdUnpackMonitor::eRawHistos::kSignalshape_St, + CbmTrdUnpackMonitor::eRawHistos::kSignalshape_Nt, CbmTrdUnpackMonitor::eRawHistos::kElinkId, + CbmTrdUnpackMonitor::eRawHistos::kSampleDistStdDev, CbmTrdUnpackMonitor::eRawHistos::kSample0perChannel, + CbmTrdUnpackMonitor::eRawHistos::kHitType}; + + std::vector<CbmTrdUnpackMonitor::eOtherHistos> otherhistovec = {CbmTrdUnpackMonitor::eOtherHistos::kSpadic_Info_Types, + CbmTrdUnpackMonitor::eOtherHistos::kMs_Flags}; + std::shared_ptr<CbmTrdUnpackMonitor> monitor(nullptr); + if (!fasp) { // SPADIC monitor + monitor = std::make_shared<CbmTrdUnpackMonitor>(); + monitor->SetActiveHistos(digihistovec); + monitor->SetActiveHistos(rawhistovec); + monitor->SetActiveHistos(otherhistovec); + monitor->SetWriteToFile(outfilename.data()); + } + else { // FASP monitoring settings + monitor = std::make_shared<CbmTrdUnpackFaspMonitor>(); + monitor->SetActiveHistos(digihistovec); + monitor->SetWriteToFile(outfilename.data()); + } + return monitor; +} + + +/** + * @brief Get the Trd Spadic + * @return std::shared_ptr<CbmTrdSpadic> +*/ +std::shared_ptr<CbmTrdSpadic> GetTrdSpadic(bool useAvgBaseline) +{ + auto spadic = std::make_shared<CbmTrdSpadic>(); + spadic->SetUseBaselineAverage(useAvgBaseline); + spadic->SetMaxAdcToEnergyCal(1.0); + + return spadic; +} + +/** + * @brief Get the Sts Monitor. Extra function to keep default macro part more silent. + * @return std::shared_ptr<CbmStsUnpackMonitor> +*/ +std::shared_ptr<CbmStsUnpackMonitor> GetStsMonitor(std::string treefilename, bool bDebugMode = false) +{ + // ----- Output filename and path ------------------------------------- + std::string outpath = ""; + std::string filename = ""; + auto filenamepos = treefilename.find_last_of("/"); + if (filenamepos != treefilename.npos) { + outpath = treefilename.substr(0, filenamepos); + filename = treefilename.substr(filenamepos++); + } + if (outpath.empty()) outpath = gSystem->GetWorkingDirectory(); + //std::string mydir = "/qa"; + //outpath += mydir; + + auto currentdir = gSystem->GetWorkingDirectory(); + + if (!gSystem->cd(outpath.data())) gSystem->MakeDirectory(outpath.data()); + else + gSystem->cd(currentdir.data()); + + std::string outfilename = outpath + filename; + auto filetypepos = outfilename.find(".digi.root"); + if (filetypepos != outfilename.npos) outfilename.replace(filetypepos, 10, ".mon.sts.root"); + else + outfilename += ".mon.sts.root"; + // ------------------------------------------------------------------------ + + auto monitor = std::make_shared<CbmStsUnpackMonitor>(); + monitor->SetHistoFileName(outfilename); + monitor->SetDebugMode(bDebugMode); + return monitor; +} + +/** + * @brief Get the Much Monitor. Extra function to keep default macro part more silent. + * @return std::shared_ptr<CbmMuchUnpackMonitor> +*/ +std::shared_ptr<CbmMuchUnpackMonitor> GetMuchMonitor(std::string treefilename, bool bDebugMode = false) +{ + // ----- Output filename and path ------------------------------------- + std::string outpath = ""; + std::string filename = ""; + auto filenamepos = treefilename.find_last_of("/"); + if (filenamepos != treefilename.npos) { + outpath = treefilename.substr(0, filenamepos); + filename = treefilename.substr(filenamepos++); + } + if (outpath.empty()) outpath = gSystem->GetWorkingDirectory(); + + auto currentdir = gSystem->GetWorkingDirectory(); + + if (!gSystem->cd(outpath.data())) gSystem->MakeDirectory(outpath.data()); + else + gSystem->cd(currentdir.data()); + + std::string outfilename = outpath + filename; + auto filetypepos = outfilename.find(".digi.root"); + if (filetypepos != outfilename.npos) outfilename.replace(filetypepos, 10, ".mon.much.root"); + else + outfilename += ".mon.much.root"; + // ------------------------------------------------------------------------ + + auto monitor = std::make_shared<CbmMuchUnpackMonitor>(); + monitor->SetHistoFileName(outfilename); + monitor->SetDebugMode(bDebugMode); + return monitor; +} + +/** + * @brief Get the Rich Monitor. Extra function to keep default macro part more silent. + * @return std::shared_ptr<CbmRichUnpackMonitor> +*/ +std::shared_ptr<CbmRichUnpackMonitor> GetRichMonitor(std::string treefilename, bool bDebugMode = false) +{ + // ----- Output filename and path ------------------------------------- + std::string outpath = ""; + std::string filename = ""; + auto filenamepos = treefilename.find_last_of("/"); + if (filenamepos != treefilename.npos) { + outpath = treefilename.substr(0, filenamepos); + filename = treefilename.substr(filenamepos++); + } + if (outpath.empty()) outpath = gSystem->GetWorkingDirectory(); + + auto currentdir = gSystem->GetWorkingDirectory(); + + if (!gSystem->cd(outpath.data())) gSystem->MakeDirectory(outpath.data()); + else + gSystem->cd(currentdir.data()); + + std::string outfilename = outpath + filename; + auto filetypepos = outfilename.find(".digi.root"); + if (filetypepos != outfilename.npos) outfilename.replace(filetypepos, 10, ".mon.rich.root"); + else + outfilename += ".mon.rich.root"; + // ------------------------------------------------------------------------ + + auto monitor = std::make_shared<CbmRichUnpackMonitor>(); + monitor->SetHistoFileName(outfilename); + monitor->SetDebugMode(bDebugMode); + + return monitor; +} + +/** + * @brief Get the Tof Monitor. Extra function to keep default macro part more silent. + * @return std::shared_ptr<CbmTofUnpackMonitor> +*/ +std::shared_ptr<CbmTofUnpackMonitor> GetTofMonitor(std::string treefilename, bool bBmonMode = false) +{ + // ----- Output filename and path ------------------------------------- + std::string outpath = ""; + std::string filename = ""; + auto filenamepos = treefilename.find_last_of("/"); + if (filenamepos != treefilename.npos) { + outpath = treefilename.substr(0, filenamepos); + filename = treefilename.substr(filenamepos++); + } + if (outpath.empty()) outpath = gSystem->GetWorkingDirectory(); + //std::string mydir = "/qa"; + //outpath += mydir; + + auto currentdir = gSystem->GetWorkingDirectory(); + + if (!gSystem->cd(outpath.data())) gSystem->MakeDirectory(outpath.data()); + else + gSystem->cd(currentdir.data()); + + std::string sSystemType = ".mon.tof.root"; + if (bBmonMode) { + // + sSystemType = ".mon.bmon.root"; + } + + std::string outfilename = outpath + filename; + auto filetypepos = outfilename.find(".digi.root"); + if (filetypepos != outfilename.npos) outfilename.replace(filetypepos, 10, sSystemType); + else + outfilename += sSystemType; + // ------------------------------------------------------------------------ + + auto monitor = std::make_shared<CbmTofUnpackMonitor>(); + monitor->SetHistoFileName(outfilename); + monitor->SetBmonMode(bBmonMode); + return monitor; +} diff --git a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx index bdce0355f5a704372c2c6bbcbffec65cd3723b2b..d48903edbf5e1691acc6fe098dadea5d6c86cfd1 100644 --- a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx +++ b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx @@ -34,12 +34,12 @@ template<> void CbmAlgoBuildRawEvents::LoopOnSeeds<Double_t>(); template<class Digi> -uint32_t GetTofDetType(Digi* /*pDigi*/) +uint32_t GetTofDetType(const Digi* /*pDigi*/) { return 0; } -uint32_t GetTofDetType(CbmTofDigi* pDigi) +uint32_t GetTofDetType(const CbmTofDigi* pDigi) { /// Used only if TOF digi, otherwise template with 0 return is called return CbmTofAddress::GetSmType(pDigi->GetAddress()); @@ -289,6 +289,12 @@ void CbmAlgoBuildRawEvents::LoopOnSeeds() for (UInt_t uDigi = 0; uDigi < uNbRefDigis; ++uDigi) { LOG(debug) << Form("Checking seed %6u / %6u", uDigi, uNbRefDigis); Double_t dTime = fT0DigiVec->at(uDigi).GetTime(); + + /// Check if seed in acceptance window + if (dTime < fdSeedWindowBeg) { continue; } + else if (fdSeedWindowEnd < dTime) { + break; + } /// Check Seed and build event if needed CheckSeed(dTime, uDigi); } @@ -406,7 +412,12 @@ void CbmAlgoBuildRawEvents::CheckSeed(Double_t dSeedTime, UInt_t uSeedDigiIdx) } } else { - AddDigiToEvent(fRefDet, uSeedDigiIdx); + if (ECbmModuleId::kT0 == fRefDet.detId && 0 != fuDetTypeT0) { + AddDigiToEvent(kRawEventBuilderDetTof, uSeedDigiIdx); + } + else { + AddDigiToEvent(fRefDet, uSeedDigiIdx); + } } } @@ -544,9 +555,6 @@ void CbmAlgoBuildRawEvents::SearchMatches(Double_t dSeedTime, RawEventBuilderDet for (UInt_t uDigi = detMatch.fuStartIndex; uDigi < uNbSelDigis; ++uDigi) { const DigiCheck* pDigi = GetDigi<DigiCheck>(uDigi); - // filter T0 digis from Tof - if (GetTofDetType(pDigi) != fuDetTypeT0) { continue; } - const Double_t dTime = pDigi->GetTime(); const Double_t dTimeDiff = dTime - dSeedTime; LOG(debug4) << detMatch.sName << Form(" => Checking match %6u / %6u, dt %f", uDigi, uNbSelDigis, dTimeDiff); @@ -562,6 +570,10 @@ void CbmAlgoBuildRawEvents::SearchMatches(Double_t dSeedTime, RawEventBuilderDet uLocalIndexEnd = uDigi; break; } + + // filter T0 digis from Tof + if (GetTofDetType(pDigi) != fuDetTypeT0) { continue; } + AddDigiToEvent(kRawEventBuilderDetTof, uDigi); if (fdPrevEvtEndTime < dTime) fdPrevEvtEndTime = dTime; } @@ -575,6 +587,22 @@ void CbmAlgoBuildRawEvents::SearchMatches(Double_t dSeedTime, RawEventBuilderDet for (UInt_t uDigi = detMatch.fuStartIndex; uDigi < uNbSelDigis; ++uDigi) { const DigiCheck* pDigi = GetDigi<DigiCheck>(uDigi); + const Double_t dTime = pDigi->GetTime(); + const Double_t dTimeDiff = dTime - dSeedTime; + LOG(debug4) << detMatch.sName << Form(" => Checking match %6u / %6u, dt %f", uDigi, uNbSelDigis, dTimeDiff); + + /// Check if within time window, update start/stop indices if needed + if (dTimeDiff < detMatch.fdTimeWinBeg) { + ++uLocalIndexStart; + continue; + } + else if (detMatch.fdTimeWinEnd < dTimeDiff) { + /// Store as end the first digi out of window to avoid double counting in case of + /// merged overlap event mode + uLocalIndexEnd = uDigi; + break; + } + // Filter TRD2D digis if 1D and reverse if (detMatch.detId == ECbmModuleId::kTrd) { const CbmTrdDigi* pTrdDigi = GetDigi<CbmTrdDigi>(uDigi); @@ -592,21 +620,6 @@ void CbmAlgoBuildRawEvents::SearchMatches(Double_t dSeedTime, RawEventBuilderDet // filter T0 digis from Tof (remove this line if T0 properly implemented) if (detMatch.detId == ECbmModuleId::kTof && 0 != fuDetTypeT0 && GetTofDetType(pDigi) == fuDetTypeT0) { continue; } - const Double_t dTime = pDigi->GetTime(); - const Double_t dTimeDiff = dTime - dSeedTime; - LOG(debug4) << detMatch.sName << Form(" => Checking match %6u / %6u, dt %f", uDigi, uNbSelDigis, dTimeDiff); - - /// Check if within time window, update start/stop indices if needed - if (dTimeDiff < detMatch.fdTimeWinBeg) { - ++uLocalIndexStart; - continue; - } - else if (detMatch.fdTimeWinEnd < dTimeDiff) { - /// Store as end the first digi out of window to avoid double counting in case of - /// merged overlap event mode - uLocalIndexEnd = uDigi; - break; - } AddDigiToEvent(detMatch, uDigi); if (fdPrevEvtEndTime < dTime) fdPrevEvtEndTime = dTime; } @@ -677,18 +690,27 @@ Bool_t CbmAlgoBuildRawEvents::CheckTriggerConditions(CbmEvent* event, const RawE /// Check trigger rejection by minimal number or absence int32_t iNbDigis = event->GetNofData(det.dataType); - if (ECbmModuleId::kT0 == det.detId && 0 != fuDetTypeT0) { + if (0 != fuDetTypeT0) { // filter T0 digis from Tof (remove this block if T0 properly implemented) - iNbDigis = 0; - int32_t uNbSelDigisTofT0 = event->GetNofData(kRawEventBuilderDetTof.dataType); - /// Loop on size of vector - for (int32_t iDigi = 0; iDigi < uNbSelDigisTofT0; ++iDigi) { - uint idx = event->GetIndex(kRawEventBuilderDetTof.dataType, iDigi); - const CbmTofDigi* pDigi = GetDigi<CbmTofDigi>(idx); - if (nullptr == pDigi) continue; + if (ECbmModuleId::kT0 == det.detId || ECbmModuleId::kTof == det.detId) { + iNbDigis = 0; + int32_t uNbSelDigisTofT0 = event->GetNofData(kRawEventBuilderDetTof.dataType); + /// Loop on size of vector + for (int32_t iDigi = 0; iDigi < uNbSelDigisTofT0; ++iDigi) { + uint idx = event->GetIndex(kRawEventBuilderDetTof.dataType, iDigi); + const CbmTofDigi* pDigi = GetDigi<CbmTofDigi>(idx); + if (nullptr == pDigi) continue; - // filter T0 digis from Tof - if (GetTofDetType(pDigi) == fuDetTypeT0) { iNbDigis++; } + // filter T0 digis from Tof + if (GetTofDetType(pDigi) == fuDetTypeT0) { // + if (ECbmModuleId::kT0 == det.detId) { // + iNbDigis++; + } + } + else if (ECbmModuleId::kTof == det.detId) { // + iNbDigis++; + } + } } } if ((-1 == iNbDigis) || (static_cast<UInt_t>(iNbDigis) < det.fuTriggerMinDigis)) { @@ -1012,6 +1034,13 @@ void CbmAlgoBuildRawEvents::CreateHistograms() } /// Same plots for the reference detector + TH2I* hNbDigiPerEvtTimeDet = new TH2I(Form("hNbDigiPerEvtTime%s", fRefDet.sName.data()), + Form("nb of %s digis per event vs seed time of the events; Seed time in TS " + "[s]; Nb Digis []; Events []", + fRefDet.sName.data()), + 1000, 0, 0.2, 5000, 0, 5000); + fvhNbDigiPerEvtTimeDet.push_back(hNbDigiPerEvtTimeDet); + TH1I* hNbDigiPerEvtDet = new TH1I(Form("hNbDigiPerEvt%s", fRefDet.sName.data()), Form("nb of %s digis per event; Nb Digis []", fRefDet.sName.data()), 10000, 0, 10000); @@ -1158,13 +1187,54 @@ void CbmAlgoBuildRawEvents::FillHistos() fhNbDigiPerEvtTime->Fill(evt->GetStartTime() * 1e-9, evt->GetNofData()); /// Loop on selection detectors + uint32_t uNbDataT0 = 0; // filter T0 digis from Tof (remove this block if T0 properly implemented) + uint32_t uNbDataTof = 0; // filter T0 digis from Tof (remove this block if T0 properly implemented) uint32_t uNbDataTrd1d = 0; uint32_t uNbDataTrd2d = 0; for (UInt_t uDetIdx = 0; uDetIdx < fvDets.size(); ++uDetIdx) { if (nullptr == fvhNbDigiPerEvtDet[uDetIdx]) continue; - fvhNbDigiPerEvtDet[uDetIdx]->Fill(TMath::Max(0, evt->GetNofData(fvDets[uDetIdx].dataType))); - if (nullptr == fvhTDiff[uDetIdx]) continue; + if (0 != fuDetTypeT0) { + // filter T0 digis from Tof (remove this block if T0 properly implemented) + if (ECbmDataType::kT0Digi == fvDets[uDetIdx].dataType) { + for (int idigi = 0; idigi < evt->GetNofData(ECbmDataType::kTofDigi); ++idigi) { + double dTimeDiff = 1.E30; + uint idx = evt->GetIndex(ECbmDataType::kTofDigi, idigi); + auto pDigi = GetDigi<CbmTofDigi>(idx); + if (nullptr == pDigi) continue; + + // filter T0 digis from Tof + if (GetTofDetType(pDigi) == fuDetTypeT0) { + uNbDataT0++; + dTimeDiff = pDigi->GetTime() - evt->GetStartTime(); + if (dTimeDiff < 1.E30) { + fvhTDiff[uDetIdx]->Fill(dTimeDiff); + fhTDiffBMonChan->Fill(dTimeDiff, pDigi->GetChannel()); + } + } + } + continue; + } // if (ECbmDataType::kT0Digi == fvDets[uDetIdx].dataType) + else if (ECbmDataType::kTofDigi == fvDets[uDetIdx].dataType) { + for (int idigi = 0; idigi < evt->GetNofData(fvDets[uDetIdx].dataType); ++idigi) { + double dTimeDiff = 1.E30; + uint idx = evt->GetIndex(fvDets[uDetIdx].dataType, idigi); + auto pDigi = GetDigi<CbmTofDigi>(idx); + if (nullptr == pDigi) continue; + + // filter T0 digis from Tof + if (GetTofDetType(pDigi) != fuDetTypeT0) { + uNbDataTof++; + dTimeDiff = pDigi->GetTime() - evt->GetStartTime(); + if (dTimeDiff < 1.E30) { // + fvhTDiff[uDetIdx]->Fill(dTimeDiff); + } + } + } + continue; + } // else if (ECbmDataType::kTofDigi == fvDets[uDetIdx].dataType) + } + for (int idigi = 0; idigi < evt->GetNofData(fvDets[uDetIdx].dataType); ++idigi) { double dTimeDiff = 1.E30; uint idx = evt->GetIndex(fvDets[uDetIdx].dataType, idigi); @@ -1251,77 +1321,128 @@ void CbmAlgoBuildRawEvents::FillHistos() if (dTimeDiff < 1.E30) fvhTDiff[uDetIdx]->Fill(dTimeDiff); } + + if (ECbmDataType::kT0Digi == fvDets[uDetIdx].dataType) { + uNbDataT0 = TMath::Max(0, evt->GetNofData(fvDets[uDetIdx].dataType)); + } + if (ECbmDataType::kTofDigi == fvDets[uDetIdx].dataType) { + uNbDataTof = TMath::Max(0, evt->GetNofData(fvDets[uDetIdx].dataType)); + } } /// Reference detector uint32_t uRefDetIdx = fvDets.size(); if (nullptr != fvhNbDigiPerEvtDet[uRefDetIdx]) { - fvhNbDigiPerEvtDet[uRefDetIdx]->Fill(TMath::Max(0, evt->GetNofData(fRefDet.dataType))); - if (nullptr == fvhTDiff[uRefDetIdx]) continue; - for (int idigi = 0; idigi < evt->GetNofData(fRefDet.dataType); ++idigi) { - double dTimeDiff = 1.E30; - uint idx = evt->GetIndex(fRefDet.dataType, idigi); - switch (fRefDet.dataType) { - case ECbmDataType::kT0Digi: { - if (fT0DigiVec->size() <= idx) continue; - dTimeDiff = fT0DigiVec->at(idx).GetTime() - evt->GetStartTime(); - break; + if (0 != fuDetTypeT0 && ECbmDataType::kT0Digi == fRefDet.dataType) { + // filter T0 digis from Tof (remove this block if T0 properly implemented) + for (int idigi = 0; idigi < evt->GetNofData(ECbmDataType::kTofDigi); ++idigi) { + double dTimeDiff = 1.E30; + uint idx = evt->GetIndex(ECbmDataType::kTofDigi, idigi); + auto pDigi = GetDigi<CbmTofDigi>(idx); + if (nullptr == pDigi) continue; + + // filter T0 digis from Tof + if (GetTofDetType(pDigi) == fuDetTypeT0) { + uNbDataT0++; + dTimeDiff = pDigi->GetTime() - evt->GetStartTime(); + if (dTimeDiff < 1.E30) { + fvhTDiff[uRefDetIdx]->Fill(dTimeDiff); + fhTDiffBMonChan->Fill(dTimeDiff, pDigi->GetChannel()); + } } - case ECbmDataType::kStsDigi: { - auto pDigi = GetDigi<CbmStsDigi>(idx); - if (nullptr == pDigi) continue; + } + } // if (0 != fuDetTypeT0 && ECbmDataType::kT0Digi == fRefDet.dataType) + else if (0 != fuDetTypeT0 && ECbmDataType::kTofDigi == fRefDet.dataType) { + // filter T0 digis from Tof (remove this block if T0 properly implemented) + for (int idigi = 0; idigi < evt->GetNofData(fRefDet.dataType); ++idigi) { + double dTimeDiff = 1.E30; + uint idx = evt->GetIndex(fRefDet.dataType, idigi); + auto pDigi = GetDigi<CbmTofDigi>(idx); + if (nullptr == pDigi) continue; + + // filter T0 digis from Tof + if (GetTofDetType(pDigi) != fuDetTypeT0) { + uNbDataTof++; dTimeDiff = pDigi->GetTime() - evt->GetStartTime(); - break; + if (dTimeDiff < 1.E30) { // + fvhTDiff[uRefDetIdx]->Fill(dTimeDiff); + } } - case ECbmDataType::kMuchDigi: { - if (fbUseMuchBeamtimeDigi) { - auto pDigi = GetDigi<CbmMuchBeamTimeDigi>(idx); + } + } // else if (0 != fuDetTypeT0 && ECbmDataType::kTofDigi == fRefDet.dataType) + else { + for (int idigi = 0; idigi < evt->GetNofData(fRefDet.dataType); ++idigi) { + double dTimeDiff = 1.E30; + uint idx = evt->GetIndex(fRefDet.dataType, idigi); + switch (fRefDet.dataType) { + case ECbmDataType::kT0Digi: { + if (fT0DigiVec->size() <= idx) continue; + dTimeDiff = fT0DigiVec->at(idx).GetTime() - evt->GetStartTime(); + break; + } + case ECbmDataType::kStsDigi: { + auto pDigi = GetDigi<CbmStsDigi>(idx); if (nullptr == pDigi) continue; dTimeDiff = pDigi->GetTime() - evt->GetStartTime(); + break; } - else { - auto pDigi = GetDigi<CbmMuchDigi>(idx); + case ECbmDataType::kMuchDigi: { + if (fbUseMuchBeamtimeDigi) { + auto pDigi = GetDigi<CbmMuchBeamTimeDigi>(idx); + if (nullptr == pDigi) continue; + dTimeDiff = pDigi->GetTime() - evt->GetStartTime(); + } + else { + auto pDigi = GetDigi<CbmMuchDigi>(idx); + if (nullptr == pDigi) continue; + dTimeDiff = pDigi->GetTime() - evt->GetStartTime(); + } + break; + } + case ECbmDataType::kTofDigi: { + auto pDigi = GetDigi<CbmTofDigi>(idx); if (nullptr == pDigi) continue; dTimeDiff = pDigi->GetTime() - evt->GetStartTime(); + break; } - break; - } - case ECbmDataType::kTofDigi: { - auto pDigi = GetDigi<CbmTofDigi>(idx); - if (nullptr == pDigi) continue; - dTimeDiff = pDigi->GetTime() - evt->GetStartTime(); - break; - } - case ECbmDataType::kTrdDigi: { - auto pDigi = GetDigi<CbmTrdDigi>(idx); - if (nullptr == pDigi) continue; - dTimeDiff = pDigi->GetTime() - evt->GetStartTime(); - if (pDigi->GetType() == CbmTrdDigi::eCbmTrdAsicType::kSPADIC) { - if (fRefDet.sName == "kTrd2D") continue; - ++uNbDataTrd1d; + case ECbmDataType::kTrdDigi: { + auto pDigi = GetDigi<CbmTrdDigi>(idx); + if (nullptr == pDigi) continue; + dTimeDiff = pDigi->GetTime() - evt->GetStartTime(); + if (pDigi->GetType() == CbmTrdDigi::eCbmTrdAsicType::kSPADIC) { + if (fRefDet.sName == "kTrd2D") continue; + ++uNbDataTrd1d; + } + else if (pDigi->GetType() == CbmTrdDigi::eCbmTrdAsicType::kFASP) { + if (fRefDet.sName == "kTrd") continue; + ++uNbDataTrd2d; + } + break; } - else if (pDigi->GetType() == CbmTrdDigi::eCbmTrdAsicType::kFASP) { - if (fRefDet.sName == "kTrd") continue; - ++uNbDataTrd2d; + case ECbmDataType::kRichDigi: { + auto pDigi = GetDigi<CbmRichDigi>(idx); // FIXME, need to find the proper digi template + if (nullptr == pDigi) continue; + dTimeDiff = pDigi->GetTime() - evt->GetStartTime(); + break; } - break; - } - case ECbmDataType::kRichDigi: { - auto pDigi = GetDigi<CbmRichDigi>(idx); // FIXME, need to find the proper digi template - if (nullptr == pDigi) continue; - dTimeDiff = pDigi->GetTime() - evt->GetStartTime(); - break; - } - case ECbmDataType::kPsdDigi: { - auto pDigi = GetDigi<CbmPsdDigi>(idx); // FIXME, need to find the proper digi template - if (nullptr == pDigi) continue; - dTimeDiff = pDigi->GetTime() - evt->GetStartTime(); - break; + case ECbmDataType::kPsdDigi: { + auto pDigi = GetDigi<CbmPsdDigi>(idx); // FIXME, need to find the proper digi template + if (nullptr == pDigi) continue; + dTimeDiff = pDigi->GetTime() - evt->GetStartTime(); + break; + } + default: LOG(error) << "Unkown dataType " << fRefDet.dataType; } - default: LOG(error) << "Unkown dataType " << fRefDet.dataType; + + if (dTimeDiff < 1.E30) fvhTDiff[uRefDetIdx]->Fill(dTimeDiff); } - if (dTimeDiff < 1.E30) fvhTDiff[uRefDetIdx]->Fill(dTimeDiff); + if (ECbmDataType::kT0Digi == fRefDet.dataType) { // + uNbDataT0 = TMath::Max(0, evt->GetNofData(fRefDet.dataType)); + } + if (ECbmDataType::kTofDigi == fRefDet.dataType) { + uNbDataTof = TMath::Max(0, evt->GetNofData(fRefDet.dataType)); + } } } @@ -1329,16 +1450,55 @@ void CbmAlgoBuildRawEvents::FillHistos() for (UInt_t uDetIdx = 0; uDetIdx < fvDets.size(); ++uDetIdx) { if (nullptr == fvhNbDigiPerEvtTimeDet[uDetIdx]) continue; - if (fvDets[uDetIdx].sName == "kTrd") { + if (0 != fuDetTypeT0 && fvDets[uDetIdx].sName == "T0") { + // filter T0 digis from Tof (remove this block if T0 properly implemented) + fvhNbDigiPerEvtDet[uDetIdx]->Fill(uNbDataT0); + fvhNbDigiPerEvtTimeDet[uDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataT0); + } + else if (0 != fuDetTypeT0 && fvDets[uDetIdx].sName == "Tof") { + // filter T0 digis from Tof (remove this block if T0 properly implemented) + fvhNbDigiPerEvtDet[uDetIdx]->Fill(uNbDataTof); + fvhNbDigiPerEvtTimeDet[uDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataTof); + } + else if (fvDets[uDetIdx].sName == "kTrd") { + fvhNbDigiPerEvtDet[uDetIdx]->Fill(uNbDataTrd1d); fvhNbDigiPerEvtTimeDet[uDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataTrd1d); } else if (fvDets[uDetIdx].sName == "kTrd2D") { + fvhNbDigiPerEvtDet[uDetIdx]->Fill(uNbDataTrd2d); fvhNbDigiPerEvtTimeDet[uDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataTrd2d); } else { - fvhNbDigiPerEvtTimeDet[uDetIdx]->Fill(evt->GetStartTime() * 1e-9, evt->GetNofData(fvDets[uDetIdx].dataType)); + fvhNbDigiPerEvtDet[uDetIdx]->Fill(TMath::Max(0, evt->GetNofData(fvDets[uDetIdx].dataType))); + fvhNbDigiPerEvtTimeDet[uDetIdx]->Fill(evt->GetStartTime() * 1e-9, + TMath::Max(0, evt->GetNofData(fvDets[uDetIdx].dataType))); } } + /// Same for the reference detector + if (0 != fuDetTypeT0 && fRefDet.sName == "T0") { + // filter T0 digis from Tof (remove this block if T0 properly implemented) + fvhNbDigiPerEvtDet[uRefDetIdx]->Fill(uNbDataT0); + fvhNbDigiPerEvtTimeDet[uRefDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataT0); + } + else if (0 != fuDetTypeT0 && fRefDet.sName == "Tof") { + // filter T0 digis from Tof (remove this block if T0 properly implemented) + fvhNbDigiPerEvtDet[uRefDetIdx]->Fill(uNbDataTof); + fvhNbDigiPerEvtTimeDet[uRefDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataTof); + } + else if (fRefDet.sName == "kTrd") { + fvhNbDigiPerEvtDet[uRefDetIdx]->Fill(uNbDataTrd1d); + fvhNbDigiPerEvtTimeDet[uRefDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataTrd1d); + } + else if (fRefDet.sName == "kTrd2D") { + fvhNbDigiPerEvtDet[uRefDetIdx]->Fill(uNbDataTrd2d); + fvhNbDigiPerEvtTimeDet[uRefDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataTrd2d); + } + else { + fvhNbDigiPerEvtDet[uRefDetIdx]->Fill(TMath::Max(0, evt->GetNofData(fRefDet.dataType))); + fvhNbDigiPerEvtTimeDet[uRefDetIdx]->Fill(evt->GetStartTime() * 1e-9, + TMath::Max(0, evt->GetNofData(fRefDet.dataType))); + } + dPreEvtTime = evt->GetStartTime(); } } @@ -1371,7 +1531,7 @@ void CbmAlgoBuildRawEvents::ResetHistograms(Bool_t /*bResetTime*/) fhTDiffMuchRpc->Reset(); } /// ==> mBMON specific histograms - if (nullptr != fhTDiffBMonChan) { + if (nullptr != fhTDiffBMonChan) { // fhTDiffBMonChan->Reset(); } diff --git a/reco/steer/CbmRecoUnpack.cxx b/reco/steer/CbmRecoUnpack.cxx index 7035638408ec2b60e7ad3b2b262ad7fa0360dfbf..a3518735e80bca898a397fd9d3e53adac82d55ce 100644 --- a/reco/steer/CbmRecoUnpack.cxx +++ b/reco/steer/CbmRecoUnpack.cxx @@ -360,6 +360,10 @@ void CbmRecoUnpack::Unpack(unique_ptr<Timeslice> ts) fCbmTsEventHeader->AddNDigisBmon(unpack(systemId, ×lice, component, fBmonConfig, fBmonConfig->GetOptOutAVec(), fBmonConfig->GetOptOutBVec())); } + else if (fTofConfig) { + fCbmTsEventHeader->AddNDigisTof(unpack(fkFlesTof, ×lice, component, fTofConfig, + fTofConfig->GetOptOutAVec(), fTofConfig->GetOptOutBVec())); + } break; } default: {