@@ -29,25 +29,28 @@ namespace o2
2929namespace itsmft
3030{
3131
32- EntropyDecoderSpec::EntropyDecoderSpec (o2::header::DataOrigin orig, int verbosity, bool getDigits)
33- : mOrigin (orig), mCTFCoder (o2::ctf::CTFCoderBase::OpType::Decoder, orig == o2::header::gDataOriginITS ? o2::detectors::DetID::ITS : o2::detectors::DetID::MFT), mGetDigits (getDigits)
32+ template <int N>
33+ EntropyDecoderSpec<N>::EntropyDecoderSpec(int verbosity, bool getDigits)
34+ : mCTFCoder (o2::ctf::CTFCoderBase::OpType::Decoder, N), mGetDigits (getDigits)
3435{
3536 assert (orig == o2::header::gDataOriginITS || orig == o2::header::gDataOriginMFT );
36- mDetPrefix = orig == o2::header::gDataOriginITS ? " _ITS" : " _MFT" ;
37+ mDetPrefix = Origin == o2::header::gDataOriginITS ? " _ITS" : " _MFT" ;
3738 mTimer .Stop ();
3839 mTimer .Reset ();
3940 mCTFCoder .setVerbosity (verbosity);
4041 mCTFCoder .setDictBinding (std::string (" ctfdict" ) + mDetPrefix );
4142}
4243
43- void EntropyDecoderSpec::init (o2::framework::InitContext& ic)
44+ template <int N>
45+ void EntropyDecoderSpec<N>::init(o2::framework::InitContext& ic)
4446{
4547 mCTFCoder .init <CTF>(ic);
4648 mMaskNoise = ic.options ().get <bool >(" mask-noise" );
4749 mUseClusterDictionary = !ic.options ().get <bool >(" ignore-cluster-dictionary" );
4850}
4951
50- void EntropyDecoderSpec::run (ProcessingContext& pc)
52+ template <int N>
53+ void EntropyDecoderSpec<N>::run(ProcessingContext& pc)
5154{
5255 if (pc.services ().get <o2::framework::TimingInfo>().globalRunNumberChanged ) {
5356 mTimer .Reset ();
@@ -81,15 +84,28 @@ void EntropyDecoderSpec::run(ProcessingContext& pc)
8184 LOG (info) << " Decoded " << compcl.size () << " clusters in " << rofs.size () << " RO frames, (" << iosize.asString () << " ) in " << mTimer .CpuTime () - cput << " s" ;
8285 }
8386 pc.outputs ().snapshot ({" ctfrep" , 0 }, iosize);
87+
88+ // hack: output empty messages
89+ for (uint32_t iLayer{1 }; iLayer < NLayers; ++iLayer) {
90+ pc.outputs ().make <std::vector<o2::itsmft::ROFRecord>>(OutputRef{" ROframes" , iLayer});
91+ if (mGetDigits ) {
92+ pc.outputs ().make <std::vector<o2::itsmft::Digit>>(OutputRef{" Digits" , iLayer});
93+ } else {
94+ pc.outputs ().make <std::vector<o2::itsmft::CompClusterExt>>(OutputRef{" compClusters" , iLayer});
95+ pc.outputs ().make <std::vector<unsigned char >>(OutputRef{" patterns" , iLayer});
96+ }
97+ }
8498}
8599
86- void EntropyDecoderSpec::endOfStream (EndOfStreamContext& ec)
100+ template <int N>
101+ void EntropyDecoderSpec<N>::endOfStream(EndOfStreamContext& ec)
87102{
88103 LOGF (info, " %s Entropy Decoding total timing: Cpu: %.3e Real: %.3e s in %d slots" ,
89- mOrigin .as <std::string>(), mTimer .CpuTime (), mTimer .RealTime (), mTimer .Counter () - 1 );
104+ Origin .as <std::string>(), mTimer .CpuTime (), mTimer .RealTime (), mTimer .Counter () - 1 );
90105}
91106
92- void EntropyDecoderSpec::updateTimeDependentParams (ProcessingContext& pc)
107+ template <int N>
108+ void EntropyDecoderSpec<N>::updateTimeDependentParams(ProcessingContext& pc)
93109{
94110 if (pc.services ().get <o2::framework::TimingInfo>().globalRunNumberChanged ) { // this params need to be queried only once
95111 if (mMaskNoise ) {
@@ -102,15 +118,16 @@ void EntropyDecoderSpec::updateTimeDependentParams(ProcessingContext& pc)
102118 mCTFCoder .updateTimeDependentParams (pc, true );
103119}
104120
105- void EntropyDecoderSpec::finaliseCCDB (o2::framework::ConcreteDataMatcher& matcher, void * obj)
121+ template <int N>
122+ void EntropyDecoderSpec<N>::finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void * obj)
106123{
107- if (matcher == ConcreteDataMatcher (mOrigin , " NOISEMAP" , 0 )) {
124+ if (matcher == ConcreteDataMatcher (Origin , " NOISEMAP" , 0 )) {
108125 mNoiseMap = (o2::itsmft::NoiseMap*)obj;
109- LOG (info) << mOrigin .as <std::string>() << " noise map updated" ;
126+ LOG (info) << Origin .as <std::string>() << " noise map updated" ;
110127 return ;
111128 }
112- if (matcher == ConcreteDataMatcher (mOrigin , " CLUSDICT" , 0 )) {
113- LOG (info) << mOrigin .as <std::string>() << " cluster dictionary updated" << (!mUseClusterDictionary ? " but its using is disabled" : " " );
129+ if (matcher == ConcreteDataMatcher (Origin , " CLUSDICT" , 0 )) {
130+ LOG (info) << Origin .as <std::string>() << " cluster dictionary updated" << (!mUseClusterDictionary ? " but its using is disabled" : " " );
114131 mPattIdConverter .setDictionary ((const TopologyDictionary*)obj);
115132 return ;
116133 }
@@ -119,42 +136,52 @@ void EntropyDecoderSpec::finaliseCCDB(o2::framework::ConcreteDataMatcher& matche
119136 }
120137}
121138
122- DataProcessorSpec getEntropyDecoderSpec (o2::header::DataOrigin orig, int verbosity, bool getDigits, unsigned int sspec)
139+ template <int N>
140+ DataProcessorSpec getEntropyDecoderSpec (int verbosity, bool getDigits, unsigned int sspec)
123141{
142+ using EntropyDecoder = EntropyDecoderSpec<N>;
143+
144+ std::string det = EntropyDecoder::Origin.template as <std::string>();
145+ std::string nm = " _" + det;
146+ std::vector<InputSpec> inputs;
147+ inputs.emplace_back (std::string (" ctf" ) + nm, EntropyDecoder::Origin, " CTFDATA" , sspec, Lifetime::Timeframe);
148+ inputs.emplace_back (std::string (" noise" ) + nm, EntropyDecoder::Origin, " NOISEMAP" , 0 , Lifetime::Condition, ccdbParamSpec (fmt::format (" {}/Calib/NoiseMap" , det)));
149+ inputs.emplace_back (std::string (" cldict" ) + nm, EntropyDecoder::Origin, " CLUSDICT" , 0 , Lifetime::Condition, ccdbParamSpec (fmt::format (" {}/Calib/ClusterDictionary" , det)));
150+ inputs.emplace_back (std::string (" ctfdict" ) + nm, EntropyDecoder::Origin, " CTFDICT" , 0 , Lifetime::Condition, ccdbParamSpec (fmt::format (" {}/Calib/CTFDictionaryTree" , det)));
151+ inputs.emplace_back (std::string (" trigoffset" ), " CTP" , " Trig_Offset" , 0 , Lifetime::Condition, ccdbParamSpec (" CTP/Config/TriggerOffsets" ));
152+
124153 std::vector<OutputSpec> outputs;
125154 // this is a special dummy input which makes sense only in sync workflows
126155
127156 // this produces weird memory problems in unrelated devices, to be understood
128157 // outputs.emplace_back(OutputSpec{{"phystrig"}, orig, "PHYSTRIG", 0, Lifetime::Timeframe});
129158
130- if (getDigits) {
131- outputs.emplace_back (OutputSpec{{" Digits" }, orig, " DIGITS" , 0 , Lifetime::Timeframe});
132- outputs.emplace_back (OutputSpec{{" ROframes" }, orig, " DIGITSROF" , 0 , Lifetime::Timeframe});
133- } else {
134- outputs.emplace_back (OutputSpec{{" compClusters" }, orig, " COMPCLUSTERS" , 0 , Lifetime::Timeframe});
135- outputs.emplace_back (OutputSpec{{" ROframes" }, orig, " CLUSTERSROF" , 0 , Lifetime::Timeframe});
136- outputs.emplace_back (OutputSpec{{" patterns" }, orig, " PATTERNS" , 0 , Lifetime::Timeframe});
159+ for (uint32_t iLayer{0 }; iLayer < EntropyDecoder::NLayers; ++iLayer) {
160+ if (getDigits) {
161+ outputs.emplace_back (OutputSpec{{" Digits" }, EntropyDecoder::Origin, " DIGITS" , iLayer, Lifetime::Timeframe});
162+ outputs.emplace_back (OutputSpec{{" ROframes" }, EntropyDecoder::Origin, " DIGITSROF" , iLayer, Lifetime::Timeframe});
163+ } else {
164+ outputs.emplace_back (OutputSpec{{" compClusters" }, EntropyDecoder::Origin, " COMPCLUSTERS" , iLayer, Lifetime::Timeframe});
165+ outputs.emplace_back (OutputSpec{{" ROframes" }, EntropyDecoder::Origin, " CLUSTERSROF" , iLayer, Lifetime::Timeframe});
166+ outputs.emplace_back (OutputSpec{{" patterns" }, EntropyDecoder::Origin, " PATTERNS" , iLayer, Lifetime::Timeframe});
167+ }
137168 }
138- outputs.emplace_back (OutputSpec{{" ctfrep" }, orig, " CTFDECREP" , 0 , Lifetime::Timeframe});
139- std::string nm = orig == o2::header::gDataOriginITS ? " _ITS" : " _MFT" ;
140- std::vector<InputSpec> inputs;
141- inputs.emplace_back (std::string (" ctf" ) + nm, orig, " CTFDATA" , sspec, Lifetime::Timeframe);
142- inputs.emplace_back (std::string (" noise" ) + nm, orig, " NOISEMAP" , 0 , Lifetime::Condition, ccdbParamSpec (fmt::format (" {}/Calib/NoiseMap" , orig.as <std::string>())));
143- inputs.emplace_back (std::string (" cldict" ) + nm, orig, " CLUSDICT" , 0 , Lifetime::Condition, ccdbParamSpec (fmt::format (" {}/Calib/ClusterDictionary" , orig.as <std::string>())));
144- inputs.emplace_back (std::string (" ctfdict" ) + nm, orig, " CTFDICT" , 0 , Lifetime::Condition, ccdbParamSpec (fmt::format (" {}/Calib/CTFDictionaryTree" , orig.as <std::string>())));
145- inputs.emplace_back (std::string (" trigoffset" ), " CTP" , " Trig_Offset" , 0 , Lifetime::Condition, ccdbParamSpec (" CTP/Config/TriggerOffsets" ));
169+ outputs.emplace_back (OutputSpec{{" ctfrep" }, EntropyDecoder::Origin, " CTFDECREP" , 0 , Lifetime::Timeframe});
146170
147171 return DataProcessorSpec{
148- EntropyDecoderSpec::getName (orig) ,
149- inputs,
150- outputs,
151- AlgorithmSpec{adaptFromTask<EntropyDecoderSpec>(orig, verbosity, getDigits)},
152- Options{
172+ . name = EntropyDecoder::DeviceName ,
173+ . inputs = inputs,
174+ . outputs = outputs,
175+ . algorithm = AlgorithmSpec{adaptFromTask<EntropyDecoder>( verbosity, getDigits)},
176+ . options = Options{
153177 {" ctf-dict" , VariantType::String, " ccdb" , {" CTF dictionary: empty or ccdb=CCDB, none=no external dictionary otherwise: local filename" }},
154178 {" mask-noise" , VariantType::Bool, false , {" apply noise mask to digits or clusters (involves reclusterization)" }},
155179 {" ignore-cluster-dictionary" , VariantType::Bool, false , {" do not use cluster dictionary, always store explicit patterns" }},
156- {" ans -version" , VariantType::String, {" version of ans entropy coder implementation to use" }}}};
180+ {" and -version" , VariantType::String, {" version of and entropy coder implementation to use" }}}};
157181}
158182
183+ framework::DataProcessorSpec getITSEntropyDecoderSpec (int verbosity, bool getDigits, unsigned int sspec) { return getEntropyDecoderSpec<o2::detectors::DetID::ITS>(verbosity, getDigits, sspec); }
184+ framework::DataProcessorSpec getMFTEntropyDecoderSpec (int verbosity, bool getDigits, unsigned int sspec) { return getEntropyDecoderSpec<o2::detectors::DetID::MFT>(verbosity, getDigits, sspec); }
185+
159186} // namespace itsmft
160187} // namespace o2
0 commit comments