From 3e83afefbf3968f638dee0e1ff478d8eec9822f8 Mon Sep 17 00:00:00 2001 From: Dominik Smith <d.smith@gsi.de> Date: Wed, 3 Jul 2024 17:22:56 +0200 Subject: [PATCH] Updated CbmTaskUnpack to reflect the current state of the online binary. Added macro run_unpack_tsa_algo.C with exemplary execution. --- macro/run/run_unpack_tsa_algo.C | 120 +++++++++++++++++ reco/tasks/CbmReco.cxx | 4 +- reco/tasks/CbmTaskUnpack.cxx | 225 +++++++------------------------- reco/tasks/CbmTaskUnpack.h | 28 ++-- 4 files changed, 180 insertions(+), 197 deletions(-) create mode 100644 macro/run/run_unpack_tsa_algo.C diff --git a/macro/run/run_unpack_tsa_algo.C b/macro/run/run_unpack_tsa_algo.C new file mode 100644 index 0000000000..2fd9dcd58a --- /dev/null +++ b/macro/run/run_unpack_tsa_algo.C @@ -0,0 +1,120 @@ +/* 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 */ + +/** @file run_unpack_tsa_algo.C + ** @author Volker Friese <v.friese@gsi.de> + ** @since May 2021 + **/ + + +// --- Includes needed for IDE +#include <RtypesCore.h> + +#include <cstdint> +#include <memory> +#include <string> +#include <vector> +#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 + +void run_unpack_tsa_algo(std::string infile, std::string outpath, std::string paramsdir, UInt_t runid, + std::int32_t nevents = -1) +{ + + // ======================================================================== + // Adjust this part according to your requirements + + // --- Logger settings ---------------------------------------------------- + TString logLevel = "INFO"; + TString logVerbosity = "LOW"; + // ------------------------------------------------------------------------ + + // ----- Environment -------------------------------------------------- + TString myName = "run_unpack_tsa_algo"; // this macro's name for screen output + TString srcDir = gSystem->Getenv("VMCWORKDIR"); // top source directory + // ------------------------------------------------------------------------ + + + // ----- Output filename ---------------------------------------------- + std::string outfilename = infile; + auto filenamepos = infile.find_last_of("/"); + filenamepos++; + std::string filename = infile.substr(filenamepos); + if (filename.find("*") != infile.npos) filename = std::to_string(runid) + ".tsa"; + if (filename.find(";") != infile.npos) filename = std::to_string(runid) + "_merged" + ".tsa"; + if (outpath.empty()) { + outpath = infile.substr(0, filenamepos); + } + outfilename = outpath + filename; + outfilename.replace(outfilename.find(".tsa"), 4, "_algo.digi.root"); + std::cout << "-I- " << myName << ": Output file will be " << outfilename << std::endl; + // ------------------------------------------------------------------------ + + + // ----- Timer -------------------------------------------------------- + TStopwatch timer; + timer.Start(); + // ------------------------------------------------------------------------ + + auto source = new CbmSourceTs(infile.c_str()); + + // ----- FairRunAna --------------------------------------------------- + auto run = new FairRunOnline(source); + auto sink = new FairRootFileSink(outfilename.data()); + + // ----- Algo Unpacker ------------------------------------------------- + //run->AddTask(new CbmTaskUnpack()); + run->AddTask(new CbmTaskUnpack(paramsdir, runid)); + + run->SetSink(sink); + auto eventheader = new CbmTsEventHeader(); + run->SetRunId(runid); + run->SetEventHeader(eventheader); + // ------------------------------------------------------------------------ + + // ----- 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 (nevents < 0) + run->Run(-1, 0); + else + run->Run(0, nevents); + // ------------------------------------------------------------------------ + + + // ----- Finish ------------------------------------------------------- + timer.Stop(); + std::cout << "Macro finished successfully." << std::endl; + std::cout << "After CpuTime = " << timer.CpuTime() << " s RealTime = " << timer.RealTime() << " s." << std::endl; + // ------------------------------------------------------------------------ + + // -- Release all shared pointers to config before ROOT destroys things - + // => We need to destroy things by hand because run->Finish calls (trhought the FairRootManager) Source->Close which + // does call the Source destructor, so due to share pointer things stay alive until out of macro scope... + run->SetSource(nullptr); + delete run; + // ------------------------------------------------------------------------ + +} // End of main macro function diff --git a/reco/tasks/CbmReco.cxx b/reco/tasks/CbmReco.cxx index 8d198b7c6e..84e865f39c 100644 --- a/reco/tasks/CbmReco.cxx +++ b/reco/tasks/CbmReco.cxx @@ -128,7 +128,9 @@ int32_t CbmReco::Run() if (!isRootInput) { CbmTaskUnpack::Config unpackConfig; unpackConfig.dumpSetup = fConfig.dumpSetup; - auto unpack = make_unique<CbmTaskUnpack>(unpackConfig); + //auto unpack = make_unique<CbmTaskUnpack>(unpackConfig); + // TO DO: This call no longer works. Parameters directory and run ID is needed! + auto unpack = make_unique<CbmTaskUnpack>(); unpack->SetMonitor(fMonitor); unpack->SetOutputBranchPersistent("DigiTimeslice.", false); run.AddTask(unpack.release()); diff --git a/reco/tasks/CbmTaskUnpack.cxx b/reco/tasks/CbmTaskUnpack.cxx index b7bcae797a..9fa2a88fda 100644 --- a/reco/tasks/CbmTaskUnpack.cxx +++ b/reco/tasks/CbmTaskUnpack.cxx @@ -18,6 +18,7 @@ #include "CbmTrdParSetDigi.h" #include "CbmTrdParSpadic.h" #include "MicrosliceDescriptor.hpp" +#include "ParFiles.h" #include "System.hpp" #include "bmon/ReadoutConfig.h" #include "sts/ChannelMaskSet.h" @@ -42,8 +43,46 @@ using namespace std; using namespace cbm::algo; + +// ----- Constructor ----------------------------------------------------- +CbmTaskUnpack::CbmTaskUnpack() : FairTask("Unpack") +{ + L_(fatal) << "Instantiated CbmTaskUnpack() without arguments (needs path to parameters and run ID)."; +} + // ----- Constructor ----------------------------------------------------- -CbmTaskUnpack::CbmTaskUnpack(Config config) : FairTask("Unpack"), fConfig(config) {} +CbmTaskUnpack::CbmTaskUnpack(fs::path paramsDir, uint32_t runId) : FairTask("Unpack") +{ + ParFiles parFiles(runId); + L_(info) << "Using parameter files for setup " << parFiles.setup; + + sts::ReadoutSetup stsSetup = yaml::ReadFromFile<sts::ReadoutSetup>(paramsDir / parFiles.sts.readout); + auto chanMask = yaml::ReadFromFile<sts::ChannelMaskSet>(paramsDir / parFiles.sts.chanMask); + auto walkMap = yaml::ReadFromFile<sts::WalkMap>(paramsDir / parFiles.sts.walkMap); + sts::ReadoutConfig readout{stsSetup, chanMask}; + sts::Unpack::Config stsCfg{.readout = readout, .walkMap = walkMap, .bCollectAuxData = false}; + fStsUnpack = std::make_unique<sts::Unpack>(stsCfg); + + tof::ReadoutSetup tofSetup = yaml::ReadFromFile<tof::ReadoutSetup>(paramsDir / parFiles.tof.readout); + tof::ReadoutConfig tofCfg{tofSetup}; + fTofUnpack = std::make_unique<tof::Unpack>(tofCfg); + + bmon::ReadoutSetup bmonSetup = yaml::ReadFromFile<bmon::ReadoutSetup>(paramsDir / parFiles.bmon.readout); + bmon::ReadoutConfig bmonCfg{bmonSetup}; + fBmonUnpack = std::make_unique<bmon::Unpack>(bmonCfg); + + auto trdCfg = yaml::ReadFromFile<trd::ReadoutConfig>(paramsDir / parFiles.trd.readout); + fTrdUnpack = std::make_unique<trd::Unpack>(trdCfg); + + auto trd2dCfg = yaml::ReadFromFile<trd2d::ReadoutConfig>(paramsDir / parFiles.trd.readout2d); + fTrd2dUnpack = std::make_unique<trd2d::Unpack>(trd2dCfg); + + much::ReadoutConfig muchCfg{}; + fMuchUnpack = std::make_unique<much::Unpack>(muchCfg); + + rich::ReadoutConfig richCfg{}; + fRichUnpack = std::make_unique<rich::Unpack>(richCfg); +} // --------------------------------------------------------------------------- @@ -83,6 +122,11 @@ void CbmTaskUnpack::Exec(Option_t*) digis.fTrd = RunUnpacker(fTrdUnpack, *timeslice, monitor); digis.fTrd2d = RunUnpacker(fTrd2dUnpack, *timeslice, monitor); + // Use lines below to combine TRD 1D and 2D + //auto& digis1d = digis.fTrd; + //auto& digis2d = digis.fTrd2d; + //std::copy(digis2d.begin(), digis2d.end(), std::back_inserter(digis1d)); + fTimeslice->fData = digis.ToStorable(); // --- Timeslice log @@ -165,189 +209,10 @@ InitStatus CbmTaskUnpack::Init() ioman->RegisterAny("DigiTimeslice.", fTimeslice, IsOutputBranchPersistent("DigiTimeslice.")); LOG(info) << "--- Registered branch DigiTimeslice."; - // ---- Initialize unpacker - - std::string bmonReadoutFile = Form("%s/parameters/online/BmonReadout_mcbm2022.yaml", std::getenv("VMCWORKDIR")); - auto bmonReadoutPars = yaml::ReadFromFile<bmon::ReadoutSetup>(bmonReadoutFile); - fBmonUnpack = std::make_unique<bmon::Unpack>(bmon::ReadoutConfig{bmonReadoutPars}); - - fMuchUnpack = std::make_unique<much::Unpack>(much::ReadoutConfig{}); - fRichUnpack = std::make_unique<rich::Unpack>(rich::ReadoutConfig{}); - - std::string stsReadoutFile = Form("%s/parameters/online/StsReadout_mcbm2022.yaml", std::getenv("VMCWORKDIR")); - sts::ReadoutSetup readoutSetup = yaml::ReadFromFile<sts::ReadoutSetup>(stsReadoutFile); - - std::string stsWalkMapFile = Form("%s/parameters/online/StsWalkMap_mcbm2022.yaml", std::getenv("VMCWORKDIR")); - auto walkMap = yaml::ReadFromFile<sts::WalkMap>(stsWalkMapFile); - - sts::ReadoutConfig readout{readoutSetup, sts::ChannelMaskSet()}; - sts::Unpack::Config cfg{.readout = readout, .walkMap = walkMap}; - fStsUnpack = std::make_unique<sts::Unpack>(cfg); - - std::string tofReadoutFile = Form("%s/parameters/online/TofReadout_mcbm2022.yaml", std::getenv("VMCWORKDIR")); - auto tofReadoutPars = yaml::ReadFromFile<tof::ReadoutSetup>(tofReadoutFile); - fTofUnpack = std::make_unique<tof::Unpack>(tof::ReadoutConfig{tofReadoutPars}); - fTrdUnpack = std::make_unique<trd::Unpack>(InitTrdReadoutConfig()); - fTrd2dUnpack = std::make_unique<trd2d::Unpack>(InitTrd2dReadoutConfig()); - - if (fConfig.dumpSetup) { - DumpUnpackSetup(); - } - return kSUCCESS; } // ---------------------------------------------------------------------------- -// ----- Initialisation --------------------------------------------------- -cbm::algo::trd2d::ReadoutConfig CbmTaskUnpack::InitTrd2dReadoutConfig() -{ - // Output object - cbm::algo::trd2d::ReadoutConfig Trd2dConfig; - - // Initialize input files - FairParAsciiFileIo asciiInput; - std::string digiparfile = Form("%s/parameters/trd/trd_v22h_mcbm.digi.par", std::getenv("VMCWORKDIR")); - std::string asicparfile = Form("%s/parameters/trd/trd_v22h_mcbm.asic.par", std::getenv("VMCWORKDIR")); - - // Read the .digi file and store result - CbmTrdParSetDigi digiparset; - if (asciiInput.open(digiparfile.data())) { - digiparset.init(&asciiInput); - } - asciiInput.close(); - - // Read the .asic file and store result - CbmTrdParSetAsic asicparset; - if (asciiInput.open(asicparfile.data())) { - asicparset.init(&asciiInput); - } - asciiInput.close(); - - // Map (moduleId) -> (array of crobId) - std::map<uint32_t, uint16_t[NCROBMOD]> crobMap; - // Map (equipId, asicId, chanId) -> (pad address, mask flag, daq offset [FASP clk]) - std::map<size_t, std::map<size_t, std::map<size_t, std::tuple<int32_t, bool, uint64_t>>>> channelMap; - - // Loop through a list of module IDs from the .digi file (can in principle contradict crob_map). - for (auto entry : digiparset.GetModuleMap()) { - - const auto moduleId = entry.first; - - // Get ASIC parameters for this module - CbmTrdParModAsic* setDet = static_cast<CbmTrdParModAsic*>(asicparset.GetModulePar(moduleId)); - if (!setDet) continue; - if (setDet->GetAsicType() != CbmTrdDigi::eCbmTrdAsicType::kFASP) continue; - auto digipar = entry.second; - - const int* crobs = setDet->GetCrobAddresses(); - for (int icrob(0); icrob < NCROBMOD; icrob++) - crobMap[moduleId][icrob] = crobs[icrob]; - - // Loop through ASICs for this module - std::vector<int32_t> addresses; - setDet->GetAsicAddresses(&addresses); - for (auto add : addresses) { - //Get local IDs for this component / equipment. - const int32_t fasp_in_mod = add - 1000 * moduleId; - const int32_t fasp_in_eq = fasp_in_mod % (NFASPCROB); - const int32_t crob_in_mod = fasp_in_mod / (NFASPCROB); - const uint16_t eq_id = crobMap[moduleId][crob_in_mod]; - - // ASIC parameter set - CbmTrdParFasp* fasppar = (CbmTrdParFasp*) setDet->GetAsicPar(add); - - // Loop through channels for this ASIC and fill map - for (int chan = 0; chan < fasppar->GetNchannels(); chan++) { - const CbmTrdParFaspChannel* faspch = fasppar->GetChannel(chan); - const int32_t pad = fasppar->GetPadAddress(chan) * (faspch->HasPairingR() ? 1 : -1); - const bool isMasked = faspch->IsMasked(); - uint64_t daq_offset = 0; - if (((CbmTrdParModDigi*) digipar)->GetPadRow(pad) % 2 == 0) daq_offset = 3; - channelMap[eq_id][fasp_in_eq][chan] = std::make_tuple(pad, isMasked, daq_offset); - } - } - } - - Trd2dConfig.InitComponentMap(crobMap); - Trd2dConfig.InitChannelMap(channelMap); - return Trd2dConfig; -} - -// ----- Initialisation --------------------------------------------------- -cbm::algo::trd::ReadoutConfig CbmTaskUnpack::InitTrdReadoutConfig() -{ - // Output object - cbm::algo::trd::ReadoutConfig TrdConfig; - - std::string trdparfile = Form("%s/parameters/trd/trd_v22h_mcbm.asic.par", std::getenv("VMCWORKDIR")); - - CbmTrdParSetAsic trdpar; - - FairParAsciiFileIo asciiInput; - if (asciiInput.open(trdparfile.data())) { - trdpar.init(&asciiInput); - } - - FairParamList parlist; - trdpar.putParams(&parlist); - - std::vector<int> moduleIds(trdpar.GetNrOfModules()); - parlist.fill("ModuleId", moduleIds.data(), moduleIds.size()); - - std::map<size_t, std::map<size_t, std::map<size_t, size_t>>> addressMap; //[criId][crobId][elinkId] -> asicAddress - std::map<size_t, std::map<size_t, std::map<size_t, std::map<size_t, size_t>>>> - channelMap; //[criId][crobId][elinkId][chanId] -> chanAddress - - for (auto module : moduleIds) { - CbmTrdParModAsic* moduleSet = (CbmTrdParModAsic*) trdpar.GetModulePar(module); - - // Skip entries for "Fasp" modules in .asic.par file - if (moduleSet->GetAsicType() != CbmTrdDigi::eCbmTrdAsicType::kSPADIC) continue; - - std::vector<int> asicAddresses; - moduleSet->GetAsicAddresses(&asicAddresses); - - for (auto address : asicAddresses) { - CbmTrdParSpadic* asicPar = (CbmTrdParSpadic*) moduleSet->GetAsicPar(address); - const uint16_t criId = asicPar->GetCriId(); - const uint8_t crobId = asicPar->GetCrobId(); - const uint8_t elinkId = asicPar->GetElinkId(0); - if (elinkId >= 98) { - continue; - } // Don't add not connected asics to the map - addressMap[criId][crobId][elinkId] = address; - addressMap[criId][crobId][elinkId + 1] = address; - - const uint8_t numChans = 16; - for (uint8_t chan = 0; chan < numChans; chan++) { - auto asicChannelId = (elinkId % 2) == 0 ? chan : chan + numChans; - auto chanAddr = asicPar->GetChannelAddresses().at(asicChannelId); - channelMap[criId][crobId][elinkId][chan] = chanAddr; - } - for (uint8_t chan = 0; chan < numChans; chan++) { - auto asicChannelId = (elinkId + 1 % 2) == 0 ? chan : chan + numChans; - auto chanAddr = asicPar->GetChannelAddresses().at(asicChannelId); - channelMap[criId][crobId][elinkId + 1][chan] = chanAddr; - } - LOG(debug) << "componentID " << asicPar->GetComponentId() << " " - << "address " << address << " key " << criId << " " << unsigned(crobId) << " " << unsigned(elinkId); - } - } - TrdConfig.Init(addressMap, channelMap); - LOG(debug) << TrdConfig.PrintReadoutMap(); - return TrdConfig; -} - -void CbmTaskUnpack::DumpUnpackSetup() -{ - LOG(info) << "--- Dumping readout setup to yaml file ---"; - - auto yaml = yaml::Dump{}(fTrdUnpack->Readout()); - std::ofstream("TrdReadoutSetup.yaml") << yaml; - - yaml = yaml::Dump{}(fTrd2dUnpack->Readout()); - std::ofstream("Trd2dReadoutSetup.yaml") << yaml; -} template<class Unpacker> auto CbmTaskUnpack::RunUnpacker(const std::unique_ptr<Unpacker>& unpacker, const fles::Timeslice& timeslice, diff --git a/reco/tasks/CbmTaskUnpack.h b/reco/tasks/CbmTaskUnpack.h index ccb50f7a87..69cec6e193 100644 --- a/reco/tasks/CbmTaskUnpack.h +++ b/reco/tasks/CbmTaskUnpack.h @@ -21,6 +21,7 @@ namespace cbm #include "AlgoTraits.h" #include "EventBuilder.h" +#include "ParFiles.h" #include "bmon/Unpack.h" #include "much/Unpack.h" #include "rich/Unpack.h" @@ -31,12 +32,15 @@ namespace cbm #include <FairTask.h> +#include <boost/filesystem.hpp> + #include <sstream> #include <vector> class CbmDigiManager; class CbmSourceTs; +namespace fs = boost::filesystem; /** @class CbmTaskUnpack ** @brief Task class for associating digis to events @@ -51,8 +55,7 @@ class CbmSourceTs; **/ class CbmTaskUnpack : public FairTask { - -public: + public: struct Config { bool dumpSetup = false; }; @@ -65,7 +68,11 @@ public: }; /** @brief Constructor **/ - CbmTaskUnpack(Config config); + CbmTaskUnpack(); + + + /** @brief Constructor **/ + CbmTaskUnpack(fs::path paramsDir, uint32_t runId); /** @brief Copy constructor (disabled) **/ @@ -92,22 +99,11 @@ public: void SetMonitor(cbm::Monitor* monitor) { fMonitor = monitor; } -private: // methods + private: // methods /** @brief Task initialisation **/ virtual InitStatus Init(); - /** @brief Initialisation of address maps for Trd **/ - cbm::algo::trd::ReadoutConfig InitTrdReadoutConfig(); - - - /** @brief Initialisation of address maps for Trd2d **/ - cbm::algo::trd2d::ReadoutConfig InitTrd2dReadoutConfig(); - - void DumpUnpackSetup(); - -private: // members - Config fConfig = {}; ///< Configuration - + private: // members CbmSourceTs* fSource = nullptr; cbm::Monitor* fMonitor = nullptr; std::string fHostname; -- GitLab