@@ -40,33 +40,53 @@ using MCLabelContainer = o2::dataformats::MCTruthContainer<o2::MCCompLabel>;
4040// / create a processor spec
4141// / convert incoming TPC clusters to HW clusters
4242// / Note: This processor does not touch the MC, see below
43- DataProcessorSpec getClusterConverterSpec (bool sendMC)
43+ DataProcessorSpec getClusterConverterSpec (bool sendMC, int fanNumber )
4444{
45- auto initFunction = [sendMC](InitContext& ic) {
45+ std::string processorName = " tpc-cluster-converter" ;
46+ o2::header::DataHeader::SubSpecificationType fanSpec = 0 ;
47+ if (fanNumber < 0 ) {
48+ // only one instance
49+ fanNumber = 0 ;
50+ } else {
51+ // multiple instances, add number to name
52+ processorName += std::to_string (fanNumber);
53+ fanSpec = fanNumber;
54+ }
55+
56+ auto initFunction = [sendMC, fanSpec](InitContext& ic) {
4657 // there is nothing to init at the moment
4758 auto verbosity = 0 ;
4859
49- auto processingFct = [verbosity, sendMC](ProcessingContext& pc) {
50- // this will return a span of TPC clusters
51- auto inClusters = pc.inputs ().get <std::vector<o2::TPC ::Cluster>>(" clusterin" );
52-
60+ auto processingFct = [verbosity, sendMC, fanSpec](ProcessingContext& pc) {
5361 // init the stacks for forwarding the sector header
5462 // FIXME check if there is functionality in the DPL to forward the stack
5563 // FIXME make one function
5664 o2::header::Stack rawHeaderStack;
5765 o2::header::Stack mcHeaderStack;
66+ o2::TPC ::TPCSectorHeader const * sectorHeaderMC = nullptr ;
5867 if (sendMC) {
59- auto const * sectorHeader = DataRefUtils::getHeader<o2::TPC ::TPCSectorHeader*>(pc.inputs ().get (" mclblin" ));
60- if (sectorHeader ) {
61- o2::header::Stack actual{ *sectorHeader };
68+ sectorHeaderMC = DataRefUtils::getHeader<o2::TPC ::TPCSectorHeader*>(pc.inputs ().get (" mclblin" ));
69+ if (sectorHeaderMC ) {
70+ o2::header::Stack actual{ *sectorHeaderMC };
6271 std::swap (mcHeaderStack, actual);
72+ if (sectorHeaderMC->sector < 0 ) {
73+ pc.outputs ().snapshot (OutputRef{ " mclblout" , fanSpec, std::move (mcHeaderStack) }, fanSpec);
74+ }
6375 }
6476 }
6577 auto const * sectorHeader = DataRefUtils::getHeader<o2::TPC ::TPCSectorHeader*>(pc.inputs ().get (" clusterin" ));
6678 if (sectorHeader) {
6779 o2::header::Stack actual{ *sectorHeader };
6880 std::swap (rawHeaderStack, actual);
81+ if (sectorHeader->sector < 0 ) {
82+ pc.outputs ().snapshot (OutputRef{ " clusterout" , fanSpec, std::move (rawHeaderStack) }, fanSpec);
83+ return ;
84+ }
6985 }
86+ assert (sectorHeaderMC == nullptr || sectorHeader->sector == sectorHeaderMC->sector );
87+
88+ // this will return a span of TPC clusters
89+ auto inClusters = pc.inputs ().get <std::vector<o2::TPC ::Cluster>>(" clusterin" );
7090 int nClusters = inClusters.size ();
7191 LOG (INFO ) << " got clusters from input: " << nClusters;
7292
@@ -118,7 +138,7 @@ DataProcessorSpec getClusterConverterSpec(bool sendMC)
118138 if (verbosity > 0 ) {
119139 LOG (INFO ) << " allocating " << nTotalPages << " output page(s), " << nTotalPages * sizeof (ClusterHardwareContainer8kb);
120140 }
121- auto outputPages = pc.outputs ().make <ClusterHardwareContainer8kb>(OutputRef{ " clusterout" , 0 , std::move (rawHeaderStack) }, nTotalPages);
141+ auto outputPages = pc.outputs ().make <ClusterHardwareContainer8kb>(OutputRef{ " clusterout" , fanSpec , std::move (rawHeaderStack) }, nTotalPages);
122142
123143 auto outputPageIterator = outputPages.begin ();
124144 unsigned mcoutIndex = 0 ;
@@ -166,7 +186,7 @@ DataProcessorSpec getClusterConverterSpec(bool sendMC)
166186 if (verbosity > 0 ) {
167187 LOG (INFO ) << " writing MC labels for " << mcoutIndex << " cluster(s), index size " << mcout.getIndexedSize ();
168188 }
169- pc.outputs ().snapshot (OutputRef{ " mclblout" , 0 , std::move (mcHeaderStack) }, mcout);
189+ pc.outputs ().snapshot (OutputRef{ " mclblout" , fanSpec , std::move (mcHeaderStack) }, mcout);
170190 }
171191 };
172192
@@ -182,32 +202,32 @@ DataProcessorSpec getClusterConverterSpec(bool sendMC)
182202 // as we do not expect any further sorting of clusters during the conversion, we do not
183203 // need to define the MC data at all, it is just routed directly to the final consumer.
184204 // Whether or not to have MC data is thus a feature of the initial producer.
185- auto createInputSpecs = [](bool makeMcInput) {
205+ auto createInputSpecs = [fanSpec ](bool makeMcInput) {
186206 std::vector<InputSpec> inputSpecs{
187- InputSpec{ { " clusterin" }, gDataOriginTPC , " CLUSTERSIM" , 0 , Lifetime::Timeframe },
207+ InputSpec{ { " clusterin" }, gDataOriginTPC , " CLUSTERSIM" , fanSpec , Lifetime::Timeframe },
188208 };
189209 if (makeMcInput) {
190210 // FIXME: define common data type specifiers
191211 constexpr o2::header::DataDescription datadesc (" CLUSTERMCLBL" );
192- inputSpecs.emplace_back (InputSpec{ " mclblin" , gDataOriginTPC , datadesc, 0 , Lifetime::Timeframe });
212+ inputSpecs.emplace_back (InputSpec{ " mclblin" , gDataOriginTPC , datadesc, fanSpec , Lifetime::Timeframe });
193213 }
194214 return std::move (inputSpecs);
195215 };
196216
197- auto createOutputSpecs = [](bool makeMcOutput) {
217+ auto createOutputSpecs = [fanSpec ](bool makeMcOutput) {
198218 std::vector<OutputSpec> outputSpecs{
199- OutputSpec{ { " clusterout" }, gDataOriginTPC , " CLUSTERHW" , 0 , Lifetime::Timeframe },
219+ OutputSpec{ { " clusterout" }, gDataOriginTPC , " CLUSTERHW" , fanSpec , Lifetime::Timeframe },
200220 };
201221 if (makeMcOutput) {
202222 OutputLabel label{ " mclblout" };
203223 // FIXME: define common data type specifiers
204224 constexpr o2::header::DataDescription datadesc (" CLUSTERHWMCLBL" );
205- outputSpecs.emplace_back (label, gDataOriginTPC , datadesc, 0 , Lifetime::Timeframe);
225+ outputSpecs.emplace_back (label, gDataOriginTPC , datadesc, fanSpec , Lifetime::Timeframe);
206226 }
207227 return std::move (outputSpecs);
208228 };
209229
210- return DataProcessorSpec{ " converter " ,
230+ return DataProcessorSpec{ processorName ,
211231 { createInputSpecs (sendMC) },
212232 { createOutputSpecs (sendMC) },
213233 AlgorithmSpec (initFunction) };
0 commit comments