@@ -52,6 +52,24 @@ int32_t nBCsPerOrbit = o2::constants::lhc::LHCMaxBunches;
5252// const int nBCinTF = 114048; /// CCDB value // to be obtained from CCDB in future
5353const int nBCinDrift = 114048 / 32 ; // / to get from ccdb in future
5454
55+ template <typename T, std::size_t N>
56+ void sortVectorOfArray (std::vector<std::array<T, N>>& myVector, const int & myIDX)
57+ {
58+ std::sort (myVector.begin (), myVector.end (), [myIDX](const std::array<T, N>& a, const std::array<T, N>& b) {
59+ return a[myIDX] < b[myIDX]; // sort at the required index
60+ });
61+ }
62+
63+ template <typename T, std::size_t N>
64+ void checkUniqueness (const std::vector<std::array<T, N>>& myVector, const int & myIDX)
65+ {
66+ for (size_t i = 1 ; i < myVector.size (); i++) {
67+ if (myVector[i][myIDX] <= myVector[i - 1 ][myIDX]) {
68+ LOG (error) << " Duplicate Entries while creating Index tables :: (vec[" << i << " ][" << myIDX << " ]) " << myVector[i][myIDX] << " >= " << myVector[i - 1 ][myIDX] << " (vec[" << i - 1 << " ][" << myIDX << " ])" ;
69+ }
70+ }
71+ }
72+
5573struct OccupancyTableProducer {
5674
5775 Service<o2::ccdb::BasicCCDBManager> ccdb;
@@ -1208,7 +1226,9 @@ struct OccupancyTableProducer {
12081226struct TrackMeanOccTableProducer {
12091227
12101228 // //declare production of tables
1211- Produces<aod::TmoTrackId> genTmoTrackId;
1229+ Produces<aod::TmoTrackIds> genTmoTrackId;
1230+ Produces<aod::TmoToTrackQA> genTmoToTrackQA;
1231+ Produces<aod::TrackQAToTmo> genTrackQAToTmo;
12121232
12131233 Produces<aod::TmoPrim> genTmoPrim;
12141234 Produces<aod::TmoT0V0> genTmoT0V0;
@@ -1262,6 +1282,9 @@ struct TrackMeanOccTableProducer {
12621282 Configurable<bool > fillQA1{" fillQA1" , true , " fill QA LOG Ratios" };
12631283 Configurable<bool > fillQA2{" fillQA2" , true , " fill QA condition dependent QAs" };
12641284
1285+ Configurable<bool > buildPointerTrackQAToTMOTable{" buildPointerTrackQAToTMOTable" , true , " buildPointerTrackQAToTMOTable" };
1286+ Configurable<bool > buildPointerTMOToTrackQATable{" buildPointerTMOToTrackQATable" , true , " buildPointerTMOToTrackQATable" };
1287+
12651288 // vectors to be used for occupancy estimation
12661289 std::vector<float > occPrimUnfm80;
12671290
@@ -1727,6 +1750,7 @@ struct TrackMeanOccTableProducer {
17271750 fillWeightMeanOccTable
17281751 };
17291752
1753+ std::vector<std::array<int64_t , 2 >> trackQAGIListforTMOList;
17301754 template <int processMode, int meanTableMode, int weightMeanTableMode, int qaMode, typename B, typename C, typename T, typename U, typename O, typename V>
17311755 void executeTrackOccProducerProcessing (B const & BCs, C const & collisions, T const & tracks, U const & tracksQA, O const & occsRobustT0V0Prim, V const & occs, bool const & executeInThisBlock)
17321756 {
@@ -1871,6 +1895,9 @@ struct TrackMeanOccTableProducer {
18711895 float weightMeanOccRobustNtrackDetUnfm80 = 0 ;
18721896 float weightMeanOccRobustMultTableUnfm80 = 0 ;
18731897
1898+ int trackTMOcounter = -1 ;
1899+ trackQAGIListforTMOList.clear ();
1900+
18741901 for (const auto & trackQA : tracksQA) {
18751902 auto const & track = trackQA.template track_as <T>();
18761903 auto collision = collisions.begin ();
@@ -2034,7 +2061,9 @@ struct TrackMeanOccTableProducer {
20342061
20352062 // If multiple process are on, fill this table only once
20362063 if (executeInThisBlock) {
2064+ trackTMOcounter++;
20372065 genTmoTrackId (track.globalIndex ());
2066+ trackQAGIListforTMOList.push_back ({trackQA.globalIndex (), trackTMOcounter});
20382067 }
20392068
20402069 if constexpr (qaMode == fillOccRobustT0V0dependentQA) {
@@ -2320,6 +2349,52 @@ struct TrackMeanOccTableProducer {
23202349 }
23212350 }
23222351 } // end of trackQA loop
2352+
2353+ // build the IndexTables here
2354+ if (executeInThisBlock) {
2355+ if (buildPointerTrackQAToTMOTable) {
2356+ // create pointer table from trackQA to TrackMeanOcc
2357+ sortVectorOfArray (trackQAGIListforTMOList, 0 ); // sort the list //Its easy to search in a sorted list
2358+ checkUniqueness (trackQAGIListforTMOList, 0 ); // check the uniqueness of track.globalIndex()
2359+
2360+ int currentIDXforCheck = 0 ;
2361+ int listSize = trackQAGIListforTMOList.size ();
2362+ for (const auto & trackQA : tracksQA) {
2363+ while (trackQA.globalIndex () > trackQAGIListforTMOList[currentIDXforCheck][0 ]) {
2364+ currentIDXforCheck++; // increment the currentIDXforCheck for missing or invalid cases e.g. value = -1;
2365+ if (currentIDXforCheck >= listSize) {
2366+ break ;
2367+ }
2368+ }
2369+ if (trackQA.globalIndex () == trackQAGIListforTMOList[currentIDXforCheck][0 ]) {
2370+ genTrackQAToTmo (trackQAGIListforTMOList[currentIDXforCheck][1 ]);
2371+ } else {
2372+ genTrackQAToTmo (-1 ); // put a dummy index when track is not found in trackQA
2373+ }
2374+ }
2375+ }
2376+ if (buildPointerTMOToTrackQATable) {
2377+ // create pointer table from TrackMeanOcc to trackQA
2378+ sortVectorOfArray (trackQAGIListforTMOList, 1 ); // sort the list //Its easy to search in a sorted list
2379+ checkUniqueness (trackQAGIListforTMOList, 1 ); // check the uniqueness of track.globalIndex()
2380+
2381+ int currentIDXforCheck = 0 ;
2382+ int listSize = trackQAGIListforTMOList.size ();
2383+ for (int iCounter = 0 ; iCounter <= trackTMOcounter; iCounter++) {
2384+ while (iCounter > trackQAGIListforTMOList[currentIDXforCheck][1 ]) {
2385+ currentIDXforCheck++; // increment the currentIDXforCheck for missing or invalid cases e.g. value = -1;
2386+ if (currentIDXforCheck >= listSize) {
2387+ break ;
2388+ }
2389+ }
2390+ if (iCounter == trackQAGIListforTMOList[currentIDXforCheck][1 ]) {
2391+ genTmoToTrackQA (trackQAGIListforTMOList[currentIDXforCheck][0 ]);
2392+ } else {
2393+ genTmoToTrackQA (-1 ); // put a dummy index when track is not found in trackQA
2394+ }
2395+ }
2396+ }
2397+ } // end of executeInThisBlock
23232398 } // end of else block of constexpr
23242399 }
23252400
@@ -2602,9 +2677,88 @@ struct TrackMeanOccTableProducer {
26022677 PROCESS_SWITCH (TrackMeanOccTableProducer, processFullOccTableProduer, " processFullOccTableProduer" , false );
26032678};
26042679
2680+ struct CreatePointerTables {
2681+
2682+ Produces<aod::TrackToTracksQA> genTrackToTracksQA;
2683+ Produces<aod::TrackToTmo> genTrackToTmo;
2684+
2685+ void processNothing (aod::Collisions const &)
2686+ {
2687+ return ;
2688+ }
2689+ PROCESS_SWITCH (CreatePointerTables, processNothing, " process Nothing" , true );
2690+
2691+ std::vector<std::array<int64_t , 2 >> trackGIForTrackQAIndexList;
2692+ using MyTracksQA = aod::TracksQAVersion;
2693+ void processTrackToTrackQAPointer (aod::Tracks const & tracks, MyTracksQA const & tracksQA)
2694+ {
2695+ trackGIForTrackQAIndexList.clear ();
2696+ for (const auto & trackQA : tracksQA) {
2697+ auto const & track = trackQA.template track_as <aod::Tracks>();
2698+ trackGIForTrackQAIndexList.push_back ({track.globalIndex (), trackQA.globalIndex ()});
2699+ }
2700+
2701+ sortVectorOfArray (trackGIForTrackQAIndexList, 0 ); // sort the list //Its easy to search in a sorted list
2702+ checkUniqueness (trackGIForTrackQAIndexList, 0 ); // check the uniqueness of track.globalIndex()
2703+
2704+ // create pointer table
2705+ int currentIDXforCheck = 0 ;
2706+ int listSize = trackGIForTrackQAIndexList.size ();
2707+
2708+ for (const auto & track : tracks) {
2709+ while (track.globalIndex () > trackGIForTrackQAIndexList[currentIDXforCheck][0 ]) {
2710+ currentIDXforCheck++; // increment the currentIDXforCheck for missing or invalid cases e.g. value = -1;
2711+ if (currentIDXforCheck >= listSize) {
2712+ break ;
2713+ }
2714+ }
2715+ if (track.globalIndex () == trackGIForTrackQAIndexList[currentIDXforCheck][0 ]) {
2716+ genTrackToTracksQA (trackGIForTrackQAIndexList[currentIDXforCheck][1 ]);
2717+ } else {
2718+ genTrackToTracksQA (-1 ); // put a dummy index when track is not found in trackQA
2719+ }
2720+ }
2721+ }
2722+ PROCESS_SWITCH (CreatePointerTables, processTrackToTrackQAPointer, " processTrackToTrackQAPointer" , false );
2723+
2724+ std::vector<std::array<int64_t , 2 >> trackGIForTMOIndexList;
2725+ void processTrackToTrackMeanOccsPointer (aod::Tracks const & tracks, aod::TmoTrackIds const & tmoTrackIds)
2726+ {
2727+ trackGIForTMOIndexList.clear ();
2728+ int tmoCounter = -1 ;
2729+ for (const auto & tmoTrackId : tmoTrackIds) {
2730+ tmoCounter++;
2731+ auto const & track = tmoTrackId.template track_as <aod::Tracks>();
2732+ trackGIForTMOIndexList.push_back ({track.globalIndex (), tmoCounter}); // tmoTrackId Global Index is not working :: tmoTrackId.globalIndex()});
2733+ }
2734+ sortVectorOfArray (trackGIForTMOIndexList, 0 ); // sort the list //Its easy to search in a sorted list
2735+ checkUniqueness (trackGIForTMOIndexList, 0 ); // check the uniqueness of track.globalIndex()
2736+
2737+ // create pointer table
2738+ int currentIDXforCheck = 0 ;
2739+ int listSize = trackGIForTMOIndexList.size ();
2740+
2741+ for (const auto & track : tracks) {
2742+ while (track.globalIndex () > trackGIForTMOIndexList[currentIDXforCheck][0 ]) {
2743+ currentIDXforCheck++; // increment the currentIDXforCheck for missing or invalid cases e.g. value = -1;
2744+ if (currentIDXforCheck >= listSize) {
2745+ break ;
2746+ }
2747+ }
2748+ if (track.globalIndex () == trackGIForTMOIndexList[currentIDXforCheck][0 ]) {
2749+ genTrackToTmo (trackGIForTMOIndexList[currentIDXforCheck][1 ]);
2750+ } else {
2751+ genTrackToTmo (-1 ); // put a dummy index when track is not found in trackQA
2752+ }
2753+ }
2754+ }
2755+ PROCESS_SWITCH (CreatePointerTables, processTrackToTrackMeanOccsPointer, " processTrackToTrackMeanOccsPointer" , false );
2756+ };
2757+
26052758WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
26062759{
26072760 return WorkflowSpec{
26082761 adaptAnalysisTask<OccupancyTableProducer>(cfgc),
2609- adaptAnalysisTask<TrackMeanOccTableProducer>(cfgc)};
2762+ adaptAnalysisTask<TrackMeanOccTableProducer>(cfgc),
2763+ adaptAnalysisTask<CreatePointerTables>(cfgc)};
26102764}
0 commit comments