| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 9b8fb23 commit 06c1b84
9 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -13,6 +13,7 @@ add_subdirectory(base) | |||
| 13 | 13 | add_subdirectory(reconstruction) | |
| 14 | 14 | add_subdirectory(calibration) | |
| 15 | 15 | add_subdirectory(simulation) | |
| 16 | + add_subdirectory(simworkflow) | ||
| 16 | 17 | add_subdirectory(monitor) | |
| 17 | 18 | add_subdirectory(workflow) | |
| 18 | 19 | add_subdirectory(qc) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,28 @@ | |||
| 1 | + # Copyright 2019-2020 CERN and copyright holders of ALICE O2. | ||
| 2 | + # See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. | ||
| 3 | + # All rights not expressly granted are reserved. | ||
| 4 | + # | ||
| 5 | + # This software is distributed under the terms of the GNU General Public | ||
| 6 | + # License v3 (GPL Version 3), copied verbatim in the file "COPYING". | ||
| 7 | + # | ||
| 8 | + # In applying this license CERN does not waive the privileges and immunities | ||
| 9 | + # granted to it by virtue of its status as an Intergovernmental Organization | ||
| 10 | + # or submit itself to any jurisdiction. | ||
| 11 | + | ||
| 12 | + o2_add_library(TPCSimWorkflow | ||
| 13 | + SOURCES | ||
| 14 | + src/ChunkedDigitPublisher.cxx | ||
| 15 | + src/TPCDigitRootWriterSpec.cxx | ||
| 16 | + PUBLIC_LINK_LIBRARIES O2::TPCSimulation O2::Framework) | ||
| 17 | + | ||
| 18 | + o2_add_executable(chunkeddigit-merger | ||
| 19 | + COMPONENT_NAME tpc | ||
| 20 | + TARGETVARNAME mergertargetName | ||
| 21 | + SOURCES src/ChunkedDigitPublisher.cxx | ||
| 22 | + PUBLIC_LINK_LIBRARIES O2::TPCSimWorkflow) | ||
| 23 | + | ||
| 24 | + if(OpenMP_CXX_FOUND) | ||
| 25 | + # Must be private, depending libraries might be compiled by compiler not understanding -fopenmp | ||
| 26 | + target_compile_definitions(${mergertargetName} PRIVATE WITH_OPENMP) | ||
| 27 | + target_link_libraries(${mergertargetName} PRIVATE OpenMP::OpenMP_CXX) | ||
| 28 | + endif() | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,6 +19,7 @@ | |||
| 19 | 19 | #include "Framework/DataAllocator.h" | |
| 20 | 20 | #include "Framework/ControlService.h" | |
| 21 | 21 | #include "DataFormatsTPC/Digit.h" | |
| 22 | + #include "TPCSimWorkflow/TPCDigitRootWriterSpec.h" | ||
| 22 | 23 | #include "CommonUtils/ConfigurableParam.h" | |
| 23 | 24 | #include "DetectorsRaw/HBFUtilsInitializer.h" | |
| 24 | 25 | #include "TPCSimulation/CommonMode.h" | |
@@ -46,6 +47,9 @@ | |||
| 46 | 47 | #include <omp.h> | |
| 47 | 48 | #endif | |
| 48 | 49 | #include <TStopwatch.h> | |
| 50 | + #include "CommonDataFormat/RangeReference.h" | ||
| 51 | + | ||
| 52 | + using DigiGroupRef = o2::dataformats::RangeReference<int, int>; | ||
| 49 | 53 | ||
| 50 | 54 | using SubSpecificationType = o2::framework::DataAllocator::SubSpecificationType; | |
| 51 | 55 | ||
@@ -71,6 +75,9 @@ void customize(std::vector<o2::framework::ConfigParamSpec>& workflowOptions) | |||
| 71 | 75 | workflowOptions.push_back( | |
| 72 | 76 | ConfigParamSpec{"tpc-sectors", VariantType::String, sectorDefault.c_str(), {sectorshelp}}); | |
| 73 | 77 | ||
| 78 | + // option to write merged data to file | ||
| 79 | + workflowOptions.push_back(ConfigParamSpec{"writer-mode", o2::framework::VariantType::Bool, false, {"enable ROOT file output"}}); | ||
| 80 | + | ||
| 74 | 81 | // option to disable MC truth | |
| 75 | 82 | workflowOptions.push_back(ConfigParamSpec{"disable-mc", o2::framework::VariantType::Bool, false, {"disable mc-truth"}}); | |
| 76 | 83 | workflowOptions.push_back(ConfigParamSpec{"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings ..."}}); | |
@@ -104,14 +111,30 @@ void copyHelper<MCTruthContainer>(MCTruthContainer const& origin, MCTruthContain | |||
| 104 | 111 | target.mergeAtBack(origin); | |
| 105 | 112 | } | |
| 106 | 113 | ||
| 114 | + // a trait to map TPC data types to a DPL channel name | ||
| 115 | + template <typename T> | ||
| 116 | + struct OutputChannelName; | ||
| 117 | + template <> | ||
| 118 | + struct OutputChannelName<std::vector<o2::tpc::Digit>> { | ||
| 119 | + static constexpr char value[] = "DIGITS"; | ||
| 120 | + }; | ||
| 121 | + template <> | ||
| 122 | + struct OutputChannelName<std::vector<o2::tpc::CommonMode>> { | ||
| 123 | + static constexpr char value[] = "COMMONMODE"; | ||
| 124 | + }; | ||
| 125 | + template <> | ||
| 126 | + struct OutputChannelName<std::vector<DigiGroupRef>> { | ||
| 127 | + static constexpr char value[] = "DIGTRIGGERS"; | ||
| 128 | + }; | ||
| 129 | + | ||
| 107 | 130 | template <typename T> | |
| 108 | 131 | auto makePublishBuffer(framework::ProcessingContext& pc, int sector, uint64_t activeSectors) | |
| 109 | 132 | { | |
| 110 | - LOG(info) << "PUBLISHING SECTOR " << sector; | ||
| 133 | + LOG(info) << "PUBLISHING SECTOR " << sector << " FOR CHANNEL " << OutputChannelName<T>::value; | ||
| 111 | 134 | ||
| 112 | 135 | o2::tpc::TPCSectorHeader header{sector}; | |
| 113 | 136 | header.activeSectors = activeSectors; | |
| 114 | - return &pc.outputs().make<T>(Output{"TPC", "DIGITS", static_cast<SubSpecificationType>(sector), header}); | ||
| 137 | + return &pc.outputs().make<T>(Output{"TPC", OutputChannelName<T>::value, static_cast<SubSpecificationType>(sector), header}); | ||
| 115 | 138 | } | |
| 116 | 139 | ||
| 117 | 140 | template <> | |
@@ -187,6 +210,30 @@ void mergeHelper(const char* brprefix, std::vector<int> const& tpcsectors, uint6 | |||
| 187 | 210 | } | |
| 188 | 211 | } | |
| 189 | 212 | ||
| 213 | + template <> | ||
| 214 | + void mergeHelper<std::vector<DigiGroupRef>>(const char* brprefix, std::vector<int> const& tpcsectors, uint64_t activeSectors, | ||
| 215 | + TFile& originfile, framework::ProcessingContext& pc) | ||
| 216 | + { | ||
| 217 | + // specialization for TPC Trigger | ||
| 218 | + auto keyslist = originfile.GetListOfKeys(); | ||
| 219 | + for (int i = 0; i < keyslist->GetEntries(); ++i) { | ||
| 220 | + auto key = keyslist->At(i); | ||
| 221 | + int sector = atoi(key->GetName()); | ||
| 222 | + if (std::find(tpcsectors.begin(), tpcsectors.end(), sector) == tpcsectors.end()) { | ||
| 223 | + // do nothing if sector not wanted | ||
| 224 | + continue; | ||
| 225 | + } | ||
| 226 | + | ||
| 227 | + using AccumType = std::decay_t<decltype(makePublishBuffer<std::vector<DigiGroupRef>>(pc, sector, activeSectors))>; | ||
| 228 | + AccumType accum; | ||
| 229 | + #pragma omp critical | ||
| 230 | + accum = makePublishBuffer<std::vector<DigiGroupRef>>(pc, sector, activeSectors); | ||
| 231 | + // no actual data sent. Continuous mode. | ||
| 232 | + | ||
| 233 | + publishBuffer(pc, sector, activeSectors, accum); | ||
| 234 | + } | ||
| 235 | + } | ||
| 236 | + | ||
| 190 | 237 | void publishMergedTimeframes(std::vector<int> const& lanes, std::vector<int> const& tpcsectors, bool domctruth, framework::ProcessingContext& pc) | |
| 191 | 238 | { | |
| 192 | 239 | uint64_t activeSectors = 0; | |
@@ -208,13 +255,21 @@ void publishMergedTimeframes(std::vector<int> const& lanes, std::vector<int> con | |||
| 208 | 255 | auto originfile = new TFile(filename.c_str(), "OPEN"); | |
| 209 | 256 | assert(originfile); | |
| 210 | 257 | ||
| 211 | - //data definitions | ||
| 258 | + // data definitions | ||
| 212 | 259 | using DigitsType = std::vector<o2::tpc::Digit>; | |
| 213 | 260 | using LabelType = o2::dataformats::MCTruthContainer<o2::MCCompLabel>; | |
| 214 | 261 | mergeHelper<DigitsType>("TPCDigit_", tpcsectors, activeSectors, *originfile, pc); | |
| 215 | 262 | if (domctruth) { | |
| 216 | 263 | mergeHelper<LabelType>("TPCDigitMCTruth_", tpcsectors, activeSectors, *originfile, pc); | |
| 217 | 264 | } | |
| 265 | + | ||
| 266 | + // we also merge common modes and publish a (fake) trigger entry | ||
| 267 | + using CommonModeType = std::vector<o2::tpc::CommonMode>; | ||
| 268 | + mergeHelper<CommonModeType>("TPCCommonMode_", tpcsectors, activeSectors, *originfile, pc); | ||
| 269 | + | ||
| 270 | + using TriggerType = std::vector<DigiGroupRef>; | ||
| 271 | + mergeHelper<TriggerType>("TPCCommonMode_", tpcsectors, activeSectors, *originfile, pc); | ||
| 272 | + | ||
| 218 | 273 | originfile->Close(); | |
| 219 | 274 | delete originfile; | |
| 220 | 275 | } | |
@@ -257,7 +312,7 @@ class Task | |||
| 257 | 312 | /// MC truth information is also aggregated and written out | |
| 258 | 313 | DataProcessorSpec getSpec(std::vector<int> const& laneConfiguration, std::vector<int> const& tpcsectors, bool mctruth, bool publish = true) | |
| 259 | 314 | { | |
| 260 | - //data definitions | ||
| 315 | + // data definitions | ||
| 261 | 316 | using DigitsOutputType = std::vector<o2::tpc::Digit>; | |
| 262 | 317 | using CommonModeOutputType = std::vector<o2::tpc::CommonMode>; | |
| 263 | 318 | ||
@@ -266,10 +321,14 @@ DataProcessorSpec getSpec(std::vector<int> const& laneConfiguration, std::vector | |||
| 266 | 321 | // effectively the input expects one sector per subspecification | |
| 267 | 322 | for (int s = 0; s < 36; ++s) { | |
| 268 | 323 | OutputLabel binding{std::to_string(s)}; | |
| 269 | - outputs.emplace_back(/*binding,*/ "TPC", "DIGITS", static_cast<SubSpecificationType>(s), Lifetime::Timeframe); | ||
| 324 | + outputs.emplace_back("TPC", "DIGITS", static_cast<SubSpecificationType>(s), Lifetime::Timeframe); | ||
| 270 | 325 | if (mctruth) { | |
| 271 | - outputs.emplace_back(/*binding,*/ "TPC", "DIGITSMCTR", static_cast<SubSpecificationType>(s), Lifetime::Timeframe); | ||
| 326 | + outputs.emplace_back("TPC", "DIGITSMCTR", static_cast<SubSpecificationType>(s), Lifetime::Timeframe); | ||
| 272 | 327 | } | |
| 328 | + // common mode | ||
| 329 | + outputs.emplace_back("TPC", "COMMONMODE", static_cast<SubSpecificationType>(s), Lifetime::Timeframe); | ||
| 330 | + // trigger records | ||
| 331 | + outputs.emplace_back("TPC", "DIGTRIGGERS", static_cast<SubSpecificationType>(s), Lifetime::Timeframe); | ||
| 273 | 332 | } | |
| 274 | 333 | } | |
| 275 | 334 | ||
@@ -287,12 +346,25 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) | |||
| 287 | 346 | ||
| 288 | 347 | auto numlanes = configcontext.options().get<int>("tpc-lanes"); | |
| 289 | 348 | bool mctruth = !configcontext.options().get<bool>("disable-mc"); | |
| 349 | + bool writeout = configcontext.options().get<bool>("writer-mode"); | ||
| 290 | 350 | auto tpcsectors = o2::RangeTokenizer::tokenize<int>(configcontext.options().get<std::string>("tpc-sectors")); | |
| 291 | 351 | ||
| 292 | 352 | std::vector<int> lanes(numlanes); | |
| 293 | 353 | std::iota(lanes.begin(), lanes.end(), 0); | |
| 294 | 354 | specs.emplace_back(o2::tpc::getSpec(lanes, tpcsectors, mctruth)); | |
| 295 | 355 | ||
| 356 | + if (writeout) { | ||
| 357 | + // for now writeout to a ROOT file only works if all sectors | ||
| 358 | + // are included | ||
| 359 | + if (tpcsectors.size() != 36) { | ||
| 360 | + LOG(error) << "You currently need to include all TPC sectors in the ROOT writer-mode"; | ||
| 361 | + } else { | ||
| 362 | + std::vector<int> writerlanes(tpcsectors.size()); | ||
| 363 | + std::iota(writerlanes.begin(), writerlanes.end(), 0); | ||
| 364 | + specs.emplace_back(o2::tpc::getTPCDigitRootWriterSpec(writerlanes, mctruth)); | ||
| 365 | + } | ||
| 366 | + } | ||
| 367 | + | ||
| 296 | 368 | // configure dpl timer to inject correct firstTForbit: start from the 1st orbit of TF containing 1st sampled orbit | |
| 297 | 369 | o2::raw::HBFUtilsInitializer hbfIni(configcontext, specs); | |
| 298 | 370 | return specs; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,7 +14,7 @@ | |||
| 14 | 14 | /// @since 2018-04-19 | |
| 15 | 15 | /// @brief Processor spec for a ROOT file writer for TPC digits | |
| 16 | 16 | ||
| 17 | - #include "TPCDigitRootWriterSpec.h" | ||
| 17 | + #include "TPCSimWorkflow/TPCDigitRootWriterSpec.h" | ||
| 18 | 18 | #include "DataFormatsTPC/TPCSectorHeader.h" | |
| 19 | 19 | #include "CommonDataFormat/RangeReference.h" | |
| 20 | 20 | #include "Framework/InputRecord.h" | |
@@ -77,7 +77,7 @@ DataProcessorSpec getTPCDigitRootWriterSpec(std::vector<int> const& laneConfigur | |||
| 77 | 77 | } | |
| 78 | 78 | }; | |
| 79 | 79 | ||
| 80 | - //branch definitions for RootTreeWriter spec | ||
| 80 | + // branch definitions for RootTreeWriter spec | ||
| 81 | 81 | using DigitsOutputType = std::vector<o2::tpc::Digit>; | |
| 82 | 82 | using CommonModeOutputType = std::vector<o2::tpc::CommonMode>; | |
| 83 | 83 | ||
@@ -156,8 +156,8 @@ DataProcessorSpec getTPCDigitRootWriterSpec(std::vector<int> const& laneConfigur | |||
| 156 | 156 | LOG(info) << "DIGIT SIZE " << digiData.size(); | |
| 157 | 157 | const auto& trigS = (*trigP2Sect.get())[sector]; | |
| 158 | 158 | int entries = 0; | |
| 159 | - if (!trigS.size()) { | ||
| 160 | - std::runtime_error("Digits for sector " + std::to_string(sector) + " are received w/o info on grouping in triggers"); | ||
| 159 | + if (trigS.size() == 0) { | ||
| 160 | + LOG(warn) << "Digits for sector " + std::to_string(sector) + " are received w/o trigger info. Will assume continuous mode"; | ||
| 161 | 161 | } else { // check consistency of Ndigits with that of expected from the trigger | |
| 162 | 162 | int nExp = trigS.back().getFirstEntry() + trigS.back().getEntries() - trigS.front().getFirstEntry(); | |
| 163 | 163 | if (nExp != digiData.size()) { | |
@@ -167,7 +167,7 @@ DataProcessorSpec getTPCDigitRootWriterSpec(std::vector<int> const& laneConfigur | |||
| 167 | 167 | } | |
| 168 | 168 | ||
| 169 | 169 | { | |
| 170 | - if (trigS.size() == 1) { // just 1 entry (continous mode?), use digits directly | ||
| 170 | + if (trigS.size() <= 1) { // just 1 entry (continous mode?), use digits directly | ||
| 171 | 171 | auto ptr = &digiData; | |
| 172 | 172 | branch.SetAddress(&ptr); | |
| 173 | 173 | branch.Fill(); | |
@@ -214,8 +214,8 @@ DataProcessorSpec getTPCDigitRootWriterSpec(std::vector<int> const& laneConfigur | |||
| 214 | 214 | LOG(info) << "MCTRUTH ELEMENTS " << labeldata.getIndexedSize() | |
| 215 | 215 | << " WITH " << labeldata.getNElements() << " LABELS"; | |
| 216 | 216 | const auto& trigS = (*trigP2Sect.get())[sector]; | |
| 217 | - if (!trigS.size()) { | ||
| 218 | - throw std::runtime_error("MCTruth for sector " + std::to_string(sector) + " are received w/o info on grouping in triggers"); | ||
| 217 | + if (trigS.size() == 0) { | ||
| 218 | + LOG(warn) << "MCTruth for sector " + std::to_string(sector) + " received w/o trigger info. Will assume continuous mode"; | ||
| 219 | 219 | } else { | |
| 220 | 220 | int nExp = trigS.back().getFirstEntry() + trigS.back().getEntries() - trigS.front().getFirstEntry(); | |
| 221 | 221 | if (nExp != labeldata.getIndexedSize()) { | |
@@ -225,7 +225,7 @@ DataProcessorSpec getTPCDigitRootWriterSpec(std::vector<int> const& laneConfigur | |||
| 225 | 225 | } | |
| 226 | 226 | } | |
| 227 | 227 | { | |
| 228 | - if (trigS.size() == 1) { // just 1 entry (continous mode?), use labels directly | ||
| 228 | + if (trigS.size() <= 1) { // just 0 or 1 entry (continous mode?), use labels directly | ||
| 229 | 229 | outputcontainer.adopt(labelbuffer); | |
| 230 | 230 | br->Fill(); | |
| 231 | 231 | br->ResetAddress(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -70,17 +70,6 @@ o2_add_library(TPCWorkflowStudies | |||
| 70 | 70 | O2::GlobalTrackingWorkflow | |
| 71 | 71 | ) | |
| 72 | 72 | ||
| 73 | - o2_add_executable(chunkeddigit-merger | ||
| 74 | - COMPONENT_NAME tpc | ||
| 75 | - TARGETVARNAME mergertargetName | ||
| 76 | - SOURCES src/ChunkedDigitPublisher.cxx | ||
| 77 | - PUBLIC_LINK_LIBRARIES O2::TPCWorkflow) | ||
| 78 | - | ||
| 79 | - if(OpenMP_CXX_FOUND) | ||
| 80 | - # Must be private, depending libraries might be compiled by compiler not understanding -fopenmp | ||
| 81 | - target_compile_definitions(${mergertargetName} PRIVATE WITH_OPENMP) | ||
| 82 | - target_link_libraries(${mergertargetName} PRIVATE OpenMP::OpenMP_CXX) | ||
| 83 | - endif() | ||
| 84 | 73 | ||
| 85 | 74 | ||
| 86 | 75 | o2_add_executable(reco-workflow | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -21,9 +21,3 @@ o2_add_library(TPCReaderWorkflow | |||
| 21 | 21 | O2::DPLUtils | |
| 22 | 22 | O2::TPCBase | |
| 23 | 23 | ) | |
| 24 | - | ||
| 25 | - if(OpenMP_CXX_FOUND) | ||
| 26 | - # Must be private, depending libraries might be compiled by compiler not understanding -fopenmp | ||
| 27 | - target_compile_definitions(${mergertargetName} PRIVATE WITH_OPENMP) | ||
| 28 | - target_link_libraries(${mergertargetName} PRIVATE OpenMP::OpenMP_CXX) | ||
| 29 | - endif() | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,7 +24,6 @@ o2_add_executable(digitizer-workflow | |||
| 24 | 24 | src/CPVDigitizerSpec.cxx | |
| 25 | 25 | src/SimReaderSpec.cxx | |
| 26 | 26 | src/SimpleDigitizerWorkflow.cxx | |
| 27 | - src/TPCDigitRootWriterSpec.cxx | ||
| 28 | 27 | src/TPCDigitizerSpec.cxx | |
| 29 | 28 | src/ZDCDigitizerSpec.cxx | |
| 30 | 29 | src/TOFDigitizerSpec.cxx | |
@@ -59,6 +58,7 @@ o2_add_executable(digitizer-workflow | |||
| 59 | 58 | O2::TOFReconstruction | |
| 60 | 59 | O2::TOFWorkflowIO | |
| 61 | 60 | O2::TPCSimulation | |
| 61 | + O2::TPCSimWorkflow | ||
| 62 | 62 | O2::TRDSimulation | |
| 63 | 63 | O2::TRDWorkflow | |
| 64 | 64 | O2::TRDWorkflowIO | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -30,7 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | 31 | // for TPC | |
| 32 | 32 | #include "TPCDigitizerSpec.h" | |
| 33 | - #include "TPCDigitRootWriterSpec.h" | ||
| 33 | + #include "TPCSimWorkflow/TPCDigitRootWriterSpec.h" | ||
| 34 | 34 | #include "TPCBase/Sector.h" | |
| 35 | 35 | #include "TPCBase/CDBInterface.h" | |
| 36 | 36 | // needed in order to init the **SHARED** polyadist file (to be done before the digitizers initialize) | |
| Back | FazBrowse Home | New Git URL |
0 commit comments