1111
1212// / \file femtoDreamProducerTask.cxx
1313// / \brief Tasks that produces the track tables used for the pairing
14- // / \author Andi Mathis , TU München, andreas.mathis@ph. tum.de
14+ // / \author Laura Serksnyte , TU München, laura.serksnyte@ tum.de
1515
1616#include " FemtoDreamCollisionSelection.h"
1717#include " FemtoDreamTrackSelection.h"
@@ -46,12 +46,18 @@ namespace o2::aod
4646using FemtoFullCollision = soa::Join<aod::Collisions,
4747 aod::EvSels,
4848 aod::Mults>::iterator;
49+ using FemtoFullCollisionMC = soa::Join<aod::Collisions,
50+ aod::EvSels,
51+ aod::Mults,
52+ aod::McCollisionLabels>::iterator;
53+
4954using FemtoFullTracks = soa::Join<aod::FullTracks,
5055 aod::TracksDCA, aod::TOFSignal,
5156 aod::pidTPCEl, aod::pidTPCMu, aod::pidTPCPi,
5257 aod::pidTPCKa, aod::pidTPCPr, aod::pidTPCDe,
5358 aod::pidTOFEl, aod::pidTOFMu, aod::pidTOFPi,
5459 aod::pidTOFKa, aod::pidTOFPr, aod::pidTOFDe>;
60+
5561// using FilteredFullV0s = soa::Filtered<aod::V0Datas>; /// predefined Join table for o2::aod::V0s = soa::Join<o2::aod::TransientV0s, o2::aod::StoredV0s> to be used when we add v0Filter
5662} // namespace o2::aod
5763
@@ -77,7 +83,9 @@ struct femtoDreamProducerTask {
7783
7884 Produces<aod::FemtoDreamCollisions> outputCollision;
7985 Produces<aod::FemtoDreamParticles> outputParts;
86+ Produces<aod::FemtoDreamParticlesMC> outputPartsMC;
8087 Produces<aod::FemtoDreamDebugParticles> outputDebugParts;
88+ Produces<aod::FemtoDreamDebugParticlesMC> outputDebugPartsMC;
8189
8290 Configurable<bool > ConfDebugOutput{" ConfDebugOutput" , true , " Debug output" };
8391
@@ -159,6 +167,13 @@ struct femtoDreamProducerTask {
159167
160168 void init (InitContext&)
161169 {
170+ if (doprocessData == false && doprocessMC == false ) {
171+ LOGF (fatal, " Neither processData nor processMC enabled. Please choose one." );
172+ }
173+ if (doprocessData == true && doprocessMC == true ) {
174+ LOGF (fatal, " Cannot enable processData and processMC at the same time. Please choose one." );
175+ }
176+
162177 colCuts.setCuts (ConfEvtZvtx, ConfEvtTriggerCheck, ConfEvtTriggerSel, ConfEvtOfflineCheck, ConfIsRun3);
163178 colCuts.init (&qaRegistry);
164179
@@ -223,9 +238,13 @@ struct femtoDreamProducerTask {
223238 }
224239
225240 // / Function to retrieve the nominal mgnetic field in kG (0.1T) and convert it directly to T
226- float getMagneticFieldTesla (uint64_t timestamp )
241+ void getMagneticFieldTesla (aod::BCsWithTimestamps::iterator bc )
227242 {
228243 // TODO done only once (and not per run). Will be replaced by CCDBConfigurable
244+ // get magnetic field for run
245+ if (mRunNumber == bc.runNumber ())
246+ return ;
247+ auto timestamp = bc.timestamp ();
229248 float output = -999 ;
230249
231250 if (ConfIsRun3 && !ConfIsMC) {
@@ -234,7 +253,7 @@ struct femtoDreamProducerTask {
234253 grpo = ccdb->getForTimeStamp <o2::parameters::GRPMagField>(" GLO/Config/GRPMagField" , timestamp);
235254 if (grpo == nullptr ) {
236255 LOGF (fatal, " GRP object not found for timestamp %llu" , timestamp);
237- return 0 ;
256+ return ;
238257 }
239258 LOGF (info, " Retrieved GRP for timestamp %llu with L3 " , timestamp, grpo->getL3Current ());
240259 }
@@ -249,24 +268,79 @@ struct femtoDreamProducerTask {
249268 grpo = ccdb->getForTimeStamp <o2::parameters::GRPObject>(" GLO/GRP/GRP" , timestamp);
250269 if (grpo == nullptr ) {
251270 LOGF (fatal, " GRP object not found for timestamp %llu" , timestamp);
252- return 0 ;
271+ return ;
253272 }
254273 LOGF (info, " Retrieved GRP for timestamp %llu with magnetic field of %d kG" , timestamp, grpo->getNominalL3Field ());
255274 }
256275 output = 0.1 * (grpo->getNominalL3Field ());
257276 }
258- return output;
277+ mMagField = output;
278+ mRunNumber = bc.runNumber ();
259279 }
260280
261- void process (aod::FemtoFullCollision const & col, aod::BCsWithTimestamps const &, aod::FemtoFullTracks const & tracks,
262- o2::aod::V0Datas const & fullV0s) // / \todo with FilteredFullV0s
281+ template < bool isTrackOrV0, typename ParticleType>
282+ void fillDebugParticle (ParticleType const & particle)
263283 {
264- // get magnetic field for run
265- auto bc = col.bc_as <aod::BCsWithTimestamps>();
266- if (mRunNumber != bc.runNumber ()) {
267- mMagField = getMagneticFieldTesla (bc.timestamp ());
268- mRunNumber = bc.runNumber ();
284+ if constexpr (isTrackOrV0) {
285+ outputDebugParts (particle.sign (),
286+ (uint8_t )particle.tpcNClsFound (),
287+ particle.tpcNClsFindable (),
288+ (uint8_t )particle.tpcNClsCrossedRows (),
289+ particle.tpcNClsShared (),
290+ particle.tpcInnerParam (),
291+ particle.itsNCls (),
292+ particle.itsNClsInnerBarrel (),
293+ particle.dcaXY (),
294+ particle.dcaZ (),
295+ particle.tpcSignal (),
296+ particle.tpcNSigmaStoreEl (),
297+ particle.tpcNSigmaStorePi (),
298+ particle.tpcNSigmaStoreKa (),
299+ particle.tpcNSigmaStorePr (),
300+ particle.tpcNSigmaStoreDe (),
301+ particle.tofNSigmaStoreEl (),
302+ particle.tofNSigmaStorePi (),
303+ particle.tofNSigmaStoreKa (),
304+ particle.tofNSigmaStorePr (),
305+ particle.tofNSigmaStoreDe (),
306+ -999 ., -999 ., -999 ., -999 ., -999 ., -999 .);
269307 }
308+ if constexpr (!isTrackOrV0) {
309+ outputDebugParts (-999 ., -999 ., -999 ., -999 ., -999 ., -999 ., -999 .,
310+ -999 ., -999 ., -999 ., -999 ., -999 ., -999 ., -999 .,
311+ -999 ., -999 ., -999 ., -999 ., -999 ., -999 ., -999 .,
312+ particle.dcaV0daughters (),
313+ particle.v0radius (),
314+ particle.x (),
315+ particle.y (),
316+ particle.z (),
317+ particle.mK0Short ()); // QA for v0
318+ }
319+ }
320+ template <typename ParticleType>
321+ void fillMCParticle (ParticleType const & particle)
322+ {
323+ if (particle.has_mcParticle ()) {
324+ // get corresponding MC particle and its info
325+ auto particleMC = particle.mcParticle ();
326+ auto pdgCode = particleMC.pdgCode ();
327+ bool isPrimary = particleMC.isPhysicalPrimary ();
328+ if (isPrimary) {
329+ outputPartsMC (outputParts.lastIndex (), aod::femtodreamparticleMC::ParticleOriginMCTruth::kPrimary , pdgCode);
330+ } else {
331+ outputPartsMC (outputParts.lastIndex (), aod::femtodreamparticleMC::ParticleOriginMCTruth::kNotPrimary , pdgCode);
332+ }
333+ // fill with correct values, this is currently placeholder
334+ outputDebugPartsMC (-999 );
335+ } else {
336+ outputPartsMC (-999 , -999 , -999 );
337+ outputDebugPartsMC (-999 );
338+ }
339+ }
340+
341+ template <bool isMC, typename V0Type, typename TrackType, typename CollisionType>
342+ void fillCollisionsAndTracksAndV0 (CollisionType const & col, TrackType const & tracks, V0Type const & fullV0s)
343+ {
270344
271345 // / First thing to do is to check whether the basic event selection criteria are fulfilled
272346 // If the basic selection is NOT fullfilled:
@@ -315,40 +389,18 @@ struct femtoDreamProducerTask {
315389 childIDs, 0 , 0 );
316390 tmpIDtrack.push_back (track.globalIndex ());
317391 if (ConfDebugOutput) {
318- outputDebugParts (track.sign (),
319- (uint8_t )track.tpcNClsFound (),
320- track.tpcNClsFindable (),
321- (uint8_t )track.tpcNClsCrossedRows (),
322- track.tpcNClsShared (),
323- track.tpcInnerParam (),
324- track.itsNCls (),
325- track.itsNClsInnerBarrel (),
326- track.dcaXY (),
327- track.dcaZ (),
328- track.tpcSignal (),
329- track.tpcNSigmaStoreEl (),
330- track.tpcNSigmaStorePi (),
331- track.tpcNSigmaStoreKa (),
332- track.tpcNSigmaStorePr (),
333- track.tpcNSigmaStoreDe (),
334- track.tofNSigmaStoreEl (),
335- track.tofNSigmaStorePi (),
336- track.tofNSigmaStoreKa (),
337- track.tofNSigmaStorePr (),
338- track.tofNSigmaStoreDe (),
339- -999 .,
340- -999 .,
341- -999 .,
342- -999 .,
343- -999 .,
344- -999 .);
392+ fillDebugParticle<true >(track);
393+ }
394+
395+ if constexpr (isMC) {
396+ fillMCParticle (track);
345397 }
346398 }
347399
348400 if (ConfStoreV0) {
349401 for (auto & v0 : fullV0s) {
350- auto postrack = v0.posTrack_as <aod::FemtoFullTracks >();
351- auto negtrack = v0.negTrack_as <aod::FemtoFullTracks >(); // /\tocheck funnily enough if we apply the filter the sign of Pos and Neg track is always negative
402+ auto postrack = v0.template posTrack_as <TrackType >();
403+ auto negtrack = v0.template negTrack_as <TrackType >(); // /\tocheck funnily enough if we apply the filter the sign of Pos and Neg track is always negative
352404 // const auto dcaXYpos = postrack.dcaXY();
353405 // const auto dcaZpos = postrack.dcaZ();
354406 // const auto dcapos = std::sqrt(pow(dcaXYpos, 2.) + pow(dcaZpos, 2.));
@@ -375,102 +427,59 @@ struct femtoDreamProducerTask {
375427 childIDs[1 ] = 0 ;
376428 outputParts (outputCollision.lastIndex (), v0.positivept (), v0.positiveeta (), v0.positivephi (), aod::femtodreamparticle::ParticleType::kV0Child , cutContainerV0.at (femtoDreamV0Selection::V0ContainerPosition::kPosCuts ), cutContainerV0.at (femtoDreamV0Selection::V0ContainerPosition::kPosPID ), 0 ., childIDs, 0 , 0 );
377429 const int rowOfPosTrack = outputParts.lastIndex ();
430+ if constexpr (isMC) {
431+ fillMCParticle (postrack);
432+ }
378433 int negtrackID = v0.negTrackId ();
379434 int rowInPrimaryTrackTableNeg = -1 ;
380435 rowInPrimaryTrackTableNeg = getRowDaughters (negtrackID, tmpIDtrack);
381436 childIDs[0 ] = 0 ;
382437 childIDs[1 ] = rowInPrimaryTrackTableNeg;
383438 outputParts (outputCollision.lastIndex (), v0.negativept (), v0.negativeeta (), v0.negativephi (), aod::femtodreamparticle::ParticleType::kV0Child , cutContainerV0.at (femtoDreamV0Selection::V0ContainerPosition::kNegCuts ), cutContainerV0.at (femtoDreamV0Selection::V0ContainerPosition::kNegPID ), 0 ., childIDs, 0 , 0 );
384439 const int rowOfNegTrack = outputParts.lastIndex ();
440+ if constexpr (isMC) {
441+ fillMCParticle (negtrack);
442+ }
385443 int indexChildID[2 ] = {rowOfPosTrack, rowOfNegTrack};
386444 outputParts (outputCollision.lastIndex (), v0.pt (), v0.eta (), v0.phi (), aod::femtodreamparticle::ParticleType::kV0 , cutContainerV0.at (femtoDreamV0Selection::V0ContainerPosition::kV0 ), 0 , v0.v0cosPA (col.posX (), col.posY (), col.posZ ()), indexChildID, v0.mLambda (), v0.mAntiLambda ());
387445 if (ConfDebugOutput) {
388- outputDebugParts (postrack.sign (),
389- (uint8_t )postrack.tpcNClsFound (),
390- postrack.tpcNClsFindable (),
391- (uint8_t )postrack.tpcNClsCrossedRows (),
392- postrack.tpcNClsShared (),
393- postrack.tpcInnerParam (),
394- postrack.itsNCls (),
395- postrack.itsNClsInnerBarrel (),
396- postrack.dcaXY (),
397- postrack.dcaZ (),
398- postrack.tpcSignal (),
399- postrack.tpcNSigmaStoreEl (),
400- postrack.tpcNSigmaStorePi (),
401- postrack.tpcNSigmaStoreKa (),
402- postrack.tpcNSigmaStorePr (),
403- postrack.tpcNSigmaStoreDe (),
404- postrack.tofNSigmaStoreEl (),
405- postrack.tofNSigmaStorePi (),
406- postrack.tofNSigmaStoreKa (),
407- postrack.tofNSigmaStorePr (),
408- postrack.tofNSigmaStoreDe (),
409- -999 .,
410- -999 .,
411- -999 .,
412- -999 .,
413- -999 .,
414- -999 .); // QA for positive daughter
415- outputDebugParts (negtrack.sign (),
416- (uint8_t )negtrack.tpcNClsFound (),
417- negtrack.tpcNClsFindable (),
418- (uint8_t )negtrack.tpcNClsCrossedRows (),
419- negtrack.tpcNClsShared (),
420- negtrack.tpcInnerParam (),
421- negtrack.itsNCls (),
422- negtrack.itsNClsInnerBarrel (),
423- negtrack.dcaXY (),
424- negtrack.dcaZ (),
425- negtrack.tpcSignal (),
426- negtrack.tpcNSigmaStoreEl (),
427- negtrack.tpcNSigmaStorePi (),
428- negtrack.tpcNSigmaStoreKa (),
429- negtrack.tpcNSigmaStorePr (),
430- negtrack.tpcNSigmaStoreDe (),
431- negtrack.tofNSigmaStoreEl (),
432- negtrack.tofNSigmaStorePi (),
433- negtrack.tofNSigmaStoreKa (),
434- negtrack.tofNSigmaStorePr (),
435- negtrack.tofNSigmaStoreDe (),
436- -999 .,
437- -999 .,
438- -999 .,
439- -999 .,
440- -999 .,
441- -999 .); // QA for negative daughter
442- outputDebugParts (-999 .,
443- -999 .,
444- -999 .,
445- -999 .,
446- -999 .,
447- -999 .,
448- -999 .,
449- -999 .,
450- -999 .,
451- -999 .,
452- -999 .,
453- -999 .,
454- -999 .,
455- -999 .,
456- -999 .,
457- -999 .,
458- -999 .,
459- -999 .,
460- -999 .,
461- -999 .,
462- -999 .,
463- v0.dcaV0daughters (),
464- v0.v0radius (),
465- v0.x (),
466- v0.y (),
467- v0.z (),
468- v0.mK0Short ()); // QA for V0
446+ fillDebugParticle<true >(postrack); // QA for positive daughter
447+ fillDebugParticle<true >(postrack); // QA for negative daughter
448+ fillDebugParticle<false >(v0); // QA for v0
449+ }
450+ if constexpr (isMC) {
451+ // write code to fill lambdas!
452+ // fill for lambda
453+ outputPartsMC (-999 , -999 , -999 );
454+ outputDebugPartsMC (-999 );
469455 }
470456 }
471457 }
472458 }
473459 }
460+
461+ void processData (aod::FemtoFullCollision const & col, aod::BCsWithTimestamps const &, aod::FemtoFullTracks const & tracks,
462+ o2::aod::V0Datas const & fullV0s) // / \todo with FilteredFullV0s
463+ {
464+ // get magnetic field for run
465+ getMagneticFieldTesla (col.bc_as <aod::BCsWithTimestamps>());
466+ // fill the tables
467+ fillCollisionsAndTracksAndV0<false >(col, tracks, fullV0s);
468+ }
469+ PROCESS_SWITCH (femtoDreamProducerTask, processData, " Provide experimental data" , true );
470+
471+ void processMC (aod::FemtoFullCollisionMC const & col,
472+ aod::BCsWithTimestamps const &,
473+ soa::Join<aod::FemtoFullTracks, aod::McTrackLabels> const & tracks,
474+ aod::McCollisions const & mcCollisions, aod::McParticles const & mcParticles,
475+ o2::aod::V0Datas const & fullV0s) // / \todo with FilteredFullV0s
476+ {
477+ // get magnetic field for run
478+ getMagneticFieldTesla (col.bc_as <aod::BCsWithTimestamps>());
479+ // fill the tables
480+ fillCollisionsAndTracksAndV0<true >(col, tracks, fullV0s);
481+ }
482+ PROCESS_SWITCH (femtoDreamProducerTask, processMC, " Provide MC data" , false );
474483};
475484
476485WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
0 commit comments