4040#include < TPDGCode.h>
4141
4242#include < string>
43+ #include < gsl/span>
44+ #include < span>
4345#include < vector>
4446
4547using namespace o2 ;
@@ -65,11 +67,11 @@ static const std::vector<int> pdgCodes{kK0Short,
6567 kOmegaPlusBar };
6668
6769struct OnTheFlyDecayer {
68- Produces<aod::OTFMCParticles> tableMcParticles ;
70+ Produces<aod::McParticlesWithDau> tableMcParticlesWithDau ;
6971 o2::upgrade::Decayer decayer;
70- Service<o2::ccdb::BasicCCDBManager> ccdb;
7172 Service<o2::framework::O2DatabasePDG> pdgDB;
7273 HistogramRegistry histos{" histos" , {}, OutputObjHandlingPolicy::AnalysisObject};
74+ std::map<int64_t , std::vector<o2::upgrade::OTFParticle>> mDecayDaughters ;
7375
7476 Configurable<int > seed{" seed" , 0 , " Set seed for particle decayer" };
7577 Configurable<float > magneticField{" magneticField" , 20 ., " Magnetic field (kG)" };
@@ -78,15 +80,12 @@ struct OnTheFlyDecayer {
7880 " Enable option for particle to be decayed: 0 - no, 1 - yes" };
7981
8082
81- ConfigurableAxis axisRadius{" axisRadius" , {1000 , 0 , 100 }, " Radius" };
8283 ConfigurableAxis axisPt{" axisPt" , {VARIABLE_WIDTH, 0 .0f , 0 .1f , 0 .2f , 0 .3f , 0 .4f , 0 .5f , 0 .6f , 0 .7f , 0 .8f , 0 .9f , 1 .0f , 1 .1f , 1 .2f , 1 .3f , 1 .4f , 1 .5f , 1 .6f , 1 .7f , 1 .8f , 1 .9f , 2 .0f , 2 .2f , 2 .4f , 2 .6f , 2 .8f , 3 .0f , 3 .2f , 3 .4f , 3 .6f , 3 .8f , 4 .0f , 4 .4f , 4 .8f , 5 .2f , 5 .6f , 6 .0f , 6 .5f , 7 .0f , 7 .5f , 8 .0f , 9 .0f , 10 .0f , 11 .0f , 12 .0f , 13 .0f , 14 .0f , 15 .0f , 17 .0f , 19 .0f , 21 .0f , 23 .0f , 25 .0f , 30 .0f , 35 .0f , 40 .0f , 50 .0f }, " pt axis for QA histograms" };
8384
8485
8586 std::vector<int > mEnabledDecays ;
8687 void init (o2::framework::InitContext&)
8788 {
88- ccdb->setURL (" http://alice-ccdb.cern.ch" );
89- ccdb->setTimestamp (-1 );
9089 decayer.setSeed (seed);
9190 decayer.setBField (magneticField);
9291 for (int i = 0 ; i < kNumDecays ; ++i) {
@@ -95,13 +94,13 @@ struct OnTheFlyDecayer {
9594 }
9695 }
9796
98- histos.add (" K0S/hGenK0S" , " hGenK0S" , kTH2D , {axisRadius, axisPt});
99- histos.add (" Lambda/hGenLambda" , " hGenLambda" , kTH2D , {axisRadius, axisPt});
100- histos.add (" AntiLambda/hGenAntiLambda" , " hGenAntiLambda" , kTH2D , {axisRadius, axisPt});
101- histos.add (" Xi/hGenXi" , " hGenXi" , kTH2D , {axisRadius, axisPt});
102- histos.add (" AntiXi/hGenAntiXi" , " hGenAntiXi" , kTH2D , {axisRadius, axisPt});
103- histos.add (" Omega/hGenOmega" , " hGenOmega" , kTH2D , {axisRadius, axisPt});
104- histos.add (" AntiOmega/hGenAntiOmega" , " hGenAntiOmega" , kTH2D , {axisRadius, axisPt});
97+ histos.add (" K0S/hGenK0S" , " hGenK0S" , kTH1D , {axisPt});
98+ histos.add (" Lambda/hGenLambda" , " hGenLambda" , kTH1D , {axisPt});
99+ histos.add (" AntiLambda/hGenAntiLambda" , " hGenAntiLambda" , kTH1D , {axisPt});
100+ histos.add (" Xi/hGenXi" , " hGenXi" , kTH1D , {axisPt});
101+ histos.add (" AntiXi/hGenAntiXi" , " hGenAntiXi" , kTH1D , {axisPt});
102+ histos.add (" Omega/hGenOmega" , " hGenOmega" , kTH1D , {axisPt});
103+ histos.add (" AntiOmega/hGenAntiOmega" , " hGenAntiOmega" , kTH1D , {axisPt});
105104 }
106105
107106 bool canDecay (const int pdgCode)
@@ -111,56 +110,133 @@ struct OnTheFlyDecayer {
111110
112111 void process (aod::McCollision const &, aod::McParticles const & mcParticles)
113112 {
114- for (const auto & particle : mcParticles) {
115- if (!canDecay (particle.pdgCode ())) {
116- continue ;
117- }
118-
119- o2::track::TrackParCov o2track;
120- o2::upgrade::convertMCParticleToO2Track (particle, o2track, pdgDB);
121- std::vector<o2::upgrade::OTFParticle> decayDaughters = decayer.decayParticle (pdgDB, o2track, particle.pdgCode ());
122- for (const auto & dau : decayDaughters) {
123- o2::track::TrackParCov dauTrack;
124- o2::upgrade::convertOTFParticleToO2Track (dau, dauTrack, pdgDB);
125- if (canDecay (dau.pdgCode )) {
126- std::vector<o2::upgrade::OTFParticle> cascadingDaughers = decayer.decayParticle (pdgDB, dauTrack, dau.pdgCode );
127- for (const auto & daudau : cascadingDaughers) {
128- decayDaughters.push_back (daudau);
113+ mDecayDaughters .clear ();
114+ u_int64_t nStoredDaughters = 0 ;
115+ for (int64_t index{0 }; index < mcParticles.size (); ++index) {
116+ const auto & particle = mcParticles.iteratorAt (index);
117+ std::vector<o2::upgrade::OTFParticle> decayDaughters;
118+ static constexpr int kMaxNestedDecays = 10 ;
119+ int nDecays = 0 ;
120+ if (canDecay (particle.pdgCode ())) {
121+ o2::track::TrackParCov o2track;
122+ o2::upgrade::convertMCParticleToO2Track (particle, o2track, pdgDB);
123+ decayDaughters = decayer.decayParticle (pdgDB, o2track, particle.pdgCode ());
124+ for (size_t idau{0 }; idau < decayDaughters.size (); ++idau) {
125+ const auto & dau = decayDaughters[idau];
126+ o2::track::TrackParCov dauTrack;
127+ o2::upgrade::convertOTFParticleToO2Track (dau, dauTrack, pdgDB);
128+ if (canDecay (dau.pdgCode ())) {
129+ std::vector<o2::upgrade::OTFParticle> cascadingDaughers = decayer.decayParticle (pdgDB, dauTrack, dau.pdgCode ());
130+ for (const auto & daudau : cascadingDaughers) {
131+ decayDaughters.push_back (daudau);
132+ if (kMaxNestedDecays < ++nDecays) {
133+ LOG (error) << " Seemingly stuck trying to perpetually decay products from pdg: " << particle.pdgCode ();
134+ }
135+ }
129136 }
130137 }
131- }
132138
133- if (decayDaughters.empty ()) {
134- LOG (error) << " Attempted to decay " << particle.pdgCode () << " but resulting vector of daugthers were empty" ;
135- continue ;
139+ if (decayDaughters.empty ()) {
140+ LOG (error) << " Attempted to decay " << particle.pdgCode () << " but resulting vector of daugthers were empty" ;
141+ continue ;
142+ }
136143 }
137144
138145
139- const float decayRadius2D = std::hypot (decayDaughters[0 ].vx , decayDaughters[0 ].vy );
140- std::cout << particle.pdgCode () << " : " << decayRadius2D << std::endl;
141146 if (particle.pdgCode () == kK0Short ) {
142- histos.fill (HIST (" K0S/hGenK0S" ), decayRadius2D, particle.pt ());
147+ histos.fill (HIST (" K0S/hGenK0S" ), particle.pt ());
143148 } else if (particle.pdgCode () == kLambda0 ) {
144- histos.fill (HIST (" Lambda/hGenLambda" ), decayRadius2D, particle.pt ());
149+ histos.fill (HIST (" Lambda/hGenLambda" ), particle.pt ());
145150 } else if (particle.pdgCode () == kLambda0Bar ) {
146- histos.fill (HIST (" AntiLambda/hGenAntiLambda" ), decayRadius2D, particle.pt ());
151+ histos.fill (HIST (" AntiLambda/hGenAntiLambda" ), particle.pt ());
147152 } else if (particle.pdgCode () == kXiMinus ) {
148- histos.fill (HIST (" Xi/hGenXi" ), decayRadius2D, particle.pt ());
153+ histos.fill (HIST (" Xi/hGenXi" ), particle.pt ());
149154 } else if (particle.pdgCode () == kXiPlusBar ) {
150- histos.fill (HIST (" AntiXi/hGenAntiXi" ), decayRadius2D, particle.pt ());
155+ histos.fill (HIST (" AntiXi/hGenAntiXi" ), particle.pt ());
151156 } else if (particle.pdgCode () == kOmegaMinus ) {
152- histos.fill (HIST (" Omega/hGenOmega" ), decayRadius2D, particle.pt ());
157+ histos.fill (HIST (" Omega/hGenOmega" ), particle.pt ());
153158 } else if (particle.pdgCode () == kOmegaPlusBar ) {
154- histos.fill (HIST (" AntiOmega/hGenAntiOmega" ), decayRadius2D, particle.pt ());
159+ histos.fill (HIST (" AntiOmega/hGenAntiOmega" ), particle.pt ());
155160 }
156-
157- for (size_t i = 0 ; i < decayDaughters.size (); ++i) {
158- const o2::upgrade::OTFParticle& dau = decayDaughters[i];
159- const bool isAlive = !canDecay (dau.pdgCode );
160- tableMcParticles (particle.globalIndex (),
161- isAlive, dau.pdgCode ,
162- dau.vx , dau.vy , dau.vz ,
163- dau.px , dau.py , dau.pz );
161+
162+ int daughtersIdSlice[2 ];
163+ if (canDecay (particle.pdgCode ())) {
164+ daughtersIdSlice[0 ] = static_cast <int >(mcParticles.size () + nStoredDaughters);
165+ daughtersIdSlice[1 ] = static_cast <int >(mcParticles.size () + nStoredDaughters + decayDaughters.size ());
166+ } else {
167+ daughtersIdSlice[0 ] = static_cast <int >(particle.daughtersIds ()[0 ]);
168+ daughtersIdSlice[1 ] = static_cast <int >(particle.daughtersIds ()[1 ]);
169+ }
170+
171+ std::span<const int > motherSpan (particle.mothersIds ().data (), particle.mothersIds ().size ());
172+ mDecayDaughters .emplace (index, decayDaughters);
173+ nStoredDaughters += decayDaughters.size ();
174+
175+ float phi = o2::constants::math::PI + std::atan2 (-1 .0f * particle.py (), -1 .0f * particle.px ());
176+ float eta; // Conditional as https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1922
177+ float pt = std::sqrt (particle.px () * particle.px () + particle.py () * particle.py ());
178+ float p = std::sqrt (particle.px () * particle.px () + particle.py () * particle.py () + particle.pz () * particle.pz ());
179+ float y; // Conditional as https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1943
180+
181+ if ((p - particle.pz ()) < 1e-7f ) {
182+ eta = (particle.pz () < 0 .0f ) ? -100 .0f : 100 .0f ;
183+ } else {
184+ eta = 0 .5f * std::log ((p + particle.pz ()) / (p - particle.pz ()));
185+ }
186+
187+ if ((particle.e () - particle.pz ()) < 1e-7f ) {
188+ y = (particle.pz () < 0 .0f ) ? -100 .0f : 100 .0f ;
189+ } else {
190+ y = 0 .5f * std::log ((particle.e () + particle.pz ()) / (particle.e () - particle.pz ()));
191+ }
192+
193+ // TODO: Particle status code
194+ // TODO: Expression columns
195+ tableMcParticlesWithDau (particle.mcCollisionId (), particle.pdgCode (), particle.statusCode (),
196+ particle.flags (), motherSpan, daughtersIdSlice, particle.weight (),
197+ particle.px (), particle.py (), particle.pz (), particle.e (),
198+ particle.vx (), particle.vy (), particle.vz (), particle.vt (),
199+ phi, eta, pt, p, y);
200+ }
201+
202+ int daughtersIdSlice[2 ] = {-1 , -1 };
203+ for (const auto & [index, decayDaughters] : mDecayDaughters ) {
204+ for (const auto & dau : decayDaughters) {
205+ if (index >= mcParticles.size ()) {
206+ LOG (warn) << " --- Index " << index << " out of bounds for mcParticles table of size " << mcParticles.size ();
207+ continue ;
208+ }
209+
210+ auto mother = mcParticles.iteratorAt (index);
211+ std::vector<int > motherIds = { static_cast <int >(index) };
212+ std::span<const int > motherSpan (motherIds.data (), motherIds.size ());
213+
214+ float phi = o2::constants::math::PI + std::atan2 (-1 .0f * dau.py (), -1 .0f * dau.px ());
215+ float eta; // Conditional as https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1922
216+ float pt = std::sqrt (dau.px () * dau.px () + dau.py () * dau.py ());
217+ float p = std::sqrt (dau.px () * dau.px () + dau.py () * dau.py () + dau.pz () * dau.pz ());
218+ float y; // Conditional as https://github.com/AliceO2Group/AliceO2/blob/dev/Framework/Core/include/Framework/AnalysisDataModel.h#L1943
219+
220+ if ((p - dau.pz ()) < 1e-7f ) {
221+ eta = (dau.pz () < 0 .0f ) ? -100 .0f : 100 .0f ;
222+ } else {
223+ eta = 0 .5f * std::log ((p + dau.pz ()) / (p - dau.pz ()));
224+ }
225+
226+ if ((dau.e () - dau.pz ()) < 1e-7f ) {
227+ y = (dau.pz () < 0 .0f ) ? -100 .0f : 100 .0f ;
228+ } else {
229+ y = 0 .5f * std::log ((dau.e () + dau.pz ()) / (dau.e () - dau.pz ()));
230+ }
231+
232+
233+ // TODO: Particle status code
234+ // TODO: Expression columns
235+ tableMcParticlesWithDau (mother.mcCollisionId (), dau.pdgCode (), 1 ,
236+ mother.flags (), motherSpan, daughtersIdSlice, mother.weight (),
237+ dau.px (), dau.py (), dau.pz (), dau.e (),
238+ dau.vx (), dau.vy (), dau.vz (), mother.vt (),
239+ phi, eta, pt, p, y);
164240 }
165241 }
166242 }
@@ -170,4 +246,4 @@ struct OnTheFlyDecayer {
170246WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
171247{
172248 return WorkflowSpec{adaptAnalysisTask<OnTheFlyDecayer>(cfgc)};
173- }
249+ }
0 commit comments