diff --git a/DataFormats/Detectors/ZDC/include/DataFormatsZDC/BCData.h b/DataFormats/Detectors/ZDC/include/DataFormatsZDC/BCData.h index bea3894807bff..2b21f35d75f81 100644 --- a/DataFormats/Detectors/ZDC/include/DataFormatsZDC/BCData.h +++ b/DataFormats/Detectors/ZDC/include/DataFormatsZDC/BCData.h @@ -27,6 +27,25 @@ namespace zdc { class ChannelData; +struct __attribute__((__packed__)) ModuleTriggerMap { + unsigned Alice_0 : 1; + unsigned Alice_1 : 1; + unsigned Alice_2 : 1; + unsigned Alice_3 : 1; + unsigned Auto_m : 1; + unsigned Auto_0 : 1; + unsigned Auto_1 : 1; + unsigned Auto_2 : 1; + unsigned Auto_3 : 1; + unsigned empty : 7; +}; + +union ModuleTriggerMapData { + uint16_t w; + struct ModuleTriggerMap f; + void reset(); +}; + struct BCData { /// we are going to refer to at most 26 channels, so 5 bits for the NChannels and 27 for the reference o2::dataformats::RangeRefComp<5> ref; @@ -48,7 +67,7 @@ struct BCData { } gsl::span getBunchChannelData(const gsl::span tfdata) const; - void print() const; + void print(uint32_t triggerMask = 0) const; ClassDefNV(BCData, 2); }; diff --git a/DataFormats/Detectors/ZDC/src/BCData.cxx b/DataFormats/Detectors/ZDC/src/BCData.cxx index ab35ea60d6aa9..db9b471bec185 100644 --- a/DataFormats/Detectors/ZDC/src/BCData.cxx +++ b/DataFormats/Detectors/ZDC/src/BCData.cxx @@ -14,7 +14,7 @@ using namespace o2::zdc; -void BCData::print() const +void BCData::print(uint32_t triggerMask) const { printf("Orbit %9u bc %4u nch %2d pos %d\n", ir.orbit, ir.bc, ref.getEntries(), ref.getFirstEntry()); printf("Read:"); @@ -32,15 +32,6 @@ void BCData::print() const printf(" "); } } - printf("]\nTrigs:"); - for (int i = 0; i < NChannels; i++) { - std::bitset<10> bb(moduleTriggers[i]); - printf("[%2d: %s]", i, bb.to_string().c_str()); - if (i % (NChannels / 3) == 0 && i) { - printf("\n"); - } - } - printf("]\nHits:"); for (int ic = 0; ic < NDigiChannels; ic++) { if (ic % NChPerModule == 0) { @@ -50,13 +41,33 @@ void BCData::print() const printf("] %d[", ic / NChPerModule); } } - if (triggers & (0x1 << ic)) { - printf("H"); + bool is_hit = triggers & (0x1 << ic); + bool is_trig = triggerMask & (0x1 << ic); + if (is_trig) { + if (is_hit) { + printf("T"); + } else { + printf("."); + } } else { - printf(" "); + if (is_hit) { + printf("H"); + } else { + printf(" "); + } } } - printf("]\n"); + printf("]\nAUTO:"); + for (int i = 0; i < NModules; i++) { + std::bitset<10> bb(moduleTriggers[i]); + printf(" %d %s%s%s%s%s", i, bb[8] ? "3" : "-", bb[7] ? "2" : "-", bb[6] ? "1" : "-", bb[5] ? "0" : "-", bb[4] ? "M" : "-"); + } + printf("\nALIT:"); + for (int i = 0; i < NModules; i++) { + std::bitset<10> bb(moduleTriggers[i]); + printf(" %d %s%s%s%s ", i, bb[3] ? "3" : "-", bb[2] ? "2" : "-", bb[1] ? "1" : "-", bb[0] ? "0" : "-"); + } + printf("\n"); } gsl::span BCData::getBunchChannelData(const gsl::span tfdata) const diff --git a/Detectors/ZDC/base/include/ZDCBase/Geometry.h b/Detectors/ZDC/base/include/ZDCBase/Geometry.h index 3eec00b9a3656..c4228e27a2d32 100644 --- a/Detectors/ZDC/base/include/ZDCBase/Geometry.h +++ b/Detectors/ZDC/base/include/ZDCBase/Geometry.h @@ -50,9 +50,9 @@ class Geometry static constexpr double ZEMPOSITION[3] = {9.69, 0., 760.}; private: - static Int_t getDetector(const Int_t det); - static Int_t getSector(const Int_t tow); - static Int_t getVolumeId(const Int_t* vol); + static int32_t getDetector(const int32_t det); + static int32_t getSector(const int32_t tow); + static int32_t getVolumeId(const int32_t* vol); ClassDefNV(Geometry, 1); }; diff --git a/Detectors/ZDC/raw/CMakeLists.txt b/Detectors/ZDC/raw/CMakeLists.txt index 64027eadc6d35..ce078675628fa 100644 --- a/Detectors/ZDC/raw/CMakeLists.txt +++ b/Detectors/ZDC/raw/CMakeLists.txt @@ -9,7 +9,7 @@ # submit itself to any jurisdiction. o2_add_library(ZDCRaw - SOURCES src/DumpRaw.cxx src/raw-parser.cxx + SOURCES src/DumpRaw.cxx src/raw-parser.cxx src/RawReaderZDCBase.cxx src/RawReaderBase.cxx PUBLIC_LINK_LIBRARIES O2::SimulationDataFormat O2::ZDCBase O2::ZDCSimulation O2::DataFormatsZDC O2::CCDB O2::SimConfig O2::DPLUtils O2::DetectorsRaw O2::Headers) @@ -28,4 +28,3 @@ o2_add_executable(raw-parser O2::DetectorsRaw O2::DetectorsCommonDataFormats O2::CommonUtils) - diff --git a/Detectors/ZDC/raw/include/ZDCRaw/DumpRaw.h b/Detectors/ZDC/raw/include/ZDCRaw/DumpRaw.h index 167b54f4b480e..465694ae0a494 100644 --- a/Detectors/ZDC/raw/include/ZDCRaw/DumpRaw.h +++ b/Detectors/ZDC/raw/include/ZDCRaw/DumpRaw.h @@ -26,7 +26,7 @@ class DumpRaw void init(); int process(const EventData& ev); int process(const EventChData& ch); - int processWord(const UInt_t* word); + int processWord(const uint32_t* word); int getHPos(uint32_t board, uint32_t ch); void write(); void setVerbosity(int v) diff --git a/Detectors/ZDC/raw/include/ZDCRaw/RawReaderBase.h b/Detectors/ZDC/raw/include/ZDCRaw/RawReaderBase.h new file mode 100644 index 0000000000000..36cb19ef2460d --- /dev/null +++ b/Detectors/ZDC/raw/include/ZDCRaw/RawReaderBase.h @@ -0,0 +1,245 @@ +// 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. +// +//file RawReaderBase.h base class for RAW data reading +// +// Artur.Furs +// afurs@cern.ch +// +//Main purpuse is to decode ZDC data blocks and push them to DigitBlockFT0 for process + +#ifndef ALICEO2_ZDC_RAWREADERBASE_H_ +#define ALICEO2_ZDC_RAWREADERBASE_H_ +#include +#include +#include + +#include +#include +#include "Headers/RAWDataHeader.h" +#include +#include "DataFormatsZDC/RawEventData.h" +#include "ZDCSimulation/Digits2Raw.h" +#include "ZDCSimulation/SimCondition.h" + +#include +namespace o2 +{ +namespace zdc +{ + +class RawReaderBase +{ + public: + RawReaderBase() = default; + ~RawReaderBase() = default; + + std::map mMapData; /// Raw data cache + const ModuleConfig* mModuleConfig = nullptr; /// Trigger/readout configuration object + void setModuleConfig(const ModuleConfig* moduleConfig) { mModuleConfig = moduleConfig; }; + const ModuleConfig* getModuleConfig() { return mModuleConfig; }; + + //decoding binary data into data blocks + EventChData mCh; // Channel data to be decoded + int processWord(const uint32_t* word) + { + if (word == nullptr) { + LOG(ERROR) << "NULL pointer"; + return 1; + } + if ((word[0] & 0x3) == Id_w0) { + for (int32_t iw = 0; iw < NWPerGBTW; iw++) { + mCh.w[0][iw] = word[iw]; + } + } else if ((word[0] & 0x3) == Id_w1) { + if (mCh.f.fixed_0 == Id_w0) { + for (int32_t iw = 0; iw < NWPerGBTW; iw++) { + mCh.w[1][iw] = word[iw]; + } + } else { + LOG(ERROR) << "Wrong word sequence"; + mCh.f.fixed_0 = Id_wn; + mCh.f.fixed_1 = Id_wn; + mCh.f.fixed_2 = Id_wn; + } + } else if ((word[0] & 0x3) == Id_w2) { + if (mCh.f.fixed_0 == Id_w0 && mCh.f.fixed_1 == Id_w1) { + for (int32_t iw = 0; iw < NWPerGBTW; iw++) { + mCh.w[2][iw] = word[iw]; + } + process(mCh); + } else { + LOG(ERROR) << "Wrong word sequence"; + } + mCh.f.fixed_0 = Id_wn; + mCh.f.fixed_1 = Id_wn; + mCh.f.fixed_2 = Id_wn; + } else { + // Word not present in payload + LOG(FATAL) << "Event format error"; + return 1; + } + return 0; + } + + void process(const EventChData& ch) + { + InteractionRecord ir(ch.f.bc, ch.f.orbit); + auto& mydata = mMapData[ir]; + int32_t im = ch.f.board; + int32_t ic = ch.f.ch; + for (int32_t iwb = 0; iwb < NWPerBc; iwb++) { + for (int32_t iwg = 0; iwg < NWPerGBTW; iwg++) { + mydata.data[im][ic].w[iwb][iwg] = mCh.w[iwb][iwg]; + } + } + } + + //processing data blocks into digits + void processBinaryData(gsl::span payload, int linkID) + { + size_t payloadSize = payload.size(); + for (int32_t ip = 0; ip < payloadSize; ip += 16) { + //o2::zdc::Digits2Raw::print_gbt_word((const uint32_t*)&payload[ip]); + processWord((const uint32_t*)&payload[ip]); + } + } + /* + void process(int linkID, gsl::span payload) + { + static_cast(this)->processDigits(linkID,payload); + } + */ + //pop digits + int getDigits(std::vector& digitsBC, std::vector& digitsCh, std::vector& pedestalData) + { + if (mModuleConfig == nullptr) { + LOG(FATAL) << "Missing ModuleConfig"; + return 0; + } + int bcCounter = mMapData.size(); + LOG(INFO) << "Processing #bc " << bcCounter; + for (auto& [ir, ev] : mMapData) { + // TODO: Error check + // Pedestal data + if (ir.bc == 3563) { + auto& pdata = pedestalData.emplace_back(); + pdata.ir = ir; + for (int32_t im = 0; im < NModules; im++) { + for (int32_t ic = 0; ic < NChPerModule; ic++) { + if (ev.data[im][ic].f.fixed_0 == Id_w0 && ev.data[im][ic].f.fixed_1 == Id_w1 && ev.data[im][ic].f.fixed_2 == Id_w2) { + // Identify connected channel + auto id = mModuleConfig->modules[im].channelID[ic]; + int offset = ev.data[im][ic].f.offset - 32768; + pdata.data[id] = offset; + } else if (ev.data[im][ic].f.fixed_0 == 0 && ev.data[im][ic].f.fixed_1 == 0 && ev.data[im][ic].f.fixed_2 == 0) { + // Empty channel + } else { + LOG(ERROR) << "Data format error"; + } + } + } + } + // BC data + auto& bcdata = digitsBC.emplace_back(); + bcdata.ir = ir; + // Channel data + bool inconsistent_event = false; + bool filled_event = false; + for (int32_t im = 0; im < NModules; im++) { + ModuleTriggerMapData mt; + mt.w = 0; + bool filled_module = false; + bool inconsistent_module = false; + for (int32_t ic = 0; ic < NChPerModule; ic++) { + if (ev.data[im][ic].f.fixed_0 == Id_w0 && ev.data[im][ic].f.fixed_1 == Id_w1 && ev.data[im][ic].f.fixed_2 == Id_w2) { + auto& ch = ev.data[im][ic]; + uint16_t us[12]; + us[0] = ch.f.s00; + us[1] = ch.f.s01; + us[2] = ch.f.s02; + us[3] = ch.f.s03; + us[4] = ch.f.s04; + us[5] = ch.f.s05; + us[6] = ch.f.s06; + us[7] = ch.f.s07; + us[8] = ch.f.s08; + us[9] = ch.f.s09; + us[10] = ch.f.s10; + us[11] = ch.f.s11; + // Identify connected channel + auto& chd = digitsCh.emplace_back(); + auto id = mModuleConfig->modules[im].channelID[ic]; + chd.id = id; + for (int32_t is = 0; is < NTimeBinsPerBC; is++) { + if (us[is] > ADCMax) { + chd.data[is] = us[is] - ADCRange; + } else { + chd.data[is] = us[is]; + } + } + // Trigger bits + if (ch.f.Hit) { + bcdata.triggers |= (0x1 << ((im - 1) * NChPerModule + ic)); + } + // TODO: Alice trigger bits + // TODO: consistency checks + if (filled_event == false) { + mt.f.Alice_0 = ch.f.Alice_0; + mt.f.Alice_1 = ch.f.Alice_1; + mt.f.Alice_2 = ch.f.Alice_2; + mt.f.Alice_3 = ch.f.Alice_3; + filled_event = true; + } else if (mt.f.Alice_0 != ch.f.Alice_0 || mt.f.Alice_1 != ch.f.Alice_1 || mt.f.Alice_2 != ch.f.Alice_2 || mt.f.Alice_3 != ch.f.Alice_3) { + inconsistent_event = true; + } + if (filled_module == false) { + mt.f.Auto_m = ch.f.Auto_m; + mt.f.Auto_0 = ch.f.Auto_0; + mt.f.Auto_1 = ch.f.Auto_1; + mt.f.Auto_2 = ch.f.Auto_2; + mt.f.Auto_3 = ch.f.Auto_3; + filled_module = true; + } else if (mt.f.Auto_m != ch.f.Auto_m || mt.f.Auto_0 != ch.f.Auto_0 || mt.f.Auto_1 != ch.f.Auto_1 || mt.f.Auto_2 != ch.f.Auto_2 || mt.f.Auto_3 != ch.f.Auto_3) { + inconsistent_module = true; + } + } else if (ev.data[im][ic].f.fixed_0 == 0 && ev.data[im][ic].f.fixed_1 == 0 && ev.data[im][ic].f.fixed_2 == 0) { + // Empty channel + } else { + LOG(ERROR) << "Data format error"; + } + } + bcdata.moduleTriggers[im] = mt.w; + if (inconsistent_module == true) { + inconsistent_event = true; + } + } + if (inconsistent_event) { + LOG(ERROR) << "Inconsistent event"; + for (int32_t im = 0; im < NModules; im++) { + for (int32_t ic = 0; ic < NChPerModule; ic++) { + if (ev.data[im][ic].f.fixed_0 == Id_w0 && ev.data[im][ic].f.fixed_1 == Id_w1 && ev.data[im][ic].f.fixed_2 == Id_w2) { + for (int32_t iw = 0; iw < NWPerBc; iw++) { + o2::zdc::Digits2Raw::print_gbt_word((const uint32_t*)&ev.data[im][ic].w[iw][0]); + } + } + } + } + } + } + mMapData.clear(); + return bcCounter; + } +}; + +} // namespace zdc +} // namespace o2 + +#endif diff --git a/Detectors/ZDC/raw/include/ZDCRaw/RawReaderZDCBase.h b/Detectors/ZDC/raw/include/ZDCRaw/RawReaderZDCBase.h new file mode 100644 index 0000000000000..6e4672f461c1b --- /dev/null +++ b/Detectors/ZDC/raw/include/ZDCRaw/RawReaderZDCBase.h @@ -0,0 +1,57 @@ +// 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. +// +//file RawReaderZDCBase.h Base class for RAW data reading +// + +#ifndef ALICEO2_FIT_RAWREADERFT0BASE_H_ +#define ALICEO2_FIT_RAWREADERFT0BASE_H_ +#include +#include +#include +#include "ZDCRaw/RawReaderBase.h" + +#include +#include + +#include +#include "Headers/RAWDataHeader.h" + +#include + +using namespace o2::zdc; +namespace o2 +{ +namespace zdc +{ +// Common raw reader for ZDC +class RawReaderZDCBase : public RawReaderBase +{ + public: + RawReaderZDCBase() = default; + ~RawReaderZDCBase() = default; + //deserialize payload to raw data blocks and proccesss them to digits + void process(int linkID, gsl::span payload) + { + if (0 <= linkID && linkID < 16) { + //PM data processing + processBinaryData(payload, linkID); + } else { + //put here code in case of bad rdh.linkID value + LOG(INFO) << "WARNING! WRONG LINK ID! " << linkID; + return; + } + // + } +}; +} // namespace zdc +} // namespace o2 + +#endif diff --git a/Detectors/ZDC/raw/src/DumpRaw.cxx b/Detectors/ZDC/raw/src/DumpRaw.cxx index cc5ec357f8208..c4d1da110dc2a 100644 --- a/Detectors/ZDC/raw/src/DumpRaw.cxx +++ b/Detectors/ZDC/raw/src/DumpRaw.cxx @@ -54,9 +54,9 @@ void DumpRaw::init() gROOT->SetBatch(); auto& sopt = ZDCSimParam::Instance(); int nbx = (sopt.nBCAheadTrig + 1) * NTimeBinsPerBC; - Double_t xmin = -sopt.nBCAheadTrig * NTimeBinsPerBC - 0.5; - Double_t xmax = NTimeBinsPerBC - 0.5; - for (UInt_t i = 0; i < NDigiChannels; i++) { + double xmin = -sopt.nBCAheadTrig * NTimeBinsPerBC - 0.5; + double xmax = NTimeBinsPerBC - 0.5; + for (uint32_t i = 0; i < NDigiChannels; i++) { uint32_t imod = i / NChPerModule; uint32_t ich = i % NChPerModule; if (mBaseline[i]) { @@ -102,25 +102,25 @@ void DumpRaw::write() LOG(FATAL) << "Cannot write to file " << f->GetName(); return; } - for (UInt_t i = 0; i < NDigiChannels; i++) { + for (uint32_t i = 0; i < NDigiChannels; i++) { if (mBunch[i] && mBunch[i]->GetEntries() > 0) { setStat(mBunch[i]); mBunch[i]->Write(); } } - for (UInt_t i = 0; i < NDigiChannels; i++) { + for (uint32_t i = 0; i < NDigiChannels; i++) { if (mBaseline[i] && mBaseline[i]->GetEntries() > 0) { setStat(mBaseline[i]); mBaseline[i]->Write(); } } - for (UInt_t i = 0; i < NDigiChannels; i++) { + for (uint32_t i = 0; i < NDigiChannels; i++) { if (mCounts[i] && mCounts[i]->GetEntries() > 0) { setStat(mCounts[i]); mCounts[i]->Write(); } } - for (UInt_t i = 0; i < NDigiChannels; i++) { + for (uint32_t i = 0; i < NDigiChannels; i++) { if (mSignal[i] && mSignal[i]->GetEntries() > 0) { setStat(mSignal[i]); mSignal[i]->Write(); @@ -140,19 +140,19 @@ inline int DumpRaw::getHPos(uint32_t board, uint32_t ch) } } -int DumpRaw::processWord(const UInt_t* word) +int DumpRaw::processWord(const uint32_t* word) { if (word == nullptr) { printf("NULL\n"); return 1; } if ((word[0] & 0x3) == Id_w0) { - for (Int_t iw = 0; iw < NWPerGBTW; iw++) { + for (int32_t iw = 0; iw < NWPerGBTW; iw++) { mCh.w[0][iw] = word[iw]; } } else if ((word[0] & 0x3) == Id_w1) { if (mCh.f.fixed_0 == Id_w0) { - for (Int_t iw = 0; iw < NWPerGBTW; iw++) { + for (int32_t iw = 0; iw < NWPerGBTW; iw++) { mCh.w[1][iw] = word[iw]; } } else { @@ -163,7 +163,7 @@ int DumpRaw::processWord(const UInt_t* word) } } else if ((word[0] & 0x3) == Id_w2) { if (mCh.f.fixed_0 == Id_w0 && mCh.f.fixed_1 == Id_w1) { - for (Int_t iw = 0; iw < NWPerGBTW; iw++) { + for (int32_t iw = 0; iw < NWPerGBTW; iw++) { mCh.w[2][iw] = word[iw]; } process(mCh); @@ -188,12 +188,12 @@ int DumpRaw::process(const EventChData& ch) auto f = ch.f; int ih = getHPos(f.board, f.ch); if (mVerbosity > 0) { - for (Int_t iw = 0; iw < NWPerBc; iw++) { + for (int32_t iw = 0; iw < NWPerBc; iw++) { Digits2Raw::print_gbt_word(ch.w[iw]); } } - UShort_t us[12]; - Short_t s[12]; + uint16_t us[12]; + int16_t s[12]; us[0] = f.s00; us[1] = f.s01; us[2] = f.s02; @@ -206,7 +206,7 @@ int DumpRaw::process(const EventChData& ch) us[9] = f.s09; us[10] = f.s10; us[11] = f.s11; - for (Int_t i = 0; i < 12; i++) { + for (int32_t i = 0; i < 12; i++) { if (us[i] > ADCMax) { s[i] = us[i] - ADCRange; } else { @@ -215,31 +215,31 @@ int DumpRaw::process(const EventChData& ch) //printf("%d %u %d\n",i,us[i],s[i]); } if (f.Alice_3) { - for (Int_t i = 0; i < 12; i++) { - mSignal[ih]->Fill(i - 36., Double_t(s[i])); + for (int32_t i = 0; i < 12; i++) { + mSignal[ih]->Fill(i - 36., double(s[i])); } } if (f.Alice_2) { - for (Int_t i = 0; i < 12; i++) { - mSignal[ih]->Fill(i - 24., Double_t(s[i])); + for (int32_t i = 0; i < 12; i++) { + mSignal[ih]->Fill(i - 24., double(s[i])); } } if (f.Alice_1 || f.Auto_1) { - for (Int_t i = 0; i < 12; i++) { - mSignal[ih]->Fill(i - 12., Double_t(s[i])); + for (int32_t i = 0; i < 12; i++) { + mSignal[ih]->Fill(i - 12., double(s[i])); } } if (f.Alice_0 || f.Auto_0) { - for (Int_t i = 0; i < 12; i++) { - mSignal[ih]->Fill(i + 0., Double_t(s[i])); + for (int32_t i = 0; i < 12; i++) { + mSignal[ih]->Fill(i + 0., double(s[i])); } - Double_t bc_d = UInt_t(f.bc / 100); - Double_t bc_m = UInt_t(f.bc % 100); + double bc_d = uint32_t(f.bc / 100); + double bc_m = uint32_t(f.bc % 100); mBunch[ih]->Fill(bc_m, -bc_d); } if (f.bc == last_bc) { - Int_t offset = f.offset - 32768; - Double_t foffset = offset / 8.; + int32_t offset = f.offset - 32768; + double foffset = offset / 8.; mBaseline[ih]->Fill(foffset); mCounts[ih]->Fill(f.hits); } @@ -248,8 +248,8 @@ int DumpRaw::process(const EventChData& ch) int DumpRaw::process(const EventData& ev) { - for (Int_t im = 0; im < NModules; im++) { - for (Int_t ic = 0; ic < NChPerModule; ic++) { + for (int32_t im = 0; im < NModules; im++) { + for (int32_t ic = 0; ic < NChPerModule; ic++) { if (ev.data[im][ic].f.fixed_0 == Id_w0 && ev.data[im][ic].f.fixed_1 == Id_w1 && ev.data[im][ic].f.fixed_2 == Id_w2) { process(ev.data[im][ic]); } else if (ev.data[im][ic].f.fixed_0 == 0 && ev.data[im][ic].f.fixed_1 == 0 && ev.data[im][ic].f.fixed_2 == 0) { diff --git a/Detectors/ZDC/raw/src/RawReaderBase.cxx b/Detectors/ZDC/raw/src/RawReaderBase.cxx new file mode 100644 index 0000000000000..292d32089e2bf --- /dev/null +++ b/Detectors/ZDC/raw/src/RawReaderBase.cxx @@ -0,0 +1,12 @@ +// 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 "ZDCRaw/RawReaderBase.h" +using namespace o2::zdc; diff --git a/Detectors/ZDC/raw/src/RawReaderZDCBase.cxx b/Detectors/ZDC/raw/src/RawReaderZDCBase.cxx new file mode 100644 index 0000000000000..f510cc58e3827 --- /dev/null +++ b/Detectors/ZDC/raw/src/RawReaderZDCBase.cxx @@ -0,0 +1,12 @@ +// 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 "ZDCRaw/RawReaderZDCBase.h" +using namespace o2::zdc; diff --git a/Detectors/ZDC/raw/src/raw-parser.cxx b/Detectors/ZDC/raw/src/raw-parser.cxx index 888d3e4d167e1..6f9a3cf828627 100644 --- a/Detectors/ZDC/raw/src/raw-parser.cxx +++ b/Detectors/ZDC/raw/src/raw-parser.cxx @@ -85,9 +85,9 @@ WorkflowSpec defineDataProcessing(ConfigContext const& config) } } if (payload != nullptr) { - for (Int_t ip = 0; ip < payloadSize; ip += 16) { - //o2::zdc::Digits2Raw::print_gbt_word((const UInt_t*)&payload[ip]); - zdc_dr.processWord((const UInt_t*)&payload[ip]); + for (int32_t ip = 0; ip < payloadSize; ip += 16) { + //o2::zdc::Digits2Raw::print_gbt_word((const uint32_t*)&payload[ip]); + zdc_dr.processWord((const uint32_t*)&payload[ip]); } } } diff --git a/Detectors/ZDC/simulation/include/ZDCSimulation/Detector.h b/Detectors/ZDC/simulation/include/ZDCSimulation/Detector.h index a97e9ee3567c2..91c0f4fa13921 100644 --- a/Detectors/ZDC/simulation/include/ZDCSimulation/Detector.h +++ b/Detectors/ZDC/simulation/include/ZDCSimulation/Detector.h @@ -12,7 +12,6 @@ #define ALICEO2_ZDC_DETECTOR_H_ #include // for vector -#include "Rtypes.h" // for Int_t, Double_t, Float_t, Bool_t, etc #include "TGeoManager.h" // for gGeoManager, TGeoManager (ptr only) #include "DetectorsBase/GeometryManager.h" // for getSensID #include "DetectorsBase/Detector.h" // for Detector @@ -63,7 +62,7 @@ class Detector : public o2::base::DetImpl void Register() override; /// Gets the produced collections - std::vector* getHits(Int_t iColl) const + std::vector* getHits(int32_t iColl) const { if (iColl == 0) { return mHits; @@ -82,9 +81,9 @@ class Detector : public o2::base::DetImpl void createMaterials(); void addAlignableVolumes() const override {} - o2::zdc::Hit* addHit(Int_t trackID, Int_t parentID, Int_t sFlag, Float_t primaryEnergy, Int_t detID, Int_t secID, - math_utils::Vector3D pos, math_utils::Vector3D mom, Float_t tof, math_utils::Vector3D xImpact, Double_t energyloss, - Int_t nphePMC, Int_t nphePMQ); + o2::zdc::Hit* addHit(int32_t trackID, int32_t parentID, int32_t sFlag, float primaryEnergy, int32_t detID, int32_t secID, + math_utils::Vector3D pos, math_utils::Vector3D mom, float tof, math_utils::Vector3D xImpact, double energyloss, + int32_t nphePMC, int32_t nphePMQ); private: /// copy constructor @@ -162,22 +161,22 @@ class Detector : public o2::base::DetImpl // helper function taking care of writing the photon response pattern at certain moments void flushSpatialResponse(); - Float_t mTrackEta; - Float_t mPrimaryEnergy; + float mTrackEta; + float mPrimaryEnergy; math_utils::Vector3D mXImpact; - Float_t mTotLightPMC; - Float_t mTotLightPMQ; - Int_t mMediumPMCid = -1; - Int_t mMediumPMQid = -2; + float mTotLightPMC; + float mTotLightPMQ; + int32_t mMediumPMCid = -1; + int32_t mMediumPMQid = -2; // /// Container for hit data std::vector* mHits; - Float_t mLumiLength = 0; //TODO: make part of configurable params - Float_t mTCLIAAPERTURE = 3.5; //TODO: make part of configurable params - Float_t mTCLIAAPERTURENEG = 3.5; //TODO: make part of configurable params - Float_t mVCollSideCCentreY = 0.; //TODO: make part of configurable params + float mLumiLength = 0; //TODO: make part of configurable params + float mTCLIAAPERTURE = 3.5; //TODO: make part of configurable params + float mTCLIAAPERTURENEG = 3.5; //TODO: make part of configurable params + float mVCollSideCCentreY = 0.; //TODO: make part of configurable params int mZNENVVolID = -1; // the volume id for the neutron det envelope volume int mZPENVVolID = -1; // the volume id for the proton det envelope volume diff --git a/Detectors/ZDC/simulation/include/ZDCSimulation/Digits2Raw.h b/Detectors/ZDC/simulation/include/ZDCSimulation/Digits2Raw.h index 48b41b73c8c05..00799ecca7618 100644 --- a/Detectors/ZDC/simulation/include/ZDCSimulation/Digits2Raw.h +++ b/Detectors/ZDC/simulation/include/ZDCSimulation/Digits2Raw.h @@ -26,6 +26,7 @@ #include "ZDCSimulation/SimCondition.h" #include "DataFormatsZDC/BCData.h" #include "DataFormatsZDC/ChannelData.h" +#include "DataFormatsZDC/PedestalData.h" namespace o2 { @@ -56,19 +57,20 @@ class Digits2Raw // void setContinuous(bool v = true) { mIsContinuous = v; } bool isContinuous() const { return mIsContinuous; } - static void print_gbt_word(const UInt_t* word, const ModuleConfig* moduleConfig = nullptr); + static void print_gbt_word(const uint32_t* word, const ModuleConfig* moduleConfig = nullptr); private: void setTriggerMask(); void updatePedestalReference(int bc); void resetSums(uint32_t orbit); - void resetOutputStructure(UShort_t bc, UInt_t orbit, bool is_dummy); /// Reset output structure not incrementing scalers for dummy bunches - void assignTriggerBits(int ibc, UShort_t bc, UInt_t orbit, bool is_dummy); /// Assign trigger bits - void insertLastBunch(int ibc, uint32_t orbit); /// Insert an empty bunch at last position in orbit - void convertDigits(int ibc); /// Convert digits into raw data - void writeDigits(); /// Writes raw data to file + void resetOutputStructure(uint16_t bc, uint32_t orbit, bool is_dummy); /// Reset output structure not incrementing scalers for dummy bunches + void assignTriggerBits(int ibc, uint16_t bc, uint32_t orbit, bool is_dummy); /// Assign trigger bits + void insertLastBunch(int ibc, uint32_t orbit); /// Insert an empty bunch at last position in orbit + void convertDigits(int ibc); /// Convert digits into raw data + void writeDigits(); /// Writes raw data to file std::vector mzdcBCData, *mzdcBCDataPtr = &mzdcBCData; std::vector mzdcChData, *mzdcChDataPtr = &mzdcChData; + std::vector mzdcPedData, *mzdcPedDataPtr = &mzdcPedData; int mNbc = 0; BCData mBCD; EventData mZDC; /// Output structure @@ -76,14 +78,14 @@ class Digits2Raw bool mOutputPerLink = false; /// Split output const ModuleConfig* mModuleConfig = nullptr; /// Trigger/readout configuration object const SimCondition* mSimCondition = nullptr; /// Pedestal/noise configuration object - UShort_t mScalers[NModules][NChPerModule] = {0}; /// ZDC orbit scalers - UInt_t mLastOrbit = 0; /// Last processed orbit + uint16_t mScalers[NModules][NChPerModule] = {0}; /// ZDC orbit scalers + uint32_t mLastOrbit = 0; /// Last processed orbit uint32_t mTriggerMask = 0; /// Trigger mask from ModuleConfig std::string mPrintTriggerMask = ""; /// Nice printout of trigger mask int32_t mNEmpty = -1; /// Number of clean empty bunches for pedestal evaluation std::array mEmpty = {0}; /// Clean empty bunches along orbit - UInt_t mLastNEmpty = 0; /// Last number of empty bunches used - Double_t mSumPed[NModules][NChPerModule] = {0}; /// Pedestal integrated on clean empty bunches + uint32_t mLastNEmpty = 0; /// Last number of empty bunches used + double mSumPed[NModules][NChPerModule] = {0}; /// Pedestal integrated on clean empty bunches uint16_t mPed[NModules][NChPerModule] = {0}; /// Current pedestal o2::raw::RawFileWriter mWriter{"ZDC"}; diff --git a/Detectors/ZDC/simulation/src/Detector.cxx b/Detectors/ZDC/simulation/src/Detector.cxx index 3b1dd03accc2d..c7aa11af57f9b 100644 --- a/Detectors/ZDC/simulation/src/Detector.cxx +++ b/Detectors/ZDC/simulation/src/Detector.cxx @@ -288,7 +288,7 @@ Bool_t Detector::ProcessHits(FairVolume* v) { // Method called from MC stepping for the sensitive volumes TString volname = fMC->CurrentVolName(); - Float_t x[3] = {0., 0., 0.}; + float x[3] = {0., 0., 0.}; fMC->TrackPosition(x[0], x[1], x[2]); // determine detectorID and sectorID @@ -304,7 +304,7 @@ Bool_t Detector::ProcessHits(FairVolume* v) int volID, copy; volID = fMC->CurrentVolID(copy); //printf("\t ---> track %d in vol. %d %d (volID %d) mother %d \n", - //trackn, detector, sector, volID, stack->GetCurrentTrack()->GetMother(0)); + //trackn, detector, sector, volID, stack->GetCurrentTrack()->GetMother(0)); // If the particle is in a ZN or ZP fiber connected to the common PMT // then the assigned sector is 0 (PMC) NB-> does not work for ZEM @@ -320,45 +320,45 @@ Bool_t Detector::ProcessHits(FairVolume* v) return false; } - Float_t p[3] = {0., 0., 0.}; - Float_t trackenergy = 0.; + float p[3] = {0., 0., 0.}; + float trackenergy = 0.; fMC->TrackMomentum(p[0], p[1], p[2], trackenergy); - Float_t eDep = fMC->Edep(); + float eDep = fMC->Edep(); int pdgCode = fMC->TrackPid(); float lightoutput = 0.; auto currentMediumid = fMC->CurrentMedium(); int nphe = 0; if (((currentMediumid == mMediumPMCid) || (currentMediumid == mMediumPMQid))) { - if(eDep){ - int ibeta = 0, iangle = 0, iradius = 0; - Bool_t isLightProduced = calculateTableIndexes(ibeta, iangle, iradius); - if (isLightProduced) { - int charge = 0; - if (pdgCode < 10000) { - charge = fMC->TrackCharge(); - } else { - charge = TMath::Abs(pdgCode / 10000 - 100000); - } - - //look into the light tables if the particle is charged - if (TMath::Abs(charge) > 0) { - if (detector == 1 || detector == 4) { - iradius = std::min((int)Geometry::ZNFIBREDIAMETER, iradius); - lightoutput = charge * charge * mLightTableZN[ibeta][iangle][iradius]; - //printf(" \t ZNtableEntry[%d %d %d] = %1.5f -> lightoutput %f\n", ibeta, iangle, iradius, mLightTableZN[ibeta][iangle][iradius], lightoutput); + if (eDep) { + int ibeta = 0, iangle = 0, iradius = 0; + Bool_t isLightProduced = calculateTableIndexes(ibeta, iangle, iradius); + if (isLightProduced) { + int charge = 0; + if (pdgCode < 10000) { + charge = fMC->TrackCharge(); } else { - iradius = std::min((int)Geometry::ZPFIBREDIAMETER, iradius); - lightoutput = charge * charge * mLightTableZP[ibeta][iangle][iradius]; - //printf(" \t ZPtableEntry[%d %d %d] = %1.5f -> lightoutput %f\n", ibeta, iangle, iradius, mLightTableZP[ibeta][iangle][iradius], lightoutput); + charge = TMath::Abs(pdgCode / 10000 - 100000); } - if (lightoutput > 0) { - nphe = gRandom->Poisson(lightoutput); - //printf(" \t\t-> nphe %d \n", nphe); + + //look into the light tables if the particle is charged + if (TMath::Abs(charge) > 0) { + if (detector == 1 || detector == 4) { + iradius = std::min((int)Geometry::ZNFIBREDIAMETER, iradius); + lightoutput = charge * charge * mLightTableZN[ibeta][iangle][iradius]; + //printf(" \t ZNtableEntry[%d %d %d] = %1.5f -> lightoutput %f\n", ibeta, iangle, iradius, mLightTableZN[ibeta][iangle][iradius], lightoutput); + } else { + iradius = std::min((int)Geometry::ZPFIBREDIAMETER, iradius); + lightoutput = charge * charge * mLightTableZP[ibeta][iangle][iradius]; + //printf(" \t ZPtableEntry[%d %d %d] = %1.5f -> lightoutput %f\n", ibeta, iangle, iradius, mLightTableZP[ibeta][iangle][iradius], lightoutput); + } + if (lightoutput > 0) { + nphe = gRandom->Poisson(lightoutput); + //printf(" \t\t-> nphe %d \n", nphe); + } } } } - } } auto tof = 1.e09 * fMC->TrackTime(); //TOF in ns @@ -498,9 +498,9 @@ bool Detector::createHitsFromImage(SpatialPhotonResponse const& image, int detec } // end function //_____________________________________________________________________________ -o2::zdc::Hit* Detector::addHit(Int_t trackID, Int_t parentID, Int_t sFlag, Float_t primaryEnergy, Int_t detID, - Int_t secID, math_utils::Vector3D pos, math_utils::Vector3D mom, Float_t tof, math_utils::Vector3D xImpact, - Double_t energyloss, Int_t nphePMC, Int_t nphePMQ) +o2::zdc::Hit* Detector::addHit(int32_t trackID, int32_t parentID, int32_t sFlag, float primaryEnergy, int32_t detID, + int32_t secID, math_utils::Vector3D pos, math_utils::Vector3D mom, float tof, math_utils::Vector3D xImpact, + double energyloss, int32_t nphePMC, int32_t nphePMQ) { LOG(DEBUG4) << "Adding hit for track " << trackID << " X (" << pos.X() << ", " << pos.Y() << ", " << pos.Z() << ") P (" << mom.X() << ", " << mom.Y() << ", " << mom.Z() << ") Ekin " @@ -513,94 +513,94 @@ o2::zdc::Hit* Detector::addHit(Int_t trackID, Int_t parentID, Int_t sFlag, Float //_____________________________________________________________________________ void Detector::createMaterials() { - Int_t ifield = 2; - Float_t fieldm = 10.0; + int32_t ifield = 2; + float fieldm = 10.0; o2::base::Detector::initFieldTrackingParams(ifield, fieldm); LOG(INFO) << "Detector::CreateMaterials >>>>> magnetic field: type " << ifield << " max " << fieldm << "\n"; // ******** MATERIAL DEFINITION ******** // --- W alloy -> ZN passive material - Float_t aW[3] = {183.85, 55.85, 58.71}; - Float_t zW[3] = {74., 26., 28.}; - Float_t wW[3] = {0.93, 0.03, 0.04}; - Float_t dW = 17.6; + float aW[3] = {183.85, 55.85, 58.71}; + float zW[3] = {74., 26., 28.}; + float wW[3] = {0.93, 0.03, 0.04}; + float dW = 17.6; // --- Brass (CuZn) -> ZP passive material - Float_t aCuZn[2] = {63.546, 65.39}; - Float_t zCuZn[2] = {29., 30.}; - Float_t wCuZn[2] = {0.63, 0.37}; - Float_t dCuZn = 8.48; + float aCuZn[2] = {63.546, 65.39}; + float zCuZn[2] = {29., 30.}; + float wCuZn[2] = {0.63, 0.37}; + float dCuZn = 8.48; // --- SiO2 -> fibres - Float_t aq[2] = {28.0855, 15.9994}; - Float_t zq[2] = {14., 8.}; - Float_t wq[2] = {1., 2.}; - Float_t dq = 2.64; + float aq[2] = {28.0855, 15.9994}; + float zq[2] = {14., 8.}; + float wq[2] = {1., 2.}; + float dq = 2.64; // --- Lead -> ZEM passive material - Float_t aPb = 207.2; - Float_t zPb = 82.; - Float_t dPb = 11.35; - Float_t radPb = 6.37 / dPb; - Float_t absPb = 199.6 / dPb; + float aPb = 207.2; + float zPb = 82.; + float dPb = 11.35; + float radPb = 6.37 / dPb; + float absPb = 199.6 / dPb; // --- Copper -> beam pipe - Float_t aCu = 63.546; - Float_t zCu = 29.; - Float_t dCu = 8.96; - Float_t radCu = 12.86 / dCu; - Float_t absCu = 137.3 / dCu; - // Int_t nCu = 1.10; + float aCu = 63.546; + float zCu = 29.; + float dCu = 8.96; + float radCu = 12.86 / dCu; + float absCu = 137.3 / dCu; + // int32_t nCu = 1.10; // --- Iron -> beam pipe - Float_t aFe = 55.845; - Float_t zFe = 26.; - Float_t dFe = 7.874; - Float_t radFe = 13.84 / dFe; - Float_t absFe = 132.1 / dFe; + float aFe = 55.845; + float zFe = 26.; + float dFe = 7.874; + float radFe = 13.84 / dFe; + float absFe = 132.1 / dFe; // --- Aluminum -> beam pipe - Float_t aAl = 26.98; - Float_t zAl = 13.; - Float_t dAl = 2.699; - Float_t radAl = 24.01 / dAl; - Float_t absAl = 107.2 / dAl; + float aAl = 26.98; + float zAl = 13.; + float dAl = 2.699; + float radAl = 24.01 / dAl; + float absAl = 107.2 / dAl; // --- Carbon -> beam pipe - Float_t aCarb = 12.01; - Float_t zCarb = 6.; - Float_t dCarb = 2.265; - Float_t radCarb = 18.8; - Float_t absCarb = 49.9; + float aCarb = 12.01; + float zCarb = 6.; + float dCarb = 2.265; + float radCarb = 18.8; + float absCarb = 49.9; // --- Residual gas -> inside beam pipe - Float_t aResGas[3] = {1.008, 12.0107, 15.9994}; - Float_t zResGas[3] = {1., 6., 8.}; - Float_t wResGas[3] = {0.28, 0.28, 0.44}; - Float_t dResGas = 3.2E-14; + float aResGas[3] = {1.008, 12.0107, 15.9994}; + float zResGas[3] = {1., 6., 8.}; + float wResGas[3] = {0.28, 0.28, 0.44}; + float dResGas = 3.2E-14; // --- Air - Float_t aAir[4] = {12.0107, 14.0067, 15.9994, 39.948}; - Float_t zAir[4] = {6., 7., 8., 18.}; - Float_t wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827}; - Float_t dAir = 1.20479E-3; + float aAir[4] = {12.0107, 14.0067, 15.9994, 39.948}; + float zAir[4] = {6., 7., 8., 18.}; + float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827}; + float dAir = 1.20479E-3; // ******** TRACKING MEDIA PARAMETERS ******** - Int_t notactiveMed = 0, sensMed = 1; // sensitive or not sensitive medium + int32_t notactiveMed = 0, sensMed = 1; // sensitive or not sensitive medium // field integration 0 no field -1 user in guswim 1 Runge Kutta 2 helix 3 const field along z - Int_t inofld = 0; // Max. field value (no field) - Int_t ifld = 2; //TODO: ????CHECK!!!! secondo me va -1!!!!! - Float_t nofieldm = 0.; - - Float_t maxnofld = 0.; // max field value (no field) - Float_t maxfld = 45.; // max field value (with field) - Float_t tmaxnofd = 0.; // max deflection angle due to magnetic field in one step - Float_t tmaxfd = 0.1; // max deflection angle due to magnetic field in one step - Float_t deemax = -1.; // maximum fractional energy loss in one step 0RegisterYourself(); //-- rotation matrices for the legs - Int_t irotpipe1, irotpipe2; + int32_t irotpipe1, irotpipe2; double rang1[6] = {90. - 1.0027, 0., 90., 90., 1.0027, 180.}; double rang2[6] = {90. + 1.0027, 0., 90., 90., 1.0027, 0.}; TVirtualMC::GetMC()->Matrix(irotpipe1, rang1[0], rang1[1], rang1[2], rang1[3], rang1[4], rang1[5]); @@ -1228,7 +1228,7 @@ void Detector::createAsideBeamLine() pQALext->SetLineColor(kBlue); pQALext->SetVisLeaves(kTRUE); // - TGeoTranslation* tr1 = new TGeoTranslation(0., 0., (Double_t)conpar[0] + 0.95 + zA); + TGeoTranslation* tr1 = new TGeoTranslation(0., 0., (double)conpar[0] + 0.95 + zA); pZDCA->AddNode(pQALext, 1, tr1); // Inner trousers TGeoCompositeShape* pIntTrousers = new TGeoCompositeShape("intTrousers", "QALint:ZDC_c1+QALint:ZDC_c2"); @@ -1287,15 +1287,15 @@ void Detector::createAsideBeamLine() //_____________________________________________________________________________ void Detector::createCsideBeamLine() { - Double_t tubpar[3] = {0., 0., 0}; - Float_t boxpar[3] = {0., 0., 0}; - Double_t tubspar[5] = {0., 0., 0., 0., 0.}; - Double_t conpar[15] = { + double tubpar[3] = {0., 0., 0}; + float boxpar[3] = {0., 0., 0}; + double tubspar[5] = {0., 0., 0., 0., 0.}; + double conpar[15] = { 0., }; - Float_t zC = 1947.2; - Float_t zCompensator = 1974.; + float zC = 1947.2; + float zCompensator = 1974.; conpar[0] = 0.; conpar[1] = 360.; @@ -1363,7 +1363,7 @@ void Detector::createCsideBeamLine() zC += conpar[0] * 2.; // 2nd section of VCTCQ+VAMTF+TCLIA+VAMTF+1st part of VCTCP - Float_t totLength1 = 160.8 + 78. + 148. + 78. + 9.3; + float totLength1 = 160.8 + 78. + 148. + 78. + 9.3; // tubpar[0] = 18.6 / 2.; tubpar[1] = 7.6 / 2.; @@ -1415,7 +1415,7 @@ void Detector::createCsideBeamLine() zC += conpar[0] * 2.; // 3rd section of VCTCP+VCDWC+VMLGB - Float_t totLenght2 = (8373.3 - zC); + float totLenght2 = (8373.3 - zC); tubpar[0] = 21.2 / 2.; tubpar[1] = 21.9 / 2.; tubpar[2] = totLenght2 / 2.; @@ -1570,16 +1570,16 @@ void Detector::createCsideBeamLine() // -------------------------------------------------------- // RECOMBINATION CHAMBER // TRANSFORMATION MATRICES - Double_t dx = -3.970000; - Double_t dy = 0.000000; - Double_t dz = 0.0; + double dx = -3.970000; + double dy = 0.000000; + double dz = 0.0; // Rotation: - Double_t thx = 84.989100; - Double_t phx = 180.000000; - Double_t thy = 90.000000; - Double_t phy = 90.000000; - Double_t thz = 185.010900; - Double_t phz = 0.000000; + double thx = 84.989100; + double phx = 180.000000; + double thy = 90.000000; + double phy = 90.000000; + double thz = 185.010900; + double phz = 0.000000; TGeoRotation* rotMatrix1c = new TGeoRotation("c", thx, phx, thy, phy, thz, phz); // Combi transformation: dx = -3.970000; @@ -1631,7 +1631,7 @@ void Detector::createCsideBeamLine() pQCLext->SetLineColor(kAzure); pQCLext->SetVisLeaves(kTRUE); // - TGeoTranslation* tr1c = new TGeoTranslation(0., 0., (Double_t)-conpar[0] - 0.95 - zC); + TGeoTranslation* tr1c = new TGeoTranslation(0., 0., (double)-conpar[0] - 0.95 - zC); // pZDCC->AddNode(pQCLext, 1, tr1c); // Inner trousers @@ -1644,7 +1644,7 @@ void Detector::createCsideBeamLine() pQCLext->AddNode(pQCLint, 1); zC += 90.1; - Double_t offset = 0.5; + double offset = 0.5; zC = zC + offset; // second section : 2 tubes (ID = 54. OD = 58.) @@ -1658,7 +1658,7 @@ void Detector::createCsideBeamLine() zC += 2. * tubpar[2]; //-- rotation matrices for the legs - Int_t irotpipe1, irotpipe2; + int32_t irotpipe1, irotpipe2; double rang1[6] = {90. - 1.0027, 0., 90., 90., 1.0027, 180.}; double rang2[6] = {90. + 1.0027, 0., 90., 90., 1.0027, 0.}; TVirtualMC::GetMC()->Matrix(irotpipe1, rang1[0], rang1[1], rang1[2], rang1[3], rang1[4], rang1[5]); @@ -1700,8 +1700,8 @@ void Detector::createCsideBeamLine() //_____________________________________________________________________________ void Detector::createMagnets() { - Float_t tubpar[3] = {0., 0., 0.}; - Float_t boxpar[3] = {0., 0., 0.}; + float tubpar[3] = {0., 0., 0.}; + float boxpar[3] = {0., 0., 0.}; // Parameters from magnet DEFINITION double zCompensatorField = 1972.5; double zITField = 2296.5; @@ -1974,7 +1974,7 @@ void Detector::createDetectors() double znSupportWallsud[3] = {3.52, 1., 50.}; //Top and bottom walls double znSupportWallside[3] = {0.4, 5.52, 50.}; //Side walls - Float_t dimPb[6], dimVoid[6]; + float dimPb[6], dimVoid[6]; // ------------------------------------------------------------------------------- //--> Neutron calorimeter (ZN) @@ -2007,8 +2007,8 @@ void Detector::createDetectors() TVirtualMC::GetMC()->Gsdvn("ZNST", "ZNSL", Geometry::ZNDIVISION[0], 1); // Sticks // --- Position the empty grooves in the sticks (4 grooves per stick) - Float_t dx = Geometry::ZNDIMENSION[0] / Geometry::ZNDIVISION[0] / 4.; - Float_t dy = Geometry::ZNDIMENSION[1] / Geometry::ZNDIVISION[1] / 4.; + float dx = Geometry::ZNDIMENSION[0] / Geometry::ZNDIVISION[0] / 4.; + float dy = Geometry::ZNDIMENSION[1] / Geometry::ZNDIVISION[1] / 4.; TVirtualMC::GetMC()->Gspos("ZNG1", 1, "ZNST", 0. - dx, 0. + dy, 0., 0, "ONLY"); TVirtualMC::GetMC()->Gspos("ZNG2", 1, "ZNST", 0. + dx, 0. + dy, 0., 0, "ONLY"); @@ -2023,7 +2023,7 @@ void Detector::createDetectors() // --- Position the neutron calorimeter in ZDC // -- Rotation of C side ZN - Int_t irotznc; + int32_t irotznc; double rangznc[6] = {90., 180., 90., 90., 180., 0.}; TVirtualMC::GetMC()->Matrix(irotznc, rangznc[0], rangznc[1], rangznc[2], rangznc[3], rangznc[4], rangznc[5]); // @@ -2198,7 +2198,7 @@ void Detector::createDetectors() // ------------------------------------------------------------------------------- // -> EM calorimeter (ZEM) - Int_t irotzem1, irotzem2; + int32_t irotzem1, irotzem2; double rangzem1[6] = {0., 0., 90., 90., -90., 0.}; double rangzem2[6] = {180., 0., 90., 45. + 90., 90., 45.}; TVirtualMC::GetMC()->Matrix(irotzem1, rangzem1[0], rangzem1[1], rangzem1[2], rangzem1[3], rangzem1[4], rangzem1[5]); @@ -2242,33 +2242,33 @@ void Detector::createDetectors() TVirtualMC::GetMC()->Gspos("ZEMF", 1, "ZES1", 0., 0., 0., irotzem2, "ONLY"); // --- Positioning the vacuum slice into the tranche - //Float_t displFib = fDimZEM[1]/fDivZEM[0]; + //float displFib = fDimZEM[1]/fDivZEM[0]; TVirtualMC::GetMC()->Gspos("ZEV0", 1, "ZETR", -zemVoidLayer[0], 0., 0., 0, "ONLY"); TVirtualMC::GetMC()->Gspos("ZEV1", 1, "ZETR", -zemVoidLayer[0] + zemPbSlice[0], 0., 0., 0, "ONLY"); // --- Positioning the ZEM into the ZDC - rotation for 90 degrees // NB -> ZEM is positioned in cave volume - const Float_t z0 = 1313.3475; // center of caveRB24 mother volume + const float z0 = 1313.3475; // center of caveRB24 mother volume TVirtualMC::GetMC()->Gspos("ZEM ", 1, "caveRB24", -Geometry::ZEMPOSITION[0], Geometry::ZEMPOSITION[1], Geometry::ZEMPOSITION[2] + Geometry::ZEMDIMENSION[0] - z0, irotzem1, "ONLY"); // Second EM ZDC (same side w.r.t. IP, just on the other side w.r.t. beam pipe) TVirtualMC::GetMC()->Gspos("ZEM ", 2, "caveRB24", Geometry::ZEMPOSITION[0], Geometry::ZEMPOSITION[1], Geometry::ZEMPOSITION[2] + Geometry::ZEMDIMENSION[0] - z0, irotzem1, "ONLY"); // --- Adding last slice at the end of the EM calorimeter - Float_t zLastSlice = Geometry::ZEMPOSITION[2] + zemPbSlice[0] + 2 * Geometry::ZEMDIMENSION[0]; + float zLastSlice = Geometry::ZEMPOSITION[2] + zemPbSlice[0] + 2 * Geometry::ZEMDIMENSION[0]; TVirtualMC::GetMC()->Gspos("ZEL2", 1, "caveRB24", Geometry::ZEMPOSITION[0], Geometry::ZEMPOSITION[1], zLastSlice - z0, irotzem1, "ONLY"); // ------------------------------------------------------------------------------- // -> ZEM supports // Platform and supports - Float_t ybox = Geometry::ZEMPOSITION[1] - Geometry::ZEMDIMENSION[1] - 2. * 2. * zemSupportBox[3 + 1] + zemSupportBox[1]; - Float_t zSupport = Geometry::ZEMPOSITION[2] - 3.5; //to take into account the titlted front face - Float_t zbox = zSupport + zemSupportBox[2]; + float ybox = Geometry::ZEMPOSITION[1] - Geometry::ZEMDIMENSION[1] - 2. * 2. * zemSupportBox[3 + 1] + zemSupportBox[1]; + float zSupport = Geometry::ZEMPOSITION[2] - 3.5; //to take into account the titlted front face + float zbox = zSupport + zemSupportBox[2]; // Bridge TVirtualMC::GetMC()->Gsvolu("ZESH", "BOX ", getMediumID(kAl), const_cast(zemSupport1), 3); - Float_t ybridge = Geometry::ZEMPOSITION[1] - Geometry::ZEMDIMENSION[1] - 2. * 2. * zemSupportBox[3 + 1] - 5. - zemSupport1[1]; + float ybridge = Geometry::ZEMPOSITION[1] - Geometry::ZEMDIMENSION[1] - 2. * 2. * zemSupportBox[3 + 1] - 5. - zemSupport1[1]; TVirtualMC::GetMC()->Gspos("ZESH", 1, "caveRB24", Geometry::ZEMPOSITION[0], ybridge, zbox - z0, 0, "ONLY"); TVirtualMC::GetMC()->Gspos("ZESH", 2, "caveRB24", -Geometry::ZEMPOSITION[0], ybridge, zbox - z0, 0, "ONLY"); // @@ -2280,7 +2280,7 @@ void Detector::createDetectors() // Table TVirtualMC::GetMC()->Gsvolu("ZETA", "BOX ", getMediumID(kAl), const_cast(zemSupportTable), 3); - Float_t ytable = ybridge - zemSupport1[1] - zemSupportTable[1]; + float ytable = ybridge - zemSupport1[1] - zemSupportTable[1]; TVirtualMC::GetMC()->Gspos("ZETA", 1, "caveRB24", 0.0, ytable, zbox - z0, 0, "ONLY"); TVirtualMC::GetMC()->Gspos("ZETA", 2, "caveRB24", 0.0, ytable - 13. + 2. * zemSupportTable[1], zbox - z0, 0, "ONLY"); @@ -2301,8 +2301,8 @@ void Detector::createDetectors() TVirtualMC::GetMC()->Gsvolu("ZEW3", "BOX ", getMediumID(kAl), const_cast(zemWallVbkw), 3); TVirtualMC::GetMC()->Gsvolu("ZEW4", "BOX ", getMediumID(kFe), const_cast(zemWallVside), 3); // - Float_t yh1 = Geometry::ZEMPOSITION[1] - Geometry::ZEMDIMENSION[1] - 2 * zemSupport3[1] - zemWallH[1]; - Float_t zh1 = zSupport + zemWallH[2]; + float yh1 = Geometry::ZEMPOSITION[1] - Geometry::ZEMDIMENSION[1] - 2 * zemSupport3[1] - zemWallH[1]; + float zh1 = zSupport + zemWallH[2]; TVirtualMC::GetMC()->Gspos("ZEW1", 1, "caveRB24", Geometry::ZEMPOSITION[0], yh1, zh1 - z0, 0, "ONLY"); TVirtualMC::GetMC()->Gspos("ZEW1", 2, "caveRB24", Geometry::ZEMPOSITION[0], yh1 + 2 * zemSupportBox[1], zh1 - z0, 0, "ONLY"); TVirtualMC::GetMC()->Gspos("ZEW1", 3, "caveRB24", -Geometry::ZEMPOSITION[0], yh1, zh1 - z0, 0, "ONLY"); @@ -2313,8 +2313,8 @@ void Detector::createDetectors() TVirtualMC::GetMC()->Gspos("ZEW2", 2, "caveRB24", -Geometry::ZEMPOSITION[0], yh1 + zemSupportBox[1], zSupport - zemWallVfwd[2] - z0, 0, "ONLY"); TVirtualMC::GetMC()->Gspos("ZEW3", 2, "caveRB24", -Geometry::ZEMPOSITION[0], yh1 + zemSupportBox[1], zSupport + 2 * zemWallH[2] - z0, 0, "ONLY"); // - Float_t xl1 = Geometry::ZEMPOSITION[0] - Geometry::ZEMDIMENSION[2] - 2. * zemSupport4[2] - zemWallVside[0]; - Float_t xl2 = Geometry::ZEMPOSITION[0] + Geometry::ZEMDIMENSION[2] + 2. * zemSupport4[2] + zemWallVside[0]; + float xl1 = Geometry::ZEMPOSITION[0] - Geometry::ZEMDIMENSION[2] - 2. * zemSupport4[2] - zemWallVside[0]; + float xl2 = Geometry::ZEMPOSITION[0] + Geometry::ZEMDIMENSION[2] + 2. * zemSupport4[2] + zemWallVside[0]; TVirtualMC::GetMC()->Gspos("ZEW4", 1, "caveRB24", xl1, yh1 + zemSupportBox[1], zh1 - z0, 0, "ONLY"); TVirtualMC::GetMC()->Gspos("ZEW4", 2, "caveRB24", xl2, yh1 + zemSupportBox[1], zh1 - z0, 0, "ONLY"); TVirtualMC::GetMC()->Gspos("ZEW4", 3, "caveRB24", -xl1, yh1 + zemSupportBox[1], zh1 - z0, 0, "ONLY"); diff --git a/Detectors/ZDC/simulation/src/Digitizer.cxx b/Detectors/ZDC/simulation/src/Digitizer.cxx index 4b6ec25f8f27f..fc6da3ee7a354 100644 --- a/Detectors/ZDC/simulation/src/Digitizer.cxx +++ b/Detectors/ZDC/simulation/src/Digitizer.cxx @@ -64,8 +64,9 @@ void Digitizer::process(const std::vector& hits, int detID = hit.GetDetectorID(); int secID = hit.getSector(); float nPhotons; - if (detID == ZEM) { // TODO: ZEMCh1 and Common are both 0, could skip the check for detID - nPhotons = (secID == ZEMCh1) ? hit.getPMCLightYield() : hit.getPMQLightYield(); + if (detID == ZEM) { + // ZEM calorimeters have only common PM + nPhotons = hit.getPMCLightYield(); } else { nPhotons = (secID == Common) ? hit.getPMCLightYield() : hit.getPMQLightYield(); } @@ -256,8 +257,9 @@ bool Digitizer::triggerBC(int ibc) int id = trigCh.id; if (id >= 0 && id < NChannels) { auto ipos = NChPerModule * md.id + ic; + int last1 = trigCh.last + 2; bool okPrev = false; - int last1 = trigCh.last + 2; // To be modified. The new requirement is 3 consecutive samples +#ifdef ZDC_DOUBLE_TRIGGER_CONDITION // look for 2 consecutive bins (the 1st one spanning trigCh.first : trigCh.last range) so that // signal[bin]-signal[bin+trigCh.shift] > trigCh.threshold for (int ib = trigCh.first; ib < last1; ib++) { // ib may be negative, so we shift by offs and look in the ADC cache @@ -274,6 +276,26 @@ bool Digitizer::triggerBC(int ibc) } okPrev = ok; } +#else + bool okPPrev = false; + // look for 3 consecutive bins (the 1st one spanning trigCh.first : trigCh.last range) so that + // signal[bin]-signal[bin+trigCh.shift] > trigCh.threshold + for (int ib = trigCh.first - 1; ib < last1; ib++) { // ib may be negative, so we shift by offs and look in the ADC cache + int binF, bcFidx = ibc + binHelper(ib, binF); + int binL, bcLidx = ibc + binHelper(ib + trigCh.shift, binL); + const auto& bcF = (bcFidx < 0 || !mFastCache[bcFidx]) ? mDummyBC : *mFastCache[bcFidx]; + const auto& bcL = (bcLidx < 0 || !mFastCache[bcLidx]) ? mDummyBC : *mFastCache[bcLidx]; + bool ok = bcF.digi[ipos][binF] - bcL.digi[ipos][binL] > trigCh.threshold; + if (ok && okPrev && okPPrev) { // trigger ok! + bcCached.trigChanMask |= 0x1 << (NChPerModule * md.id + ic); // register trigger mask + LOG(DEBUG) << bcF.digi[ipos][binF] << " - " << bcL.digi[ipos][binL] << " = " << bcF.digi[ipos][binF] - bcL.digi[ipos][binL] << " > " << trigCh.threshold; + LOG(DEBUG) << " hit [" << md.id << "," << ic << "] " << int(id) << "(" << ChannelNames[id] << ") => " << bcCached.trigChanMask; + break; + } + okPPrev = okPrev; + okPrev = ok; + } +#endif } } } @@ -539,9 +561,8 @@ void Digitizer::assignTriggerBits(uint32_t ibc, std::vector& bcData) // Triggers refer to the HW trigger conditions (32 possible channels) uint32_t nbcTot = bcData.size(); - auto currBC = bcData[ibc]; + auto& currBC = bcData[ibc]; - uint32_t triggers[5] = {0}; for (int is = -1; is < 4; is++) { int ibc_peek = ibc + is; if (ibc_peek < 0) { @@ -551,29 +572,29 @@ void Digitizer::assignTriggerBits(uint32_t ibc, std::vector& bcData) break; } const auto& otherBC = bcData[ibc_peek]; - if (otherBC.triggers) { - auto diffBC = otherBC.ir.differenceInBC(currBC.ir); - if (diffBC < -1 || diffBC > 3) { - continue; - } - diffBC++; - if (otherBC.ext_triggers) { - for (int im = 0; im < NModules; im++) { - currBC.moduleTriggers[im] |= 0x1 << diffBC; - } + auto diffBC = otherBC.ir.differenceInBC(currBC.ir); + if (diffBC < -1) { + continue; + } + if (diffBC > 3) { + break; + } + if (otherBC.ext_triggers && diffBC >= 0) { + for (int im = 0; im < NModules; im++) { + currBC.moduleTriggers[im] |= 0x1 << diffBC; } - triggers[diffBC] = otherBC.triggers; - } - // Assign trigger bits in payload - for (int im = 0; im < NModules; im++) { - uint32_t tmask = (0xf << (im * NChPerModule)) & mTriggerMask; - for (int it = 0; it < 5; it++) { - if (triggers[it] & tmask) { - currBC.moduleTriggers[im] |= 0x1 << (5 + it); + } + if (otherBC.triggers) { + // Assign trigger bits in payload + for (int im = 0; im < NModules; im++) { + uint32_t tmask = (0xf << (im * NChPerModule)) & mTriggerMask; + if (otherBC.triggers & tmask) { + currBC.moduleTriggers[im] |= 0x1 << (5 + diffBC); } } } } + currBC.print(mTriggerMask); } //______________________________________________________________________________ diff --git a/Detectors/ZDC/simulation/src/Digits2Raw.cxx b/Detectors/ZDC/simulation/src/Digits2Raw.cxx index b6bbf3724e4e8..a5835d3d233cc 100644 --- a/Detectors/ZDC/simulation/src/Digits2Raw.cxx +++ b/Detectors/ZDC/simulation/src/Digits2Raw.cxx @@ -67,27 +67,34 @@ void Digits2Raw::processDigits(const std::string& outDir, const std::string& fil std::unique_ptr digiFile(TFile::Open(fileDigitsName.c_str())); if (!digiFile || digiFile->IsZombie()) { - LOG(ERROR) << "Failed to open input digits file " << fileDigitsName; + LOG(FATAL) << "Failed to open input digits file " << fileDigitsName; return; } TTree* digiTree = (TTree*)digiFile->Get("o2sim"); if (!digiTree) { - LOG(ERROR) << "Failed to get digits tree"; + LOG(FATAL) << "Failed to get digits tree"; return; } if (digiTree->GetBranch("ZDCDigitBC")) { digiTree->SetBranchAddress("ZDCDigitBC", &mzdcBCDataPtr); } else { - LOG(ERROR) << "Branch ZDCDigitBC is missing"; + LOG(FATAL) << "Branch ZDCDigitBC is missing"; return; } if (digiTree->GetBranch("ZDCDigitCh")) { digiTree->SetBranchAddress("ZDCDigitCh", &mzdcChDataPtr); } else { - LOG(ERROR) << "Branch ZDCDigitCh is missing"; + LOG(FATAL) << "Branch ZDCDigitCh is missing"; + return; + } + + if (digiTree->GetBranch("ZDCDigitPed")) { + digiTree->SetBranchAddress("ZDCDigitPed", &mzdcPedDataPtr); + } else { + LOG(FATAL) << "Branch ZDCDigitPed is missing"; return; } @@ -131,15 +138,15 @@ void Digits2Raw::setTriggerMask() { mTriggerMask = 0; mPrintTriggerMask = ""; - for (Int_t im = 0; im < NModules; im++) { + for (int32_t im = 0; im < NModules; im++) { if (im > 0) { mPrintTriggerMask += " "; } mPrintTriggerMask += std::to_string(im); mPrintTriggerMask += "["; - for (UInt_t ic = 0; ic < NChPerModule; ic++) { + for (uint32_t ic = 0; ic < NChPerModule; ic++) { if (mModuleConfig->modules[im].trigChannel[ic]) { - UInt_t tmask = 0x1 << (im * NChPerModule + ic); + uint32_t tmask = 0x1 << (im * NChPerModule + ic); mTriggerMask = mTriggerMask | tmask; mPrintTriggerMask += "T"; } else { @@ -147,7 +154,7 @@ void Digits2Raw::setTriggerMask() } } mPrintTriggerMask += "]"; - UInt_t mytmask = mTriggerMask >> (im * NChPerModule); + uint32_t mytmask = mTriggerMask >> (im * NChPerModule); printf("Trigger mask for module %d 0123 %s%s%s%s\n", im, mytmask & 0x1 ? "T" : "N", mytmask & 0x2 ? "T" : "N", @@ -160,8 +167,8 @@ void Digits2Raw::setTriggerMask() //______________________________________________________________________________ inline void Digits2Raw::resetSums(uint32_t orbit) { - for (Int_t im = 0; im < NModules; im++) { - for (Int_t ic = 0; ic < NChPerModule; ic++) { + for (int32_t im = 0; im < NModules; im++) { + for (int32_t ic = 0; ic < NChPerModule; ic++) { mScalers[im][ic] = 0; mSumPed[im][ic] = 0; mPed[im][ic] = 0; @@ -175,22 +182,52 @@ inline void Digits2Raw::resetSums(uint32_t orbit) inline void Digits2Raw::updatePedestalReference(int bc) { // Compute or update baseline reference - if (mEmpty[bc] > 0 && mEmpty[bc] != mLastNEmpty) { - for (Int_t im = 0; im < NModules; im++) { - for (Int_t ic = 0; ic < NChPerModule; ic++) { + // In the last BC we copy what is stored in the digits + if (bc == 3563) { + int io = 0; + for (; io < mzdcPedData.size(); io++) { + uint32_t orbit = mBCD.ir.orbit; + if (orbit == mzdcPedData[io].ir.orbit) { + break; + } + } + if (io == mzdcPedData.size()) { + LOG(FATAL) << "Cannot find orbit"; + } + + for (int32_t im = 0; im < NModules; im++) { + for (int32_t ic = 0; ic < NChPerModule; ic++) { + // Identify connected channel + auto id = mModuleConfig->modules[im].channelID[ic]; + double myped = mzdcPedData[io].data[id] + 32768.; + if (myped < 0) { + myped = 0; + } + if (myped > 65535) { + myped = 65535; + } + mPed[im][ic] = myped; + } + } + } else if (mEmpty[bc] > 0 && mEmpty[bc] != mLastNEmpty) { + // For the preceding bunch crossing we make-up the fields in a random walk + // fashion like in the hardware. The result however cannot be coherent with + // what is stored in the last bunch + for (int32_t im = 0; im < NModules; im++) { + for (int32_t ic = 0; ic < NChPerModule; ic++) { // Identify connected channel auto id = mModuleConfig->modules[im].channelID[ic]; auto base_m = mSimCondition->channels[id].pedestal; // Average pedestal auto base_s = mSimCondition->channels[id].pedestalFluct; // Baseline oscillations auto base_n = mSimCondition->channels[id].pedestalNoise; // Electronic noise - Double_t deltan = mEmpty[bc] - mLastNEmpty; + double deltan = mEmpty[bc] - mLastNEmpty; // We assume to have a fluctuation every two bunch crossings // Will need to tune this parameter - Double_t k = 2.; + double k = 2.; mSumPed[im][ic] += gRandom->Gaus(12. * deltan * base_m, 12. * k * base_s * TMath::Sqrt(deltan / k)); // Adding in quadrature the RMS of pedestal electronic noise mSumPed[im][ic] += gRandom->Gaus(0, base_n * TMath::Sqrt(12. * deltan)); - Double_t myped = TMath::Nint(8. * mSumPed[im][ic] / Double_t(mEmpty[bc]) / 12. + 32768); + double myped = TMath::Nint(8. * mSumPed[im][ic] / double(mEmpty[bc]) / 12. + 32768); if (myped < 0) { myped = 0; } @@ -205,11 +242,11 @@ inline void Digits2Raw::updatePedestalReference(int bc) } //______________________________________________________________________________ -inline void Digits2Raw::resetOutputStructure(UShort_t bc, UInt_t orbit, bool is_dummy) +inline void Digits2Raw::resetOutputStructure(uint16_t bc, uint32_t orbit, bool is_dummy) { // Increment scalers and reset output structure - for (UInt_t im = 0; im < NModules; im++) { - for (UInt_t ic = 0; ic < NChPerModule; ic++) { + for (uint32_t im = 0; im < NModules; im++) { + for (uint32_t ic = 0; ic < NChPerModule; ic++) { // Fixed words mZDC.data[im][ic].w[0][0] = Id_w0; mZDC.data[im][ic].w[0][1] = 0; @@ -243,149 +280,25 @@ inline void Digits2Raw::resetOutputStructure(UShort_t bc, UInt_t orbit, bool is_ } //______________________________________________________________________________ -inline void Digits2Raw::assignTriggerBits(int ibc, UShort_t bc, UInt_t orbit, bool is_dummy) +inline void Digits2Raw::assignTriggerBits(int ibc, uint16_t bc, uint32_t orbit, bool is_dummy) { // Triggers refer to the HW trigger conditions (32 possible channels) // Autotrigger, current bunch crossing - UInt_t triggers_0 = 0; + ModuleTriggerMapData triggers; // Autotrigger and ALICE trigger bits are zero for a dummy bunch crossing if (!is_dummy) { - triggers_0 = mBCD.triggers; - // ALICE current bunch crossing - if (mBCD.ext_triggers) { - for (UInt_t im = 0; im < NModules; im++) { - for (UInt_t ic = 0; ic < NChPerModule; ic++) { - mZDC.data[im][ic].f.Alice_0 = 1; - } - } - } - } - - // Next bunch crossings (ALICE and autotrigger) - UInt_t triggers_1 = 0, triggers_2 = 0, triggers_3 = 0, triggers_m = 0; - for (Int_t is = 1; is < 4; is++) { - Int_t ibc_peek = ibc + is; - if (ibc_peek >= mNbc) { - break; - } - const auto& bcd_peek = mzdcBCData[ibc_peek]; - UShort_t bc_peek = bcd_peek.ir.bc; - UInt_t orbit_peek = bcd_peek.ir.orbit; - if (bcd_peek.triggers) { - if (orbit_peek == orbit) { - if ((bc_peek - bc) == 1) { - triggers_1 = bcd_peek.triggers; - if (bcd_peek.ext_triggers) { - for (UInt_t im = 0; im < NModules; im++) { - for (UInt_t ic = 0; ic < NChPerModule; ic++) { - mZDC.data[im][ic].f.Alice_1 = 1; - } - } - } - } else if ((bc_peek - bc) == 2) { - triggers_2 = bcd_peek.triggers; - if (bcd_peek.ext_triggers) { - for (UInt_t im = 0; im < NModules; im++) { - for (UInt_t ic = 0; ic < NChPerModule; ic++) { - mZDC.data[im][ic].f.Alice_2 = 1; - } - } - } - } else if ((bc_peek - bc) == 3) { - triggers_3 = bcd_peek.triggers; - if (bcd_peek.ext_triggers) { - for (UInt_t im = 0; im < NModules; im++) { - for (UInt_t ic = 0; ic < NChPerModule; ic++) { - mZDC.data[im][ic].f.Alice_3 = 1; - } - } - } - break; - } - } else if (orbit_peek == (orbit + 1)) { - if ((bc_peek + 3564 - bc) == 1) { - triggers_1 = bcd_peek.triggers; - if (bcd_peek.ext_triggers) { - for (UInt_t im = 0; im < NModules; im++) { - for (UInt_t ic = 0; ic < NChPerModule; ic++) { - mZDC.data[im][ic].f.Alice_1 = 1; - } - } - } - } else if ((bc_peek + 3564 - bc) == 2) { - triggers_2 = bcd_peek.triggers; - if (bcd_peek.ext_triggers) { - for (UInt_t im = 0; im < NModules; im++) { - for (UInt_t ic = 0; ic < NChPerModule; ic++) { - mZDC.data[im][ic].f.Alice_2 = 1; - } - } - } - } else if ((bc_peek + 3564 - bc) == 3) { - triggers_3 = bcd_peek.triggers; - if (bcd_peek.ext_triggers) { - for (UInt_t im = 0; im < NModules; im++) { - for (UInt_t ic = 0; ic < NChPerModule; ic++) { - mZDC.data[im][ic].f.Alice_3 = 1; - } - } - } - break; - } - } else { - break; - } - } - } - - // Previous bunch crossing just for autotrigger - // For a dummy last bunch crossing previous bunch is the one pointed by ibc - { - Int_t ibc_peek = is_dummy ? ibc : ibc - 1; - if (ibc_peek >= 0) { - const auto& bcd_peek = mzdcBCData[ibc - 1]; - UShort_t bc_peek = bcd_peek.ir.bc; - UInt_t orbit_peek = bcd_peek.ir.orbit; - if (bcd_peek.triggers) { - if (orbit_peek == orbit) { - if ((bc - bc_peek) == 1) { - triggers_m = bcd_peek.triggers; - } - } else if (orbit_peek == (orbit - 1)) { - if (bc == 0 && bc_peek == 3563) { - triggers_m = bcd_peek.triggers; - } - } - } - } - } - - // Assign trigger bits in payload - for (Int_t im = 0; im < NModules; im++) { - UInt_t tmask = (0xf << (im * NChPerModule)) & mTriggerMask; - if (triggers_m & tmask) { - for (UInt_t ic = 0; ic < NChPerModule; ic++) { - mZDC.data[im][ic].f.Auto_m = 1; - } - } - if (triggers_0 & tmask) { - for (UInt_t ic = 0; ic < NChPerModule; ic++) { - mZDC.data[im][ic].f.Auto_0 = 1; - } - } - if (triggers_1 & tmask) { - for (UInt_t ic = 0; ic < NChPerModule; ic++) { - mZDC.data[im][ic].f.Auto_1 = 1; - } - } - if (triggers_2 & tmask) { - for (UInt_t ic = 0; ic < NChPerModule; ic++) { - mZDC.data[im][ic].f.Auto_2 = 1; - } - } - if (triggers_3 & tmask) { - for (UInt_t ic = 0; ic < NChPerModule; ic++) { - mZDC.data[im][ic].f.Auto_3 = 1; + for (uint32_t im = 0; im < NModules; im++) { + triggers.w = mzdcBCData[ibc].moduleTriggers[im]; + for (uint32_t ic = 0; ic < NChPerModule; ic++) { + mZDC.data[im][ic].f.Alice_0 = triggers.f.Alice_0; + mZDC.data[im][ic].f.Alice_1 = triggers.f.Alice_1; + mZDC.data[im][ic].f.Alice_2 = triggers.f.Alice_2; + mZDC.data[im][ic].f.Alice_3 = triggers.f.Alice_3; + mZDC.data[im][ic].f.Auto_m = triggers.f.Auto_m; + mZDC.data[im][ic].f.Auto_0 = triggers.f.Auto_0; + mZDC.data[im][ic].f.Auto_1 = triggers.f.Auto_1; + mZDC.data[im][ic].f.Auto_2 = triggers.f.Auto_2; + mZDC.data[im][ic].f.Auto_3 = triggers.f.Auto_3; } } } @@ -396,7 +309,7 @@ void Digits2Raw::insertLastBunch(int ibc, uint32_t orbit) { // Orbit and bunch crossing identifiers - UShort_t bc = 3563; + uint16_t bc = 3563; // Reset scalers at orbit change if (orbit != mLastOrbit) { @@ -412,16 +325,16 @@ void Digits2Raw::insertLastBunch(int ibc, uint32_t orbit) assignTriggerBits(ibc, bc, orbit, true); // Insert payload for all channels - for (Int_t im = 0; im < NModules; im++) { - for (UInt_t ic = 0; ic < NChPerModule; ic++) { + for (int32_t im = 0; im < NModules; im++) { + for (uint32_t ic = 0; ic < NChPerModule; ic++) { if (mModuleConfig->modules[im].readChannel[ic]) { auto id = mModuleConfig->modules[im].channelID[ic]; auto base_m = mSimCondition->channels[id].pedestal; // Average pedestal auto base_s = mSimCondition->channels[id].pedestalFluct; // Baseline oscillations auto base_n = mSimCondition->channels[id].pedestalNoise; // Electronic noise - Double_t base = gRandom->Gaus(base_m, base_s); - Int_t is = 0; - Double_t val = base + gRandom->Gaus(0, base_n); + double base = gRandom->Gaus(base_m, base_s); + int32_t is = 0; + double val = base + gRandom->Gaus(0, base_n); mZDC.data[im][ic].f.s00 = val < ADCMax ? (val > ADCMin ? val : ADCMin) : ADCMax; is++; val = base + gRandom->Gaus(0, base_n); @@ -466,8 +379,8 @@ void Digits2Raw::convertDigits(int ibc) { // Orbit and bunch crossing identifiers - UShort_t bc = mBCD.ir.bc; - UInt_t orbit = mBCD.ir.orbit; + uint16_t bc = mBCD.ir.bc; + uint32_t orbit = mBCD.ir.orbit; // Reset scalers at orbit change if (orbit != mLastOrbit) { @@ -483,8 +396,7 @@ void Digits2Raw::convertDigits(int ibc) assignTriggerBits(ibc, bc, orbit, false); if (mVerbosity > 0) { - mBCD.print(); - printf("Mask: %s\n", mPrintTriggerMask.data()); + mBCD.print(mTriggerMask); } int chEnt = mBCD.ref.getFirstEntry(); @@ -493,16 +405,16 @@ void Digits2Raw::convertDigits(int ibc) if (mVerbosity > 0) { chd.print(); } - UShort_t bc = mBCD.ir.bc; - UInt_t orbit = mBCD.ir.orbit; + uint16_t bc = mBCD.ir.bc; + uint32_t orbit = mBCD.ir.orbit; // Look for channel ID in digits and store channel (just one copy in output) // This is a limitation of software but we are not supposed to acquire the // same signal twice anyway - for (Int_t im = 0; im < NModules; im++) { - for (UInt_t ic = 0; ic < NChPerModule; ic++) { + for (int32_t im = 0; im < NModules; im++) { + for (uint32_t ic = 0; ic < NChPerModule; ic++) { if (mModuleConfig->modules[im].channelID[ic] == chd.id && mModuleConfig->modules[im].readChannel[ic]) { - Int_t is = 0; + int32_t is = 0; mZDC.data[im][ic].f.s00 = chd.data[is]; is++; mZDC.data[im][ic].f.s01 = chd.data[is]; @@ -539,7 +451,7 @@ void Digits2Raw::writeDigits() constexpr static int data_size = sizeof(uint32_t) * NWPerGBTW; // Local interaction record (true and empty bunches) o2::InteractionRecord ir(mZDC.data[0][0].f.bc, mZDC.data[0][0].f.orbit); - for (UInt_t im = 0; im < o2::zdc::NModules; im++) { + for (uint32_t im = 0; im < o2::zdc::NModules; im++) { // Check if module has been filled with data // N.B. All channels are initialized if module is supposed to be readout // Trigger bits are the same for all the channels connected to a module @@ -557,9 +469,9 @@ void Digits2Raw::writeDigits() bool tcond_last = mZDC.data[im][0].f.bc == 3563; // Condition to write GBT data if (tcond_triggered || (mIsContinuous && tcond_continuous) || (mZDC.data[im][0].f.bc == 3563)) { - for (UInt_t ic = 0; ic < o2::zdc::NChPerModule; ic++) { + for (uint32_t ic = 0; ic < o2::zdc::NChPerModule; ic++) { if (mModuleConfig->modules[im].readChannel[ic]) { - for (Int_t iw = 0; iw < o2::zdc::NWPerBc; iw++) { + for (int32_t iw = 0; iw < o2::zdc::NWPerBc; iw++) { gsl::span payload{reinterpret_cast(&mZDC.data[im][ic].w[iw][0]), data_size}; mWriter.addData(mFeeID, mCruID, mLinkID, mEndPointID, ir, payload); } @@ -577,9 +489,9 @@ void Digits2Raw::writeDigits() printf("M%d is last BC\n", im); } if (tcond_triggered || (mIsContinuous && tcond_continuous) || (mZDC.data[im][0].f.bc == 3563)) { - for (UInt_t ic = 0; ic < o2::zdc::NChPerModule; ic++) { + for (uint32_t ic = 0; ic < o2::zdc::NChPerModule; ic++) { if (mModuleConfig->modules[im].readChannel[ic]) { - for (Int_t iw = 0; iw < o2::zdc::NWPerBc; iw++) { + for (int32_t iw = 0; iw < o2::zdc::NWPerBc; iw++) { print_gbt_word(&mZDC.data[im][ic].w[iw][0], mModuleConfig); } } @@ -594,7 +506,7 @@ void Digits2Raw::writeDigits() } //______________________________________________________________________________ -void Digits2Raw::print_gbt_word(const UInt_t* word, const ModuleConfig* moduleConfig) +void Digits2Raw::print_gbt_word(const uint32_t* word, const ModuleConfig* moduleConfig) { if (word == nullptr) { printf("NULL\n"); @@ -605,30 +517,30 @@ void Digits2Raw::print_gbt_word(const UInt_t* word, const ModuleConfig* moduleCo val = val | word[1]; val = val << 32; val = val | word[0]; - static UInt_t last_orbit = 0, last_bc = 0; + static uint32_t last_orbit = 0, last_bc = 0; ULong64_t lsb = val; ULong64_t msb = val >> 64; - UInt_t a = word[0]; - UInt_t b = word[1]; - UInt_t c = word[2]; - //UInt_t d=(msb>>32)&0xffffffff; + uint32_t a = word[0]; + uint32_t b = word[1]; + uint32_t c = word[2]; + //uint32_t d=(msb>>32)&0xffffffff; //printf("\n%llx %llx ",lsb,msb); //printf("\n%8x %8x %8x %8x ",d,c,b,a); if ((a & 0x3) == 0) { - UInt_t myorbit = (val >> 48) & 0xffffffff; - UInt_t mybc = (val >> 36) & 0xfff; + uint32_t myorbit = (val >> 48) & 0xffffffff; + uint32_t mybc = (val >> 36) & 0xfff; if (myorbit != last_orbit || mybc != last_bc) { printf("Orbit %9u bc %4u\n", myorbit, mybc); last_orbit = myorbit; last_bc = mybc; } printf("%04x %08x %08x ", c, b, a); - UInt_t hits = (val >> 24) & 0xfff; - Int_t offset = (lsb >> 8) & 0xffff - 32768; + uint32_t hits = (val >> 24) & 0xfff; + int32_t offset = (lsb >> 8) & 0xffff - 32768; Float_t foffset = offset / 8.; - UInt_t board = (lsb >> 2) & 0xf; - UInt_t ch = (lsb >> 6) & 0x3; + uint32_t board = (lsb >> 2) & 0xf; + uint32_t ch = (lsb >> 6) & 0x3; //printf("orbit %9u bc %4u hits %4u offset %+6i Board %2u Ch %1u", myorbit, mybc, hits, offset, board, ch); printf("orbit %9u bc %4u hits %4u offset %+8.3f Board %2u Ch %1u", myorbit, mybc, hits, foffset, board, ch); if (board >= NModules) { @@ -649,9 +561,9 @@ void Digits2Raw::print_gbt_word(const UInt_t* word, const ModuleConfig* moduleCo printf("%04x %08x %08x ", c, b, a); printf(" %s %s %s %s ", a & 0x10 ? "A0" : " ", a & 0x20 ? "A1" : " ", a & 0x40 ? "A2" : " ", a & 0x80 ? "A3" : " "); printf("0-5 "); - Short_t s[6]; + int16_t s[6]; val = val >> 8; - for (Int_t i = 0; i < 6; i++) { + for (int32_t i = 0; i < 6; i++) { s[i] = val & 0xfff; if (s[i] > ADCMax) { s[i] = s[i] - ADCRange; @@ -663,9 +575,9 @@ void Digits2Raw::print_gbt_word(const UInt_t* word, const ModuleConfig* moduleCo printf("%04x %08x %08x ", c, b, a); printf("%s %s %s %s %s %s ", a & 0x4 ? "H" : " ", a & 0x8 ? "TM" : " ", a & 0x10 ? "T0" : " ", a & 0x20 ? "T1" : " ", a & 0x40 ? "T2" : " ", a & 0x80 ? "T3" : " "); printf("6-b "); - Short_t s[6]; + int16_t s[6]; val = val >> 8; - for (Int_t i = 0; i < 6; i++) { + for (int32_t i = 0; i < 6; i++) { s[i] = val & 0xfff; if (s[i] > ADCMax) { s[i] = s[i] - ADCRange; @@ -685,13 +597,13 @@ void Digits2Raw::emptyBunches(std::bitset<3564>& bunchPattern) { const int LHCMaxBunches = o2::constants::lhc::LHCMaxBunches; mNEmpty = 0; - for (Int_t ib = 0; ib < LHCMaxBunches; ib++) { - Int_t mb = (ib + 31) % LHCMaxBunches; // beam gas from back of calorimeter - Int_t m1 = (ib + 1) % LHCMaxBunches; // previous bunch - Int_t cb = ib; // current bunch crossing - Int_t p1 = (ib - 1) % LHCMaxBunches; // colliding + 1 - Int_t p2 = (ib + 1) % LHCMaxBunches; // colliding + 2 - Int_t p3 = (ib + 1) % LHCMaxBunches; // colliding + 3 + for (int32_t ib = 0; ib < LHCMaxBunches; ib++) { + int32_t mb = (ib + 31) % LHCMaxBunches; // beam gas from back of calorimeter + int32_t m1 = (ib + 1) % LHCMaxBunches; // previous bunch + int32_t cb = ib; // current bunch crossing + int32_t p1 = (ib - 1) % LHCMaxBunches; // colliding + 1 + int32_t p2 = (ib + 1) % LHCMaxBunches; // colliding + 2 + int32_t p3 = (ib + 1) % LHCMaxBunches; // colliding + 3 if (bunchPattern[mb] || bunchPattern[m1] || bunchPattern[cb] || bunchPattern[p1] || bunchPattern[p2] || bunchPattern[p3]) { mEmpty[ib] = mNEmpty; } else { diff --git a/Detectors/ZDC/workflow/CMakeLists.txt b/Detectors/ZDC/workflow/CMakeLists.txt index c17403a1a7a54..7ee50c5a6bc24 100644 --- a/Detectors/ZDC/workflow/CMakeLists.txt +++ b/Detectors/ZDC/workflow/CMakeLists.txt @@ -11,8 +11,21 @@ o2_add_library(ZDCWorkflow SOURCES src/DigitReaderSpec.cxx src/EntropyEncoderSpec.cxx + src/ZDCDataReaderDPLSpec.cxx src/EntropyDecoderSpec.cxx + src/ZDCWorkflow.cxx + src/RawReaderZDC.cxx + src/ZDCDigitWriterDPLSpec.cxx PUBLIC_LINK_LIBRARIES O2::Framework + O2::DataFormatsZDC + O2::ZDCRaw O2::SimulationDataFormat + O2::DPLUtils O2::ZDCReconstruction O2::DataFormatsZDC) + +o2_add_executable(flp-dpl-workflow + COMPONENT_NAME zdc + SOURCES src/zdc-flp-workflow.cxx + PUBLIC_LINK_LIBRARIES O2::ZDCWorkflow + TARGETVARNAME zdcflpexe) diff --git a/Detectors/ZDC/workflow/include/ZDCWorkflow/RawReaderZDC.h b/Detectors/ZDC/workflow/include/ZDCWorkflow/RawReaderZDC.h new file mode 100644 index 0000000000000..b9b83dd13c941 --- /dev/null +++ b/Detectors/ZDC/workflow/include/ZDCWorkflow/RawReaderZDC.h @@ -0,0 +1,80 @@ +// 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. +// +//file RawReaderZDC.h class for RAW data reading + +#ifndef ALICEO2_FIT_RAWREADERZDC_H_ +#define ALICEO2_FIT_RAWREADERZDC_H_ +#include +#include +#include +#include "ZDCRaw/RawReaderZDCBase.h" +#include "DataFormatsZDC/RawEventData.h" +#include "DataFormatsZDC/ChannelData.h" +#include "DataFormatsZDC/BCData.h" +#include "DataFormatsZDC/PedestalData.h" + +#include "Framework/ProcessingContext.h" +#include "Framework/DataAllocator.h" +#include "Framework/OutputSpec.h" +#include "Framework/Lifetime.h" +#include + +namespace o2 +{ +namespace zdc +{ +class RawReaderZDC : public RawReaderZDCBase +{ + public: + RawReaderZDC(bool dumpData) : mDumpData(dumpData) {} + RawReaderZDC(const RawReaderZDC&) = default; + + RawReaderZDC() = default; + ~RawReaderZDC() = default; + + std::vector mDigitsBC; + std::vector mDigitsCh; + std::vector mPedestalData; + + void clear() + { + mDigitsBC.clear(); + mDigitsCh.clear(); + mPedestalData.clear(); + } + void accumulateDigits() + { + getDigits(mDigitsBC, mDigitsCh, mPedestalData); + LOG(INFO) << "Number of Digits: " << mDigitsBC.size(); + LOG(INFO) << "Number of ChannelData: " << mDigitsCh.size(); + LOG(INFO) << "Number of PedestalData: " << mPedestalData.size(); + if (mDumpData) { + //DigitBlockZDC::print(mVecDigits, mVecChannelData); + } + } + static void prepareOutputSpec(std::vector& outputSpec) + { + outputSpec.emplace_back("ZDC", "DIGITSBC", 0, o2::framework::Lifetime::Timeframe); + outputSpec.emplace_back("ZDC", "DIGITSCH", 0, o2::framework::Lifetime::Timeframe); + outputSpec.emplace_back("ZDC", "DIGITSPD", 0, o2::framework::Lifetime::Timeframe); + } + void makeSnapshot(o2::framework::ProcessingContext& pc) + { + pc.outputs().snapshot(o2::framework::Output{o2::header::gDataOriginZDC, "DIGITSBC", 0, o2::framework::Lifetime::Timeframe}, mDigitsBC); + pc.outputs().snapshot(o2::framework::Output{o2::header::gDataOriginZDC, "DIGITSCH", 0, o2::framework::Lifetime::Timeframe}, mDigitsCh); + pc.outputs().snapshot(o2::framework::Output{o2::header::gDataOriginZDC, "DIGITSCH", 0, o2::framework::Lifetime::Timeframe}, mPedestalData); + } + bool mDumpData; +}; +} // namespace zdc +} // namespace o2 + +#endif diff --git a/Detectors/ZDC/workflow/include/ZDCWorkflow/ZDCDataReaderDPLSpec.h b/Detectors/ZDC/workflow/include/ZDCWorkflow/ZDCDataReaderDPLSpec.h new file mode 100644 index 0000000000000..b9b66345bb61a --- /dev/null +++ b/Detectors/ZDC/workflow/include/ZDCWorkflow/ZDCDataReaderDPLSpec.h @@ -0,0 +1,103 @@ +// 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. + +/// @file ZDCDataReaderDPLSpec.h + +#ifndef O2_ZDCDATAREADERDPLSPEC_H +#define O2_ZDCDATAREADERDPLSPEC_H + +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CCDBTimeStampUtils.h" +#include "Framework/DataProcessorSpec.h" +#include "Framework/Task.h" +#include "Framework/CallbackService.h" +#include "Framework/ConfigParamRegistry.h" +#include "Framework/ControlService.h" +#include "Framework/Lifetime.h" +#include "Framework/Output.h" +#include "Framework/WorkflowSpec.h" +#include "Framework/SerializationMethods.h" +#include "DPLUtils/DPLRawParser.h" +#include "DPLUtils/MakeRootTreeWriterSpec.h" +#include "Framework/InputSpec.h" +#include "CommonUtils/ConfigurableParam.h" +#include "ZDCBase/Constants.h" +#include "ZDCBase/ModuleConfig.h" +# +#include +#include +#include +using namespace o2::framework; + +namespace o2 +{ +namespace zdc +{ +template +class ZDCDataReaderDPLSpec : public Task +{ + public: + ZDCDataReaderDPLSpec(const RawReader& rawReader) : mRawReader(rawReader) {} + ZDCDataReaderDPLSpec() = default; + ~ZDCDataReaderDPLSpec() override = default; + void init(InitContext& ic) final {} + void run(ProcessingContext& pc) final + { + DPLRawParser parser(pc.inputs()); + mRawReader.clear(); + long timeStamp = 0; + std::string ccdbHost = "http://ccdb-test.cern.ch:8080"; + auto& mgr = o2::ccdb::BasicCCDBManager::instance(); + mgr.setURL(ccdbHost); + if (timeStamp == mgr.getTimestamp()) { + return; + } + mgr.setTimestamp(timeStamp); + auto moduleConfig = mgr.get(o2::zdc::CCDBPathConfigModule); + if (!moduleConfig) { + LOG(FATAL) << "Cannot module configuratio for timestamp " << timeStamp; + return; + } + LOG(INFO) << "Loaded module configuration for timestamp " << timeStamp; + mRawReader.setModuleConfig(moduleConfig); + LOG(INFO) << "ZDCDataReaderDPLSpec"; + uint64_t count = 0; + for (auto it = parser.begin(), end = parser.end(); it != end; ++it) { + //Proccessing each page + count++; + auto rdhPtr = it.get_if(); + gsl::span payload(it.data(), it.size()); + mRawReader.process(rdhPtr->linkID, payload); + } + LOG(INFO) << "Pages: " << count; + mRawReader.accumulateDigits(); + mRawReader.makeSnapshot(pc); + } + RawReader mRawReader; +}; + +template +framework::DataProcessorSpec getZDCDataReaderDPLSpec(const RawReader& rawReader) +{ + LOG(INFO) << "DataProcessorSpec initDataProcSpec() for RawReaderZDC"; + std::vector outputSpec; + RawReader::prepareOutputSpec(outputSpec); + return DataProcessorSpec{ + "zdc-datareader-dpl", + o2::framework::select("TF:ZDC/RAWDATA"), + outputSpec, + adaptFromTask>(rawReader), + Options{}}; +} + +} // namespace zdc +} // namespace o2 + +#endif /* O2_ZDCDATAREADERDPL_H */ diff --git a/Detectors/ZDC/workflow/include/ZDCWorkflow/ZDCDigitWriterDPLSpec.h b/Detectors/ZDC/workflow/include/ZDCWorkflow/ZDCDigitWriterDPLSpec.h new file mode 100644 index 0000000000000..52613477ca486 --- /dev/null +++ b/Detectors/ZDC/workflow/include/ZDCWorkflow/ZDCDigitWriterDPLSpec.h @@ -0,0 +1,31 @@ +// 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. + +/// @file ZDCDigitWriterSpec.h + +#ifndef O2_ZDCDIGITWRITERDPL_H +#define O2_ZDCDIGITWRITERDPL_H + +#include "Framework/DataProcessorSpec.h" + +using namespace o2::framework; + +namespace o2 +{ +namespace zdc +{ + +/// create a processor spec +framework::DataProcessorSpec getZDCDigitWriterDPLSpec(); + +} // namespace zdc +} // namespace o2 + +#endif /* O2_ZDCDIGITWRITER_H */ diff --git a/Detectors/ZDC/workflow/include/ZDCWorkflow/ZDCWorkflow.h b/Detectors/ZDC/workflow/include/ZDCWorkflow/ZDCWorkflow.h new file mode 100644 index 0000000000000..5e317c06f51ed --- /dev/null +++ b/Detectors/ZDC/workflow/include/ZDCWorkflow/ZDCWorkflow.h @@ -0,0 +1,27 @@ +// 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. + +#ifndef O2_FIT_ZDCWORKFLOW_H +#define O2_FIT_ZDCWORKFLOW_H + +/// @file ZDCWorkflow.h + +#include "Framework/WorkflowSpec.h" + +namespace o2 +{ +namespace zdc +{ +framework::WorkflowSpec getZDCWorkflow(bool useProcess, + bool dumpProcessor, bool dumpReader, + bool disableRootOut); +} // namespace zdc +} // namespace o2 +#endif diff --git a/Detectors/ZDC/workflow/src/RawReaderZDC.cxx b/Detectors/ZDC/workflow/src/RawReaderZDC.cxx new file mode 100644 index 0000000000000..613c30e169037 --- /dev/null +++ b/Detectors/ZDC/workflow/src/RawReaderZDC.cxx @@ -0,0 +1,12 @@ +// 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 "ZDCWorkflow/RawReaderZDC.h" +using namespace o2::zdc; diff --git a/Detectors/ZDC/workflow/src/ZDCDataReaderDPLSpec.cxx b/Detectors/ZDC/workflow/src/ZDCDataReaderDPLSpec.cxx new file mode 100644 index 0000000000000..5ef3cf3928e19 --- /dev/null +++ b/Detectors/ZDC/workflow/src/ZDCDataReaderDPLSpec.cxx @@ -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. + +/// @file ZDCDataReaderDPLSpec.cxx + +#include "ZDCWorkflow/ZDCDataReaderDPLSpec.h" + +using namespace o2::framework; + +namespace o2 +{ +namespace zdc +{ + +} // namespace zdc +} // namespace o2 diff --git a/Detectors/ZDC/workflow/src/ZDCDigitWriterDPLSpec.cxx b/Detectors/ZDC/workflow/src/ZDCDigitWriterDPLSpec.cxx new file mode 100644 index 0000000000000..fa32519d5c742 --- /dev/null +++ b/Detectors/ZDC/workflow/src/ZDCDigitWriterDPLSpec.cxx @@ -0,0 +1,44 @@ +// 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. + +/// @file FT0DigitWriterSpec.cxx + +#include + +#include "DPLUtils/MakeRootTreeWriterSpec.h" +#include "DataFormatsZDC/ChannelData.h" +#include "DataFormatsZDC/BCData.h" +#include "DataFormatsZDC/PedestalData.h" + +#include "ZDCWorkflow/ZDCDigitWriterDPLSpec.h" +using namespace o2::framework; + +namespace o2 +{ +namespace zdc +{ + +template +using BranchDefinition = MakeRootTreeWriterSpec::BranchDefinition; +DataProcessorSpec getZDCDigitWriterDPLSpec() +{ + // // Spectators for logging + // auto logger = [](DigitType const& digits) { + // LOG(INFO) << "FT0DigitWriter pulled " << digits.size() << " digits"; + // }; + return MakeRootTreeWriterSpec( + "zdc-digit-writer", "o2digit_zdc.root", "o2sim", + BranchDefinition>{InputSpec{"digitBCinput", "ZDC", "DIGITSBC"}, "ZDCDigitBC"}, + BranchDefinition>{InputSpec{"digitChinput", "ZDC", "DIGITSCH"}, "ZDCDigitCh"}, + BranchDefinition>{InputSpec{"digitPDinput", "ZDC", "DIGITSPD"}, "ZDCDigitPed"})(); +} + +} // namespace zdc +} // namespace o2 diff --git a/Detectors/ZDC/workflow/src/ZDCWorkflow.cxx b/Detectors/ZDC/workflow/src/ZDCWorkflow.cxx new file mode 100644 index 0000000000000..4f410d0f8acdb --- /dev/null +++ b/Detectors/ZDC/workflow/src/ZDCWorkflow.cxx @@ -0,0 +1,40 @@ +// 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. + +/// @file ZDCWorkflow.cxx + +#include "ZDCWorkflow/ZDCWorkflow.h" +//#include "ZDCWorkflow/ZDCDataProcessDPLSpec.h" +#include "ZDCWorkflow/ZDCDataReaderDPLSpec.h" +#include "ZDCWorkflow/ZDCDigitWriterDPLSpec.h" +#include "ZDCWorkflow/RawReaderZDC.h" +namespace o2 +{ +namespace zdc +{ + +framework::WorkflowSpec getZDCWorkflow(bool useProcess, + bool dumpProcessor, bool dumpReader, + bool disableRootOut) +{ + LOG(INFO) << "framework::WorkflowSpec getZDCWorkflow"; + framework::WorkflowSpec specs; + specs.emplace_back(o2::zdc::getZDCDataReaderDPLSpec(RawReaderZDC{dumpReader})); + // if (useProcess) { + // specs.emplace_back(o2::zdc::getZDCDataProcessDPLSpec(dumpProcessor)); + // } + if (!disableRootOut) { + specs.emplace_back(o2::zdc::getZDCDigitWriterDPLSpec()); + } + return specs; +} + +} // namespace zdc +} // namespace o2 diff --git a/Detectors/ZDC/workflow/src/zdc-flp-workflow.cxx b/Detectors/ZDC/workflow/src/zdc-flp-workflow.cxx new file mode 100644 index 0000000000000..922e272ef675f --- /dev/null +++ b/Detectors/ZDC/workflow/src/zdc-flp-workflow.cxx @@ -0,0 +1,60 @@ +// 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 "CommonUtils/ConfigurableParam.h" +#include "ZDCWorkflow/ZDCWorkflow.h" + +using namespace o2::framework; + +// ------------------------------------------------------------------ + +// we need to add workflow options before including Framework/runDataProcessing +void customize(std::vector& workflowOptions) +{ + // option allowing to set parameters + + workflowOptions.push_back( + ConfigParamSpec{"use-process", + o2::framework::VariantType::Bool, + false, + {"enable processor for data taking/dumping"}}); + workflowOptions.push_back( + ConfigParamSpec{"dump-blocks-process", + o2::framework::VariantType::Bool, + false, + {"enable dumping of event blocks at processor side"}}); + workflowOptions.push_back( + ConfigParamSpec{"dump-blocks-reader", + o2::framework::VariantType::Bool, + false, + {"enable dumping of event blocks at reader side"}}); + workflowOptions.push_back( + ConfigParamSpec{"disable-root-output", + o2::framework::VariantType::Bool, + false, + {"disable root-files output writers"}}); +} + +// ------------------------------------------------------------------ + +#include "Framework/runDataProcessing.h" + +WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) +{ + LOG(INFO) << "WorkflowSpec defineDataProcessing"; + auto useProcessor = configcontext.options().get("use-process"); + auto dumpProcessor = configcontext.options().get("dump-blocks-process"); + auto dumpReader = configcontext.options().get("dump-blocks-reader"); + auto disableRootOut = + configcontext.options().get("disable-root-output"); + LOG(INFO) << "WorkflowSpec FLPWorkflow"; + return std::move(o2::zdc::getZDCWorkflow( + useProcessor, dumpProcessor, dumpReader, disableRootOut)); +} diff --git a/Steer/DigitizerWorkflow/src/ZDCDigitWriterSpec.h b/Steer/DigitizerWorkflow/src/ZDCDigitWriterSpec.h index eadcf31c2d920..7f96ba3701d08 100644 --- a/Steer/DigitizerWorkflow/src/ZDCDigitWriterSpec.h +++ b/Steer/DigitizerWorkflow/src/ZDCDigitWriterSpec.h @@ -38,7 +38,7 @@ o2::framework::DataProcessorSpec getZDCDigitWriterSpec(bool mctruth = true) 1, BranchDefinition>{InputSpec{"digitBCinput", "ZDC", "DIGITSBC"}, "ZDCDigitBC"}, BranchDefinition>{InputSpec{"digitChinput", "ZDC", "DIGITSCH"}, "ZDCDigitCh"}, - BranchDefinition>{InputSpec{"digitPDinput", "ZDC", "DIGITSPD"}, "ZDCDigitPed"}, + BranchDefinition>{InputSpec{"digitPDinput", "ZDC", "DIGITSPD"}, "ZDCDigitPed"}, BranchDefinition>{InputSpec{"labelinput", "ZDC", "DIGITSLBL"}, "ZDCDigitLabels", mctruth ? 1 : 0})(); }