2525#include " Common/CCDB/EventSelectionParams.h"
2626#include " EventFiltering/Zorro.h"
2727
28+ #include " DataFormatsParameters/GRPMagField.h"
2829#include " Framework/AnalysisHelpers.h"
2930#include " Framework/Configurable.h"
3031
3132#include " fairlogger/Logger.h"
3233
34+ #include < algorithm>
3335#include < cmath>
3436#include < string>
3537#include < unordered_map>
38+ #include < vector>
3639
3740namespace o2 ::analysis::femto
3841{
@@ -73,13 +76,14 @@ struct ConfCollisionBits : o2::framework::ConfigurableGroup {
7376 o2::framework::Configurable<std::vector<float >> occupancyMax{" occupancyMax" , {}, " Maximum occpancy" };
7477 o2::framework::Configurable<std::vector<float >> sphericityMin{" sphericityMin" , {}, " Minimum sphericity" };
7578 o2::framework::Configurable<std::vector<float >> sphericityMax{" sphericityMax" , {}, " Maximum sphericity" };
79+ o2::framework::Configurable<std::vector<std::string>> triggers{" triggers" , {}, " List of all triggers to be used" };
7680};
7781
78- struct ConfCollisionTriggers : o2::framework::ConfigurableGroup {
79- std::string prefix = std::string(" CollisionTriggers " );
80- o2::framework::Configurable<bool > useTrigger{ " useTrigger " , false , " Set to true to only selected triggered collisions " };
81- o2::framework::Configurable<std::string> ccdbPath{ " ccdbPath " , std::string ( " EventFiltering/Zorro/ " ) , " CCDB path for trigger information " };
82- o2::framework::Configurable<std::string> triggers{ " triggers " , std::string ( " fPPP,fPPL " ) , " Comma seperated list of all triggers to be used " };
82+ struct ConfCcdb : o2::framework::ConfigurableGroup {
83+ std::string prefix = std::string(" ConfCcdb " );
84+ o2::framework::Configurable<std::string> ccdbUrl{ " ccdbUrl " , " http://alice-ccdb.cern.ch " , " URL to ccdb " };
85+ o2::framework::Configurable<std::string> grpPath{ " grpPath " , " GLO/Config/GRPMagField " , " Path to GRP object (Run3 -> GLO/Config/GRPMagField/Run2 -> GLO/GRP/GRP " };
86+ o2::framework::Configurable<std::string> triggerPath{ " triggerPath " , " EventFiltering/Zorro/ " , " CCDB path for trigger information " };
8387};
8488
8589struct ConfCollisionRctFlags : o2::framework::ConfigurableGroup {
@@ -125,6 +129,8 @@ enum CollisionSels {
125129 kSphericityMin , // /< Min. sphericity
126130 kSphericityMax , // /< Max. sphericity
127131
132+ kTriggers ,
133+
128134 kCollisionSelsMax
129135};
130136
@@ -146,14 +152,16 @@ const std::unordered_map<CollisionSels, std::string> colSelsToString = {
146152 {kOccupancyMin , " Minimum Occupancy" },
147153 {kOccupancyMax , " Maximum Occupancy" },
148154 {kSphericityMin , " Minimum Sphericity" },
149- {kSphericityMax , " Maximum Sphericity" }
155+ {kSphericityMax , " Maximum Sphericity" },
156+
157+ {kTriggers , " Triggers" }
150158
151159};
152160
153161class CollisionSelection : public BaseSelection <float , o2::aod::femtodatatypes::CollisionMaskType, kCollisionSelsMax >
154162{
155163 public:
156- CollisionSelection () {}
164+ CollisionSelection () = default ;
157165 virtual ~CollisionSelection () = default ;
158166
159167 template <typename T1, typename T2>
@@ -188,6 +196,10 @@ class CollisionSelection : public BaseSelection<float, o2::aod::femtodatatypes::
188196 this ->addSelection (config.occupancyMax .value , kOccupancyMax , limits::kUpperLimit , true , true );
189197 this ->addSelection (config.sphericityMin .value , kSphericityMin , limits::kLowerLimit , true , true );
190198 this ->addSelection (config.sphericityMax .value , kSphericityMax , limits::kUpperLimit , true , true );
199+
200+ std::vector<float > triggerValues (config.triggers .value .size (), 1 .f );
201+ this ->addSelection (triggerValues, kTriggers , limits::kEqualArray , false , true );
202+ this ->addComments (kTriggers , config.triggers .value );
191203 };
192204
193205 void setMagneticField (int MagField)
@@ -255,13 +267,12 @@ class CollisionSelection : public BaseSelection<float, o2::aod::femtodatatypes::
255267 }
256268
257269 template <typename T>
258- void applySelections (T const & col)
270+ void applySelections (T const & col, std::vector< bool > const & triggerDecisions )
259271 {
260272 this ->reset ();
261273
262- // casting bool to float gurantees
263- // false -> 0
264- // true -> 1
274+ // casting bool to float gurantees false -> 0 and true -> 1
275+ // and we check for equality to 1, so evaluation succeeds if the selection bit is true
265276 this ->evaluateObservable (kSel8 , static_cast <float >(col.sel8 ()));
266277 this ->evaluateObservable (kNoSameBunchPileUp , static_cast <float >(col.selection_bit (o2::aod::evsel::kNoSameBunchPileup )));
267278 this ->evaluateObservable (kIsVertexItsTpc , static_cast <float >(col.selection_bit (o2::aod::evsel::kIsVertexITSTPC )));
@@ -280,6 +291,13 @@ class CollisionSelection : public BaseSelection<float, o2::aod::femtodatatypes::
280291 this ->evaluateObservable (kSphericityMin , mSphericity );
281292 this ->evaluateObservable (kSphericityMax , mSphericity );
282293
294+ // for the trigger we need to pass an vector of 0 (false) and 1 (true) for all configured trigger selections
295+ if (!triggerDecisions.empty ()) {
296+ std::vector<float > trigger (triggerDecisions.size ());
297+ std::transform (triggerDecisions.begin (), triggerDecisions.end (), trigger.begin (), [](bool b) { return b ? 1 .0f : 0 .0f ; });
298+ this ->evaluateObservable (kTriggers , trigger);
299+ }
300+
283301 this ->assembleBitmask ();
284302 };
285303
@@ -330,18 +348,24 @@ class CollisionBuilder
330348 virtual ~CollisionBuilder () = default ;
331349
332350 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
333- void init (T1& confFilter, T2& confBits, T3& confRct, T4& confTrigger , T5& confTable, T6& initContext)
351+ void init (T1& confFilter, T2& confBits, T3& confRct, T4& confCcdb , T5& confTable, T6& initContext)
334352 {
335353 mCollisionSelection .configure (confFilter, confBits);
336- if (confTrigger. useTrigger .value ) {
354+ if (!confBits. triggers .value . empty () ) {
337355 mUseTrigger = true ;
338- mTriggerNames = confTrigger.triggers .value ;
339- mZorro .setBaseCCDBPath (confTrigger.ccdbPath .value );
356+ for (size_t i = 0 ; i < confBits.triggers .value .size (); ++i) {
357+ mTriggerNames += confBits.triggers .value [i];
358+ if (i != confBits.triggers .value .size () - 1 ) {
359+ mTriggerNames += " ," ;
360+ }
361+ }
362+ mZorro .setBaseCCDBPath (confCcdb.triggerPath .value );
340363 }
341364 if (confRct.useRctFlags .value ) {
342365 mUseRctFlags = true ;
343366 mRctFlagsChecker .init (confRct.label .value , confRct.useZdc .value , confRct.treatLimitedAcceptanceAsBad .value );
344367 }
368+ mGrpPath = confCcdb.grpPath .value ;
345369
346370 LOG (info) << " Initialize femto collision builder..." ;
347371 mProducedCollisions = utils::enableTable (" FCols_001" , confTable.produceCollisions .value , initContext);
@@ -360,31 +384,45 @@ class CollisionBuilder
360384 LOG (info) << " Initialization done..." ;
361385 }
362386
363- template <modes::System system, typename T1, typename T2, typename T3, typename T4>
364- void buildCollision (T1& bc, T2& col, T3& tracks, T4& ccdb, int magField )
387+ template <modes::System system, typename T1, typename T2, typename T3, typename T4, typename T5 >
388+ void initCollision (T1& bc, T2& col, T3& tracks, T4& ccdb, T5& histRegistry )
365389 {
366- if (mUseTrigger ) {
367- mZorro .initCCDB (ccdb.service , bc.runNumber (), bc.timestamp (), mTriggerNames );
390+ if (mRunNumber != bc.runNumber ()) {
391+ mRunNumber = bc.runNumber ();
392+ static o2::parameters::GRPMagField* grpo = nullptr ;
393+ grpo = ccdb->template getForRun <o2::parameters::GRPMagField>(mGrpPath , mRunNumber );
394+ if (grpo == nullptr ) {
395+ LOG (fatal) << " GRP object not found for Run " << mRunNumber ;
396+ }
397+ mMagField = static_cast <int >(grpo->getNominalL3Field ()); // get magnetic field in kG
398+
399+ if (mUseTrigger ) {
400+ mZorro .initCCDB (ccdb.service , mRunNumber , bc.timestamp (), mTriggerNames );
401+ mZorro .populateHistRegistry (histRegistry, mRunNumber );
402+ }
368403 }
369- mCollisionSelection .setMagneticField (magField);
404+
405+ mCollisionSelection .setMagneticField (mMagField );
370406 mCollisionSelection .setSphericity (tracks);
371407 mCollisionSelection .setMultiplicity <system>(col);
372408 mCollisionSelection .setCentrality <system>(col);
373- mCollisionSelection .applySelections (col);
409+
410+ std::vector<bool > triggerDecisions = {};
411+ if (mUseTrigger ) {
412+ triggerDecisions = mZorro .getTriggerOfInterestResults (bc.globalBC ());
413+ }
414+
415+ mCollisionSelection .applySelections (col, triggerDecisions);
374416 }
375417
376- template <typename T1, typename T2 >
377- bool checkCollision (T1 const & bc, T2 const & col)
418+ template <typename T1>
419+ bool checkCollision (T1 const & col)
378420 {
379- // First: if triggers are enabled, the object must be selected
380- if (mUseTrigger && !mZorro .isSelected (bc.globalBC ())) {
381- return false ;
382- }
383- // Then: if RCT flags are enabled, check them
421+ // check RCT flags first
384422 if (mUseRctFlags && !mRctFlagsChecker (col)) {
385423 return false ;
386424 }
387- // Finally: do the expensive checks
425+ // make other checks
388426 return mCollisionSelection .checkFilters (col) &&
389427 mCollisionSelection .passesAllRequiredSelections ();
390428 }
@@ -438,6 +476,9 @@ class CollisionBuilder
438476 CollisionSelection mCollisionSelection ;
439477 Zorro mZorro ;
440478 bool mUseTrigger = false ;
479+ int mRunNumber = -1 ;
480+ std::string mGrpPath = std::string(" " );
481+ int mMagField = 0 ;
441482 aod::rctsel::RCTFlagsChecker mRctFlagsChecker ;
442483 bool mUseRctFlags = false ;
443484 std::string mTriggerNames = std::string(" " );
0 commit comments