3131#include " Common/Core/RecoDecay.h"
3232#include " DetectorsVertexing/DCAFitterN.h"
3333#include " PWGDQ/DataModel/ReducedInfoTables.h"
34+ #include " DetectorsBase/Propagator.h"
35+ #include " DetectorsBase/GeometryManager.h"
36+ #include " DataFormatsParameters/GRPObject.h"
37+ #include < CCDB/BasicCCDBManager.h>
3438
3539#include < Math/Vector4D.h>
3640#include < array>
@@ -230,7 +234,7 @@ struct v0selector {
230234 };
231235
232236 // Configurables
233- Configurable<double > d_bz {" d_bz" , -5.0 , " bz field" };
237+ Configurable<double > d_bz_input {" d_bz" , -999 , " bz field, -999 is automatic " };
234238 Configurable<double > v0cospa{" v0cospa" , 0.998 , " V0 CosPA" }; // double -> N.B. dcos(x)/dx = 0 at x=0)
235239 Configurable<float > dcav0dau{" dcav0dau" , 0.3 , " DCA V0 Daughters" };
236240 Configurable<float > v0Rmin{" v0Rmin" , 0.0 , " v0Rmin" };
@@ -239,27 +243,66 @@ struct v0selector {
239243 Configurable<float > dcamax{" dcamax" , 1e+10 , " dcamax" };
240244 Configurable<int > mincrossedrows{" mincrossedrows" , 70 , " min crossed rows" };
241245 Configurable<float > maxchi2tpc{" maxchi2tpc" , 4.0 , " max chi2/NclsTPC" };
246+ int mRunNumber ;
247+ float d_bz;
248+ Service<o2::ccdb::BasicCCDBManager> ccdb;
242249
243- // aod::Collision gives you tracks matched with collision.
244- // aod::Collisions gives you all tracks.
245- // void process(aod::Collisions const& collision, FullTracksExt const& tracks, aod::V0s const& V0s)
246- // void process(FullTracksExt const& tracks, aod::Collisions const& collision, aod::V0s const& V0s)
247- // void process(FullTracksExt const& tracks, aod::Collisions const&, aod::V0s const& V0s)
248- void process (aod::Collisions const &, FullTracksExt const & tracks, aod::V0s const & V0s, aod::Cascades const & Cascades)
249- // void process(FullTracksExt const& tracks, soa::Join<aod::Collisions, aod::EvSels>::iterator const& collision, aod::V0s const& V0s)
250+ void init (InitContext& context)
250251 {
251- registry.fill (HIST (" hEventCounter" ), 0.5 );
252+ // using namespace analysis::lambdakzerobuilder;
253+ mRunNumber = 0 ;
254+ d_bz = 0 ;
255+
256+ ccdb->setURL (" http://alice-ccdb.cern.ch" );
257+ ccdb->setCaching (true );
258+ ccdb->setLocalObjectValidityChecking ();
259+
260+ auto lut = o2::base::MatLayerCylSet::rectifyPtrFromFile (ccdb->get <o2::base::MatLayerCylSet>(" GLO/Param/MatLUT" ));
261+
262+ if (!o2::base::GeometryManager::isGeometryLoaded ()) {
263+ ccdb->get <TGeoManager>(" GLO/Config/GeometryAligned" );
264+ /* it seems this is needed at this level for the material LUT to work properly */
265+ /* but what happens if the run changes while doing the processing? */
266+ constexpr long run3grp_timestamp = (1619781650000 + 1619781529000 ) / 2 ;
267+
268+ o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp <o2::parameters::GRPObject>(" GLO/GRP/GRP" , run3grp_timestamp);
269+ o2::base::Propagator::initFieldFromGRP (grpo);
270+ o2::base::Propagator::Instance ()->setMatLUT (lut);
271+ }
272+ }
273+
274+ float getMagneticField (uint64_t timestamp)
275+ {
276+ // TODO done only once (and not per run). Will be replaced by CCDBConfigurable
277+ static o2::parameters::GRPObject* grpo = nullptr ;
278+ if (grpo == nullptr ) {
279+ grpo = ccdb->getForTimeStamp <o2::parameters::GRPObject>(" GLO/GRP/GRP" , timestamp);
280+ if (grpo == nullptr ) {
281+ LOGF (fatal, " GRP object not found for timestamp %llu" , timestamp);
282+ return 0 ;
283+ }
284+ LOGF (info, " Retrieved GRP for timestamp %llu with magnetic field of %d kG" , timestamp, grpo->getNominalL3Field ());
285+ }
286+ float output = grpo->getNominalL3Field ();
287+ return output;
288+ }
289+
290+ void CheckAndUpdate (Int_t lRunNumber, uint64_t lTimeStamp)
291+ {
292+ if (lRunNumber != mRunNumber ) {
293+ if (d_bz_input < -990 ) {
294+ // Fetch magnetic field from ccdb for current collision
295+ d_bz = getMagneticField (lTimeStamp);
296+ } else {
297+ d_bz = d_bz_input;
298+ }
299+ mRunNumber = lRunNumber;
300+ }
301+ }
252302
253- // Define o2 fitter, 2-prong
254- o2::vertexing::DCAFitterN<2 > fitter;
255- fitter.setBz (d_bz);
256- fitter.setPropagateToPCA (true );
257- fitter.setMaxR (200 .);
258- fitter.setMinParamChange (1e-3 );
259- fitter.setMinRelChi2Change (0.9 );
260- fitter.setMaxDZIni (1e9 );
261- fitter.setMaxChi2 (1e9 );
262- fitter.setUseAbsDCA (true ); // use d_UseAbsDCA once we want to use the weighted DCA
303+ void process (aod::Collisions const &, aod::BCsWithTimestamps const &, FullTracksExt const & tracks, aod::V0s const & V0s, aod::Cascades const & Cascades)
304+ {
305+ registry.fill (HIST (" hEventCounter" ), 0.5 );
263306
264307 std::map<int , uint8_t > pidmap;
265308
@@ -313,6 +356,18 @@ struct v0selector {
313356 continue ;
314357 }
315358 auto const & collision = V0 .posTrack_as <FullTracksExt>().collision ();
359+ auto bc = collision.bc_as <aod::BCsWithTimestamps>();
360+ CheckAndUpdate (bc.runNumber (), bc.timestamp ());
361+ // Define o2 fitter, 2-prong
362+ o2::vertexing::DCAFitterN<2 > fitter;
363+ fitter.setBz (d_bz);
364+ fitter.setPropagateToPCA (true );
365+ fitter.setMaxR (200 .);
366+ fitter.setMinParamChange (1e-3 );
367+ fitter.setMinRelChi2Change (0.9 );
368+ fitter.setMaxDZIni (1e9 );
369+ fitter.setMaxChi2 (1e9 );
370+ fitter.setUseAbsDCA (true ); // use d_UseAbsDCA once we want to use the weighted DCA
316371
317372 if (V0 .collisionId () != collision.globalIndex ()) {
318373 continue ;
@@ -428,17 +483,6 @@ struct v0selector {
428483
429484 } // end of V0 loop
430485
431- // next, cascade, Omega -> LK
432- o2::vertexing::DCAFitterN<2 > fitterCasc;
433- fitterCasc.setBz (d_bz);
434- fitterCasc.setPropagateToPCA (true );
435- fitterCasc.setMaxR (200 .);
436- fitterCasc.setMinParamChange (1e-3 );
437- fitterCasc.setMinRelChi2Change (0.9 );
438- fitterCasc.setMaxDZIni (1e9 );
439- fitterCasc.setMaxChi2 (1e9 );
440- fitterCasc.setUseAbsDCA (true );
441-
442486 // cascade loop
443487 for (auto & casc : Cascades) {
444488 registry.fill (HIST (" hCascCandidate" ), 0.5 );
@@ -468,6 +512,30 @@ struct v0selector {
468512 continue ;
469513 }
470514
515+ auto bc = collision.bc_as <aod::BCsWithTimestamps>();
516+ CheckAndUpdate (bc.runNumber (), bc.timestamp ());
517+ // Define o2 fitter, 2-prong
518+ o2::vertexing::DCAFitterN<2 > fitterV0;
519+ fitterV0.setBz (d_bz);
520+ fitterV0.setPropagateToPCA (true );
521+ fitterV0.setMaxR (200 .);
522+ fitterV0.setMinParamChange (1e-3 );
523+ fitterV0.setMinRelChi2Change (0.9 );
524+ fitterV0.setMaxDZIni (1e9 );
525+ fitterV0.setMaxChi2 (1e9 );
526+ fitterV0.setUseAbsDCA (true ); // use d_UseAbsDCA once we want to use the weighted DCA
527+
528+ // next, cascade, Omega -> LK
529+ o2::vertexing::DCAFitterN<2 > fitterCasc;
530+ fitterCasc.setBz (d_bz);
531+ fitterCasc.setPropagateToPCA (true );
532+ fitterCasc.setMaxR (200 .);
533+ fitterCasc.setMinParamChange (1e-3 );
534+ fitterCasc.setMinRelChi2Change (0.9 );
535+ fitterCasc.setMaxDZIni (1e9 );
536+ fitterCasc.setMaxChi2 (1e9 );
537+ fitterCasc.setUseAbsDCA (true );
538+
471539 std::array<float , 3 > pos = {0 .};
472540 std::array<float , 3 > pvecpos = {0 .};
473541 std::array<float , 3 > pvecneg = {0 .};
@@ -485,18 +553,18 @@ struct v0selector {
485553 nTrack = getTrackParCov (casc.v0_as <aod::V0s>().posTrack_as <FullTracksExt>());
486554 }
487555
488- int nCand = fitter .process (pTrack, nTrack);
556+ int nCand = fitterV0 .process (pTrack, nTrack);
489557 if (nCand != 0 ) {
490- fitter .propagateTracksToVertex ();
558+ fitterV0 .propagateTracksToVertex ();
491559 } else {
492560 continue ;
493561 }
494- const auto & v0vtx = fitter .getPCACandidate ();
562+ const auto & v0vtx = fitterV0 .getPCACandidate ();
495563 for (int i = 0 ; i < 3 ; i++) {
496564 pos[i] = v0vtx[i];
497565 }
498566
499- auto V0dca = fitter .getChi2AtPCACandidate (); // distance between 2 legs.
567+ auto V0dca = fitterV0 .getChi2AtPCACandidate (); // distance between 2 legs.
500568 registry.fill (HIST (" hDCAV0Dau_Casc" ), V0dca);
501569 // if (V0dca > 1.0) {
502570 // continue;
@@ -509,16 +577,16 @@ struct v0selector {
509577
510578 // Covariance matrix calculation
511579 const int momInd[6 ] = {9 , 13 , 14 , 18 , 19 , 20 }; // cov matrix elements for momentum component
512- fitter .getTrack (0 ).getPxPyPzGlo (pvecpos);
513- fitter .getTrack (1 ).getPxPyPzGlo (pvecneg);
514- fitter .getTrack (0 ).getCovXYZPxPyPzGlo (cov0);
515- fitter .getTrack (1 ).getCovXYZPxPyPzGlo (cov1);
580+ fitterV0 .getTrack (0 ).getPxPyPzGlo (pvecpos);
581+ fitterV0 .getTrack (1 ).getPxPyPzGlo (pvecneg);
582+ fitterV0 .getTrack (0 ).getCovXYZPxPyPzGlo (cov0);
583+ fitterV0 .getTrack (1 ).getCovXYZPxPyPzGlo (cov1);
516584
517585 for (int i = 0 ; i < 6 ; i++) {
518586 int j = momInd[i];
519587 covV0[j] = cov0[j] + cov1[j];
520588 }
521- auto covVtxV0 = fitter .calcPCACovMatrix ();
589+ auto covVtxV0 = fitterV0 .calcPCACovMatrix ();
522590 covV0[0 ] = covVtxV0 (0 , 0 );
523591 covV0[1 ] = covVtxV0 (1 , 0 );
524592 covV0[2 ] = covVtxV0 (1 , 1 );
@@ -652,23 +720,23 @@ struct trackPIDQA {
652720 },
653721 };
654722
655- void process (soa::Join<aod::Collisions, aod::EvSels>::iterator const & collision, soa::Join<FullTracksExt, aod::V0Bits> const & tracks)
723+ void processQA (soa::Join<aod::Collisions, aod::EvSels>::iterator const & collision, soa::Join<FullTracksExt, aod::V0Bits> const & tracks)
656724 {
657725
658726 registry.fill (HIST (" hEventCounter" ), 1.0 ); // all
659727 // if (!collision.alias()[kINT7]) {
660728 // return;
661729 // }
662730 // registry.fill(HIST("hEventCounter"), 2.0); //INT7
663-
664- if (abs (collision.posZ ()) > 10.0 ) {
731+ if (collision.numContrib () < 0.5 ) {
665732 return ;
666733 }
667- registry.fill (HIST (" hEventCounter" ), 3.0 ); // |Zvtx| < 10 cm
668- if (collision.numContrib () < 0.5 ) {
734+ registry.fill (HIST (" hEventCounter" ), 3.0 ); // Ncontrib > 0
735+
736+ if (abs (collision.posZ ()) > 10.0 ) {
669737 return ;
670738 }
671- registry.fill (HIST (" hEventCounter" ), 4.0 ); // accepted
739+ registry.fill (HIST (" hEventCounter" ), 4.0 ); // |Zvtx| < 10 cm
672740
673741 for (auto & track : tracks) {
674742 if (!track.has_collision ()) {
@@ -733,6 +801,14 @@ struct trackPIDQA {
733801
734802 } // end of track loop
735803 } // end of process
804+
805+ void processDummy (soa::Join<aod::Collisions, aod::EvSels>::iterator const & collision)
806+ {
807+ // do nothing
808+ }
809+
810+ PROCESS_SWITCH (trackPIDQA, processQA, " Run PID QA for barrel tracks" , true );
811+ PROCESS_SWITCH (trackPIDQA, processDummy, " Dummy function" , false );
736812};
737813
738814WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
0 commit comments