|
| 1 | +// Copyright 2019-2020 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 | +/// \author Andrea Rossi <andrea.rossi@cern.ch> |
| 12 | + |
| 13 | +/// \brief Simple task to filter tracks and save infos to trees for DCA-related studies (alignment, HF-related issues) |
| 14 | + |
| 15 | +#include "Common/Core/RecoDecay.h" |
| 16 | +#include "Common/Core/TrackSelection.h" |
| 17 | +#include "Common/Core/trackUtilities.h" |
| 18 | +#include "Common/DataModel/CollisionAssociationTables.h" |
| 19 | +#include "Common/DataModel/EventSelection.h" |
| 20 | +#include "Common/DataModel/PIDResponse.h" |
| 21 | +#include "Common/DataModel/TrackSelectionTables.h" |
| 22 | + |
| 23 | +#include "Framework/ASoA.h" |
| 24 | +#include "Framework/ASoAHelpers.h" |
| 25 | +#include "Framework/AnalysisTask.h" |
| 26 | +#include "Framework/runDataProcessing.h" |
| 27 | + |
| 28 | +using namespace o2; |
| 29 | +using namespace o2::framework; |
| 30 | +using namespace o2::aod::track; |
| 31 | +using namespace o2::aod::mctracklabel; |
| 32 | +using namespace o2::framework::expressions; |
| 33 | + |
| 34 | +namespace o2::aod |
| 35 | +{ |
| 36 | +namespace filterTracks |
| 37 | +{ |
| 38 | + |
| 39 | +DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! Collision index |
| 40 | +DECLARE_SOA_COLUMN(IsInsideBeamPipe, isInsideBeamPipe, int); //! is within beam pipe |
| 41 | +DECLARE_SOA_COLUMN(Pt, pt, float); //! track pt |
| 42 | +DECLARE_SOA_COLUMN(Px, px, float); //! track px |
| 43 | +DECLARE_SOA_COLUMN(Py, py, float); //! track py |
| 44 | +DECLARE_SOA_COLUMN(Pz, pz, float); //! track pz |
| 45 | +// DECLARE_SOA_COLUMN(Eta, eta, float); //! track eta |
| 46 | +// DECLARE_SOA_COLUMN(X, x, float); //! track x position at the DCA to the primary vertex |
| 47 | +// DECLARE_SOA_COLUMN(Y, y, float); //! track y position at the DCA to the primary vertex |
| 48 | +// DECLARE_SOA_COLUMN(Z, z, float); //! track z position at the DCA to the primary vertex |
| 49 | +// DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); //! track distance of closest approach at the primary vertex: in xy plane |
| 50 | +// DECLARE_SOA_COLUMN(DcaZ, dcaz, float); //! track distance of closest approach at the primary vertex: along z (beam line) direction |
| 51 | +DECLARE_SOA_COLUMN(Charge, charge, int); //! track sign, not really charge |
| 52 | +DECLARE_SOA_COLUMN(NsigmaTPCpi, nsigmaTPCpi, float); //! TPC nsigma w.r.t. pion mass hypothesis |
| 53 | +DECLARE_SOA_COLUMN(NsigmaTPCka, nsigmaTPCka, float); //! TPC nsigma w.r.t. kaon mass hypothesis |
| 54 | +DECLARE_SOA_COLUMN(NsigmaTPCpr, nsigmaTPCpr, float); //! TPC nsigma w.r.t. proton mass hypothesis |
| 55 | +DECLARE_SOA_COLUMN(NsigmaTOFpi, nsigmaTOFpi, float); //! TOF nsigma w.r.t. pion mass hypothesis |
| 56 | +DECLARE_SOA_COLUMN(NsigmaTOFka, nsigmaTOFka, float); //! TOF nsigma w.r.t. kaon mass hypothesis |
| 57 | +DECLARE_SOA_COLUMN(NsigmaTOFpr, nsigmaTOFpr, float); //! TOF nsigma w.r.t. proton mass hypothesis |
| 58 | +DECLARE_SOA_COLUMN(TpcNCluster, tpcNCluster, int); //! TOF nsigma w.r.t. proton mass hypothesis |
| 59 | + |
| 60 | +///// MC INFO |
| 61 | +DECLARE_SOA_COLUMN(MainHfMotherPdgCode, mainMotherPdgCode, int); //! mother pdg code for particles coming from HF, skipping intermediate resonance states. Not trustable when mother is not HF. Not suited for Sc->Lc decays, since Sc are never pointed to |
| 62 | +DECLARE_SOA_COLUMN(IsPhysicalPrimary, isPhysicalPrimary, bool); //! is phyiscal primary according to ALICE definition |
| 63 | +DECLARE_SOA_COLUMN(MainBeautyAncestorPdgCode, mainBeautyAncestorPdgCode, int); //! pdgcode of beauty particle when this is an ancestor, otherwise -1 |
| 64 | +DECLARE_SOA_COLUMN(MainMotherOrigIndex, mainMotherOrigIndex, int); //! original index in MCParticle tree of main mother: needed when checking if particles come from same mother |
| 65 | +DECLARE_SOA_COLUMN(MainMotherNfinalStateDaught, mainMotherNfinalStateDaught, int); //! number of final state (we consider only pions, kaons, muons, electrons, protons) daughter in main mother decay. To be noted that this is computed only for decays of particles of interest (D0, Lc, K0s). If the sign is negative, it means that the decay is not in one of the desired channels (K0s->pi pi, Lc->pKpi, D0->K-pi+) |
| 66 | + |
| 67 | +DECLARE_SOA_COLUMN(MainMotherPt, mainMotherPt, float); //! original index in MCParticle tree of main mother: needed when chekcing if particles come from same mother |
| 68 | +DECLARE_SOA_COLUMN(MainMotherY, mainMotherY, float); //! original index in MCParticle tree of main mother: needed when chekcing if particles come from same mother |
| 69 | +DECLARE_SOA_COLUMN(MainBeautyAncestorPt, mainBeautyAncestorPt, float); //! original index in MCParticle tree of main mother: needed when chekcing if particles come from same mother |
| 70 | +DECLARE_SOA_COLUMN(MainBeautyAncestorY, mainBeautyAncestorY, float); //! original index in MCParticle tree of main mother: needed when chekcing if particles come from same mother |
| 71 | +DECLARE_SOA_COLUMN(MaxEtaDaughter, maxEtaDaughter, float); //! max (abs) eta of daughter particles, needed to reproduce acceptance cut |
| 72 | +} // namespace filterTracks |
| 73 | +DECLARE_SOA_TABLE(FilterTrack, "AOD", "FILTERTRACK", |
| 74 | + o2::aod::track::CollisionId, |
| 75 | + aod::filterTracks::IsInsideBeamPipe, |
| 76 | + o2::aod::track::TrackType, |
| 77 | + o2::aod::track::X, |
| 78 | + o2::aod::track::Alpha, |
| 79 | + o2::aod::track::Y, |
| 80 | + o2::aod::track::Z, |
| 81 | + o2::aod::track::Snp, |
| 82 | + o2::aod::track::Tgl, |
| 83 | + o2::aod::track::Signed1Pt); |
| 84 | +DECLARE_SOA_TABLE(FilterTrackExtr, "AOD", "FILTERTRACKEXTR", |
| 85 | + // aod::filterTracks::Px,aod::filterTracks::Py, aod::filterTracks::Pz, |
| 86 | + aod::filterTracks::Pt, o2::aod::track::Eta, |
| 87 | + o2::aod::filterTracks::Charge, |
| 88 | + o2::aod::track::DcaXY, |
| 89 | + o2::aod::track::DcaZ, |
| 90 | + o2::aod::track::SigmaDcaXY2, |
| 91 | + o2::aod::track::SigmaDcaZ2, |
| 92 | + aod::filterTracks::NsigmaTPCpi, aod::filterTracks::NsigmaTPCka, aod::filterTracks::NsigmaTPCpr, |
| 93 | + aod::filterTracks::NsigmaTOFpi, aod::filterTracks::NsigmaTOFka, aod::filterTracks::NsigmaTOFpr); |
| 94 | +DECLARE_SOA_TABLE(FiltTracExtDet, "AOD", "FILTTRACEXTDET", |
| 95 | + o2::aod::track::ITSClusterSizes, |
| 96 | + o2::aod::track::ITSChi2NCl, |
| 97 | + o2::aod::track::TPCChi2NCl, |
| 98 | + aod::filterTracks::TpcNCluster, |
| 99 | + o2::aod::track::TrackTime); |
| 100 | +DECLARE_SOA_TABLE(FilterTrackMC, "AOD", "FILTERTRACKMC", |
| 101 | + // aod::filterTracks::Px,aod::filterTracks::Py, aod::filterTracks::Pz, |
| 102 | + o2::aod::mcparticle::PdgCode, |
| 103 | + o2::aod::filterTracks::IsPhysicalPrimary, |
| 104 | + o2::aod::filterTracks::MainHfMotherPdgCode, |
| 105 | + o2::aod::filterTracks::MainBeautyAncestorPdgCode, |
| 106 | + o2::aod::filterTracks::MainMotherOrigIndex, |
| 107 | + o2::aod::filterTracks::MainMotherNfinalStateDaught, |
| 108 | + o2::aod::filterTracks::MainMotherPt, |
| 109 | + o2::aod::filterTracks::MainMotherY, |
| 110 | + o2::aod::filterTracks::MainBeautyAncestorPt, |
| 111 | + o2::aod::filterTracks::MainBeautyAncestorY); |
| 112 | +DECLARE_SOA_TABLE(GenParticles, "AOD", "GENPARTICLES", |
| 113 | + // aod::filterTracks::Px,aod::filterTracks::Py, aod::filterTracks::Pz, |
| 114 | + o2::aod::mcparticle::PdgCode, |
| 115 | + o2::aod::mcparticle::McCollisionId, |
| 116 | + o2::aod::filterTracks::MainBeautyAncestorPdgCode, |
| 117 | + o2::aod::filterTracks::MainMotherPt, |
| 118 | + o2::aod::filterTracks::MainMotherY, |
| 119 | + o2::aod::filterTracks::MaxEtaDaughter, |
| 120 | + o2::aod::filterTracks::MainBeautyAncestorPt, |
| 121 | + o2::aod::filterTracks::MainBeautyAncestorY); |
| 122 | +} // namespace o2::aod |
| 123 | + |
| 124 | +struct FilterTracks { |
| 125 | + |
| 126 | + Produces<aod::FilterTrackExtr> filteredTracksTableExtra; |
| 127 | + Produces<aod::FilterTrack> filteredTracksTable; |
| 128 | + Produces<aod::FiltTracExtDet> filteredTracksTableExtraDet; |
| 129 | + Produces<aod::FilterTrackMC> filteredTracksMC; |
| 130 | + Produces<aod::GenParticles> selectedGenParticles; |
| 131 | + |
| 132 | + // Configurable<int> dummy{"dummy", 0, "dummy"}; |
| 133 | + Configurable<float> minTrackPt{"minTrackPt", 0.25, "min track pt"}; |
| 134 | + Configurable<float> trackDcaXyMax{"trackDcaXyMax", 0.5, "max track pt"}; |
| 135 | + Configurable<int> trackPtSampling{"trackPtSampling", 0, "track sampling mode"}; |
| 136 | + Configurable<float> trackPtWeightLowPt{"trackPtWeightLowPt", 0.01f, "trackPtWeightLowPt"}; |
| 137 | + Configurable<float> trackPtWeightMidPt{"trackPtWeightMidPt", 0.10f, "trackPtWeightMidPt"}; |
| 138 | + |
| 139 | + Filter trackFilter = requireGlobalTrackWoDCAInFilter() && aod::track::pt > minTrackPt&& nabs(aod::track::dcaXY) < trackDcaXyMax; |
| 140 | + using TracksWithSelAndDca = soa::Join<aod::Tracks, aod::TracksCov, aod::TracksDCA, aod::TracksDCACov, aod::TracksExtra, aod::TrackSelection, aod::pidTPCFullPi, aod::pidTOFFullPi, aod::pidTPCFullKa, aod::pidTOFFullKa, aod::pidTPCFullPr, aod::pidTOFFullPr>; |
| 141 | + using TracksWithSelAndDcaMc = soa::Join<TracksWithSelAndDca, aod::McTrackLabels>; |
| 142 | + Partition<soa::Filtered<TracksWithSelAndDca>> lowPtTracks = aod::track::pt < 2.f && (nabs(aod::track::pt * 10000.f - nround(aod::track::pt * 10000.f)) < trackPtWeightLowPt * 2.f); |
| 143 | + Partition<soa::Filtered<TracksWithSelAndDca>> midPtTracks = aod::track::pt > 2.f && aod::track::pt < 5.f && (nabs(aod::track::pt * 10000.f - nround(aod::track::pt * 10000.f)) < trackPtWeightMidPt * 2.f); |
| 144 | + Partition<soa::Filtered<TracksWithSelAndDca>> highPtTracks = aod::track::pt > 5.f; |
| 145 | + |
| 146 | + Partition<soa::Filtered<TracksWithSelAndDcaMc>> lowPtTracksMC = aod::track::pt < 2.f && (nabs(aod::track::pt * 10000.f - nround(aod::track::pt * 10000.f)) < trackPtWeightLowPt * 2.f); |
| 147 | + Partition<soa::Filtered<TracksWithSelAndDcaMc>> midPtTracksMC = aod::track::pt > 2.f && aod::track::pt < 5.f && (nabs(aod::track::pt * 10000.f - nround(aod::track::pt * 10000.f)) < trackPtWeightMidPt * 2.f); |
| 148 | + Partition<soa::Filtered<TracksWithSelAndDcaMc>> highPtTracksMC = aod::track::pt > 5.f; |
| 149 | + |
| 150 | + std::array<int, 3> pdgSignalParticleArray = {310, 421, 4122}; // K0s, D0 and Lc |
| 151 | + std::array<int, 3> pdgDecayLc = {2212, -321, 211}; |
| 152 | + std::array<int, 2> pdgDecayDzero = {-321, 211}; |
| 153 | + std::array<int, 2> pdgDecayKzero = {-211, 211}; |
| 154 | + |
| 155 | + void init(InitContext&) |
| 156 | + { |
| 157 | + } |
| 158 | + |
| 159 | + void fillTableData(auto track) |
| 160 | + { |
| 161 | + |
| 162 | + filteredTracksTableExtra(track.pt(), track.eta(), track.sign(), track.dcaXY(), track.dcaZ(), track.sigmaDcaXY2(), track.sigmaDcaZ2(), track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr()); |
| 163 | + filteredTracksTable(track.collisionId(), track.isWithinBeamPipe() ? 1 : 0, track.trackType(), track.x(), track.alpha(), track.y(), track.z(), track.snp(), track.tgl(), track.signed1Pt()); |
| 164 | + |
| 165 | + filteredTracksTableExtraDet(track.itsClusterSizes(), track.itsChi2NCl(), track.tpcChi2NCl(), track.tpcNClsFound(), track.trackTime()); |
| 166 | + } |
| 167 | + |
| 168 | + void fillTableDataMC(auto track, aod::McParticles const& mcParticles) |
| 169 | + { |
| 170 | + |
| 171 | + fillTableData(track); |
| 172 | + bool has_MCparticle = track.has_mcParticle(); |
| 173 | + if (has_MCparticle) { |
| 174 | + /// the track is not fake |
| 175 | + |
| 176 | + // check whether the particle comes from a charm or beauty hadron and store its index |
| 177 | + |
| 178 | + auto mcparticle = track.mcParticle(); |
| 179 | + int pdgParticleMother = 0; |
| 180 | + for (int iSignPart = 0; iSignPart < 3; iSignPart++) { |
| 181 | + pdgParticleMother = pdgSignalParticleArray[iSignPart]; |
| 182 | + auto motherIndex = RecoDecay::getMother(mcParticles, mcparticle, pdgParticleMother, true); // check whether mcparticle derives from a particle with pdg = pdgparticlemother, accepting also antiparticle (<- the true parameter) |
| 183 | + if (motherIndex != -1) { |
| 184 | + auto particleMother = mcParticles.rawIteratorAt(motherIndex); |
| 185 | + // just for internal check |
| 186 | + // double mass=particleMother.e()*particleMother.e()-particleMother.pt()*particleMother.pt()-particleMother.pz()*particleMother.pz(); |
| 187 | + // filteredTracksMC(mcparticle.pdgCode(),mcparticle.isPhysicalPrimary(),particleMother.pdgCode(),0,motherIndex,0,particleMother.pt(),particleMother.y(),std::sqrt(mass),0); |
| 188 | + if (pdgParticleMother == 310) { |
| 189 | + auto daughtersSlice = mcparticle.template daughters_as<aod::McParticles>(); |
| 190 | + int ndaught = daughtersSlice.size(); // might not be accurate in case K0s interact with material before decaying |
| 191 | + if (ndaught != 2) |
| 192 | + ndaught *= -1; |
| 193 | + filteredTracksMC(mcparticle.pdgCode(), mcparticle.isPhysicalPrimary(), particleMother.pdgCode(), 0, motherIndex, ndaught, particleMother.pt(), particleMother.y(), 0, 0); |
| 194 | + // std::cout<<"FOUND K0s, MATCHED! size array "<<ndaught<<std::endl; |
| 195 | + break; |
| 196 | + } |
| 197 | + |
| 198 | + int ndaught = 0; |
| 199 | + std::vector<int> indxDaughers; |
| 200 | + if (pdgParticleMother == 421) { |
| 201 | + if (RecoDecay::isMatchedMCGen<true, false>(mcParticles, particleMother, pdgParticleMother, pdgDecayDzero, true, nullptr, 3, &indxDaughers)) { |
| 202 | + ndaught = 2; |
| 203 | + // std::cout<<"######## FOUND D0, MATCHED! pdg: " <<particleMother.pdgCode()<<"################ size array "<<indxDaughers.size()<<std::endl; |
| 204 | + } else |
| 205 | + ndaught = -indxDaughers.size(); |
| 206 | + } else if (pdgParticleMother == 4122) { |
| 207 | + if (RecoDecay::isMatchedMCGen<true, false>(mcParticles, particleMother, pdgParticleMother, pdgDecayLc, true, nullptr, 3, &indxDaughers)) { |
| 208 | + ndaught = 3; |
| 209 | + } else |
| 210 | + ndaught = -indxDaughers.size(); |
| 211 | + } |
| 212 | + // now check whether the charm hadron is prompt or comes from beauty decay |
| 213 | + std::vector<int> idxBhadMothers; |
| 214 | + if (RecoDecay::getCharmHadronOrigin(mcParticles, particleMother, false, &idxBhadMothers) == RecoDecay::OriginType::NonPrompt) { |
| 215 | + if (idxBhadMothers.size() > 1) { |
| 216 | + LOG(info) << "more than 1 B mother hadron found, should not be: "; |
| 217 | + for (unsigned long iBhM = 0; iBhM < idxBhadMothers.size(); iBhM++) { |
| 218 | + auto particleBhadr = mcParticles.rawIteratorAt(idxBhadMothers[iBhM]); |
| 219 | + LOG(info) << particleBhadr.pdgCode(); |
| 220 | + } |
| 221 | + } |
| 222 | + auto particleBhadr = mcParticles.rawIteratorAt(idxBhadMothers[0]); |
| 223 | + // int pdgBhad=particleBhadr.pdgCode(); |
| 224 | + filteredTracksMC(mcparticle.pdgCode(), mcparticle.isPhysicalPrimary(), particleMother.pdgCode(), particleBhadr.pdgCode(), motherIndex, ndaught, particleMother.pt(), particleMother.y(), particleBhadr.pt(), particleBhadr.y()); |
| 225 | + } else { |
| 226 | + filteredTracksMC(mcparticle.pdgCode(), mcparticle.isPhysicalPrimary(), particleMother.pdgCode(), 0, motherIndex, ndaught, particleMother.pt(), particleMother.y(), 0, 0); |
| 227 | + } |
| 228 | + break; |
| 229 | + } |
| 230 | + pdgParticleMother = 0; |
| 231 | + } |
| 232 | + if (pdgParticleMother == 0) |
| 233 | + filteredTracksMC(mcparticle.pdgCode(), mcparticle.isPhysicalPrimary(), 0, 0, -1, 0, 0, 0, 0, 0); |
| 234 | + // std::cout<<mcparticle.pdgCode()<<std::endl; |
| 235 | + } else { |
| 236 | + filteredTracksMC(0, 0, 0, 0, 0, 0, 0, 0, 0, 0); |
| 237 | + } |
| 238 | + } |
| 239 | + void processData(soa::Filtered<TracksWithSelAndDca> const& tracks) |
| 240 | + { |
| 241 | + if (trackPtSampling == 0) { |
| 242 | + for (auto& track : tracks) { |
| 243 | + fillTableData(track); |
| 244 | + } |
| 245 | + } else { |
| 246 | + for (auto& track : lowPtTracks) { |
| 247 | + fillTableData(track); |
| 248 | + } |
| 249 | + for (auto& track : midPtTracks) { |
| 250 | + fillTableData(track); |
| 251 | + } |
| 252 | + for (auto& track : highPtTracks) { |
| 253 | + fillTableData(track); |
| 254 | + } |
| 255 | + } |
| 256 | + } |
| 257 | + PROCESS_SWITCH(FilterTracks, processData, "process data", true); |
| 258 | + |
| 259 | + void processMC(soa::Filtered<TracksWithSelAndDcaMc> const& tracks, aod::McParticles const& mcParticles) |
| 260 | + { |
| 261 | + if (trackPtSampling == 0) { |
| 262 | + for (auto& track : tracks) { |
| 263 | + fillTableDataMC(track, mcParticles); |
| 264 | + } |
| 265 | + } else { |
| 266 | + for (auto& track : lowPtTracksMC) { |
| 267 | + fillTableDataMC(track, mcParticles); |
| 268 | + } |
| 269 | + for (auto& track : midPtTracksMC) { |
| 270 | + fillTableDataMC(track, mcParticles); |
| 271 | + } |
| 272 | + for (auto& track : highPtTracksMC) { |
| 273 | + fillTableDataMC(track, mcParticles); |
| 274 | + } |
| 275 | + } |
| 276 | + |
| 277 | + for (auto& mcpart : mcParticles) { // NOTE THAT OF COURSE IN CASE OF SAMPLING THE GEN TABLE WON'T MATCH THE RECO EVEN CONSIDERING EFFICIENCY |
| 278 | + int pdgCode = mcpart.pdgCode(); |
| 279 | + // for(int iSignPart=0;iSignPart<3;iSignPart++){ |
| 280 | + |
| 281 | + std::vector<int> indxDaughers; |
| 282 | + float etamax = 0; |
| 283 | + bool isMatchedToSignal = false; |
| 284 | + if (std::abs(pdgCode) == 310) { |
| 285 | + isMatchedToSignal = RecoDecay::isMatchedMCGen<true, false>(mcParticles, mcpart, 310, pdgDecayKzero, true, nullptr, 1, &indxDaughers); |
| 286 | + } |
| 287 | + if (std::abs(pdgCode) == 421) { |
| 288 | + isMatchedToSignal = RecoDecay::isMatchedMCGen<true, false>(mcParticles, mcpart, 421, pdgDecayDzero, true, nullptr, 3, &indxDaughers); |
| 289 | + } else if (std::abs(pdgCode) == 4122) { |
| 290 | + isMatchedToSignal = RecoDecay::isMatchedMCGen<true, false>(mcParticles, mcpart, 4122, pdgDecayLc, true, nullptr, 3, &indxDaughers); |
| 291 | + // std::cout<<"Lc found, matched to MC? "<<isMatchedToSignal<<std::endl; |
| 292 | + // if(!isMatchedToSignal){ |
| 293 | + // auto daughtersLxSlice = mcpart.daughters_as<aod::McParticles>(); |
| 294 | + // int ndaught = daughtersLxSlice.size(); |
| 295 | + // for(auto lcDaught : daughtersLxSlice){ |
| 296 | + // std::cout<<"Lc daught, total daught "<<ndaught<<" pdg: "<<lcDaught.pdgCode()<<std::endl; |
| 297 | + // } |
| 298 | + // } |
| 299 | + } |
| 300 | + if (isMatchedToSignal) { |
| 301 | + for (auto mcpartdaughtIdx : indxDaughers) { |
| 302 | + auto mcPartDaught = mcParticles.rawIteratorAt(mcpartdaughtIdx); |
| 303 | + double eta = std::abs(mcPartDaught.eta()); |
| 304 | + if ((eta) > etamax) { |
| 305 | + etamax = eta; |
| 306 | + } |
| 307 | + } |
| 308 | + if (pdgCode == 310) { |
| 309 | + selectedGenParticles(mcpart.pdgCode(), mcpart.mcCollisionId(), 0, mcpart.pt(), mcpart.y(), etamax, 0, 0); |
| 310 | + continue; |
| 311 | + } |
| 312 | + std::vector<int> idxBhadMothers; |
| 313 | + if (RecoDecay::getCharmHadronOrigin(mcParticles, mcpart, false, &idxBhadMothers) == RecoDecay::OriginType::NonPrompt) { |
| 314 | + if (idxBhadMothers.size() > 1) { |
| 315 | + LOG(info) << "loop on gen particles: more than 1 B mother hadron found, should not be: "; |
| 316 | + for (unsigned long iBhM = 0; iBhM < idxBhadMothers.size(); iBhM++) { |
| 317 | + auto particleBhadr = mcParticles.rawIteratorAt(idxBhadMothers[iBhM]); |
| 318 | + LOG(info) << particleBhadr.pdgCode(); |
| 319 | + } |
| 320 | + } |
| 321 | + auto particleBhadr = mcParticles.rawIteratorAt(idxBhadMothers[0]); |
| 322 | + // int pdgBhad=particleBhadr.pdgCode(); |
| 323 | + selectedGenParticles(mcpart.pdgCode(), mcpart.mcCollisionId(), particleBhadr.pdgCode(), mcpart.pt(), mcpart.y(), etamax, particleBhadr.pt(), particleBhadr.y()); |
| 324 | + } else |
| 325 | + selectedGenParticles(mcpart.pdgCode(), mcpart.mcCollisionId(), 0, mcpart.pt(), mcpart.y(), etamax, 0, 0); |
| 326 | + } |
| 327 | + // |
| 328 | + } |
| 329 | + } |
| 330 | + PROCESS_SWITCH(FilterTracks, processMC, "process MC", false); |
| 331 | +}; |
| 332 | + |
| 333 | +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) |
| 334 | +{ |
| 335 | + return WorkflowSpec{ |
| 336 | + adaptAnalysisTask<FilterTracks>(cfgc)}; |
| 337 | +} |
0 commit comments