File indexing completed on 2025-08-03 08:20:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #ifdef DO_TPCCATRACKER_EFF_PERFORMANCE
0023
0024 #include "KFTopoPerformance.h"
0025
0026 #ifdef KFPWITHTRACKER
0027 #ifdef MAIN_DRAW
0028 #include "AliHLTTPCCADisplay.h"
0029 #endif
0030 #include "AliHLTTPCCATracker.h"
0031 #include "AliHLTTPCCAPerformance.h"
0032 #endif
0033
0034 #include "KFParticleTopoReconstructor.h"
0035 #include "KFParticleSIMD.h"
0036 #include "KFPHistogram/KFPHistogram.h"
0037 #include "TParticlePDG.h"
0038 #include "TDatabasePDG.h"
0039
0040 #include "TMath.h"
0041 #include "TH1.h"
0042 #include "TH2.h"
0043 #include "TH3.h"
0044 #include "TProfile.h"
0045 #include "TProfile2D.h"
0046
0047 #include <map>
0048 #include <algorithm>
0049 using std::sort;
0050 using std::vector;
0051
0052 KFTopoPerformance::KFTopoPerformance():KFParticlePerformanceBase(),fTopoReconstructor(0),fPrimVertices(0), fMCTrackToMCPVMatch(0),
0053 fPVPurity(0), fNCorrectPVTracks(0), fTrackMatch(0), vMCTracks(0), vMCParticles(0), fNeutralIndex(0), MCtoRParticleId(0), RtoMCParticleId(0),
0054 MCtoRPVId(0), RtoMCPVId(0), fPrintEffFrequency(1), fCentralityBin(-1), fCentralityWeight(0.f)
0055 {
0056 }
0057
0058 KFTopoPerformance::~KFTopoPerformance()
0059 {
0060 }
0061
0062 #ifdef KFPWITHTRACKER
0063 void KFTopoPerformance::SetNewEvent(
0064 const AliHLTTPCCAGBTracker * const tracker,
0065 AliHLTResizableArray<AliHLTTPCCAHitLabel> *hitLabels,
0066 AliHLTResizableArray<AliHLTTPCCAMCTrack> *mcTracks,
0067 AliHLTResizableArray<AliHLTTPCCALocalMCPoint> *localMCPoints)
0068 {
0069 vMCTracks.resize(mcTracks->Size());
0070 for(int iTr=0; iTr<vMCTracks.size(); iTr++)
0071 {
0072 for(int iP=0; iP<3; iP++)
0073 vMCTracks[iTr].SetPar(iP, (*mcTracks)[iTr].Par(iP));
0074 for(int iP=3; iP<6; iP++)
0075 vMCTracks[iTr].SetPar(iP, (*mcTracks)[iTr].Par(iP) * (*mcTracks)[iTr].P());
0076 vMCTracks[iTr].SetPar(6, (*mcTracks)[iTr].Par(6));
0077
0078 vMCTracks[iTr].SetPDG( (*mcTracks)[iTr].PDG() );
0079 vMCTracks[iTr].SetMotherId( (*mcTracks)[iTr].MotherId() );
0080 vMCTracks[iTr].SetNMCPoints( (*mcTracks)[iTr].NMCPoints() );
0081 }
0082 }
0083 #endif
0084
0085 void KFTopoPerformance::SetTopoReconstructor( const KFParticleTopoReconstructor * const TopoReconstructor)
0086 {
0087
0088 fTopoReconstructor = TopoReconstructor;
0089 }
0090
0091 void KFTopoPerformance::CheckMCTracks()
0092 {
0093
0094 fMCTrackToMCPVMatch.clear();
0095 fPrimVertices.clear();
0096
0097
0098 if (vMCTracks.size() <= 0) return;
0099
0100 fMCTrackToMCPVMatch.resize(vMCTracks.size(),-1);
0101
0102 vector<int> pvIndex;
0103 for(unsigned int iTr=0; iTr<vMCTracks.size(); iTr++)
0104 {
0105 KFMCTrack &mctr = vMCTracks[iTr];
0106 int motherID = mctr.MotherId();
0107 if(motherID <0 )
0108 {
0109 bool newPV = 1;
0110 for(unsigned int iPV=0; iPV<pvIndex.size(); iPV++)
0111 {
0112 if(motherID == pvIndex[iPV])
0113 {
0114 fPrimVertices[iPV].AddDaughterTrack(iTr);
0115 fMCTrackToMCPVMatch[iTr] = iPV;
0116 newPV = 0;
0117 }
0118 }
0119 if(newPV)
0120 {
0121 KFMCVertex primVertex;
0122 primVertex.SetX( mctr.X() );
0123 primVertex.SetY( mctr.Y() );
0124 primVertex.SetZ( mctr.Z() );
0125 primVertex.AddDaughterTrack(iTr);
0126 if(motherID == -1)
0127 primVertex.SetTriggerPV();
0128 fPrimVertices.push_back(primVertex);
0129 fMCTrackToMCPVMatch[iTr] = pvIndex.size();
0130 pvIndex.push_back(motherID);
0131 }
0132 }
0133 }
0134 }
0135
0136 void KFTopoPerformance::GetMCParticles()
0137 {
0138
0139
0140 vMCParticles.clear();
0141 vMCParticles.reserve(vMCTracks.size());
0142
0143 for(unsigned int iMC=0; iMC < vMCTracks.size(); iMC++)
0144 {
0145 KFMCTrack &mtra = vMCTracks[iMC];
0146 KFMCParticle part;
0147 part.SetMCTrackID( iMC );
0148 part.SetMotherId ( mtra.MotherId() );
0149 part.SetPDG ( mtra.PDG() );
0150 vMCParticles.push_back( part );
0151 }
0152
0153 const int nMCParticles = vMCParticles.size();
0154 for (int iP = 0; iP < nMCParticles; iP++ ) {
0155 KFMCParticle &part = vMCParticles[iP];
0156 int motherId = part.GetMotherId();
0157 if(motherId < 0) continue;
0158 if(motherId >= nMCParticles)
0159 {
0160 std::cout << "ERROR!!!!! KF Particle Performance: MC track mother Id is out of range." << std::endl;
0161 exit(1);
0162 }
0163 KFMCParticle &motherPart = vMCParticles[motherId];
0164 motherPart.AddDaughter(iP);
0165 }
0166
0167 fNeutralIndex.clear();
0168 fNeutralIndex.resize(nMCParticles, -1);
0169
0170 for(unsigned int iMC=0; iMC < vMCParticles.size(); iMC++)
0171 {
0172 KFMCParticle &part = vMCParticles[iMC];
0173 part.SetMCTrackID( iMC );
0174 }
0175
0176 const int NmmPDG = 7;
0177 vector<int> mmMotherPDG(NmmPDG);
0178 vector<int> mmChargedDaughterPDG(NmmPDG);
0179 vector<int> mmNeutralDaughterPDG(NmmPDG);
0180 vector<int> newMotherPDG(NmmPDG);
0181 vector<int> newNeutralPDG(NmmPDG);
0182
0183 mmMotherPDG[ 0] = 3112; mmChargedDaughterPDG[ 0] = 211; mmNeutralDaughterPDG[ 0] = 2112;
0184 mmMotherPDG[ 1] = 3222; mmChargedDaughterPDG[ 1] = 211; mmNeutralDaughterPDG[ 1] = 2112;
0185 mmMotherPDG[ 2] = 3312; mmChargedDaughterPDG[ 2] = 211; mmNeutralDaughterPDG[ 2] = 3122;
0186 mmMotherPDG[ 3] = 3334; mmChargedDaughterPDG[ 3] = 211; mmNeutralDaughterPDG[ 3] = 3322;
0187 mmMotherPDG[ 4] = 321; mmChargedDaughterPDG[ 4] = 211; mmNeutralDaughterPDG[ 4] = 111;
0188 mmMotherPDG[ 5] = 3334; mmChargedDaughterPDG[ 5] = 321; mmNeutralDaughterPDG[ 5] = 3122;
0189 mmMotherPDG[ 6] = 3222; mmChargedDaughterPDG[ 6] = 2212; mmNeutralDaughterPDG[ 6] = 111;
0190
0191 newMotherPDG[ 0] = 7003112; newNeutralPDG[ 0] = 7002112;
0192 newMotherPDG[ 1] = 7003222; newNeutralPDG[ 1] = 8002112;
0193 newMotherPDG[ 2] = 7003312; newNeutralPDG[ 2] = 7003122;
0194 newMotherPDG[ 3] = 7003334; newNeutralPDG[ 3] = 7003322;
0195 newMotherPDG[ 4] = 9000321; newNeutralPDG[ 4] = 9000111;
0196 newMotherPDG[ 5] = 8003334; newNeutralPDG[ 5] = 8003122;
0197 newMotherPDG[ 6] = 8003222; newNeutralPDG[ 6] = 8000111;
0198
0199
0200 for(int iMC=0; iMC<nMCParticles; iMC++)
0201 {
0202 if( abs(vMCParticles[iMC].GetPDG()) == 211 || abs(vMCParticles[iMC].GetPDG()) == 321 )
0203 {
0204 int muonIndex = -1;
0205 for(int iD=0; iD<vMCParticles[iMC].NDaughters(); iD++)
0206 if( abs(vMCParticles[vMCParticles[iMC].GetDaughterIds()[iD]].GetPDG()) == 13 )
0207 muonIndex = vMCParticles[iMC].GetDaughterIds()[iD];
0208
0209 if(muonIndex > -1)
0210 {
0211 int newPDG = 0;
0212 if(vMCParticles[iMC].GetPDG() >0)
0213 newPDG = vMCParticles[iMC].GetPDG() + 7000000;
0214 else
0215 newPDG = vMCParticles[iMC].GetPDG() - 7000000;
0216 KFMCParticle motherPart = vMCParticles[iMC];
0217 KFMCTrack motherTrack = vMCTracks[motherPart.GetMCTrackID()];
0218 motherTrack.SetPDG(newPDG);
0219 motherTrack.SetNotReconstructed();
0220 int newMotherIndex = vMCTracks.size();
0221 motherPart.SetPDG(newPDG);
0222 motherPart.SetMCTrackID(newMotherIndex);
0223
0224 const KFMCParticle& daughterPart = vMCParticles[muonIndex];
0225 const KFMCTrack& daughterTrack = vMCTracks[daughterPart.GetMCTrackID()];
0226
0227 int neutrinoPDG = 7000014;
0228 if(vMCParticles[iMC].GetPDG() == -211) neutrinoPDG = -7000014;
0229 if(vMCParticles[iMC].GetPDG() == 321) neutrinoPDG = 8000014;
0230 if(vMCParticles[iMC].GetPDG() == -321) neutrinoPDG = -8000014;
0231
0232 int neutrinoIndex = vMCTracks.size()+1;
0233 vMCParticles[iMC].AddDaughter(neutrinoIndex);
0234
0235 fNeutralIndex[iMC] = neutrinoIndex;
0236
0237 KFMCParticle neutrinoPart;
0238 KFMCTrack neutrinoTrack;
0239 neutrinoTrack.SetX(daughterTrack.X());
0240 neutrinoTrack.SetY(daughterTrack.Y());
0241 neutrinoTrack.SetZ(daughterTrack.Z());
0242 neutrinoTrack.SetPx(motherTrack.Px() - daughterTrack.Px());
0243 neutrinoTrack.SetPy(motherTrack.Py() - daughterTrack.Py());
0244 neutrinoTrack.SetPz(motherTrack.Pz() - daughterTrack.Pz());
0245 neutrinoTrack.SetQP(0);
0246 neutrinoTrack.SetMotherId(newMotherIndex);
0247 neutrinoTrack.SetPDG(neutrinoPDG);
0248
0249 motherPart.CleanDaughters();
0250 motherPart.AddDaughter(muonIndex);
0251 motherPart.AddDaughter(neutrinoIndex);
0252 motherPart.SetInitialParticleId(iMC);
0253 vMCTracks.push_back(motherTrack);
0254 vMCParticles.push_back(motherPart);
0255 fNeutralIndex.push_back(-1);
0256
0257 neutrinoPart.SetMCTrackID(neutrinoIndex);
0258 neutrinoPart.SetMotherId(newMotherIndex);
0259 neutrinoPart.SetPDG(neutrinoPDG);
0260 neutrinoPart.AddDaughter(iMC);
0261 neutrinoPart.AddDaughter(muonIndex);
0262 vMCTracks.push_back(neutrinoTrack);
0263 vMCParticles.push_back(neutrinoPart);
0264 fNeutralIndex.push_back(-1);
0265
0266 vMCParticles[iMC].SetAsReconstructable(4);
0267 vMCParticles[muonIndex].SetAsReconstructable(4);
0268 }
0269 }
0270
0271 if( vMCParticles[iMC].NDaughters() >= 2 &&
0272 (abs(vMCParticles[iMC].GetPDG()) == 3112 ||
0273 abs(vMCParticles[iMC].GetPDG()) == 3222 ||
0274 abs(vMCParticles[iMC].GetPDG()) == 3312 ||
0275 abs(vMCParticles[iMC].GetPDG()) == 3334 ||
0276 abs(vMCParticles[iMC].GetPDG()) == 321) )
0277 {
0278 int neutralDaughterId = -1, chargedDaughterId = -1;
0279
0280 int newPDG = 0;
0281 int neutralPDG = 0;
0282
0283 for(int iPDG=0; iPDG<NmmPDG; iPDG++)
0284 {
0285 if(abs(vMCParticles[iMC].GetPDG()) == mmMotherPDG[iPDG])
0286 {
0287 bool isDaughter[2] = {0,0};
0288
0289 vector<float> xDaughter;
0290 vector<float> yDaughter;
0291 vector<float> zDaughter;
0292 vector< vector<int> > nDaughtersAtPoint;
0293
0294 for(int iMCDaughter=0; iMCDaughter<vMCParticles[iMC].NDaughters(); iMCDaughter++)
0295 {
0296 bool isNewDecayPoint = 1;
0297
0298 for(unsigned int iPoint=0; iPoint<xDaughter.size(); iPoint++)
0299 {
0300 float dx = fabs(vMCTracks[vMCParticles[iMC].GetDaughterIds()[iMCDaughter]].X() - xDaughter[iPoint]);
0301 float dy = fabs(vMCTracks[vMCParticles[iMC].GetDaughterIds()[iMCDaughter]].Y() - yDaughter[iPoint]);
0302 float dz = fabs(vMCTracks[vMCParticles[iMC].GetDaughterIds()[iMCDaughter]].Z() - zDaughter[iPoint]);
0303
0304 bool isSamePoint = (dx < 1.e-5 && dy < 1.e-5 && dz < 1.e-5);
0305 if(isSamePoint)
0306 nDaughtersAtPoint[iPoint].push_back(iMCDaughter);
0307
0308 isNewDecayPoint &= !isSamePoint;
0309 }
0310
0311 if(isNewDecayPoint)
0312 {
0313 xDaughter.push_back(vMCTracks[vMCParticles[iMC].GetDaughterIds()[iMCDaughter]].X());
0314 yDaughter.push_back(vMCTracks[vMCParticles[iMC].GetDaughterIds()[iMCDaughter]].Y());
0315 zDaughter.push_back(vMCTracks[vMCParticles[iMC].GetDaughterIds()[iMCDaughter]].Z());
0316 vector<int> newPointIndex;
0317 newPointIndex.push_back(iMCDaughter);
0318 nDaughtersAtPoint.push_back(newPointIndex);
0319 }
0320 }
0321
0322 for(unsigned int iPoint = 0; iPoint<nDaughtersAtPoint.size(); iPoint++)
0323 {
0324 if(nDaughtersAtPoint[iPoint].size() == 2)
0325 {
0326 for(unsigned int iDaughter=0; iDaughter<nDaughtersAtPoint[iPoint].size(); iDaughter++)
0327 {
0328 int iMCDaughter = nDaughtersAtPoint[iPoint][iDaughter];
0329 if(abs(vMCParticles[vMCParticles[iMC].GetDaughterIds()[iMCDaughter]].GetPDG()) == mmChargedDaughterPDG[iPDG])
0330 {
0331 isDaughter[0] = 1;
0332 chargedDaughterId = vMCParticles[iMC].GetDaughterIds()[iMCDaughter];
0333 }
0334 if(abs(vMCParticles[vMCParticles[iMC].GetDaughterIds()[iMCDaughter]].GetPDG()) == mmNeutralDaughterPDG[iPDG])
0335 {
0336 isDaughter[1] = 1;
0337 neutralDaughterId = vMCParticles[iMC].GetDaughterIds()[iMCDaughter];
0338 }
0339 }
0340
0341 if(isDaughter[0] && isDaughter[1])
0342 {
0343 int signPDG = vMCParticles[iMC].GetPDG()/abs(vMCParticles[iMC].GetPDG());
0344 newPDG = signPDG * newMotherPDG[iPDG];
0345 neutralPDG = signPDG * newNeutralPDG[iPDG];
0346 }
0347 }
0348 }
0349 }
0350 }
0351
0352 if(newPDG != 0)
0353 {
0354 KFMCParticle motherPart = vMCParticles[iMC];
0355 KFMCTrack motherTrack = vMCTracks[motherPart.GetMCTrackID()];
0356 motherTrack.SetPDG(newPDG);
0357 motherTrack.SetNotReconstructed();
0358 int newMotherIndex = vMCTracks.size();
0359 motherPart.SetPDG(newPDG);
0360 motherPart.SetMCTrackID(newMotherIndex);
0361
0362 int neutrinoIndex = vMCTracks.size()+1;
0363 fNeutralIndex[iMC] = neutrinoIndex;
0364
0365 KFMCTrack neutralTrack = vMCTracks[neutralDaughterId];
0366 neutralTrack.SetMotherId(newMotherIndex);
0367 neutralTrack.SetPDG(neutralPDG);
0368
0369 motherPart.CleanDaughters();
0370 motherPart.AddDaughter(chargedDaughterId);
0371 motherPart.AddDaughter(neutrinoIndex);
0372 motherPart.SetInitialParticleId(iMC);
0373 vMCTracks.push_back(motherTrack);
0374 vMCParticles.push_back(motherPart);
0375 fNeutralIndex.push_back(-1);
0376
0377 KFMCParticle neutralPart;
0378 neutralPart.SetMCTrackID(neutrinoIndex);
0379 neutralPart.SetMotherId(newMotherIndex);
0380 neutralPart.SetPDG(neutralPDG);
0381 neutralPart.AddDaughter(iMC);
0382 neutralPart.AddDaughter(chargedDaughterId);
0383 vMCTracks.push_back(neutralTrack);
0384 vMCParticles.push_back(neutralPart);
0385 fNeutralIndex.push_back(-1);
0386
0387 vMCParticles[iMC].SetAsReconstructable(4);
0388 vMCParticles[chargedDaughterId].SetAsReconstructable(4);
0389 }
0390 }
0391 }
0392
0393
0394 for(unsigned int iMC=0; iMC < vMCParticles.size(); iMC++)
0395 {
0396 KFMCParticle &part = vMCParticles[iMC];
0397
0398
0399 {
0400
0401 vector<int> newDaughters;
0402 for(unsigned int iD=0; iD<part.GetDaughterIds().size(); iD++)
0403 {
0404 KFMCParticle &d = vMCParticles[part.GetDaughterIds()[iD]];
0405 if( abs(d.GetPDG())==3224 ||
0406 abs(d.GetPDG())==3114 ||
0407 abs(d.GetPDG())==113 ||
0408 abs(d.GetPDG())==313 ||
0409 abs(d.GetPDG())==323 ||
0410 abs(d.GetPDG())==2224 ||
0411 abs(d.GetPDG())==2214 ||
0412 abs(d.GetPDG())==2114 ||
0413 abs(d.GetPDG())==1114
0414 )
0415 {
0416 for(unsigned int iDaughter=0; iDaughter<d.GetDaughterIds().size(); iDaughter++)
0417 {
0418 newDaughters.push_back(d.GetDaughterIds()[iDaughter]);
0419 vMCParticles[d.GetDaughterIds()[iDaughter]].SetMotherId(iMC);
0420 }
0421 }
0422 else
0423
0424 newDaughters.push_back(part.GetDaughterIds()[iD]);
0425 }
0426 part.CleanDaughters();
0427 for(unsigned int iDaughter=0; iDaughter<newDaughters.size(); iDaughter++)
0428 part.AddDaughter(newDaughters[iDaughter]);
0429
0430
0431 int indexPDG = fParteff.GetParticleIndex(part.GetPDG());
0432 for(int iPDG=indexPDG; iPDG<indexPDG+10; iPDG++)
0433 {
0434 const int nDaughters = part.GetDaughterIds().size();
0435
0436 if(int(fParteff.partDaughterPdg[iPDG].size()) != nDaughters)
0437 continue;
0438
0439 vector<bool> isDaughterFound(nDaughters);
0440 vector<bool> isDaughterUsed(nDaughters);
0441 for(int iDMC=0; iDMC<nDaughters; iDMC++)
0442 {
0443 isDaughterFound[iDMC] = 0;
0444 isDaughterUsed[iDMC] = 0;
0445 }
0446
0447 bool isCorrectPDG = 1;
0448 for(int iDMC=0; iDMC<nDaughters; iDMC++)
0449 for(int iD=0; iD<nDaughters; iD++)
0450 {
0451 if(isDaughterUsed[iD]) continue;
0452 if(vMCParticles[part.GetDaughterIds()[iD]].GetPDG() == fParteff.partDaughterPdg[iPDG][iDMC])
0453 {
0454 isDaughterUsed[iD] = 1;
0455 isDaughterFound[iDMC] = 1;
0456 break;
0457 }
0458 }
0459
0460 for(int iDMC=0; iDMC<nDaughters; iDMC++)
0461 isCorrectPDG &= isDaughterFound[iDMC];
0462
0463 if(isCorrectPDG)
0464 {
0465 part.SetPDG(fParteff.partPDG[iPDG]);
0466 break;
0467 }
0468 }
0469 }
0470 }
0471 }
0472
0473 void KFTopoPerformance::FindReconstructableMCParticles()
0474 {
0475
0476 const unsigned int nMCParticles = vMCParticles.size();
0477
0478 for ( unsigned int iP = 0; iP < nMCParticles; iP++ ) {
0479 KFMCParticle &part = vMCParticles[iP];
0480 CheckMCParticleIsReconstructable(part);
0481 }
0482 }
0483
0484 void KFTopoPerformance::CheckMCParticleIsReconstructable(KFMCParticle &part)
0485 {
0486
0487 if ( part.IsReconstructable(0) ) return;
0488 if ( vMCTracks[part.GetMCTrackID()].IsOutOfDetector() ) return;
0489
0490 if( abs(part.GetPDG()) == 211 ||
0491 abs(part.GetPDG()) == 2212 ||
0492 abs(part.GetPDG()) == 321 ||
0493 abs(part.GetPDG()) == 13 ||
0494 abs(part.GetPDG()) == 3112 ||
0495 abs(part.GetPDG()) == 3222 ||
0496 abs(part.GetPDG()) == 3312 ||
0497 abs(part.GetPDG()) == 3334 )
0498 {
0499 int iMCTrack = part.GetMCTrackID();
0500 KFMCTrack &mcTrack = vMCTracks[iMCTrack];
0501
0502
0503 if(mcTrack.IsReconstructed())
0504 part.SetAsReconstructable(3);
0505 }
0506
0507 if ( abs(part.GetPDG()) == 211 ||
0508 abs(part.GetPDG()) == 2212 ||
0509 abs(part.GetPDG()) == 321 ||
0510 abs(part.GetPDG()) == 11 ||
0511 abs(part.GetPDG()) == 13 ||
0512 abs(part.GetPDG()) == 1000010020 ||
0513 abs(part.GetPDG()) == 1000010030 ||
0514 abs(part.GetPDG()) == 1000020030 ||
0515 abs(part.GetPDG()) == 1000020040 ||
0516 ( (part.GetPDG() == 22) && (vMCTracks[part.GetMCTrackID()].IsReconstructed()) ) )
0517 {
0518 int iMCTrack = part.GetMCTrackID();
0519 KFMCTrack &mcTrack = vMCTracks[iMCTrack];
0520
0521 part.SetAsReconstructable(0);
0522
0523 if(mcTrack.NMCPoints() >= 15)
0524 part.SetAsReconstructable(1);
0525
0526
0527
0528 if(mcTrack.IsReconstructed())
0529 part.SetAsReconstructable(2);
0530 }
0531
0532 else
0533 {
0534
0535
0536 if(part.NDaughters() >= 2)
0537 {
0538 bool isPositiveDaughter[5] = {0,0,0,0,0};
0539 bool isNegativeDaughter[5] = {0,0,0,0,0};
0540
0541 int nRecoDaughters[5] = {0,0,0,0,0};
0542
0543 for(int iD=0; iD < part.NDaughters(); iD++)
0544 {
0545 KFMCParticle &daughter = vMCParticles[part.GetDaughterIds()[iD]];
0546 CheckMCParticleIsReconstructable(daughter);
0547
0548 TParticlePDG* particlePDG = TDatabasePDG::Instance()->GetParticle(daughter.GetPDG());
0549 Double_t charge = (particlePDG) ? particlePDG->Charge()/3 : 0;
0550
0551 for(int iEff=0; iEff<5; iEff++)
0552 {
0553 if(charge > 0)
0554 isPositiveDaughter[iEff] |= daughter.IsReconstructable(iEff);
0555 else
0556 isNegativeDaughter[iEff] |= daughter.IsReconstructable(iEff);
0557
0558 if(daughter.IsReconstructable(iEff))
0559 nRecoDaughters[iEff]++;
0560 }
0561 }
0562
0563
0564
0565
0566 for(int iEff=0; iEff<3; iEff++)
0567 if(nRecoDaughters[iEff] > 1)
0568 part.SetAsReconstructableV0(iEff);
0569 }
0570
0571 for(int iPart=0; iPart<fParteff.nParticles; iPart++)
0572 {
0573 if(part.GetPDG() == fParteff.partPDG[iPart])
0574 {
0575 const unsigned int nDaughters = fParteff.partDaughterPdg[iPart].size();
0576 if( part.GetDaughterIds().size() != nDaughters ) return;
0577 vector<int> pdg(nDaughters);
0578
0579 for(unsigned int iD=0; iD<nDaughters; iD++)
0580 pdg[iD] = vMCParticles[part.GetDaughterIds()[iD]].GetPDG();
0581
0582 vector<bool> isDaughterFound(nDaughters);
0583 for(unsigned int iDMC=0; iDMC<nDaughters; iDMC++)
0584 isDaughterFound[iDMC] = 0;
0585
0586 bool isReco = 1;
0587 for(unsigned int iDMC=0; iDMC<nDaughters; iDMC++)
0588 for(unsigned int iD=0; iD<nDaughters; iD++)
0589 if(pdg[iD] == fParteff.partDaughterPdg[iPart][iDMC]) isDaughterFound[iDMC] = 1;
0590
0591 for(unsigned int iDMC=0; iDMC<nDaughters; iDMC++)
0592 isReco = isReco && isDaughterFound[iDMC];
0593
0594 if(!isReco) return;
0595 }
0596 }
0597
0598 const vector<int>& dIds = part.GetDaughterIds();
0599 const unsigned int nD = dIds.size();
0600 if(nD == 0) return;
0601
0602 bool reco1 = 1;
0603 bool reco2 = 1;
0604 bool reco3 = 1;
0605 bool reco4 = 1;
0606 bool reco5 = 1;
0607
0608 for ( unsigned int iD = 0; iD < nD && (reco1 || reco2 || reco3 || reco4 || reco5); iD++ ) {
0609 KFMCParticle &dp = vMCParticles[dIds[iD]];
0610 CheckMCParticleIsReconstructable(dp);
0611 reco1 &= dp.IsReconstructable(0);
0612 reco2 &= dp.IsReconstructable(1);
0613 reco3 &= dp.IsReconstructable(2);
0614 reco4 &= dp.IsReconstructable(3);
0615 reco5 &= dp.IsReconstructable(4);
0616 }
0617
0618 if (reco1) part.SetAsReconstructable(0);
0619 if (reco2) part.SetAsReconstructable(1);
0620 if (reco3) part.SetAsReconstructable(2);
0621 int iParticle = fParteff.GetParticleIndex(part.GetPDG());
0622 if (reco4 && iParticle>=KFPartEfficiencies::fFirstMissingMassParticleIndex &&
0623 iParticle<=KFPartEfficiencies::fLastMissingMassParticleIndex ) part.SetAsReconstructable(3);
0624 if (reco5 && iParticle>=KFPartEfficiencies::fFirstMissingMassParticleIndex &&
0625 iParticle<=KFPartEfficiencies::fLastMissingMassParticleIndex ) part.SetAsReconstructable(4);
0626 }
0627 }
0628
0629
0630 void KFTopoPerformance::FindReconstructableMCVertices()
0631 {
0632
0633 const unsigned int nMCVertices = fPrimVertices.size();
0634
0635 for ( unsigned int iV = 0; iV < nMCVertices; iV++ ) {
0636 KFMCVertex &vert = fPrimVertices[iV];
0637
0638 int nReconstructableDaughters = 0;
0639 int nMCReconstructableDaughters = 0;
0640
0641 for(int iP=0; iP<vert.NDaughterTracks(); iP++)
0642 {
0643 int idDaughter = vert.DaughterTrack(iP);
0644 KFMCParticle &part = vMCParticles[idDaughter];
0645
0646 if(part.IsReconstructable(2)) nReconstructableDaughters++;
0647 if(part.IsReconstructable(1)) nMCReconstructableDaughters++;
0648 }
0649
0650 if(nReconstructableDaughters >= 2) vert.SetReconstructable();
0651 else vert.SetUnReconstructable();
0652
0653 if(nMCReconstructableDaughters >= 2) vert.SetMCReconstructable();
0654 else vert.SetMCUnReconstructable();
0655 }
0656 }
0657
0658 void KFTopoPerformance::MatchParticles()
0659 {
0660
0661 MCtoRParticleId.clear();
0662 RtoMCParticleId.clear();
0663 MCtoRParticleId.resize(vMCParticles.size());
0664 RtoMCParticleId.resize(fTopoReconstructor->GetParticles().size() );
0665
0666
0667 for( unsigned int iRP = 0; iRP < fTopoReconstructor->GetParticles().size(); iRP++ )
0668 {
0669 const KFParticle &rPart = fTopoReconstructor->GetParticles()[iRP];
0670
0671 if (rPart.NDaughters() != 1) continue;
0672
0673 const int rTrackId = rPart.DaughterIds()[0];
0674 const int mcTrackId = fTrackMatch[rTrackId];
0675
0676 if(mcTrackId < 0) continue;
0677
0678 KFMCParticle &mPart = vMCParticles[mcTrackId];
0679 if( mPart.GetPDG() == rPart.GetPDG() )
0680 {
0681 MCtoRParticleId[mcTrackId].ids.push_back(iRP);
0682 RtoMCParticleId[iRP].ids.push_back(mcTrackId);
0683 }
0684 else {
0685 MCtoRParticleId[mcTrackId].idsMI.push_back(iRP);
0686 RtoMCParticleId[iRP].idsMI.push_back(mcTrackId);
0687 }
0688 }
0689
0690
0691 for( unsigned int iRP = 0; iRP < fTopoReconstructor->GetParticles().size(); iRP++ ) {
0692 const KFParticle &rPart = fTopoReconstructor->GetParticles()[iRP];
0693 const unsigned int NRDaughters = rPart.NDaughters();
0694
0695 if (NRDaughters < 2) continue;
0696
0697 bool isMissingMass = ((abs(rPart.GetPDG()) == 7000211)||(abs(rPart.GetPDG()) == 7000321)||(abs(rPart.GetPDG()) == 7003112) || (abs(rPart.GetPDG()) == 7003222)|| (abs(rPart.GetPDG()) == 7003312)|| (abs(rPart.GetPDG()) == 7003334)|| (abs(rPart.GetPDG()) == 9000321)|| (abs(rPart.GetPDG()) == 8003334)||(abs(rPart.GetPDG()) == 8003222));
0698
0699
0700 if ( (abs(rPart.GetPDG()) == 7000014 ) || (abs(rPart.GetPDG()) == 8000014 ) || (abs(rPart.GetPDG()) == 7002112 ) ||
0701 (abs(rPart.GetPDG()) == 8002112 ) || (abs(rPart.GetPDG()) == 7003122 ) || (abs(rPart.GetPDG()) == 7003322 ) ||
0702 (abs(rPart.GetPDG()) == 9000111 ) || (abs(rPart.GetPDG()) == 8003122 ) || (abs(rPart.GetPDG()) == 8000111 ) )
0703 {
0704
0705
0706 int mcNeutralDaughterId = -1;
0707 const int recoMotherId = rPart.DaughterIds()[0];
0708 if ( !RtoMCParticleId[recoMotherId].IsMatched() ) continue;
0709
0710 const int mcMotherId = RtoMCParticleId[recoMotherId].GetBestMatch();
0711
0712 const int recoChargedDaughterId = rPart.DaughterIds()[1];
0713 if ( !RtoMCParticleId[recoChargedDaughterId].IsMatched() ) continue;
0714
0715 const int mcChargedDaughterId = RtoMCParticleId[recoChargedDaughterId].GetBestMatch();
0716 const KFMCParticle& chargedDaughter = vMCParticles[mcChargedDaughterId];
0717
0718 if(chargedDaughter.GetMotherId() != mcMotherId) continue;
0719 const KFMCParticle& mother = vMCParticles[mcMotherId];
0720
0721 if(fNeutralIndex[mcMotherId] > -1)
0722 mcNeutralDaughterId = fNeutralIndex[mcMotherId];
0723
0724 if(mcNeutralDaughterId > -1)
0725 {
0726 KFMCParticle &neutralDaughter = vMCParticles[mcNeutralDaughterId];
0727
0728 int iParticle = fParteff.GetParticleIndex(rPart.GetPDG());
0729
0730 bool allCorrectDaughters = mother.GetPDG() == fParteff.partDaughterPdg[iParticle][0] &&
0731 chargedDaughter.GetPDG() == fParteff.partDaughterPdg[iParticle][1];
0732
0733 if( neutralDaughter.GetPDG() == rPart.GetPDG() &&
0734 neutralDaughter.NDaughters() == rPart.NDaughters() &&
0735 allCorrectDaughters) {
0736 MCtoRParticleId[mcNeutralDaughterId].ids.push_back(iRP);
0737 RtoMCParticleId[iRP].ids.push_back(mcNeutralDaughterId);
0738 }
0739 else {
0740 MCtoRParticleId[mcNeutralDaughterId].idsMI.push_back(iRP);
0741 RtoMCParticleId[iRP].idsMI.push_back(mcNeutralDaughterId);
0742 }
0743 }
0744 }
0745
0746
0747
0748
0749 else
0750 {
0751 unsigned int iD = 0;
0752 vector<int> mcDaughterIds;
0753 int mmId = -2;
0754 {
0755 const int rdId = rPart.DaughterIds()[iD];
0756 if ( !RtoMCParticleId[rdId].IsMatched() ) continue;
0757 const int mdId = RtoMCParticleId[rdId].GetBestMatch();
0758 mcDaughterIds.push_back(mdId);
0759 mmId = vMCParticles[mdId].GetMotherId();
0760 }
0761
0762 iD++;
0763 for ( ; iD < NRDaughters; iD++ ) {
0764 const int rdId = rPart.DaughterIds()[iD];
0765 if ( !RtoMCParticleId[rdId].IsMatched() ) break;
0766 const int mdId = RtoMCParticleId[rdId].GetBestMatch();
0767 mcDaughterIds.push_back(mdId);
0768
0769 if(isMissingMass)
0770 {
0771 const KFMCParticle &neutralDaughter = vMCParticles[mdId];
0772 if(mmId != vMCParticles[neutralDaughter.GetMotherId()].InitialParticleId()) break;
0773 mmId = neutralDaughter.GetMotherId();
0774 }
0775
0776 if( !(isMissingMass) && (vMCParticles[mdId].GetMotherId() != mmId) ) break;
0777 }
0778
0779 int nClones = 0;
0780 sort(mcDaughterIds.begin(), mcDaughterIds.end());
0781 for(unsigned int ie=1; ie<mcDaughterIds.size(); ie++)
0782 {
0783 if(mcDaughterIds[ie] == mcDaughterIds[ie-1])
0784 nClones++;
0785 }
0786
0787 if(nClones > 0) continue;
0788
0789 if ( iD == NRDaughters && mmId > -1 ) {
0790 KFMCParticle &mmPart = vMCParticles[mmId];
0791
0792 if( mmPart.GetPDG() == rPart.GetPDG() &&
0793 mmPart.NDaughters() == rPart.NDaughters() ) {
0794 MCtoRParticleId[mmId].ids.push_back(iRP);
0795 RtoMCParticleId[iRP].ids.push_back(mmId);
0796 }
0797 else {
0798 MCtoRParticleId[mmId].idsMI.push_back(iRP);
0799 RtoMCParticleId[iRP].idsMI.push_back(mmId);
0800 }
0801 }
0802 }
0803 }
0804 }
0805
0806 void KFTopoPerformance::MatchPV()
0807 {
0808
0809 MCtoRPVId.clear();
0810 RtoMCPVId.clear();
0811 MCtoRPVId.resize(fPrimVertices.size());
0812 RtoMCPVId.resize(fTopoReconstructor->NPrimaryVertices() );
0813
0814 fPVPurity.clear();
0815 fPVPurity.resize(fTopoReconstructor->NPrimaryVertices(), 0.);
0816 fNCorrectPVTracks.clear();
0817 fNCorrectPVTracks.resize(fTopoReconstructor->NPrimaryVertices(), 0);
0818
0819 for(int iE = 0; iE<4; iE++)
0820 {
0821 fPVTracksRate[iE].clear();
0822 fPVTracksRate[iE].resize(fTopoReconstructor->NPrimaryVertices(),0);
0823 }
0824
0825 for( unsigned int iMCPV=0; iMCPV<fPrimVertices.size(); iMCPV++)
0826 {
0827 KFMCVertex &mcPV = fPrimVertices[iMCPV];
0828 int nReconstructedDaughters = 0;
0829 for(int iD=0; iD<mcPV.NDaughterTracks(); iD++)
0830 if(MCtoRParticleId[ mcPV.DaughterTrack(iD) ].IsMatched())
0831 nReconstructedDaughters++;
0832
0833 mcPV.SetNReconstructedDaughters(nReconstructedDaughters);
0834 }
0835
0836 for( int iPV = 0; iPV < fTopoReconstructor->NPrimaryVertices(); iPV++ ) {
0837
0838 vector<int> &tracks = fTopoReconstructor->GetPVTrackIndexArray(iPV);
0839
0840 int nPVTracks = tracks.size()>0 ? tracks.size() : -1;
0841
0842 vector<short int> nTracksFromMCPV(fPrimVertices.size() + vMCParticles.size(), 0);
0843 vector< vector<int> > mcIDs(fPrimVertices.size() + vMCParticles.size());
0844
0845 int nGhostTracks = 0;
0846 int nTriggerTracks = 0;
0847 int nPileupTracks = 0;
0848 int nBGTracks = 0;
0849
0850 for(int iRP=0; iRP < nPVTracks; iRP++)
0851 {
0852 const int rTrackId = tracks[iRP];
0853 if ( !RtoMCParticleId[rTrackId].IsMatched() )
0854 {
0855 nGhostTracks++;
0856 continue;
0857 }
0858
0859 int iMCPart = RtoMCParticleId[rTrackId].GetBestMatch();
0860 KFMCParticle &mcPart = vMCParticles[iMCPart];
0861 int iMCTrack = mcPart.GetMCTrackID();
0862 KFMCTrack &mcTrack = vMCTracks[iMCTrack];
0863
0864 int motherId = mcTrack.MotherId();
0865
0866 if(motherId < 0)
0867 {
0868 if(motherId == -1)
0869 nTriggerTracks++;
0870 if(motherId < -1)
0871 nPileupTracks++;
0872
0873 int iMCPV = fMCTrackToMCPVMatch[iMCTrack];
0874 if(iMCPV < 0)
0875 {
0876 std::cout << "Error!!! iMCPV < 0" << std::endl;
0877 continue;
0878 }
0879
0880 nTracksFromMCPV[iMCPV]++;
0881 mcIDs[iMCPV].push_back(iMCTrack);
0882 }
0883 else
0884 {
0885 if(motherId >-1)
0886 {
0887 nBGTracks++;
0888
0889 int iMCPV = motherId + fPrimVertices.size();
0890
0891 nTracksFromMCPV[iMCPV]++;
0892 mcIDs[iMCPV].push_back(iMCTrack);
0893 }
0894 }
0895 }
0896
0897
0898
0899 for(unsigned int iMCPV=0; iMCPV<nTracksFromMCPV.size(); iMCPV++)
0900 {
0901 int nClones = 0;
0902 sort(mcIDs[iMCPV].begin(), mcIDs[iMCPV].end());
0903 for(unsigned int ie=1; ie<mcIDs[iMCPV].size(); ie++)
0904 {
0905 if(mcIDs[iMCPV][ie] == mcIDs[iMCPV][ie-1])
0906 nClones++;
0907 }
0908 nTracksFromMCPV[iMCPV] = nTracksFromMCPV[iMCPV] - nClones;
0909 nPVTracks -= nClones;
0910 }
0911
0912
0913 fPVTracksRate[0][iPV] = double(nGhostTracks)/double(nPVTracks);
0914 fPVTracksRate[1][iPV] = double(nTriggerTracks)/double(nPVTracks);
0915 fPVTracksRate[2][iPV] = double(nPileupTracks)/double(nPVTracks);
0916 fPVTracksRate[3][iPV] = double(nBGTracks)/double(nPVTracks);
0917
0918 int iBestMCPV=-1;
0919 int nTracksBestMCPV = 1;
0920 for(unsigned int iMCPV=0; iMCPV<nTracksFromMCPV.size(); iMCPV++ )
0921 {
0922 if(nTracksFromMCPV[iMCPV] > nTracksBestMCPV )
0923 {
0924 nTracksBestMCPV = nTracksFromMCPV[iMCPV];
0925 iBestMCPV = iMCPV;
0926 }
0927 }
0928
0929 if( (iBestMCPV > -1) && (iBestMCPV<int(fPrimVertices.size())) )
0930 {
0931 fNCorrectPVTracks[iPV] = nTracksFromMCPV[iBestMCPV];
0932 }
0933 else
0934 fNCorrectPVTracks[iPV] = 0;
0935
0936 double purity = double(nTracksBestMCPV)/double(nPVTracks);
0937
0938 fPVPurity[iPV] = purity;
0939
0940
0941 if(iBestMCPV < 0) continue;
0942
0943 if(iBestMCPV < int(fPrimVertices.size()))
0944 {
0945 fPrimVertices[iBestMCPV].SetReconstructed();
0946
0947 MCtoRPVId[iBestMCPV].ids.push_back(iPV);
0948 RtoMCPVId[iPV].ids.push_back(iBestMCPV);
0949 }
0950 else
0951 {
0952 RtoMCPVId[iPV].idsMI.push_back(iBestMCPV);
0953 }
0954 }
0955 }
0956
0957 void KFTopoPerformance::MatchTracks()
0958 {
0959
0960 #ifdef KFPWITHTRACKER
0961 for(int iTr=0; iTr<vMCTracks.size(); iTr++)
0962 {
0963 if( (AliHLTTPCCAPerformance::Instance().GetSubPerformance("Global Performance")->GetMCData())[iTr].IsReconstructed() )
0964 vMCTracks[iTr].SetReconstructed();
0965 }
0966 fTrackMatch.resize(AliHLTTPCCAPerformance::Instance().GetSubPerformance("Global Performance")->GetRecoData().size());
0967 for(int iTr=0; iTr<fTrackMatch.size(); iTr++)
0968 {
0969 const AliHLTTPCCAPerformanceRecoTrackData& matchInfo = (AliHLTTPCCAPerformance::Instance().GetSubPerformance("Global Performance")->GetRecoData())[iTr];
0970 if( matchInfo.IsGhost(PParameters::MinTrackPurity) || matchInfo.GetMCTrackId()<0 )
0971 fTrackMatch[iTr] = -1;
0972 else
0973 fTrackMatch[iTr] = matchInfo.GetMCTrackId();
0974 }
0975 #endif
0976
0977 GetMCParticles();
0978 FindReconstructableMCParticles();
0979 MatchParticles();
0980 CalculateEfficiency();
0981
0982 FindReconstructableMCVertices();
0983 MatchPV();
0984 CalculatePVEfficiency();
0985 }
0986
0987 void KFTopoPerformance::CalculateEfficiency()
0988 {
0989
0990 KFPartEfficiencies partEff;
0991
0992 const int NRP = fTopoReconstructor->GetParticles().size();
0993 for ( int iP = 0; iP < NRP; ++iP ) {
0994
0995 const KFParticle &part = fTopoReconstructor->GetParticles()[iP];
0996 const int pdg = part.GetPDG();
0997
0998 const bool isBG = RtoMCParticleId[iP].idsMI.size() != 0;
0999 const bool isGhost = !RtoMCParticleId[iP].IsMatched();
1000
1001 for(int iPart=0; iPart<fParteff.nParticles; iPart++)
1002 if ( pdg == fParteff.partPDG[iPart] )
1003 partEff.IncReco(isGhost, isBG, fParteff.partName[iPart].data());
1004
1005
1006 if(abs(pdg) == 310
1007
1008
1009 )
1010 {
1011 partEff.IncReco(isGhost, 0, fParteff.partName[fParteff.nParticles - 1].data());
1012 }
1013 }
1014
1015 const int NMP = vMCParticles.size();
1016 for ( int iP = 0; iP < NMP; ++iP ) {
1017 const KFMCParticle &part = vMCParticles[iP];
1018 const int pdg = part.GetPDG();
1019 const int mId = part.GetMotherId();
1020
1021 vector<bool> isReco;
1022 vector<int> nClones;
1023
1024 vector<int> iParticle;
1025 iParticle.push_back(fParteff.GetParticleIndex(pdg));
1026 vector< vector<bool> > isReconstructable;
1027 vector<bool> isRecPart;
1028
1029 const std::map<int,bool>& decays = fTopoReconstructor->GetKFParticleFinder()->GetReconstructionList();
1030 if(!(decays.empty()) && (iParticle[0] < fParteff.fFirstStableParticleIndex || iParticle[0] > fParteff.fLastStableParticleIndex))
1031 if(decays.find(pdg) == decays.end()) continue;
1032
1033 if( fParteff.GetParticleIndex(pdg)>=KFPartEfficiencies::fFirstMissingMassParticleIndex &&
1034 fParteff.GetParticleIndex(pdg)<=KFPartEfficiencies::fLastMissingMassParticleIndex )
1035 {
1036 isRecPart.push_back(part.IsReconstructable(4));
1037 isRecPart.push_back(part.IsReconstructable(1));
1038 isRecPart.push_back(part.IsReconstructable(3));
1039 }
1040 else
1041 for(int iEff = 0; iEff < 3; iEff++)
1042 isRecPart.push_back(part.IsReconstructable(iEff));
1043
1044 isReconstructable.push_back(isRecPart);
1045 isReco.push_back( MCtoRParticleId[iP].ids.size() != 0 );
1046 nClones.push_back( MCtoRParticleId[iP].ids.size() - 1 );
1047
1048 if(decays.empty() && (part.IsReconstructableV0(0) || part.IsReconstructableV0(1) || part.IsReconstructableV0(2)) )
1049 {
1050 iParticle.push_back(fParteff.nParticles - 1);
1051 vector<bool> isRecV0;
1052 for(int iEff = 0; iEff < 3; iEff++)
1053 isRecV0.push_back(part.IsReconstructableV0(iEff));
1054 isReconstructable.push_back(isRecV0);
1055 isReco.push_back( (MCtoRParticleId[iP].ids.size() != 0) || (MCtoRParticleId[iP].idsMI.size() != 0) );
1056
1057 int nClonesV0 = MCtoRParticleId[iP].ids.size() + MCtoRParticleId[iP].idsMI.size() - 1;
1058 nClones.push_back( nClonesV0 );
1059 }
1060
1061 {
1062 for(unsigned int iPType=0; iPType<iParticle.size(); iPType++)
1063 {
1064 int iPart = iParticle[iPType];
1065 if(iPart<0) continue;
1066
1067 partEff.Inc(isReco[iPType], nClones[iPType], isReconstructable[iPType][0], isReconstructable[iPType][1], isReconstructable[iPType][2], fParteff.partName[iPart].data());
1068 if ( mId == -1 )
1069 partEff.Inc(isReco[iPType], nClones[iPType], isReconstructable[iPType][0], isReconstructable[iPType][1], isReconstructable[iPType][2], (fParteff.partName[iPart]+"_prim").data());
1070 else
1071 partEff.Inc(isReco[iPType], nClones[iPType], isReconstructable[iPType][0], isReconstructable[iPType][1], isReconstructable[iPType][2], (fParteff.partName[iPart]+"_sec").data());
1072
1073 for(int iEff=0; iEff<3; iEff++)
1074 {
1075 if(!isReconstructable[iPType][iEff]) continue;
1076
1077 int iMCTrack = part.GetMCTrackID();
1078 KFMCTrack &mcTrack = vMCTracks[iMCTrack];
1079
1080 Double_t massMC = fParteff.partMass[iPart];
1081 Double_t E = sqrt(mcTrack.P()*mcTrack.P() + massMC*massMC);
1082 Double_t Y = 0.5*log((E + mcTrack.Pz())/(E - mcTrack.Pz()));
1083 Double_t Z = mcTrack.Z();
1084 Double_t R = -1, L=-1;
1085 Double_t Mt_mc = sqrt(mcTrack.Pt()*mcTrack.Pt()+massMC*massMC)-massMC;
1086 Double_t cT = -1.e10;
1087 Double_t decayLength = -1.e10;
1088
1089 if(part.NDaughters() > 0)
1090 {
1091 int mcDaughterId = part.GetDaughterIds()[0];
1092 KFMCTrack &mcDaughter = vMCTracks[mcDaughterId];
1093 R = sqrt(mcDaughter.X()*mcDaughter.X() + mcDaughter.Y()*mcDaughter.Y());
1094 L = sqrt(mcDaughter.X()*mcDaughter.X() + mcDaughter.Y()*mcDaughter.Y());
1095 Z = mcDaughter.Z();
1096
1097 if(mcTrack.MotherId() < 0)
1098 {
1099 KFParticle motherKFParticle;
1100 float decayPoint[3] = { mcDaughter.X(), mcDaughter.Y(), mcDaughter.Z() };
1101 for(int iP=0; iP<6; iP++)
1102 motherKFParticle.Parameter(iP) = mcTrack.Par()[iP];
1103
1104 float dsdr[6];
1105 double s = motherKFParticle.GetDStoPoint(decayPoint, dsdr);
1106 int jParticlePDG = fParteff.GetParticleIndex(mcTrack.PDG());
1107 Double_t massMC = (jParticlePDG>=0) ? fParteff.partMass[jParticlePDG] :0.13957;
1108
1109 cT = s*massMC;
1110 decayLength = s*mcTrack.P();
1111 }
1112 }
1113
1114 if(fStoreMCHistograms)
1115 {
1116 hPartEfficiency[iPart][iEff][0]->Fill( mcTrack.P(), isReco[iPType] );
1117 hPartEfficiency[iPart][iEff][1]->Fill( mcTrack.Pt(), isReco[iPType] );
1118 hPartEfficiency[iPart][iEff][2]->Fill( Y, isReco[iPType] );
1119 hPartEfficiency[iPart][iEff][3]->Fill( Z, isReco[iPType] );
1120 if(cT > -1.e10) hPartEfficiency[iPart][iEff][4]->Fill( cT, isReco[iPType] );
1121 if(decayLength > -1.e10) hPartEfficiency[iPart][iEff][5]->Fill( decayLength, isReco[iPType] );
1122 hPartEfficiency[iPart][iEff][3]->Fill( Z, isReco[iPType] );
1123 hPartEfficiency[iPart][iEff][6]->Fill( L, isReco[iPType] );
1124 hPartEfficiency[iPart][iEff][7]->Fill( R, isReco[iPType] );
1125 hPartEfficiency[iPart][iEff][8]->Fill( Mt_mc, isReco[iPType] );
1126
1127 hPartEfficiency2D[iPart][iEff][0]->Fill( Y, mcTrack.Pt(), isReco[iPType] );
1128 hPartEfficiency2D[iPart][iEff][1]->Fill( Y, Mt_mc, isReco[iPType] );
1129 }
1130 }
1131 }
1132 }
1133 }
1134
1135 fNEvents++;
1136
1137 fParteff += partEff;
1138
1139 partEff.CalcEff();
1140 fParteff.CalcEff();
1141
1142 if(fNEvents%fPrintEffFrequency == 0)
1143 {
1144 std::cout << " ---- KF Particle finder --- " << std::endl;
1145 std::cout << "ACCUMULATED STAT : " << fNEvents << " EVENTS " << std::endl << std::endl;
1146 fParteff.PrintEff();
1147 std::cout<<std::endl;
1148 }
1149 }
1150
1151 void KFTopoPerformance::CalculatePVEfficiency()
1152 {
1153
1154 KFPVEfficiencies pvEff;
1155 KFPVEfficiencies pvEffMCReconstructable;
1156 int nTracks = 0;
1157
1158 for( unsigned int iRP = 0; iRP < fTopoReconstructor->GetParticles().size(); iRP++ ) {
1159
1160 const KFParticle &rPart = fTopoReconstructor->GetParticles()[iRP];
1161
1162 if (rPart.NDaughters() != 1) continue;
1163
1164 nTracks++;
1165 }
1166
1167 const int NRecoPV = fTopoReconstructor->NPrimaryVertices();
1168 for ( int iP = 0; iP < NRecoPV; ++iP ) {
1169
1170 const bool isBG = RtoMCPVId[iP].idsMI.size() != 0;
1171 const bool isGhost = !RtoMCPVId[iP].IsMatched();
1172
1173 pvEff.IncReco(isGhost, isBG, "PV");
1174 pvEffMCReconstructable.IncReco(isGhost, isBG, "PV");
1175 }
1176
1177 const int NMCPV = fPrimVertices.size();
1178 for ( int iV = 0; iV < NMCPV; ++iV ) {
1179 const KFMCVertex &pvMC = fPrimVertices[iV];
1180 if ( pvMC.IsReconstructable() )
1181 {
1182 const bool isReco = pvMC.IsReconstructed();
1183 const int nClones = MCtoRPVId[iV].ids.size() - 1;
1184
1185
1186 pvEff.Inc(isReco, nClones, "PV");
1187 if ( pvMC.IsTriggerPV() )
1188 {
1189 pvEff.Inc(isReco, nClones, "PVtrigger");
1190 hPVefficiency[0][0]->Fill( pvMC.NDaughterTracks(), isReco );
1191 hPVefficiency[0][1]->Fill( NMCPV, isReco );
1192 hPVefficiency[0][2]->Fill( vMCTracks.size(), isReco );
1193 hPVefficiency[0][3]->Fill( pvMC.NReconstructedDaughterTracks(), isReco );
1194 hPVefficiency[0][4]->Fill( NRecoPV, isReco );
1195 hPVefficiency[0][5]->Fill( nTracks, isReco );
1196 }
1197 else
1198 {
1199 pvEff.Inc(isReco, nClones, "PVpileup");
1200 hPVefficiency[1][0]->Fill( pvMC.NDaughterTracks(), isReco );
1201 hPVefficiency[1][1]->Fill( NMCPV, isReco );
1202 hPVefficiency[1][2]->Fill( vMCTracks.size(), isReco );
1203 hPVefficiency[1][3]->Fill( pvMC.NReconstructedDaughterTracks(), isReco );
1204 hPVefficiency[1][4]->Fill( NRecoPV, isReco );
1205 hPVefficiency[1][5]->Fill( nTracks, isReco );
1206 }
1207 }
1208 if ( pvMC.IsMCReconstructable() )
1209 {
1210 const bool isReco = pvMC.IsReconstructed();
1211 const int nClones = MCtoRPVId[iV].ids.size() - 1;
1212
1213
1214 pvEffMCReconstructable.Inc(isReco, nClones, "PV");
1215 if ( pvMC.IsTriggerPV() )
1216 {
1217 pvEffMCReconstructable.Inc(isReco, nClones, "PVtrigger");
1218 hPVefficiency[2][0]->Fill( pvMC.NDaughterTracks(), isReco );
1219 hPVefficiency[2][1]->Fill( NMCPV, isReco );
1220 hPVefficiency[2][2]->Fill( vMCTracks.size(), isReco );
1221 hPVefficiency[2][3]->Fill( pvMC.NReconstructedDaughterTracks(), isReco );
1222 hPVefficiency[2][4]->Fill( NRecoPV, isReco );
1223 hPVefficiency[2][5]->Fill( nTracks, isReco );
1224 }
1225 else
1226 {
1227 pvEffMCReconstructable.Inc(isReco, nClones, "PVpileup");
1228 hPVefficiency[3][0]->Fill( pvMC.NDaughterTracks(), isReco );
1229 hPVefficiency[3][1]->Fill( NMCPV, isReco );
1230 hPVefficiency[3][2]->Fill( vMCTracks.size(), isReco );
1231 hPVefficiency[3][3]->Fill( pvMC.NReconstructedDaughterTracks(), isReco );
1232 hPVefficiency[3][4]->Fill( NRecoPV, isReco );
1233 hPVefficiency[3][5]->Fill( nTracks, isReco );
1234 }
1235 }
1236 }
1237
1238 fPVeff += pvEff;
1239
1240 pvEff.CalcEff();
1241 fPVeff.CalcEff();
1242
1243 fPVeffMCReconstructable += pvEffMCReconstructable;
1244 pvEffMCReconstructable.CalcEff();
1245 fPVeffMCReconstructable.CalcEff();
1246
1247 if(fNEvents%fPrintEffFrequency == 0)
1248 {
1249 std::cout << " ---- KF PV finder --- " << std::endl;
1250 std::cout << "ACCUMULATED STAT : " << fNEvents << " EVENTS " << std::endl << std::endl;
1251 std::cout << "PV with at least 2 reconstructed tracks is reconstructable:" << std::endl;
1252 fPVeff.PrintEff();
1253 std::cout << std::endl;
1254 std::cout << "PV with at least 2 MC tracks with 15 MC points is reconstructable:" << std::endl;
1255 fPVeffMCReconstructable.PrintEff();
1256
1257 std::cout<<std::endl;
1258 }
1259 }
1260
1261 void KFTopoPerformance::FillParticleParameters(KFParticle& TempPart,
1262 int iParticle,
1263 int iP,
1264 int iPV,
1265 TH1F* histoParameters[nParametersSet][KFPartEfficiencies::nParticles][nHistoPartParam],
1266 TH2F* histoParameters2D[nParametersSet][KFPartEfficiencies::nParticles][nHistoPartParam2D],
1267 TH3F* histoParameters3D[1][KFPartEfficiencies::nParticles][nHistoPartParam3D],
1268 TH1F* histoFit[KFPartEfficiencies::nParticles][nFitQA],
1269 TH1F* histoFitDaughtersQA[KFPartEfficiencies::nParticles][nFitQA],
1270 TH1F* histoDSToParticleQA[KFPartEfficiencies::nParticles][nDSToParticleQA],
1271 vector<int>* multiplicities)
1272 {
1273
1274
1275 const std::map<int,bool>& decays = fTopoReconstructor->GetKFParticleFinder()->GetReconstructionList();
1276 if(!(decays.empty()) && (iParticle < fParteff.fFirstStableParticleIndex || iParticle > fParteff.fLastStableParticleIndex))
1277 if(decays.find(TempPart.GetPDG()) == decays.end()) return;
1278
1279 float M, M_t, ErrM;
1280 float dL, ErrdL;
1281 float cT, ErrcT;
1282 float P, ErrP;
1283 float Pt;
1284 float Rapidity;
1285 float Theta;
1286 float Phi;
1287 float X,Y,Z,R;
1288 float QtAlpha[2];
1289
1290 TempPart.GetMass(M,ErrM);
1291 TempPart.GetMomentum(P,ErrP);
1292 Pt = TempPart.GetPt();
1293 Rapidity = TempPart.GetRapidity();
1294
1295 KFParticle TempPartTopo = TempPart;
1296 TempPartTopo.SetProductionVertex(fTopoReconstructor->GetPrimVertex(0));
1297 TempPartTopo.GetDecayLength(dL,ErrdL);
1298 TempPartTopo.GetLifeTime(cT,ErrcT);
1299
1300 float chi2 = TempPart.GetChi2();
1301 Int_t ndf = TempPart.GetNDF();
1302 float prob = TMath::Prob(chi2, ndf);
1303 Theta = TempPart.GetTheta();
1304 Phi = TempPart.GetPhi();
1305 X = TempPart.GetX();
1306 Y = TempPart.GetY();
1307 Z = TempPart.GetZ();
1308 #ifdef CBM
1309 if(Z>=1. && iParticle>=54 && iParticle<=64) return;
1310 #endif
1311 R = sqrt(X*X+Y*Y);
1312 M_t = sqrt(Pt*Pt+fParteff.GetMass(iParticle)*fParteff.GetMass(iParticle))-fParteff.GetMass(iParticle);
1313
1314 KFParticleSIMD tempSIMDPart(TempPart);
1315 float_v l,dl;
1316 KFParticleSIMD pv(fTopoReconstructor->GetPrimVertex(iPV));
1317 tempSIMDPart.GetDistanceToVertexLine(pv, l, dl);
1318 #ifdef __ROOT__
1319 if( (l[0] > 0.2f || Pt < 0.f) && (abs( TempPart.GetPDG() ) == 4122 ||
1320 abs( TempPart.GetPDG() ) == 104122 ||
1321 abs( TempPart.GetPDG() ) == 204122 ||
1322 abs( TempPart.GetPDG() ) == 304122 ||
1323 abs( TempPart.GetPDG() ) == 404122 ||
1324 abs( TempPart.GetPDG() ) == 504122 ) ) return;
1325 if( (l[0] > 0.2f || Pt < 0.f) && (abs( TempPart.GetPDG() ) == 421 ||
1326 abs( TempPart.GetPDG() ) == 420 ||
1327 abs( TempPart.GetPDG() ) == 425 ||
1328 abs( TempPart.GetPDG() ) == 426 ||
1329 abs( TempPart.GetPDG() ) == 427 ||
1330 abs( TempPart.GetPDG() ) == 429) ) return;
1331 if( (l[0] > 0.4f || Pt < 0.f) && (abs( TempPart.GetPDG() ) == 411 ||
1332 abs( TempPart.GetPDG() ) == 100411 ||
1333 abs( TempPart.GetPDG() ) == 200411 ||
1334 abs( TempPart.GetPDG() ) == 300411) ) return;
1335 if( (l[0] > 0.2f || Pt < 0.f) && (abs( TempPart.GetPDG() ) == 431 ||
1336 abs( TempPart.GetPDG() ) == 100431 ||
1337 abs( TempPart.GetPDG() ) == 200431 ||
1338 abs( TempPart.GetPDG() ) == 300431 ||
1339 abs( TempPart.GetPDG() ) == 400431) ) return;
1340
1341
1342
1343
1344
1345
1346
1347
1348 if(Pt < 0.5f && (abs( TempPart.GetPDG() ) == 3000 ||
1349 abs( TempPart.GetPDG() ) == 3001) ) return;
1350 #endif
1351 float parameters[17] = {M, P, Pt, Rapidity, dL, cT, chi2/ndf, prob, Theta, Phi, X, Y, Z, R, l[0], l[0]/dl[0], M_t };
1352
1353
1354 for(int iParam=0; iParam<17; iParam++)
1355 histoParameters[0][iParticle][iParam]->Fill(parameters[iParam]);
1356
1357 if(multiplicities)
1358 multiplicities[0][iParticle]++;
1359
1360 histoParameters2D[0][iParticle][0]->Fill(Rapidity,Pt,1);
1361 histoParameters2D[0][iParticle][3]->Fill(Rapidity,M_t,1);
1362
1363 const bool drawZR = IsCollectZRHistogram(iParticle);
1364 if(histoParameters2D[0][iParticle][1] && drawZR)
1365 {
1366 histoParameters2D[0][iParticle][1]->Fill(Z,R,1);
1367 }
1368
1369 if(TempPart.NDaughters() == 2 && IsCollectArmenteros(iParticle))
1370 {
1371 int index1 = TempPart.DaughterIds()[0];
1372 int index2 = TempPart.DaughterIds()[1];
1373 if(index1 >= int(fTopoReconstructor->GetParticles().size()) ||
1374 index2 >= int(fTopoReconstructor->GetParticles().size()) ||
1375 index1 < 0 || index2 < 0 )
1376 return;
1377
1378 KFParticle posDaughter, negDaughter;
1379 if(int(fTopoReconstructor->GetParticles()[index1].Q()) > 0)
1380 {
1381 posDaughter = fTopoReconstructor->GetParticles()[index1];
1382 negDaughter = fTopoReconstructor->GetParticles()[index2];
1383 }
1384 else
1385 {
1386 negDaughter = fTopoReconstructor->GetParticles()[index1];
1387 posDaughter = fTopoReconstructor->GetParticles()[index2];
1388 }
1389 float vertex[3] = {TempPart.GetX(), TempPart.GetY(), TempPart.GetZ()};
1390 posDaughter.TransportToPoint(vertex);
1391 negDaughter.TransportToPoint(vertex);
1392 KFParticle::GetArmenterosPodolanski(posDaughter, negDaughter, QtAlpha );
1393
1394 histoParameters2D[0][iParticle][2]->Fill(QtAlpha[1],QtAlpha[0],1);
1395 }
1396
1397
1398 if( histoParameters3D && IsCollect3DHistogram(iParticle))
1399 {
1400 histoParameters3D[0][iParticle][0]->Fill(Rapidity,Pt,M,1);
1401 histoParameters3D[0][iParticle][1]->Fill(Rapidity,M_t,M,1);
1402 if(fCentralityBin>=0)
1403 {
1404 histoParameters3D[0][iParticle][2]->Fill(fCentralityBin, Pt, M, fCentralityWeight);
1405 histoParameters3D[0][iParticle][3]->Fill(fCentralityBin, Rapidity, M, fCentralityWeight);
1406 histoParameters3D[0][iParticle][4]->Fill(fCentralityBin, M_t, M, fCentralityWeight);
1407 }
1408 histoParameters3D[0][iParticle][5]->Fill(cT, Pt, M, 1);
1409 }
1410
1411
1412 if(histoDSToParticleQA && IsCollect3DHistogram(iParticle))
1413 {
1414 if(fabs(fParteff.GetMass(iParticle)-M) < 3.f*fParteff.GetMassSigma(iParticle))
1415 {
1416 for(int iParam=0; iParam<17; iParam++)
1417 histoParameters[4][iParticle][iParam]->Fill(parameters[iParam]);
1418
1419 if(multiplicities)
1420 multiplicities[4][iParticle]++;
1421
1422 histoParameters2D[4][iParticle][0]->Fill(Rapidity,Pt,1);
1423 histoParameters2D[4][iParticle][3]->Fill(Rapidity,M_t,1);
1424
1425 if(drawZR)
1426 {
1427 if(histoParameters2D[4][iParticle][1])
1428 histoParameters2D[4][iParticle][1]->Fill(Z,R,1);
1429 if(histoParameters2D[4][iParticle][2])
1430 histoParameters2D[4][iParticle][2]->Fill(QtAlpha[1],QtAlpha[0],1);
1431 }
1432 }
1433
1434 if( fabs(fParteff.GetMass(iParticle)-M) > 3.f*fParteff.GetMassSigma(iParticle) &&
1435 fabs(fParteff.GetMass(iParticle)-M) <= 6.f*fParteff.GetMassSigma(iParticle) )
1436 {
1437 for(int iParam=0; iParam<17; iParam++)
1438 histoParameters[5][iParticle][iParam]->Fill(parameters[iParam]);
1439
1440 if(multiplicities)
1441 multiplicities[5][iParticle]++;
1442
1443 histoParameters2D[5][iParticle][0]->Fill(Rapidity,Pt,1);
1444 histoParameters2D[5][iParticle][3]->Fill(Rapidity,M_t,1);
1445
1446 if(drawZR)
1447 {
1448 if(histoParameters2D[5][iParticle][1])
1449 histoParameters2D[5][iParticle][1]->Fill(Z,R,1);
1450 if(histoParameters2D[5][iParticle][2])
1451 histoParameters2D[5][iParticle][2]->Fill(QtAlpha[1],QtAlpha[0],1);
1452 }
1453 }
1454 }
1455
1456 if(!fStoreMCHistograms) return;
1457
1458 int iSet = 1;
1459 if(!RtoMCParticleId[iP].IsMatchedWithPdg())
1460 {
1461 if(!RtoMCParticleId[iP].IsMatched()) iSet = 3;
1462 else iSet = 2;
1463 }
1464
1465
1466 if(!histoDSToParticleQA && iSet == 1)
1467 {
1468 int iMCPart = RtoMCParticleId[iP].GetBestMatchWithPdg();
1469 KFMCParticle &mcPart = vMCParticles[iMCPart];
1470 int iMCTrack = mcPart.GetMCTrackID();
1471 KFMCTrack &mcTrack = vMCTracks[iMCTrack];
1472 int motherId = mcTrack.MotherId();
1473 bool isSecondaryParticle = motherId >= 0;
1474
1475 if(iPV >=0)
1476 {
1477 if(isSecondaryParticle)
1478 iSet = 4;
1479 else
1480 {
1481 int iMCPV = -1;
1482 if(RtoMCPVId[iPV].IsMatchedWithPdg())
1483 iMCPV = RtoMCPVId[iPV].GetBestMatch();
1484
1485 int iMCPVFromParticle = fMCTrackToMCPVMatch[iMCTrack];
1486 if(iMCPV != iMCPVFromParticle)
1487 iSet = 4;
1488 }
1489 }
1490 else
1491 {
1492 if(!isSecondaryParticle)
1493 iSet = 4;
1494 }
1495 }
1496
1497
1498 for(int iParam=0; iParam<17; iParam++)
1499 histoParameters[iSet][iParticle][iParam]->Fill(parameters[iParam]);
1500
1501 if(multiplicities)
1502 multiplicities[iSet][iParticle]++;
1503
1504 histoParameters2D[iSet][iParticle][0]->Fill(Rapidity,Pt,1);
1505 if(drawZR)
1506 {
1507 if(histoParameters2D[iSet][iParticle][1])
1508 histoParameters2D[iSet][iParticle][1]->Fill(Z,R,1);
1509 if(histoParameters2D[iSet][iParticle][2])
1510 histoParameters2D[iSet][iParticle][2]->Fill(QtAlpha[1],QtAlpha[0],1);
1511 }
1512 histoParameters2D[iSet][iParticle][3]->Fill(Rapidity,M_t,1);
1513
1514 if(iSet != 1) return;
1515
1516 int iMCPart = RtoMCParticleId[iP].GetBestMatchWithPdg();
1517 KFMCParticle &mcPart = vMCParticles[iMCPart];
1518
1519 if(histoFit)
1520 {
1521 int iMCTrack = mcPart.GetMCTrackID();
1522 KFMCTrack &mcTrack = vMCTracks[iMCTrack];
1523 int mcDaughterId = -1;
1524 if(iParticle >= fParteff.fFirstStableParticleIndex && iParticle <= fParteff.fLastStableParticleIndex)
1525 mcDaughterId = iMCTrack;
1526 else if(mcTrack.PDG() == 22 && TempPart.NDaughters() == 1)
1527 mcDaughterId = iMCTrack;
1528 else if(iParticle >= fParteff.fFirstMissingMassParticleIndex && iParticle <= fParteff.fLastMissingMassParticleIndex)
1529 mcDaughterId = mcPart.GetDaughterIds()[1];
1530 else
1531 mcDaughterId = mcPart.GetDaughterIds()[0];
1532
1533 KFMCTrack &mcDaughter = vMCTracks[mcDaughterId];
1534
1535 float mcX = mcTrack.X();
1536 float mcY = mcTrack.Y();
1537 float mcZ = mcTrack.Z();
1538 if(histoDSToParticleQA || hPartParamPrimary == histoParameters)
1539 {
1540 mcX = mcDaughter.X();
1541 mcY = mcDaughter.Y();
1542 mcZ = mcDaughter.Z();
1543 }
1544 const float mcPx = mcTrack.Par(3);
1545 const float mcPy = mcTrack.Par(4);
1546 const float mcPz = mcTrack.Par(5);
1547
1548 float decayVtx[3] = { mcTrack.X(), mcTrack.Y(), mcTrack.Z() };
1549 float recParam[8] = { 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f };
1550 float errParam[8] = { 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f };
1551
1552 for(int iPar=0; iPar<3; iPar++)
1553 {
1554 recParam[iPar] = TempPart.GetParameter(iPar);
1555 Double_t error = TempPart.GetCovariance(iPar,iPar);
1556 if(error < 0.) { error = 1.e20;}
1557 errParam[iPar] = TMath::Sqrt(error);
1558 }
1559 TempPart.TransportToPoint(decayVtx);
1560 for(int iPar=3; iPar<7; iPar++)
1561 {
1562 recParam[iPar] = TempPart.GetParameter(iPar);
1563 Double_t error = TempPart.GetCovariance(iPar,iPar);
1564 if(error < 0.) { error = 1.e20;}
1565 errParam[iPar] = TMath::Sqrt(error);
1566 }
1567
1568 int jParticlePDG = fParteff.GetParticleIndex(mcTrack.PDG());
1569 Double_t massMC = (jParticlePDG>=0) ? fParteff.partMass[jParticlePDG] :0.13957;
1570
1571 Double_t Emc = sqrt(mcTrack.P()*mcTrack.P() + massMC*massMC);
1572 Double_t res[8] = {0},
1573 pull[8] = {0},
1574 mcParam[8] = { mcX, mcY, mcZ,
1575 mcPx, mcPy, mcPz, Emc, massMC };
1576 for(int iPar=0; iPar < 7; iPar++ )
1577 {
1578 res[iPar] = recParam[iPar] - mcParam[iPar];
1579 if(fabs(errParam[iPar]) > 1.e-20) pull[iPar] = res[iPar]/errParam[iPar];
1580 }
1581
1582 res[7] = M - mcParam[7];
1583 if(fabs(ErrM) > 1.e-20) pull[7] = res[7]/ErrM;
1584
1585 for(int iPar=0; iPar < 8; iPar++ )
1586 {
1587 histoFit[iParticle][iPar]->Fill(res[iPar]);
1588 histoFit[iParticle][iPar+8]->Fill(pull[iPar]);
1589 }
1590 }
1591
1592 int daughterIndex[2] = {-1, -1};
1593
1594 if(histoFitDaughtersQA)
1595 {
1596 for(int iD=0; iD<mcPart.NDaughters(); ++iD)
1597 {
1598 int mcDaughterId = mcPart.GetDaughterIds()[iD];
1599
1600 if(!MCtoRParticleId[mcDaughterId].IsMatched()) continue;
1601 KFMCTrack &mcTrack = vMCTracks[mcDaughterId];
1602
1603 int recDaughterId = MCtoRParticleId[mcDaughterId].GetBestMatch();
1604 KFParticle Daughter = fTopoReconstructor->GetParticles()[recDaughterId];
1605 Daughter.GetMass(M,ErrM);
1606
1607 const float mcX = mcTrack.X();
1608 const float mcY = mcTrack.Y();
1609 const float mcZ = mcTrack.Z();
1610 const float mcPx = mcTrack.Px();
1611 const float mcPy = mcTrack.Py();
1612 const float mcPz = mcTrack.Pz();
1613
1614 float_v decayVtx[3] = {mcX, mcY, mcZ};
1615
1616 KFParticleSIMD DaughterSIMD(Daughter);
1617 DaughterSIMD.TransportToPoint(decayVtx);
1618
1619 int jParticlePDG = fParteff.GetParticleIndex(mcTrack.PDG());
1620 Double_t massMC = (jParticlePDG>=0) ? fParteff.partMass[jParticlePDG] :0.13957;
1621 Double_t Emc = sqrt(mcTrack.P()*mcTrack.P() + massMC*massMC);
1622
1623 Double_t res[8] = {0},
1624 pull[8] = {0},
1625 mcParam[8] = { mcX, mcY, mcZ,
1626 mcPx, mcPy, mcPz, Emc, massMC };
1627 for(int iPar=0; iPar < 7; iPar++ )
1628 {
1629 Double_t error = DaughterSIMD.GetCovariance(iPar,iPar)[0];
1630 if(error < 0.) { error = 1.e20;}
1631 error = TMath::Sqrt(error);
1632 Double_t recoPar = DaughterSIMD.GetParameter(iPar)[0];
1633 res[iPar] = recoPar - mcParam[iPar];
1634 if(fabs(error) > 1.e-20) pull[iPar] = res[iPar]/error;
1635 }
1636 res[7] = M - mcParam[7];
1637 if(fabs(ErrM) > 1.e-20) pull[7] = res[7]/ErrM;
1638
1639 for(int iPar=0; iPar < 8; iPar++ )
1640 {
1641 histoFitDaughtersQA[iParticle][iPar]->Fill(res[iPar]);
1642 histoFitDaughtersQA[iParticle][iPar+8]->Fill(pull[iPar]);
1643 }
1644
1645
1646 if(iD == 0)
1647 daughterIndex[0] = recDaughterId;
1648 if(iD == 1 && daughterIndex[0] > -1 && histoDSToParticleQA)
1649 {
1650 daughterIndex[1] = recDaughterId;
1651 KFParticle d1 = fTopoReconstructor->GetParticles()[daughterIndex[0]];
1652 KFParticle d2 = fTopoReconstructor->GetParticles()[daughterIndex[1]];
1653
1654 KFParticleSIMD daughters[2] = {d2, d1};
1655
1656 float_v dS[2] = {0.f, 0.f};
1657 float_v dsdr[4][6];
1658 for(int i1=0; i1<4; i1++)
1659 for(int i2=0; i2<6; i2++)
1660 dsdr[i1][i2] = 0.f;
1661
1662 daughters[0].GetDStoParticle(daughters[1], dS, dsdr);
1663 float_v pD[2][8], cD[2][36], corrPD[2][36], corrCD[2][36];
1664
1665 for(int iDR=0; iDR<2; iDR++)
1666 {
1667 for(int iPD = 0; iPD<8; iPD++)
1668 {
1669 pD[iDR][iPD] = 0;
1670 corrPD[iDR][iPD] = 0;
1671 }
1672 for(int iCD=0; iCD<36; iCD++)
1673 {
1674 cD[iDR][iCD] = 0;
1675 corrCD[iDR][iCD] = 0;
1676 }
1677 }
1678
1679 float_v F[4][36];
1680 {
1681 for(int i1=0; i1<4; i1++)
1682 for(int i2=0; i2<36; i2++)
1683 F[i1][i2] = 0;
1684 }
1685 daughters[0].Transport(dS[0], dsdr[0], pD[0], cD[0], dsdr[1], F[0], F[1]);
1686 daughters[1].Transport(dS[1], dsdr[3], pD[1], cD[1], dsdr[2], F[3], F[2]);
1687
1688 daughters[0].MultQSQt( F[1], daughters[1].CovarianceMatrix(), corrCD[0], 6);
1689 daughters[0].MultQSQt( F[2], daughters[0].CovarianceMatrix(), corrCD[1], 6);
1690 for(int iDR=0; iDR<2; iDR++)
1691 for(int iC=0; iC<6; iC++)
1692 cD[iDR][iC] += corrCD[iDR][iC];
1693
1694 for(int iDR=0; iDR<2; iDR++)
1695 {
1696 cD[iDR][1] = cD[iDR][2];
1697 cD[iDR][2] = cD[iDR][5];
1698 for(int iPar=0; iPar<3; iPar++)
1699 {
1700 res[iPar] = pD[iDR][iPar][0] - decayVtx[iPar][0];
1701
1702 Double_t error = cD[iDR][iPar][0];
1703 if(error < 0.) { error = 1.e20;}
1704 error = sqrt(error);
1705
1706 pull[iPar] = res[iPar] / error;
1707
1708 histoDSToParticleQA[iParticle][iPar]->Fill(res[iPar]);
1709 histoDSToParticleQA[iParticle][iPar+3]->Fill(pull[iPar]);
1710 }
1711 }
1712
1713 Double_t dXds = pD[0][0][0] - pD[1][0][0];
1714 Double_t dYds = pD[0][1][0] - pD[1][1][0];
1715 Double_t dZds = pD[0][2][0] - pD[1][2][0];
1716
1717 Double_t dRds = sqrt(dXds*dXds + dYds*dYds + dZds*dZds);
1718 histoDSToParticleQA[iParticle][6]->Fill(dRds);
1719 }
1720 }
1721 }
1722 }
1723
1724 void KFTopoPerformance::FillHistos()
1725 {
1726
1727 vector<int> multiplicities[6];
1728 for(int iV=0; iV<6; iV++)
1729 multiplicities[iV].resize(KFPartEfficiencies::nParticles, 0);
1730
1731
1732 for(unsigned int iP=0; iP<fTopoReconstructor->GetParticles().size(); iP++)
1733 {
1734 int iParticle = fParteff.GetParticleIndex(fTopoReconstructor->GetParticles()[iP].GetPDG());
1735 if(iParticle < 0) continue;
1736 KFParticle TempPart = fTopoReconstructor->GetParticles()[iP];
1737
1738 FillParticleParameters(TempPart,iParticle, iP, 0, hPartParam, hPartParam2D, hPartParam3D,
1739 hFitQA, hFitDaughtersQA, hDSToParticleQA, multiplicities);
1740 }
1741
1742 if(fStoreMCHistograms)
1743 {
1744 for(int iSet=0; iSet<KFParticleFinder::GetNSecondarySets(); iSet++)
1745 {
1746 const std::vector<KFParticle>& SecondaryCandidates = fTopoReconstructor->GetKFParticleFinder()->GetSecondaryCandidates()[iSet];
1747 for(unsigned int iP=0; iP<SecondaryCandidates.size(); iP++)
1748 {
1749 KFParticle TempPart = SecondaryCandidates[iP];
1750 int iParticle = fParteff.GetParticleIndex(TempPart.GetPDG());
1751 if(iParticle < 0) continue;
1752
1753 const int id = TempPart.Id();
1754 FillParticleParameters(TempPart, iParticle, id, 0, hPartParamSecondaryMass, hPartParam2DSecondaryMass, 0);
1755
1756 TempPart = fTopoReconstructor->GetParticles()[id];
1757 FillParticleParameters(TempPart, iParticle, id, 0, hPartParamSecondary, hPartParam2DSecondary, 0);
1758 }
1759 }
1760
1761 for(int iSet=0; iSet<KFParticleFinder::GetNPrimarySets(); iSet++)
1762 {
1763 for(int iPV=0; iPV<fTopoReconstructor->NPrimaryVertices(); iPV++)
1764 {
1765 const std::vector<KFParticle>& PrimaryCandidates = fTopoReconstructor->GetKFParticleFinder()->GetPrimaryCandidates()[iSet][iPV];
1766 for(unsigned int iP=0; iP<PrimaryCandidates.size(); iP++)
1767 {
1768 KFParticle TempPart = PrimaryCandidates[iP];
1769 int iParticle = fParteff.GetParticleIndex(TempPart.GetPDG());
1770 if(iParticle < 0) continue;
1771
1772 const int id = TempPart.Id();
1773 FillParticleParameters(TempPart,iParticle, id, iPV, hPartParamPrimaryMass, hPartParam2DPrimaryMass, 0, hFitQAMassConstraint);
1774
1775 TempPart = fTopoReconstructor->GetParticles()[id];
1776 FillParticleParameters(TempPart,iParticle, id, iPV, hPartParamPrimary, hPartParam2DPrimary, 0, hFitQANoConstraint);
1777 }
1778
1779 const std::vector<KFParticle>& PrimaryCandidatesTopo = fTopoReconstructor->GetKFParticleFinder()->GetPrimaryTopoCandidates()[iSet][iPV];
1780 for(unsigned int iP=0; iP<PrimaryCandidatesTopo.size(); iP++)
1781 {
1782 KFParticle TempPart = PrimaryCandidatesTopo[iP];
1783 int iParticle = fParteff.GetParticleIndex(TempPart.GetPDG());
1784 if(iParticle < 0) continue;
1785
1786 FillParticleParameters(TempPart,iParticle, TempPart.Id(), iPV, hPartParamPrimaryTopo, hPartParam2DPrimaryTopo, 0, hFitQATopoConstraint);
1787 }
1788
1789 const std::vector<KFParticle>& PrimaryCandidatesTopoMass = fTopoReconstructor->GetKFParticleFinder()->GetPrimaryTopoMassCandidates()[iSet][iPV];
1790 for(unsigned int iP=0; iP<PrimaryCandidatesTopoMass.size(); iP++)
1791 {
1792 KFParticle TempPart = PrimaryCandidatesTopoMass[iP];
1793 int iParticle = fParteff.GetParticleIndex(TempPart.GetPDG());
1794 if(iParticle < 0) continue;
1795
1796 FillParticleParameters(TempPart,iParticle, TempPart.Id(), iPV, hPartParamPrimaryTopoMass, hPartParam2DPrimaryTopoMass, 0, hFitQATopoMassConstraint);
1797 }
1798 }
1799 }
1800 }
1801
1802 for(unsigned int iP=0; iP<fTopoReconstructor->GetParticles().size(); iP++)
1803 {
1804 KFParticle TempPart = fTopoReconstructor->GetParticles()[iP];
1805 KFParticle vtx = fTopoReconstructor->GetPrimVertex(0);
1806
1807 if(RtoMCParticleId[iP].IsMatched())
1808 {
1809 int iMCPV = vMCParticles[RtoMCParticleId[iP].GetBestMatch()].GetMotherId();
1810 if(iMCPV<0.)
1811 {
1812 iMCPV = -iMCPV - 1;
1813 if(MCtoRPVId[iMCPV].IsMatched())
1814 {
1815 vtx = fTopoReconstructor->GetPrimVertex(MCtoRPVId[iMCPV].GetBestMatch());
1816 }
1817 }
1818 }
1819
1820
1821
1822
1823 float chi2 = TempPart.GetDeviationFromVertex(vtx);
1824 int ndf = 2;
1825
1826 hTrackParameters[KFPartEfficiencies::nParticles]->Fill(chi2);
1827 hTrackParameters[KFPartEfficiencies::nParticles+4]->Fill(TMath::Prob(chi2, ndf));
1828
1829 if(!RtoMCParticleId[iP].IsMatched())
1830 {
1831 hTrackParameters[KFPartEfficiencies::nParticles+3]->Fill(chi2);
1832 hTrackParameters[KFPartEfficiencies::nParticles+7]->Fill(TMath::Prob(chi2, ndf));
1833 continue;
1834 }
1835
1836 int iMCPart = RtoMCParticleId[iP].GetBestMatch();
1837 KFMCParticle &mcPart = vMCParticles[iMCPart];
1838 if(mcPart.GetMotherId() < 0)
1839 {
1840 hTrackParameters[KFPartEfficiencies::nParticles+1]->Fill(chi2 );
1841 hTrackParameters[KFPartEfficiencies::nParticles+5]->Fill(TMath::Prob(chi2, ndf));
1842 }
1843 else
1844 {
1845 hTrackParameters[KFPartEfficiencies::nParticles+2]->Fill(chi2 );
1846 hTrackParameters[KFPartEfficiencies::nParticles+6]->Fill(TMath::Prob(chi2, ndf));
1847 }
1848 int iParticle = fParteff.GetParticleIndex(fTopoReconstructor->GetParticles()[iP].GetPDG());
1849 if(iParticle > -1 && iParticle<KFPartEfficiencies::nParticles)
1850 hTrackParameters[iParticle]->Fill(chi2 );
1851
1852 }
1853
1854
1855
1856 for(int iPV = 0; iPV<fTopoReconstructor->NPrimaryVertices(); iPV++)
1857 {
1858 KFParticle & vtx = fTopoReconstructor->GetPrimVertex(iPV);
1859 vector<int> &tracks = fTopoReconstructor->GetPVTrackIndexArray(iPV);
1860
1861 Double_t probPV = TMath::Prob(vtx.Chi2(), vtx.NDF());
1862 vector<Double_t> dzPV;
1863 if(RtoMCPVId[iPV].IsMatched())
1864 {
1865 int iCurrMCPV = RtoMCPVId[iPV].GetBestMatch();
1866 for(int iPV2 = iPV+1; iPV2 < fTopoReconstructor->NPrimaryVertices(); iPV2++)
1867 {
1868 if(!RtoMCPVId[iPV2].IsMatched()) continue;
1869 int iCurrMCPV2 = RtoMCPVId[iPV2].GetBestMatch();
1870 if(iCurrMCPV != iCurrMCPV2) continue;
1871 KFParticle & vtx2 = fTopoReconstructor->GetPrimVertex(iPV2);
1872
1873 dzPV.push_back(fabs(vtx.Z() - vtx2.Z()));
1874 }
1875 }
1876
1877 hPVParam[ 0]->Fill(vtx.X());
1878 hPVParam[ 1]->Fill(vtx.Y());
1879 hPVParam[ 2]->Fill(vtx.Z());
1880 hPVParam[ 3]->Fill(sqrt(vtx.X()*vtx.X() + vtx.Y()*vtx.Y()));
1881 hPVParam[ 4]->Fill(tracks.size());
1882 hPVParam[ 5]->Fill(vtx.Chi2());
1883 hPVParam[ 6]->Fill(vtx.NDF());
1884 hPVParam[ 7]->Fill(vtx.Chi2()/vtx.NDF());
1885 hPVParam[ 8]->Fill(probPV);
1886 hPVParam[ 9]->Fill(fPVPurity[iPV]);
1887 hPVParam[10]->Fill(fPVTracksRate[0][iPV]);
1888 hPVParam[11]->Fill(fPVTracksRate[1][iPV]);
1889 hPVParam[12]->Fill(fPVTracksRate[2][iPV]);
1890 hPVParam[13]->Fill(fPVTracksRate[3][iPV]);
1891 for(unsigned int iZ=0; iZ<dzPV.size(); iZ++)
1892 hPVParam[14]->Fill(dzPV[iZ]);
1893
1894 hPVParam2D[0]->Fill(vtx.X(),vtx.Y());
1895
1896
1897 if(!RtoMCPVId[iPV].IsMatchedWithPdg())
1898 {
1899 if(!RtoMCPVId[iPV].IsMatched())
1900 {
1901 hPVParamGhost[ 0]->Fill(vtx.X());
1902 hPVParamGhost[ 1]->Fill(vtx.Y());
1903 hPVParamGhost[ 2]->Fill(vtx.Z());
1904 hPVParamGhost[ 3]->Fill(sqrt(vtx.X()*vtx.X() + vtx.Y()*vtx.Y()));
1905 hPVParamGhost[ 4]->Fill(tracks.size());
1906 hPVParamGhost[ 5]->Fill(vtx.Chi2());
1907 hPVParamGhost[ 6]->Fill(vtx.NDF());
1908 hPVParamGhost[ 7]->Fill(vtx.Chi2()/vtx.NDF());
1909 hPVParamGhost[ 8]->Fill(probPV);
1910 hPVParamGhost[ 9]->Fill(fPVPurity[iPV]);
1911 hPVParamGhost[10]->Fill(fPVTracksRate[0][iPV]);
1912 hPVParamGhost[11]->Fill(fPVTracksRate[1][iPV]);
1913 hPVParamGhost[12]->Fill(fPVTracksRate[2][iPV]);
1914 hPVParamGhost[13]->Fill(fPVTracksRate[3][iPV]);
1915 for(unsigned int iZ=0; iZ<dzPV.size(); iZ++)
1916 hPVParamGhost[14]->Fill(dzPV[iZ]);
1917 }
1918 else
1919 {
1920 hPVParamBG[ 0]->Fill(vtx.X());
1921 hPVParamBG[ 1]->Fill(vtx.Y());
1922 hPVParamBG[ 2]->Fill(vtx.Z());
1923 hPVParamBG[ 3]->Fill(sqrt(vtx.X()*vtx.X() + vtx.Y()*vtx.Y()));
1924 hPVParamBG[ 4]->Fill(tracks.size());
1925 hPVParamBG[ 5]->Fill(vtx.Chi2());
1926 hPVParamBG[ 6]->Fill(vtx.NDF());
1927 hPVParamBG[ 7]->Fill(vtx.Chi2()/vtx.NDF());
1928 hPVParamBG[ 8]->Fill(probPV);
1929 hPVParamBG[ 9]->Fill(fPVPurity[iPV]);
1930 hPVParamBG[10]->Fill(fPVTracksRate[0][iPV]);
1931 hPVParamBG[11]->Fill(fPVTracksRate[1][iPV]);
1932 hPVParamBG[12]->Fill(fPVTracksRate[2][iPV]);
1933 hPVParamBG[13]->Fill(fPVTracksRate[3][iPV]);
1934 for(unsigned int iZ=0; iZ<dzPV.size(); iZ++)
1935 hPVParamBG[14]->Fill(dzPV[iZ]);
1936 }
1937 continue;
1938 }
1939
1940 int iMCPV = RtoMCPVId[iPV].GetBestMatch();
1941 KFMCVertex &mcPV = fPrimVertices[iMCPV];
1942
1943 int iPVType = 0;
1944 if(mcPV.IsTriggerPV())
1945 {
1946 hPVParamSignal[ 0]->Fill(vtx.X());
1947 hPVParamSignal[ 1]->Fill(vtx.Y());
1948 hPVParamSignal[ 2]->Fill(vtx.Z());
1949 hPVParamSignal[ 3]->Fill(sqrt(vtx.X()*vtx.X() + vtx.Y()*vtx.Y()));
1950 hPVParamSignal[ 4]->Fill(tracks.size());
1951 hPVParamSignal[ 5]->Fill(vtx.Chi2());
1952 hPVParamSignal[ 6]->Fill(vtx.NDF());
1953 hPVParamSignal[ 7]->Fill(vtx.Chi2()/vtx.NDF());
1954 hPVParamSignal[ 8]->Fill(probPV);
1955 hPVParamSignal[ 9]->Fill(fPVPurity[iPV]);
1956 hPVParamSignal[10]->Fill(fPVTracksRate[0][iPV]);
1957 hPVParamSignal[11]->Fill(fPVTracksRate[1][iPV]);
1958 hPVParamSignal[12]->Fill(fPVTracksRate[2][iPV]);
1959 hPVParamSignal[13]->Fill(fPVTracksRate[3][iPV]);
1960 for(unsigned int iZ=0; iZ<dzPV.size(); iZ++)
1961 hPVParamSignal[14]->Fill(dzPV[iZ]);
1962 }
1963 else
1964 {
1965 hPVParamPileup[ 0]->Fill(vtx.X());
1966 hPVParamPileup[ 1]->Fill(vtx.Y());
1967 hPVParamPileup[ 2]->Fill(vtx.Z());
1968 hPVParamPileup[ 3]->Fill(sqrt(vtx.X()*vtx.X() + vtx.Y()*vtx.Y()));
1969 hPVParamPileup[ 4]->Fill(tracks.size());
1970 hPVParamPileup[ 5]->Fill(vtx.Chi2());
1971 hPVParamPileup[ 6]->Fill(vtx.NDF());
1972 hPVParamPileup[ 7]->Fill(vtx.Chi2()/vtx.NDF());
1973 hPVParamPileup[ 8]->Fill(probPV);
1974 hPVParamPileup[ 9]->Fill(fPVPurity[iPV]);
1975 hPVParamPileup[10]->Fill(fPVTracksRate[0][iPV]);
1976 hPVParamPileup[11]->Fill(fPVTracksRate[1][iPV]);
1977 hPVParamPileup[12]->Fill(fPVTracksRate[2][iPV]);
1978 hPVParamPileup[13]->Fill(fPVTracksRate[3][iPV]);
1979 for(unsigned int iZ=0; iZ<dzPV.size(); iZ++)
1980 hPVParamPileup[14]->Fill(dzPV[iZ]);
1981 iPVType = 1;
1982 }
1983
1984 float mcPVx[3]={mcPV.X(), mcPV.Y(), mcPV.Z()};
1985
1986 float errPV[3] = {vtx.CovarianceMatrix()[0], vtx.CovarianceMatrix()[2], vtx.CovarianceMatrix()[5]};
1987 for(int iErr=0; iErr<3; iErr++)
1988 if(fabs(errPV[iErr]) < 1.e-8f) errPV[iErr] = 1.e8;
1989
1990 float dRPVr[3] = {vtx.X()-mcPVx[0],
1991 vtx.Y()-mcPVx[1],
1992 vtx.Z()-mcPVx[2]};
1993 float dRPVp[3] = {static_cast<float>(dRPVr[0]/sqrt(errPV[0])),
1994 static_cast<float>(dRPVr[1]/sqrt(errPV[1])),
1995 static_cast<float>(dRPVr[2]/sqrt(errPV[2]))};
1996
1997 for(unsigned int iHPV=0; iHPV<3; ++iHPV)
1998 hPVFitQa[iPVType][iHPV]->Fill(dRPVr[iHPV]);
1999 for(unsigned int iHPV=3; iHPV<6; ++iHPV)
2000 hPVFitQa[iPVType][iHPV]->Fill(dRPVp[iHPV-3]);
2001
2002 for(unsigned int iHPV=0; iHPV<3; ++iHPV)
2003 hPVFitQa2D[iPVType][1][iHPV]->Fill(fNCorrectPVTracks[iPV],dRPVr[iHPV]);
2004 for(unsigned int iHPV=3; iHPV<6; ++iHPV)
2005 hPVFitQa2D[iPVType][1][iHPV]->Fill(fNCorrectPVTracks[iPV],dRPVp[iHPV-3]);
2006
2007 for(unsigned int iHPV=0; iHPV<3; ++iHPV)
2008 hPVFitQa2D[iPVType][0][iHPV]->Fill(mcPV.NReconstructedDaughterTracks(),dRPVr[iHPV]);
2009 for(unsigned int iHPV=3; iHPV<6; ++iHPV)
2010 hPVFitQa2D[iPVType][0][iHPV]->Fill(mcPV.NReconstructedDaughterTracks(),dRPVp[iHPV-3]);
2011
2012 hPVFitQa[iPVType][6]->Fill( double(mcPV.NReconstructedDaughterTracks() - fNCorrectPVTracks[iPV])/double(mcPV.NReconstructedDaughterTracks()) );
2013 }
2014
2015
2016 for(unsigned int iP=0; iP<fTopoReconstructor->GetParticles().size(); iP++)
2017 {
2018 KFParticle TempPart = fTopoReconstructor->GetParticles()[iP];
2019 int nDaughters = TempPart.NDaughters();
2020 if(nDaughters > 1) continue;
2021
2022 if(!RtoMCParticleId[iP].IsMatchedWithPdg()) continue;
2023
2024 int iMCPart = RtoMCParticleId[iP].GetBestMatchWithPdg();
2025 KFMCParticle &mcPart = vMCParticles[iMCPart];
2026
2027 int iMCTrack = mcPart.GetMCTrackID();
2028 KFMCTrack &mcTrack = vMCTracks[iMCTrack];
2029
2030 if( mcTrack.MotherId() > -1 ) continue;
2031
2032 const float mcX = mcTrack.X();
2033 const float mcY = mcTrack.Y();
2034 const float mcZ = mcTrack.Z();
2035 const float mcPx = mcTrack.Px();
2036 const float mcPy = mcTrack.Py();
2037 const float mcPz = mcTrack.Pz();
2038
2039 float decayVtx[3] = {mcX, mcY, mcZ};
2040 TempPart.TransportToPoint(decayVtx);
2041
2042
2043 Double_t res[6] = {0},
2044 pull[6] = {0},
2045 mcParam[6] = { mcX, mcY, mcZ,
2046 mcPx, mcPy, mcPz };
2047 for(int iPar=0; iPar < 6; iPar++ )
2048 {
2049 Double_t error = TempPart.GetCovariance(iPar,iPar);
2050 if(error < 0.) { error = 1.e20;}
2051 error = TMath::Sqrt(error);
2052 res[iPar] = TempPart.GetParameter(iPar) - mcParam[iPar];
2053 if(fabs(error) > 1.e-20) pull[iPar] = res[iPar]/error;
2054
2055 hFitPVTracksQA[iPar]->Fill(res[iPar]);
2056 hFitPVTracksQA[iPar+6]->Fill(pull[iPar]);
2057 }
2058 }
2059
2060 if(fStoreMCHistograms)
2061 {
2062 for(int iV=0; iV<6; iV++)
2063 for(int iP=0; iP < KFPartEfficiencies::nParticles; iP++)
2064 if(hPartParam[iV][iP][17])
2065 hPartParam[iV][iP][17]->Fill(multiplicities[iV][iP]);
2066 FillMCHistos();
2067 }
2068 else
2069 for(int iP=0; iP < KFPartEfficiencies::nParticles; iP++)
2070 if(hPartParam[0][iP][17])
2071 hPartParam[0][iP][17]->Fill(multiplicities[0][iP]);
2072 }
2073
2074 void KFTopoPerformance::FillMCHistos()
2075 {
2076
2077 for(unsigned int iMCTrack=0; iMCTrack<vMCTracks.size(); iMCTrack++)
2078 {
2079 int iPDG = fParteff.GetParticleIndex(vMCTracks[iMCTrack].PDG());
2080 if(iPDG < 0) continue;
2081
2082 if(vMCTracks[iMCTrack].MotherId()>=0) continue;
2083 KFMCParticle &part = vMCParticles[iMCTrack];
2084
2085 float M = fParteff.partMass[iPDG];
2086 float P = vMCTracks[iMCTrack].P();
2087 float Pt = vMCTracks[iMCTrack].Pt();
2088 float E = sqrt(M*M+P*P);
2089 float Rapidity = 0.5*log((E+vMCTracks[iMCTrack].Pz())/(E-vMCTracks[iMCTrack].Pz()));
2090 float M_t = sqrt(Pt*Pt+M*M)-M;
2091
2092 float X;
2093 float Y;
2094 float Z;
2095 float R;
2096
2097 if (part.NDaughters()>0)
2098 {
2099 X = vMCTracks[part.GetDaughterIds()[0]].X();
2100 Y = vMCTracks[part.GetDaughterIds()[0]].Y();
2101 Z = vMCTracks[part.GetDaughterIds()[0]].Z();
2102 }
2103 else
2104 {
2105 X = vMCTracks[iMCTrack].X();
2106 Y = vMCTracks[iMCTrack].Y();
2107 Z = vMCTracks[iMCTrack].Z();
2108 }
2109 R = sqrt(X*X+Y*Y);
2110
2111
2112 float parameters[17] = {M, P, Pt, Rapidity, 0, 0, 0, 0, 0, 0, X, Y, Z, R, 0, 0, M_t};
2113
2114 for(int iParam=0; iParam<17; iParam++)
2115 if(hPartParam[6][iPDG][iParam]) hPartParam[6][iPDG][iParam]->Fill(parameters[iParam]);
2116
2117 if(hPartParam2D[6][iPDG][0]) hPartParam2D[6][iPDG][0]->Fill(Rapidity,Pt,1);
2118 if(hPartParam2D[6][iPDG][3]) hPartParam2D[6][iPDG][3]->Fill(Rapidity,M_t,1);
2119
2120 if(IsCollectZRHistogram(iPDG))
2121 if(hPartParam2D[6][iPDG][1]) hPartParam2D[6][iPDG][1]->Fill(Z,R,1);
2122
2123 if( part.IsReconstructable(2) && IsCollectArmenteros(iPDG))
2124 {
2125 int index1 = part.GetDaughterIds()[0];
2126 int index2 = part.GetDaughterIds()[1];
2127 KFMCTrack positive, negative;
2128 if(vMCTracks[index1].Par(6) > 0)
2129 {
2130 positive = vMCTracks[index1];
2131 negative = vMCTracks[index2];
2132 }
2133 else
2134 {
2135 negative = vMCTracks[index1];
2136 positive = vMCTracks[index2];
2137 }
2138
2139 float alpha = 0., qt = 0.;
2140 float spx = positive.Px() + negative.Px();
2141 float spy = positive.Py() + negative.Py();
2142 float spz = positive.Pz() + negative.Pz();
2143 float sp = sqrt(spx*spx + spy*spy + spz*spz);
2144 float pn, pln, plp;
2145 pn = sqrt(negative.Px()*negative.Px() + negative.Py()*negative.Py() + negative.Pz()*negative.Pz());
2146 pln = (negative.Px()*spx+negative.Py()*spy+negative.Pz()*spz)/sp;
2147 plp = (positive.Px()*spx+positive.Py()*spy+positive.Pz()*spz)/sp;
2148 float ptm = (1.-((pln/pn)*(pln/pn)));
2149 qt= (ptm>=0.)? pn*sqrt(ptm) :0;
2150 alpha = (plp-pln)/(plp+pln);
2151
2152 if(hPartParam2D[6][iPDG][2]) hPartParam2D[6][iPDG][2]->Fill(alpha,qt,1);
2153 }
2154 }
2155 }
2156
2157 void KFTopoPerformance::AddV0Histos()
2158 {
2159
2160 int iV0 = fParteff.nParticles - 1;
2161 int iK0 = fParteff.GetParticleIndex(310);
2162
2163 for(int iH=0; iH<nFitQA; iH++)
2164 {
2165 hFitDaughtersQA[iV0][iH]->Add(hFitDaughtersQA[iK0][iH]);
2166 hFitQA[iV0][iH]->Add(hFitQA[iK0][iH]);
2167 }
2168
2169 for(int iV=0; iV<4; iV++)
2170 for(int iH=0; iH<nHistoPartParam; iH++)
2171 hPartParam[iV][iV0][iH]->Add(hPartParam[iV][iK0][iH]);
2172 }
2173
2174 void KFTopoPerformance::FillHistos(const KFPHistogram* histograms)
2175 {
2176
2177 for(int iParticle=0; iParticle<KFPartEfficiencies::nParticles; iParticle++)
2178 {
2179 const int& nHistograms = histograms->GetHistogramSet(0).GetNHisto1D();
2180 for(int iHistogram=0; iHistogram<nHistograms; iHistogram++)
2181 {
2182 const KFPHistogram1D& histogram = histograms->GetHistogram(iParticle,iHistogram);
2183 for(int iBin=0; iBin<histogram.Size(); iBin++)
2184 hPartParam[0][iParticle][iHistogram]->SetBinContent( iBin, histogram.GetHistogram()[iBin] );
2185 }
2186 }
2187 }
2188
2189 #endif