Skip to content

Commit d0544ae

Browse files
cholmccalcaliva
authored andcommitted
cherry-picked commits
1 parent fb0c728 commit d0544ae

14 files changed

+1534
-584
lines changed

Detectors/AOD/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ o2_add_executable(
4141
workflow
4242
COMPONENT_NAME aod-producer
4343
TARGETVARNAME targetName
44-
SOURCES src/aod-producer-workflow.cxx src/AODProducerWorkflowSpec.cxx
44+
SOURCES src/aod-producer-workflow.cxx src/AODProducerWorkflowSpec.cxx src/AODMcProducerHelpers.cxx
4545
PUBLIC_LINK_LIBRARIES internal::AODProducerWorkflow O2::Version
4646
)
4747

4848
o2_add_executable(
4949
workflow
5050
COMPONENT_NAME aod-mc-producer
51-
SOURCES src/aod-mc-producer-workflow.cxx src/AODMcProducerWorkflowSpec.cxx
51+
SOURCES src/aod-mc-producer-workflow.cxx src/AODMcProducerWorkflowSpec.cxx src/AODMcProducerHelpers.cxx
5252
PUBLIC_LINK_LIBRARIES internal::AODProducerWorkflow O2::Version
5353
)
5454

Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
// Copyright 2023-2099 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// @file AODMcProducerHelpers.h
13+
/// @author Christian Holm Christensen <cholm@nbi.dk>
14+
/// common helpers for AOD MC producers
15+
16+
#ifndef O2_AODMCPRODUCER_HELPERS
17+
#define O2_AODMCPRODUCER_HELPERS
18+
#include <SimulationDataFormat/MCEventHeader.h>
19+
#include <SimulationDataFormat/MCTrack.h>
20+
#include <Framework/AnalysisDataModel.h>
21+
#include <Framework/FunctionalHelpers.h>
22+
#include <Framework/TableBuilder.h>
23+
#include <string>
24+
#include <vector>
25+
#include <unordered_map>
26+
27+
/**
28+
* Utilities to transform simulated data into AO2D tables.
29+
*
30+
* The function templates below are templated on the cursor type over
31+
* the relevant AOD tables. Such a table can be obtained from the
32+
* ProcessingContext @c pc
33+
*
34+
* @code
35+
* auto builder = pc.make<TableBulder>(OutputForTable<Table>::ref());
36+
* auto cursor = builder->cursor<Table>();
37+
* @endcode
38+
*
39+
* If the task uses the @c Produces<Table> template,
40+
*
41+
* @code
42+
* Produces<Table> mTable;
43+
* @endcode
44+
*
45+
* then a cursor is obtained via,
46+
*
47+
* @code
48+
* auto cursor = mTable.cursor;
49+
* @endcode
50+
*
51+
* Note that these functions cannot be moved into a compilation unit,
52+
* because that would require deducing the table cursor type, by
53+
* f.ex.
54+
*
55+
* @code
56+
* template <typename Table>
57+
* struct TableCursor {
58+
* using cursor_t = decltype(std::declval<framework::TableBuilder>()
59+
* .cursor<Table>());
60+
* };
61+
* using CollisionCursor = TableCursor<aod::McCollisions>:cursor_t;
62+
* @endcode
63+
*
64+
* but since cursors are really Lambdas and Lambda types are specific
65+
* to the compilation unit, then the implementation file (compilation
66+
* unit) of these functions definitions and their use (another
67+
* compilation unit) would have different types of the the cursers,
68+
* and thus not be able to link. More information is given at
69+
* https://stackoverflow.com/questions/50033797.
70+
*/
71+
namespace o2::aodmchelpers
72+
{
73+
//==================================================================
74+
/**
75+
* Deduce cursor type and wrap in std::function
76+
*/
77+
template <typename Table>
78+
struct TableCursor {
79+
using type = decltype(framework::FFL(std::declval<framework::TableBuilder>()
80+
.cursor<Table>()));
81+
};
82+
//==================================================================
83+
/** Cursor over aod::McCollisions */
84+
using CollisionCursor = TableCursor<aod::McCollisions>::type;
85+
/** Cursor over aod::McParticles */
86+
using ParticleCursor = TableCursor<aod::StoredMcParticles_001>::type;
87+
/** Cursor over aod::HepMCXSections */
88+
using XSectionCursor = TableCursor<aod::HepMCXSections>::type;
89+
/** Cursor over aod::HepMCPdfInfos */
90+
using PdfInfoCursor = TableCursor<aod::HepMCPdfInfos>::type;
91+
/** Cursor over aod::HepMCHeavyIons */
92+
using HeavyIonCursor = TableCursor<aod::HepMCHeavyIons>::type;
93+
//==================================================================
94+
/** Types of updates on HepMC tables. */
95+
enum HepMCUpdate {
96+
never,
97+
always,
98+
anyKey,
99+
allKeys
100+
};
101+
102+
//==================================================================
103+
/**
104+
* Check if header has keys. If the argument @a anyNotAll is true,
105+
* then this member function returns true if @e any of the keys
106+
* were found. If @a anyNotAll is false, then return true only if
107+
* @a all keys were found.
108+
*
109+
* @param header MC event header
110+
* @param keys Keys to look for
111+
* @param anyNotAll If true, return true if @e any key was found.
112+
* If false, return true only if @a all keys were found
113+
*
114+
* @return true if any or all keys were found
115+
*/
116+
bool hasKeys(o2::dataformats::MCEventHeader const& header,
117+
const std::vector<std::string>& keys,
118+
bool anyNotall = true);
119+
//--------------------------------------------------------------------
120+
/**
121+
* Get a property from the header, or if not set or not valid, a
122+
* default value.
123+
*
124+
* @param header The MC event header
125+
* @param key Key to look for
126+
* @param def Value to return if key is not found
127+
*
128+
* @return Value of key or def if key is not found
129+
*/
130+
template <typename T>
131+
const T getEventInfo(o2::dataformats::MCEventHeader const& header,
132+
std::string const& key,
133+
T const& def)
134+
{
135+
if (not header.hasInfo(key))
136+
return def;
137+
138+
bool isValid = false;
139+
const T& val = header.getInfo<T>(key, isValid);
140+
if (not isValid)
141+
return def;
142+
143+
return val;
144+
}
145+
//====================================================================
146+
/**
147+
* Fill in collision information. This is read from the passed MC
148+
* header and stored in the MCCollision table. The member function
149+
* returns the encoded generator ID.
150+
*
151+
* @param cursor Cursor over o2::aod::McCollisions table
152+
* @param bcId Bunch-crossing Identifier
153+
* @param time Time of collisions
154+
* @param header Event header from generator
155+
* @param generatorId Default generator
156+
* @param sourceId Identifier of source
157+
*
158+
* @return encoded generator ID
159+
*/
160+
short updateMCCollisions(const CollisionCursor& cursor,
161+
int bcId,
162+
float time,
163+
o2::dataformats::MCEventHeader const& header,
164+
short generatorId = 0,
165+
int sourceId = 0,
166+
unsigned int mask = 0xFFFFFFF0);
167+
//--------------------------------------------------------------------
168+
/**
169+
* Fill in HepMC cross-section table from event generator header.
170+
*
171+
* @param cursor Cursor over o2::aod::HepMCXSections table
172+
* @param collisionID Identifier of collision (as given updateMCCollision)
173+
* @param generatorID Encoded generator ID
174+
* @param header Event header from generator
175+
* @param anyNotAll If true, then any key present trigger and update.
176+
* If false, then all keys must be present to update
177+
* the table.
178+
*
179+
* @return true if table was updated
180+
*/
181+
bool updateHepMCXSection(const XSectionCursor& cursor,
182+
int collisionID,
183+
short generatorID,
184+
o2::dataformats::MCEventHeader const& header,
185+
HepMCUpdate when = HepMCUpdate::anyKey);
186+
//--------------------------------------------------------------------
187+
/**
188+
* Fill in HepMC parton distribution function table from event
189+
* generator header
190+
*
191+
* @param cursor Cursor over o2::aod::HepMCXSections table
192+
* @param collisionID Identifier of collision (as given updateMCCollision)
193+
* @param generatorID Encoded generator ID
194+
* @param header Event header from generator
195+
* @param anyNotAll If true, then any key present trigger and update.
196+
* If false, then all keys must be present to update
197+
* the table.
198+
*
199+
* @return true if table was updated
200+
*/
201+
bool updateHepMCPdfInfo(const PdfInfoCursor& cursor,
202+
int collisionID,
203+
short generatorID,
204+
o2::dataformats::MCEventHeader const& header,
205+
HepMCUpdate when = HepMCUpdate::anyKey);
206+
//--------------------------------------------------------------------
207+
/**
208+
* Fill in HepMC heavy-ion table from generator event header.
209+
*
210+
* @param cursor Cursor over o2::aod::HepMCXSections table
211+
* @param collisionID Identifier of collision (as given updateMCCollision)
212+
* @param generatorID Encoded generator ID
213+
* @param header Event header from generator
214+
* @param anyNotAll If true, then any key present trigger and update.
215+
* If false, then all keys must be present to update
216+
* the table.
217+
*
218+
* @return true if table was updated
219+
*/
220+
bool updateHepMCHeavyIon(const HeavyIonCursor& cursor,
221+
int collisionID,
222+
short generatorID,
223+
o2::dataformats::MCEventHeader const& header,
224+
HepMCUpdate when = HepMCUpdate::anyKey);
225+
//--------------------------------------------------------------------
226+
/**
227+
* Type of mapping from track number to row index
228+
*/
229+
using TrackToIndex = std::unordered_map<int, int>;
230+
//--------------------------------------------------------------------
231+
/**
232+
* Update aod::McParticles table with information from an MC track.
233+
*
234+
* @param cursor Cursor over aod::McParticles table
235+
* @param mapping Maps track number to index in table
236+
* @param collisionID Collision identifier
237+
* @param track Track to update table with
238+
* @param tracks List of all tracks of current collision
239+
* @param flags Base flags of this track
240+
* @param weightMask Mask on weight floating point value
241+
* @param momentumMask Mask on momentum floating point values
242+
* @param positionMask Mask on position floating point values
243+
*/
244+
void updateParticle(const ParticleCursor& cursor,
245+
const TrackToIndex& toStore,
246+
int collisionID,
247+
o2::MCTrack const& track,
248+
std::vector<MCTrack> const& tracks,
249+
uint8_t flags = 0,
250+
uint32_t weightMask = 0xFFFFFFF0,
251+
uint32_t momentumMask = 0xFFFFFFF0,
252+
uint32_t positionMask = 0xFFFFFFF0);
253+
//--------------------------------------------------------------------
254+
/**
255+
* Update aod::McParticles table with tracks from MC.
256+
*
257+
* To add particles from many events, one will do
258+
*
259+
* @code
260+
* TrackToIndex preselect = findMcTracksToStore(...);
261+
*
262+
* size_t offset = 0;
263+
* for (auto event : events)
264+
* offset = updateParticles(cursor,
265+
* event.getCollisionID(),
266+
* event.getTracks(),
267+
* offset,
268+
* filter,
269+
* event.isBackground(),
270+
* preselect);
271+
* @endcode
272+
*
273+
* Here @a preselect must be a map from track number to a positive
274+
* value. Tracks that are mapped as such in @a preselect are stored
275+
* in addition to other tracks selected by the function. Note that @a
276+
* preselect may be empty.
277+
*
278+
* If @a filter is false, then @a all tracks will be stored.
279+
*
280+
* If @a filter is true, then tracks that are
281+
*
282+
* - generated by the generator,
283+
* - physical primaries
284+
* (MCTrackNavigator::isPhysicalPrimary),
285+
* - to be kept for physics
286+
* (MCTrackNavigator::isKeepPhysics), or
287+
* - is listed with a positive value in @a preselect, or
288+
* - either a mother or daughter of one such track, then
289+
*
290+
* that track is kept
291+
*
292+
* On return, the @a preselect will map from track number (index in
293+
* the @a tracks container) to the table row index (including offset
294+
* from previous events in the same time-frame).
295+
*
296+
* @param cursor Cursor over aod::McParticles
297+
* @param int Collision identifier
298+
* @param tracks List of all tracks of current collision
299+
* @param offset Index just beyond last table entry
300+
* @param filter Filter tracks
301+
* @param background True of from background event
302+
* @param preselect Mapping of preselected tracks
303+
* @param weightMask Mask on weight floating point value
304+
* @param momentumMask Mask on momentum floating point values
305+
* @param positionMask Mask on position floating point values
306+
*
307+
* @return Index beyond the last particle added to table
308+
*/
309+
uint32_t updateParticles(const ParticleCursor& cursor,
310+
int collisionID,
311+
std::vector<MCTrack> const& tracks,
312+
TrackToIndex& preselect,
313+
uint32_t offset = 0,
314+
bool filter = false,
315+
bool background = false,
316+
uint32_t weightMask = 0xFFFFFFF0,
317+
uint32_t momentumMask = 0xFFFFFFF0,
318+
uint32_t positionMask = 0xFFFFFFF0);
319+
} // namespace o2::aodmchelpers
320+
321+
#endif /* O2_AODMCPRODUCER_HELPERS */
322+
// Local Variables:
323+
// mode: C++
324+
// End:

0 commit comments

Comments
 (0)