@@ -1386,7 +1386,7 @@ struct AnalysisSameEventPairing {
13861386 if (context.mOptions .get <bool >(" processDummy" )) {
13871387 return ;
13881388 }
1389- bool isMCGen = context.mOptions .get <bool >(" processMCGen" );
1389+ bool isMCGen = context.mOptions .get <bool >(" processMCGen" ) || context. mOptions . get < bool >( " processMCGenWithGrouping " ) ;
13901390 VarManager::SetDefaultVarNames ();
13911391
13921392 fEnableBarrelHistos = context.mOptions .get <bool >(" processAllSkimmed" ) || context.mOptions .get <bool >(" processBarrelOnlySkimmed" ) || context.mOptions .get <bool >(" processBarrelOnlyWithCollSkimmed" );
@@ -2318,6 +2318,109 @@ struct AnalysisSameEventPairing {
23182318 } // end loop over reconstructed events
23192319 }
23202320
2321+ void processMCGenWithGrouping (soa::Filtered<MyEventsVtxCovSelected> const & events, ReducedMCEvents const & mcEvents, ReducedMCTracks const & mcTracks)
2322+ {
2323+ uint32_t mcDecision = 0 ;
2324+ int isig = 0 ;
2325+
2326+ for (auto & mctrack : mcTracks) {
2327+ VarManager::FillTrackMC (mcTracks, mctrack);
2328+ // NOTE: Signals are checked here mostly based on the skimmed MC stack, so depending on the requested signal, the stack could be incomplete.
2329+ // NOTE: However, the working model is that the decisions on MC signals are precomputed during skimming and are stored in the mcReducedFlags member.
2330+ // TODO: Use the mcReducedFlags to select signals
2331+ for (auto & sig : fGenMCSignals ) {
2332+ if (sig->CheckSignal (true , mctrack)) {
2333+ fHistMan ->FillHistClass (Form (" MCTruthGen_%s" , sig->GetName ()), VarManager::fgValues);
2334+ }
2335+ }
2336+ }
2337+ // Fill Generated histograms taking into account selected collisions
2338+ for (auto & event : events) {
2339+ if (!event.isEventSelected_bit (0 )) {
2340+ continue ;
2341+ }
2342+ if (!event.has_reducedMCevent ()) {
2343+ continue ;
2344+ }
2345+
2346+ for (auto & track : mcTracks) {
2347+ if (track.reducedMCeventId () != event.reducedMCeventId ()) {
2348+ continue ;
2349+ }
2350+ VarManager::FillTrackMC (mcTracks, track);
2351+ auto track_raw = mcTracks.rawIteratorAt (track.globalIndex ());
2352+ mcDecision = 0 ;
2353+ isig = 0 ;
2354+ for (auto & sig : fGenMCSignals ) {
2355+ if (sig->CheckSignal (true , track_raw)) {
2356+ mcDecision |= (static_cast <uint32_t >(1 ) << isig);
2357+ fHistMan ->FillHistClass (Form (" MCTruthGenSel_%s" , sig->GetName ()), VarManager::fgValues);
2358+ MCTruthTableEffi (VarManager::fgValues[VarManager::kMCPt ], VarManager::fgValues[VarManager::kMCEta ], VarManager::fgValues[VarManager::kMCY ], VarManager::fgValues[VarManager::kMCPhi ], VarManager::fgValues[VarManager::kMCVz ], VarManager::fgValues[VarManager::kMCVtxZ ], VarManager::fgValues[VarManager::kMultFT0A ], VarManager::fgValues[VarManager::kMultFT0C ], VarManager::fgValues[VarManager::kCentFT0M ], VarManager::fgValues[VarManager::kVtxNcontribReal ]);
2359+
2360+ if (useMiniTree.fConfigMiniTree ) {
2361+ auto mcEvent = mcEvents.rawIteratorAt (track_raw.reducedMCeventId ());
2362+ dileptonMiniTreeGen (mcDecision, mcEvent.impactParameter (), track_raw.pt (), track_raw.eta (), track_raw.phi (), -999 , -999 , -999 );
2363+ }
2364+ }
2365+ isig++;
2366+ }
2367+ }
2368+ } // end loop over reconstructed events
2369+ if (fHasTwoProngGenMCsignals ) {
2370+ for (auto & [t1, t2] : combinations (mcTracks, mcTracks)) {
2371+ auto t1_raw = mcTracks.rawIteratorAt (t1.globalIndex ());
2372+ auto t2_raw = mcTracks.rawIteratorAt (t2.globalIndex ());
2373+ if (t1_raw.reducedMCeventId () == t2_raw.reducedMCeventId ()) {
2374+ for (auto & sig : fGenMCSignals ) {
2375+ if (sig->GetNProngs () != 2 ) { // NOTE: 2-prong signals required here
2376+ continue ;
2377+ }
2378+ if (sig->CheckSignal (true , t1_raw, t2_raw)) {
2379+ VarManager::FillPairMC<VarManager::kDecayToMuMu >(t1, t2); // NOTE: This feature will only work for muons
2380+ fHistMan ->FillHistClass (Form (" MCTruthGenPair_%s" , sig->GetName ()), VarManager::fgValues);
2381+ }
2382+ }
2383+ }
2384+ }
2385+ }
2386+ for (auto & event : events) {
2387+ if (!event.isEventSelected_bit (0 )) {
2388+ continue ;
2389+ }
2390+ if (!event.has_reducedMCevent ()) {
2391+ continue ;
2392+ }
2393+ // CURRENTLY ONLY FOR 1-GENERATION 2-PRONG SIGNALS
2394+ if (fHasTwoProngGenMCsignals ) {
2395+ auto groupedMCTracks = mcTracks.sliceBy (perReducedMcEvent, event.reducedMCeventId ());
2396+ groupedMCTracks.bindInternalIndicesTo (&mcTracks);
2397+ for (auto & [t1, t2] : combinations (groupedMCTracks, groupedMCTracks)) {
2398+ auto t1_raw = groupedMCTracks.rawIteratorAt (t1.globalIndex ());
2399+ auto t2_raw = groupedMCTracks.rawIteratorAt (t2.globalIndex ());
2400+ if (t1_raw.reducedMCeventId () == t2_raw.reducedMCeventId ()) {
2401+ mcDecision = 0 ;
2402+ isig = 0 ;
2403+ for (auto & sig : fGenMCSignals ) {
2404+ if (sig->GetNProngs () != 2 ) { // NOTE: 2-prong signals required here
2405+ continue ;
2406+ }
2407+ if (sig->CheckSignal (true , t1_raw, t2_raw)) {
2408+ mcDecision |= (static_cast <uint32_t >(1 ) << isig);
2409+ VarManager::FillPairMC<VarManager::kDecayToMuMu >(t1, t2); // NOTE: This feature will only work for muons
2410+ fHistMan ->FillHistClass (Form (" MCTruthGenPairSel_%s" , sig->GetName ()), VarManager::fgValues);
2411+ if (useMiniTree.fConfigMiniTree ) {
2412+ // WARNING! To be checked
2413+ dileptonMiniTreeGen (mcDecision, -999 , t1.pt (), t1.eta (), t1.phi (), t2.pt (), t2.eta (), t2.phi ());
2414+ }
2415+ }
2416+ isig++;
2417+ }
2418+ }
2419+ }
2420+ } // end loop over reconstructed events
2421+ }
2422+ }
2423+
23212424 void processDummy (MyEvents&)
23222425 {
23232426 // do nothing
@@ -2328,6 +2431,7 @@ struct AnalysisSameEventPairing {
23282431 PROCESS_SWITCH (AnalysisSameEventPairing, processBarrelOnlyWithCollSkimmed, " Run barrel only pairing, with skimmed tracks and with collision information" , false );
23292432 PROCESS_SWITCH (AnalysisSameEventPairing, processMuonOnlySkimmed, " Run muon only pairing, with skimmed tracks" , false );
23302433 PROCESS_SWITCH (AnalysisSameEventPairing, processMCGen, " Loop over MC particle stack and fill generator level histograms" , false );
2434+ PROCESS_SWITCH (AnalysisSameEventPairing, processMCGenWithGrouping, " Loop over MC particle stack (grouped MCTracks) and fill generator level histograms" , false );
23312435 PROCESS_SWITCH (AnalysisSameEventPairing, processDummy, " Dummy function, enabled only if none of the others are enabled" , true );
23322436};
23332437
0 commit comments