2 #include <TDatabasePDG.h>
9 #include <AliExternalTrackParam.h>
10 #include <AliTPCcalibDB.h>
11 #include <AliTPCclusterMI.h>
12 #include <AliTPCCorrection.h>
13 #include <AliTrackerBase.h>
14 #include <AliTrackPointArray.h>
16 #include <AliTPCParam.h>
17 #include <AliTPCROC.h>
18 #include <TTreeStream.h>
19 #include <AliTPCReconstructor.h>
20 #include <AliTPCTransform.h>
21 #include <AliTPCseed.h>
22 #include <AliTPCtracker.h>
23 #include <AliTPCtrackerSector.h>
24 #include <AliRieman.h>
26 #include "AliToyMCTrack.h"
27 #include "AliToyMCEvent.h"
29 #include "AliToyMCReconstruction.h"
37 //____________________________________________________________________________________
38 AliToyMCReconstruction::AliToyMCReconstruction() : TObject()
42 , fCorrectionType(kNoCorrection)
44 , fUseMaterial(kFALSE)
45 , fIdealTracking(kFALSE)
47 , fCreateT0seed(kFALSE)
54 , fkNSectorInner(18) // hard-coded to avoid loading the parameters before
55 , fInnerSectorArray(0x0)
56 , fkNSectorOuter(18) // hard-coded to avoid loading the parameters before
57 , fOuterSectorArray(0x0)
58 , fAllClusters("AliTPCclusterMI",10000)
59 , fMapTrackEvent(10000)
60 , fMapTrackTrackInEvent(10000)
66 fTPCParam=AliTPCcalibDB::Instance()->GetParameters();
70 //____________________________________________________________________________________
71 AliToyMCReconstruction::~AliToyMCReconstruction()
80 //____________________________________________________________________________________
81 void AliToyMCReconstruction::RunReco(const char* file, Int_t nmaxEv)
84 // Recostruction from associated clusters
87 ConnectInputFile(file);
90 // read spacecharge from the Userinfo ot the tree
93 TString debugName=file;
94 debugName.ReplaceAll(".root","");
95 debugName.Append(Form(".%1d.%1d_%1d_%1d_%03d_%02d",
96 fUseMaterial,fIdealTracking,fClusterType,
97 Int_t(fCorrectionType),fSeedingRow,fSeedingDist));
98 debugName.Append(".debug.root");
100 gSystem->Exec(Form("test -f %s && rm %s", debugName.Data(), debugName.Data()));
101 if (!fStreamer) fStreamer=new TTreeSRedirector(debugName.Data());
105 static AliExternalTrackParam dummySeedT0;
106 static AliExternalTrackParam dummySeed;
107 static AliExternalTrackParam dummyTrack;
109 AliExternalTrackParam t0seed;
110 AliExternalTrackParam seed;
111 AliExternalTrackParam track;
112 AliExternalTrackParam tOrig;
114 AliExternalTrackParam *dummy;
116 Int_t maxev=fTree->GetEntries();
117 if (nmaxEv>0&&nmaxEv<maxev) maxev=nmaxEv;
119 for (Int_t iev=0; iev<maxev; ++iev){
120 printf("============== Processing Event %6d =================\n",iev);
121 fTree->GetEvent(iev);
122 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
123 // printf(" > ====== Processing Track %6d ======== \n",itr);
124 const AliToyMCTrack *tr=fEvent->GetTrack(itr);
129 t0seed = dummySeedT0;
133 Float_t z0=fEvent->GetZ();
134 Float_t t0=fEvent->GetT0();
136 Float_t vDrift=GetVDrift();
137 Float_t zLength=GetZLength(0);
139 // crate time0 seed, steered by fCreateT0seed
140 // printf("t0 seed\n");
143 dummy = GetSeedFromTrack(tr);
149 // crate real seed using the time 0 from the first seed
150 // set fCreateT0seed now to false to get the seed in z coordinates
151 fTime0 = t0seed.GetZ()-zLength/vDrift;
152 fCreateT0seed = kFALSE;
153 // printf("seed (%.2g)\n",fTime0);
154 dummy = GetSeedFromTrack(tr);
159 // create fitted track
161 // printf("track\n");
162 dummy = GetFittedTrackFromSeed(tr, &seed);
167 // propagate seed to 0
168 const Double_t kMaxSnp = 0.85;
169 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
170 AliTrackerBase::PropagateTrackTo(&seed,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
175 Int_t ctype(fCorrectionType);
178 (*fStreamer) << "Tracks" <<
182 "fTime0=" << fTime0 <<
184 "clsType=" << fClusterType <<
185 "corrType=" << ctype <<
186 "seedRow=" << fSeedingRow <<
187 "seedDist=" << fSeedingDist <<
188 "vDrift=" << vDrift <<
189 "zLength=" << zLength <<
190 "t0seed.=" << &t0seed <<
192 "track.=" << &track <<
193 "tOrig.=" << &tOrig <<
205 //____________________________________________________________________________________
206 void AliToyMCReconstruction::RunRecoAllClusters(const char* file, Int_t nmaxEv)
209 // Reconstruction for seed from associated clusters, but array of clusters:
210 // Step 1) Filling of cluster arrays
211 // Step 2) Seeding from clusters associated to tracks
212 // Step 3) Free track reconstruction using all clusters
216 if (!f.IsOpen() || f.IsZombie()) {
217 printf("ERROR: couldn't open the file '%s'\n", file);
221 fTree=(TTree*)f.Get("toyMCtree");
223 printf("ERROR: couldn't read the 'toyMCtree' from file '%s'\n", file);
228 fTree->SetBranchAddress("event",&fEvent);
230 // read spacecharge from the Userinfo ot the tree
233 TString debugName=file;
234 debugName.ReplaceAll(".root","");
235 debugName.Append(Form(".%1d.%1d_%1d_%1d_%03d_%02d",
236 fUseMaterial,fIdealTracking,fClusterType,
237 Int_t(fCorrectionType),fSeedingRow,fSeedingDist));
238 debugName.Append(".allClusters.debug.root");
240 gSystem->Exec(Form("test -f %s && rm %s", debugName.Data(), debugName.Data()));
241 if (!fStreamer) fStreamer=new TTreeSRedirector(debugName.Data());
245 static AliExternalTrackParam dummySeedT0;
246 static AliExternalTrackParam dummySeed;
247 static AliExternalTrackParam dummyTrack;
249 AliExternalTrackParam t0seed;
250 AliExternalTrackParam seed;
251 AliExternalTrackParam track;
252 AliExternalTrackParam tOrig;
254 AliExternalTrackParam *dummy;
256 Int_t maxev=fTree->GetEntries();
257 if (nmaxEv>0&&nmaxEv<maxev) maxev=nmaxEv;
259 // ===========================================================================================
260 // Loop 1: Fill AliTPCtrackerSector structure
261 // ===========================================================================================
262 FillSectorStructure(maxev);
264 // settings (TODO: find the correct settings)
265 AliTPCRecoParam *tpcRecoParam = new AliTPCRecoParam();
266 tpcRecoParam->SetDoKinks(kFALSE);
267 AliTPCcalibDB::Instance()->GetTransform()->SetCurrentRecoParam(tpcRecoParam);
268 //tpcRecoParam->Print();
270 // need AliTPCReconstructor for parameter settings in AliTPCtracker
271 AliTPCReconstructor *tpcRec = new AliTPCReconstructor();
272 tpcRec->SetRecoParam(tpcRecoParam);
275 // ===========================================================================================
276 // Loop 2: Seeding from clusters associated to tracks
277 // TODO: Implement tracking from given seed!
278 // ===========================================================================================
279 for (Int_t iev=0; iev<maxev; ++iev){
280 printf("============== Processing Event %6d =================\n",iev);
281 fTree->GetEvent(iev);
282 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
283 printf(" > ====== Processing Track %6d ======== \n",itr);
284 const AliToyMCTrack *tr=fEvent->GetTrack(itr);
289 t0seed = dummySeedT0;
293 Float_t z0=fEvent->GetZ();
294 Float_t t0=fEvent->GetT0();
296 Float_t vDrift=GetVDrift();
297 Float_t zLength=GetZLength(0);
301 // crate time0 seed, steered by fCreateT0seed
305 dummy = GetSeedFromTrack(tr);
311 // crate real seed using the time 0 from the first seed
312 // set fCreateT0seed now to false to get the seed in z coordinates
313 fTime0 = t0seed.GetZ()-zLength/vDrift;
314 fCreateT0seed = kFALSE;
315 printf("seed (%.2g)\n",fTime0);
316 dummy = GetSeedFromTrack(tr);
321 // create fitted track
324 dummy = GetFittedTrackFromSeedAllClusters(tr, &seed,nClus);
329 // propagate seed to 0
330 const Double_t kMaxSnp = 0.85;
331 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
332 AliTrackerBase::PropagateTrackTo(&seed,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,kFALSE);
337 Int_t ctype(fCorrectionType);
340 (*fStreamer) << "Tracks" <<
344 "fTime0=" << fTime0 <<
346 "clsType=" << fClusterType <<
347 "corrType=" << ctype <<
348 "seedRow=" << fSeedingRow <<
349 "seedDist=" << fSeedingDist <<
350 "vDrift=" << vDrift <<
351 "zLength=" << zLength <<
353 "t0seed.=" << &t0seed <<
355 "track.=" << &track <<
356 "tOrig.=" << &tOrig <<
376 //____________________________________________________________________________________
377 void AliToyMCReconstruction::RunRecoAllClustersStandardTracking(const char* file, Int_t nmaxEv)
380 // Reconstruction for seed from associated clusters, but array of clusters
381 // Step 1) Filling of cluster arrays
382 // Step 2) Use the standard tracking: AliTPCtracker::Clusters2Tracks();
386 if (!f.IsOpen() || f.IsZombie()) {
387 printf("ERROR: couldn't open the file '%s'\n", file);
391 fTree=(TTree*)f.Get("toyMCtree");
393 printf("ERROR: couldn't read the 'toyMCtree' from file '%s'\n", file);
398 fTree->SetBranchAddress("event",&fEvent);
400 // read spacecharge from the Userinfo ot the tree
403 TString debugName=file;
404 debugName.ReplaceAll(".root","");
405 debugName.Append(Form(".%1d.%1d_%1d_%1d_%03d_%02d",
406 fUseMaterial,fIdealTracking,fClusterType,
407 Int_t(fCorrectionType),fSeedingRow,fSeedingDist));
408 debugName.Append(".allClusters.debug.root");
410 gSystem->Exec(Form("test -f %s && rm %s", debugName.Data(), debugName.Data()));
411 if (!fStreamer) fStreamer=new TTreeSRedirector(debugName.Data());
415 AliExternalTrackParam t0seed;
416 AliExternalTrackParam seed;
417 AliExternalTrackParam track;
418 AliExternalTrackParam tOrig;
419 AliToyMCTrack tOrigToy;
421 AliExternalTrackParam *dummy;
422 AliTPCseed *seedBest;
424 AliTPCclusterMI *cluster;
426 Int_t maxev=fTree->GetEntries();
427 if (nmaxEv>0&&nmaxEv<maxev) maxev=nmaxEv;
430 // ===========================================================================================
431 // Loop 1: Fill AliTPCtrackerSector structure
432 // ===========================================================================================
433 FillSectorStructure(maxev);
435 // ===========================================================================================
436 // Loop 2: Use the TPC tracker for seeding (MakeSeeds3)
437 // TODO: - check tracking configuration
438 // - add clusters and original tracks to output (how?)
439 // ===========================================================================================
441 // settings (TODO: find the correct settings)
442 AliTPCRecoParam *tpcRecoParam = new AliTPCRecoParam();
443 tpcRecoParam->SetDoKinks(kFALSE);
444 AliTPCcalibDB::Instance()->GetTransform()->SetCurrentRecoParam(tpcRecoParam);
445 //tpcRecoParam->Print();
447 // need AliTPCReconstructor for parameter settings in AliTPCtracker
448 AliTPCReconstructor *tpcRec = new AliTPCReconstructor();
449 tpcRec->SetRecoParam(tpcRecoParam);
452 AliTPCtracker *tpcTracker = new AliTPCtracker(fTPCParam);
453 tpcTracker->SetDebug(10);
456 tpcTracker->SetTPCtrackerSectors(fInnerSectorArray,fOuterSectorArray);
457 tpcTracker->LoadInnerSectors();
458 tpcTracker->LoadOuterSectors();
461 static TObjArray arrTracks;
462 TObjArray * arr = &arrTracks;
463 TObjArray * seeds = new TObjArray;
467 // cuts[0]=0.0070; // cuts[0] - fP4 cut
468 // cuts[1] = 1.5; // cuts[1] - tan(phi) cut
469 // cuts[2] = 3.; // cuts[2] - zvertex cut
470 // cuts[3] = 3.; // cuts[3] - fP3 cut
473 Int_t lowerRow = fSeedingRow;
474 Int_t upperRow = fSeedingRow+2*fSeedingDist;
475 const AliTPCROC * roc = AliTPCROC::Instance();
476 const Int_t kNRowsInnerTPC = roc->GetNRows(0);
477 const Int_t kNRowsTPC = kNRowsInnerTPC + roc->GetNRows(36);
478 if(lowerRow < kNRowsInnerTPC){
479 Printf("Seeding row requested (%d) is lower than kNRowsInnerTPC --> use %d",lowerRow,kNRowsInnerTPC);
480 lowerRow = kNRowsInnerTPC;
481 upperRow = lowerRow + 20;
483 if(upperRow >= kNRowsTPC){
484 Printf("Seeding row requested (%d) is larger than kNRowsTPC --> use %d",upperRow,kNRowsTPC-1);
485 upperRow = kNRowsTPC-1;
486 lowerRow = upperRow-20;
490 for (Int_t sec=0;sec<fkNSectorOuter;sec++){
492 //tpcTracker->MakeSeeds3(arr, sec,upperRow,lowerRow,cuts,-1,1);
493 // MakeSeeds(arr, sec,upperRow,lowerRow); // own function (based on TLinearFitter)
494 MakeSeeds2(arr, sec,upperRow,lowerRow); // own function (based on TLinearFitter)
495 //tpcTracker->SumTracks(seeds,arr);
496 //tpcTracker->SignClusters(seeds,3.0,3.0);
500 Printf("After seeding we have %d tracks",seeds->GetEntriesFast());
503 tpcTracker->SetSeeds(seeds);
504 tpcTracker->PropagateForward();
505 Printf("After trackinging we have %d tracks",seeds->GetEntriesFast());
508 // Loop over all input tracks and connect to found seeds
509 for (Int_t iev=0; iev<maxev; ++iev){
510 printf("============== Fill Tracks: Processing Event %6d =================\n",iev);
511 fTree->GetEvent(iev);
512 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
513 printf(" > ====== Fill Tracks: Processing Track %6d ======== \n",itr);
514 const AliToyMCTrack *tr=fEvent->GetTrack(itr);
518 Float_t z0=fEvent->GetZ();
519 Float_t t0=fEvent->GetT0();
520 Float_t vDrift=GetVDrift();
521 Float_t zLength=GetZLength(0);
523 // find the corresponding seed (and track)
524 Int_t trackID = tr->GetUniqueID();
525 Int_t nClustersMC = tr->GetNumberOfSpacePoints(); // number of findable clusters (ideal)
527 nClustersMC = tr->GetNumberOfDistSpacePoints(); // number of findable clusters (distorted)
528 // Int_t idxSeed = 0; // index of best seed (best is with maximum number of clusters with correct ID)
529 Int_t nSeeds = 0; // number of seeds for MC track
530 Int_t nSeedClusters = 0; // number of clusters for best seed
531 Int_t nSeedClustersTmp = 0; // number of clusters for current seed
532 Int_t nSeedClustersID = 0; // number of clusters with correct ID for best seed
533 Int_t nSeedClustersIDTmp = 0; // number of clusters with correct ID for current seed
534 for(Int_t iSeeds = 0; iSeeds < seeds->GetEntriesFast(); ++iSeeds){
536 // set current seed and reset counters
537 seedTmp = (AliTPCseed*)(seeds->At(iSeeds));
538 nSeedClustersTmp = 0;
539 nSeedClustersIDTmp = 0;
541 if(!seedTmp) continue;
543 // loop over all rows
544 for(Int_t iRow = seedTmp->GetRow(); iRow < seedTmp->GetRow() + seedTmp->GetNumberOfClustersIndices(); iRow++ ){
546 // get cluster and increment counters
547 cluster = seedTmp->GetClusterFast(iRow);
550 if(cluster->GetLabel(0)==trackID){
551 nSeedClustersIDTmp++;
556 // if number of corresponding clusters > 0,
558 if(nSeedClustersTmp > 0){
562 // if number of corresponding clusters bigger than current nSeedClusters,
563 // take this seed as the best one
564 if(nSeedClustersIDTmp > nSeedClustersID){
567 nSeedClusters = nSeedClustersTmp; // number of correctly assigned clusters
568 nSeedClustersID = nSeedClustersIDTmp; // number of all clusters
573 // cluster to track association (commented out, when used standard tracking)
574 if (nSeeds>0&&nSeedClusters>0) {
575 t0seed = (AliExternalTrackParam)*seedBest;
576 // fTime0 = t0seed.GetZ()-zLength/vDrift;
577 // get the refitted track from the seed
578 // this will also set the fTime0 from the seed extrapolation
579 dummy=GetRefittedTrack(*seedBest);
582 //printf("seed (%.2g): %d seeds with %d clusters\n",fTime0,nSeeds,nSeedClusters);
584 // // cluster to track association for all good seeds
585 // // set fCreateT0seed to true to get the seed in time coordinates
586 // fCreateT0seed = kTRUE;
587 // dummy = ClusterToTrackAssociation(seedBest,trackID,nClus);
589 //// propagate track to 0
590 //const Double_t kMaxSnp = 0.85;
591 //const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
592 //AliTrackerBase::PropagateTrackTo(&track,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,kFALSE);
596 Int_t ctype(fCorrectionType);
599 (*fStreamer) << "Tracks" <<
603 "fTime0=" << fTime0 <<
605 "clsType=" << fClusterType <<
606 "corrType=" << ctype <<
607 "seedRow=" << fSeedingRow <<
608 "seedDist=" << fSeedingDist <<
609 "vDrift=" << vDrift <<
610 "zLength=" << zLength <<
611 "nClustersMC=" << nClustersMC <<
612 "nSeeds=" << nSeeds <<
613 "nSeedClusters=" << nSeedClusters <<
614 "nSeedClustersID=" << nSeedClustersID <<
615 "t0seed.=" << &t0seed <<
616 "track.=" << &track <<
617 "tOrig.=" << &tOrig <<
618 "tOrigToy.=" << &tOrigToy <<
637 //____________________________________________________________________________________
638 AliExternalTrackParam* AliToyMCReconstruction::GetSeedFromTrack(const AliToyMCTrack * const tr)
641 // if we don't have a valid time0 informaion (fTime0) available yet
642 // assume we create a seed for the time0 estimate
645 // seed point informaion
646 AliTrackPoint seedPoint[3];
647 const AliTPCclusterMI *seedCluster[3]={0x0,0x0,0x0};
649 // number of clusters to loop over
650 const Int_t ncls=(fClusterType==0)?tr->GetNumberOfSpacePoints():tr->GetNumberOfDistSpacePoints();
652 UChar_t nextSeedRow=fSeedingRow;
655 //assumes sorted clusters
656 for (Int_t icl=0;icl<ncls;++icl) {
657 const AliTPCclusterMI *cl=tr->GetSpacePoint(icl);
658 if (fClusterType==1) cl=tr->GetDistortedSpacePoint(icl);
661 const UChar_t row=cl->GetRow() + 63*(cl->GetDetector()>35);
662 // skip clusters without proper pad row
663 if (row>200) continue;
666 // if we are in the last row and still miss a seed we use the last row
667 // even if the row spacing will not be equal
668 if (row>=nextSeedRow || icl==ncls-1){
669 seedCluster[nseeds]=cl;
670 SetTrackPointFromCluster(cl, seedPoint[nseeds]);
672 nextSeedRow+=fSeedingDist;
674 if (nseeds==3) break;
678 // check we really have 3 seeds
680 AliError(Form("Seeding failed for parameters %d, %d\n",fSeedingDist,fSeedingRow));
684 // do cluster correction for fCorrectionType:
689 // assign the cluster abs time as z component to all seeds
690 for (Int_t iseed=0; iseed<3; ++iseed) {
691 Float_t xyz[3]={0,0,0};
692 seedPoint[iseed].GetXYZ(xyz);
693 const Float_t r=TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
695 const Int_t sector=seedCluster[iseed]->GetDetector();
696 const Int_t sign=1-2*((sector/18)%2);
698 if ( (fClusterType == 1) && (fCorrectionType != kNoCorrection) ) {
699 // printf("correction type: %d\n",(Int_t)fCorrectionType);
701 // the settings below are for the T0 seed
702 // for known T0 the z position is already calculated in SetTrackPointFromCluster
703 if ( fCreateT0seed ){
704 if ( fCorrectionType == kTPCCenter ) xyz[2] = 125.*sign;
705 //!!! TODO: is this the correct association?
706 if ( fCorrectionType == kAverageEta ) xyz[2] = TMath::Tan(45./2.*TMath::DegToRad())*r*sign;
709 if ( fCorrectionType == kIdeal ) xyz[2] = seedCluster[iseed]->GetZ();
711 //!!! TODO: to be replaced with the proper correction
712 fTPCCorrection->CorrectPoint(xyz, seedCluster[iseed]->GetDetector());
715 // after the correction set the time bin as z-Position in case of a T0 seed
717 xyz[2]=seedCluster[iseed]->GetTimeBin();
719 seedPoint[iseed].SetXYZ(xyz);
722 const Double_t kMaxSnp = 0.85;
723 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
725 AliExternalTrackParam *seed = AliTrackerBase::MakeSeed(seedPoint[0], seedPoint[1], seedPoint[2]);
726 seed->ResetCovariance(10);
729 // if fTime0 < 0 we assume that we create a seed for the T0 estimate
730 AliTrackerBase::PropagateTrackTo(seed,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,kFALSE);
731 if (TMath::Abs(seed->GetX())>3) {
732 // printf("Could not propagate track to 0, %.2f, %.2f, %.2f\n",seed->GetX(),seed->GetAlpha(),seed->Pt());
741 //____________________________________________________________________________________
742 void AliToyMCReconstruction::SetTrackPointFromCluster(const AliTPCclusterMI *cl, AliTrackPoint &p )
745 // make AliTrackPoint out of AliTPCclusterMI
749 Float_t xyz[3]={0.,0.,0.};
750 // ClusterToSpacePoint(cl,xyz);
751 // cl->GetGlobalCov(cov);
752 //TODO: what to do with the covariance matrix???
753 //TODO: the problem is that it is used in GetAngle in AliTrackPoint
754 //TODO: which is used by AliTrackerBase::MakeSeed to get alpha correct ...
755 //TODO: for the moment simply assign 1 permill squared
756 // in AliTrackPoint the cov is xx, xy, xz, yy, yz, zz
757 // Float_t cov[6]={xyz[0]*xyz[0]*1e-6,xyz[0]*xyz[1]*1e-6,xyz[0]*xyz[2]*1e-6,
758 // xyz[1]*xyz[1]*1e-6,xyz[1]*xyz[2]*1e-6,xyz[2]*xyz[2]*1e-6};
759 // cl->GetGlobalXYZ(xyz);
760 // cl->GetGlobalCov(cov);
761 // voluem ID to add later ....
764 // AliTrackPoint *tp=const_cast<AliTPCclusterMI*>(cl)->MakePoint(p);
767 const_cast<AliTPCclusterMI*>(cl)->MakePoint(p);
770 p.SetVolumeID(cl->GetDetector());
773 if ( !fCreateT0seed && !fIdealTracking ) {
775 const Int_t sector=cl->GetDetector();
776 const Int_t sign=1-2*((sector/18)%2);
777 const Float_t zT0=( GetZLength(sector) - (cl->GetTimeBin()-fTime0)*GetVDrift() )*sign;
778 // printf(" z: %.2f %.2f\n",xyz[2],zT0);
784 // p.Rotate(p.GetAngle()).Print();
787 //____________________________________________________________________________________
788 void AliToyMCReconstruction::ClusterToSpacePoint(const AliTPCclusterMI *cl, Float_t xyz[3])
791 // convert the cluster to a space point in global coordinates
796 xyz[2]=cl->GetTimeBin(); // this will not be correct at all
797 Int_t i[3]={0,cl->GetDetector(),cl->GetRow()};
798 // printf("%.2f, %.2f, %.2f - %d, %d, %d\n",xyz[0],xyz[1],xyz[2],i[0],i[1],i[2]);
799 fTPCParam->Transform8to4(xyz,i);
800 // printf("%.2f, %.2f, %.2f - %d, %d, %d\n",xyz[0],xyz[1],xyz[2],i[0],i[1],i[2]);
801 fTPCParam->Transform4to3(xyz,i);
802 // printf("%.2f, %.2f, %.2f - %d, %d, %d\n",xyz[0],xyz[1],xyz[2],i[0],i[1],i[2]);
803 fTPCParam->Transform2to1(xyz,i);
804 // printf("%.2f, %.2f, %.2f - %d, %d, %d\n",xyz[0],xyz[1],xyz[2],i[0],i[1],i[2]);
807 //____________________________________________________________________________________
808 AliExternalTrackParam* AliToyMCReconstruction::GetFittedTrackFromSeed(const AliToyMCTrack *tr, const AliExternalTrackParam *seed)
815 AliExternalTrackParam *track = new AliExternalTrackParam(*seed);
817 Int_t ncls=(fClusterType == 0)?tr->GetNumberOfSpacePoints():tr->GetNumberOfDistSpacePoints();
819 const AliTPCROC * roc = AliTPCROC::Instance();
821 const Double_t kRTPC0 = roc->GetPadRowRadii(0,0);
822 const Double_t kRTPC1 = roc->GetPadRowRadii(36,roc->GetNRows(36)-1);
823 const Double_t kMaxSnp = 0.85;
824 const Double_t kMaxR = 500.;
825 const Double_t kMaxZ = 500.;
827 // const Double_t kMaxZ0=220;
828 // const Double_t kZcut=3;
830 const Double_t refX = tr->GetX();
832 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
834 // loop over all other points and add to the track
835 for (Int_t ipoint=ncls-1; ipoint>=0; --ipoint){
837 const AliTPCclusterMI *cl=tr->GetSpacePoint(ipoint);
838 if (fClusterType == 1) cl=tr->GetDistortedSpacePoint(ipoint);
839 SetTrackPointFromCluster(cl, pIn);
840 if (fCorrectionType != kNoCorrection){
841 Float_t xyz[3]={0,0,0};
843 // if ( fCorrectionType == kIdeal ) xyz[2] = cl->GetZ();
844 fTPCCorrection->CorrectPoint(xyz, cl->GetDetector());
847 // rotate the cluster to the local detector frame
848 track->Rotate(((cl->GetDetector()%18)*20+10)*TMath::DegToRad());
849 AliTrackPoint prot = pIn.Rotate(track->GetAlpha()); // rotate to the local frame - non distoted point
850 if (TMath::Abs(prot.GetX())<kRTPC0) continue;
851 if (TMath::Abs(prot.GetX())>kRTPC1) continue;
853 Bool_t res=AliTrackerBase::PropagateTrackTo(track,prot.GetX(),kMass,5,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
857 if (TMath::Abs(track->GetZ())>kMaxZ) break;
858 if (TMath::Abs(track->GetX())>kMaxR) break;
859 // if (TMath::Abs(track->GetZ())<kZcut)continue;
861 Double_t pointPos[2]={0,0};
862 Double_t pointCov[3]={0,0,0};
863 pointPos[0]=prot.GetY();//local y
864 pointPos[1]=prot.GetZ();//local z
865 pointCov[0]=prot.GetCov()[3];//simay^2
866 pointCov[1]=prot.GetCov()[4];//sigmayz
867 pointCov[2]=prot.GetCov()[5];//sigmaz^2
869 if (!track->Update(pointPos,pointCov)) {printf("no update\n"); break;}
872 AliTrackerBase::PropagateTrackTo2(track,refX,kMass,5.,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
874 // rotate fittet track to the frame of the original track and propagate to same reference
875 track->Rotate(tr->GetAlpha());
877 AliTrackerBase::PropagateTrackTo2(track,refX,kMass,1.,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
883 //____________________________________________________________________________________
884 AliExternalTrackParam* AliToyMCReconstruction::GetFittedTrackFromSeedAllClusters(const AliToyMCTrack *tr, const AliExternalTrackParam *seed, Int_t &nClus)
887 // Tracking for given seed on an array of clusters
891 AliExternalTrackParam *track = new AliExternalTrackParam(*seed);
893 const AliTPCROC * roc = AliTPCROC::Instance();
895 const Double_t kRTPC0 = roc->GetPadRowRadii(0,0);
896 const Double_t kRTPC1 = roc->GetPadRowRadii(36,roc->GetNRows(36)-1);
897 const Int_t kNRowsTPC = roc->GetNRows(0) + roc->GetNRows(36) - 1;
898 const Int_t kIRowsTPC = roc->GetNRows(0) - 1;
899 const Double_t kMaxSnp = 0.85;
900 const Double_t kMaxR = 500.;
901 const Double_t kMaxZ = 500.;
902 const Double_t roady = 100.;
903 const Double_t roadz = 100.;
905 const Double_t refX = tr->GetX();
907 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
911 Double_t xCur, yCur, zCur = 0.;
913 Float_t vDrift = GetVDrift();
915 // first propagate seed to outermost row
916 AliTrackerBase::PropagateTrackTo(track,kRTPC1,kMass,5,kFALSE,kMaxSnp);
918 // Loop over rows and find the cluster candidates
919 for( Int_t iRow = kNRowsTPC; iRow >= 0; --iRow ){
921 // inner or outer sector
922 Bool_t bInnerSector = kTRUE;
923 if(iRow > kIRowsTPC) bInnerSector = kFALSE;
925 // nearest track point/cluster (to be found)
926 AliTrackPoint nearestPoint;
927 AliTPCclusterMI *nearestCluster = NULL;
932 // Propagate to center of pad row and extract parameters
933 AliTrackerBase::PropagateTrackTo(track,roc->GetPadRowRadii(0,iRow),kMass,5,kFALSE,kMaxSnp);
934 xCur = track->GetX();
935 yCur = track->GetY();
936 zCur = track->GetZ();
937 if ( !fIdealTracking ) {
938 zCur = zCur/vDrift + fTime0; // Look at time, not at z!
940 secCur = GetSector(track);
942 // Find the nearest cluster (TODO: correct road settings!)
943 Printf("inner tracking here: x = %.2f, y = %.2f, z = %.2f (Row %d Sector %d)",xCur,yCur,zCur,iRow,secCur);
944 nearestCluster = fInnerSectorArray[secCur%fkNSectorInner][iRow].FindNearest2(yCur,zCur,roady,roadz,indexCur);
946 // Move to next row if now cluster found
947 if(!nearestCluster) continue;
948 //Printf("Nearest Clusters = %d (of %d) ",indexCur,fInnerSectorArray[secCur%fkNSectorInner][iRow].GetN());
955 // Propagate to center of pad row and extract parameters
956 AliTrackerBase::PropagateTrackTo(track,roc->GetPadRowRadii(36,iRow-kIRowsTPC-1),kMass,5,kFALSE,kMaxSnp);
957 xCur = track->GetX();
958 yCur = track->GetY();
959 zCur = track->GetZ();
960 if ( !fIdealTracking ) {
961 zCur = zCur/vDrift + fTime0; // Look at time, not at z!
963 secCur = GetSector(track);
965 // Find the nearest cluster (TODO: correct road settings!)
966 Printf("outer tracking here: x = %.2f, y = %.2f, z = %.2f (Row %d Sector %d)",xCur,yCur,zCur,iRow,secCur);
967 nearestCluster = fOuterSectorArray[(secCur-fkNSectorInner*2)%fkNSectorOuter][iRow-kIRowsTPC-1].FindNearest2(yCur,zCur,roady,roadz,indexCur);
969 // Move to next row if now cluster found
970 if(!nearestCluster) continue;
971 //Printf("Nearest Clusters = %d (of %d)",indexCur,fOuterSectorArray[(secCur-fkNSectorInner*2)%fkNSectorOuter][iRow-kIRowsTPC-1].GetN());
975 // create track point from cluster
976 SetTrackPointFromCluster(nearestCluster,nearestPoint);
978 //Printf("Track point = %.2f %.2f %.2f",nearestPoint.GetX(),nearestPoint.GetY(),nearestPoint.GetZ());
981 // TODO: also correction when looking for the next cluster?
982 if (fCorrectionType != kNoCorrection){
983 Float_t xyz[3]={0,0,0};
984 nearestPoint.GetXYZ(xyz);
985 fTPCCorrection->CorrectPoint(xyz, nearestCluster->GetDetector());
986 nearestPoint.SetXYZ(xyz);
989 // rotate the cluster to the local detector frame
990 track->Rotate(((nearestCluster->GetDetector()%18)*20+10)*TMath::DegToRad());
991 AliTrackPoint prot = nearestPoint.Rotate(track->GetAlpha()); // rotate to the local frame - non distoted point
992 if (TMath::Abs(prot.GetX())<kRTPC0) continue;
993 if (TMath::Abs(prot.GetX())>kRTPC1) continue;
996 //Printf("Rotated Track point = %.2f %.2f %.2f",prot.GetX(),prot.GetY(),prot.GetZ());
998 // update track with the nearest track point
999 Bool_t res=AliTrackerBase::PropagateTrackTo(track,prot.GetX(),kMass,5,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
1003 if (TMath::Abs(track->GetZ())>kMaxZ) break;
1004 if (TMath::Abs(track->GetX())>kMaxR) break;
1005 //if (TMath::Abs(track->GetZ())<kZcut)continue;
1007 Double_t pointPos[2]={0,0};
1008 Double_t pointCov[3]={0,0,0};
1009 pointPos[0]=prot.GetY();//local y
1010 pointPos[1]=prot.GetZ();//local z
1011 pointCov[0]=prot.GetCov()[3];//simay^2
1012 pointCov[1]=prot.GetCov()[4];//sigmayz
1013 pointCov[2]=prot.GetCov()[5];//sigmaz^2
1015 if (!track->Update(pointPos,pointCov)) {printf("no update\n");}
1021 // propagation to refX
1022 AliTrackerBase::PropagateTrackTo(track,refX,kMass,5.,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
1024 // rotate fittet track to the frame of the original track and propagate to same reference
1025 track->Rotate(tr->GetAlpha());
1027 AliTrackerBase::PropagateTrackTo(track,refX,kMass,1.,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
1029 Printf("We have %d clusters in this track!",nClus);
1034 //____________________________________________________________________________________
1035 AliExternalTrackParam* AliToyMCReconstruction::ClusterToTrackAssociation(const AliTPCseed *seed, Int_t trackID, Int_t &nClus)
1038 // Cluster to track association for given seed on an array of clusters
1042 AliExternalTrackParam *track = new AliExternalTrackParam(*seed);
1044 const AliTPCROC * roc = AliTPCROC::Instance();
1046 const Double_t kRTPC0 = roc->GetPadRowRadii(0,0);
1047 const Double_t kRTPC1 = roc->GetPadRowRadii(36,roc->GetNRows(36)-1);
1048 const Int_t kNRowsTPC = roc->GetNRows(0) + roc->GetNRows(36) - 1;
1049 const Int_t kIRowsTPC = roc->GetNRows(0) - 1;
1050 const Double_t kMaxSnp = 0.85;
1051 const Double_t kMaxR = 500.;
1052 const Double_t kMaxZ = 500.;
1053 const Double_t roady = 0.1;
1054 const Double_t roadz = 0.01;
1056 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
1058 Int_t secCur, secOld = -1;
1059 UInt_t indexCur = 0;
1060 Double_t xCur, yCur, zCur = 0.;
1062 // Float_t vDrift = GetVDrift();
1064 // first propagate seed to outermost row
1065 Bool_t res0=AliTrackerBase::PropagateTrackTo(track,kRTPC1,kMass,5,kFALSE,kMaxSnp);
1067 // Loop over rows and find the cluster candidates
1068 for( Int_t iRow = kNRowsTPC; iRow >= 0; --iRow ){
1070 // inner or outer sector
1071 Bool_t bInnerSector = kTRUE;
1072 if(iRow > kIRowsTPC) bInnerSector = kFALSE;
1074 // nearest track point/cluster (to be found)
1075 AliTrackPoint nearestPoint;
1076 AliTPCclusterMI *nearestCluster = NULL;
1081 // Propagate to center of pad row and extract parameters
1082 AliTrackerBase::PropagateTrackTo(track,roc->GetPadRowRadii(0,iRow),kMass,5,kFALSE,kMaxSnp);
1083 xCur = track->GetX();
1084 yCur = track->GetY();
1085 zCur = track->GetZ();
1086 secCur = GetSector(track);
1088 // Find the nearest cluster (TODO: correct road settings!)
1089 //Printf("inner tracking here: x = %.2f, y = %.2f, z = %.6f (Row %d Sector %d)",xCur,yCur,zCur,iRow,secCur);
1090 nearestCluster = fInnerSectorArray[secCur%fkNSectorInner][iRow].FindNearest2(yCur,zCur,roady,roadz,indexCur);
1092 // Look again at -y if nothing found here and the sector changed with respect to the last found cluster
1093 // Increase also the road in this case
1094 if(!nearestCluster && secCur != secOld && secOld > -1){
1095 //Printf("inner tracking here 2: x = %.2f, y = %.2f, z = %.6f (Row %d Sector %d)",xCur,-yCur,zCur,iRow,secCur);
1096 nearestCluster = fInnerSectorArray[secCur%fkNSectorInner][iRow].FindNearest2(-yCur,zCur,roady*100,roadz,indexCur);
1099 // Move to next row if now cluster found
1100 if(!nearestCluster) continue;
1101 //Printf("Nearest Clusters = %d (of %d) ",indexCur,fInnerSectorArray[secCur%fkNSectorInner][iRow].GetN());
1108 // Propagate to center of pad row and extract parameters
1109 AliTrackerBase::PropagateTrackTo(track,roc->GetPadRowRadii(36,iRow-kIRowsTPC-1),kMass,5,kFALSE,kMaxSnp);
1110 xCur = track->GetX();
1111 yCur = track->GetY();
1112 zCur = track->GetZ();
1113 secCur = GetSector(track);
1115 // Find the nearest cluster (TODO: correct road settings!)
1116 Printf("res0 = %d, outer tracking here: x = %.2f, y = %.2f, z = %.6f (Row %d Sector %d)",res0,xCur,yCur,zCur,iRow,secCur);
1117 nearestCluster = fOuterSectorArray[(secCur-fkNSectorInner*2)%fkNSectorOuter][iRow-kIRowsTPC-1].FindNearest2(yCur,zCur,roady,roadz,indexCur);
1119 // Look again at -y if nothing found here and the sector changed with respect to the last found cluster
1120 // Increase also the road in this case
1121 if(!nearestCluster && secCur != secOld && secOld > -1){
1122 Printf("outer tracking here 2: x = %.2f, y = %.2f, z = %.6f (Row %d Sector %d)",xCur,-yCur,zCur,iRow,secCur);
1123 nearestCluster = fOuterSectorArray[(secCur-fkNSectorInner*2)%fkNSectorOuter][iRow-kIRowsTPC-1].FindNearest2(-yCur,zCur,roady*100,roadz,indexCur);
1127 // Move to next row if now cluster found
1128 if(!nearestCluster) continue;
1129 Printf("Nearest Clusters = %d (of %d)",indexCur,fOuterSectorArray[(secCur-fkNSectorInner*2)%fkNSectorOuter][iRow-kIRowsTPC-1].GetN());
1133 // create track point from cluster
1134 SetTrackPointFromCluster(nearestCluster,nearestPoint);
1136 //Printf("Track point = %.2f %.2f %.2f",nearestPoint.GetX(),nearestPoint.GetY(),nearestPoint.GetZ());
1138 // rotate the cluster to the local detector frame
1139 track->Rotate(((nearestCluster->GetDetector()%18)*20+10)*TMath::DegToRad());
1140 AliTrackPoint prot = nearestPoint.Rotate(track->GetAlpha()); // rotate to the local frame - non distoted point
1141 if (TMath::Abs(prot.GetX())<kRTPC0) continue;
1142 if (TMath::Abs(prot.GetX())>kRTPC1) continue;
1145 //Printf("Rotated Track point = %.2f %.2f %.2f",prot.GetX(),prot.GetY(),prot.GetZ());
1147 // update track with the nearest track point
1148 Bool_t res=AliTrackerBase::PropagateTrackTo(track,prot.GetX(),kMass,5,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
1152 if (TMath::Abs(track->GetZ())>kMaxZ) break;
1153 if (TMath::Abs(track->GetX())>kMaxR) break;
1154 //if (TMath::Abs(track->GetZ())<kZcut)continue;
1156 Double_t pointPos[2]={0,0};
1157 Double_t pointCov[3]={0,0,0};
1158 pointPos[0]=prot.GetY();//local y
1159 pointPos[1]=prot.GetZ();//local z
1160 pointCov[0]=prot.GetCov()[3];//simay^2
1161 pointCov[1]=prot.GetCov()[4];//sigmayz
1162 pointCov[2]=prot.GetCov()[5];//sigmaz^2
1164 if (!track->Update(pointPos,pointCov)) {printf("no update\n");}
1167 //Printf("Cluster belongs to track = %d",nearestCluster->GetLabel(0));
1169 // only count as associate cluster if it belongs to correct track!
1170 if(nearestCluster->GetLabel(0) == trackID)
1174 Printf("We have %d clusters in this track!",nClus);
1180 //____________________________________________________________________________________
1181 void AliToyMCReconstruction::InitSpaceCharge()
1184 // Init the space charge map
1187 TString filename="$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2_eps5_50kHz_precal.root";
1189 TList *l=fTree->GetUserInfo();
1190 for (Int_t i=0; i<l->GetEntries(); ++i) {
1191 TString s(l->At(i)->GetName());
1192 if (s.Contains("SC_")) {
1199 printf("Initialising the space charge map using the file: '%s'\n",filename.Data());
1200 TFile f(filename.Data());
1201 fTPCCorrection=(AliTPCCorrection*)f.Get("map");
1203 // fTPCCorrection = new AliTPCSpaceCharge3D();
1204 // fTPCCorrection->SetSCDataFileName("$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2_eps10_50kHz.root");
1205 // fTPCCorrection->SetOmegaTauT1T2(0.325,1,1); // Ne CO2
1206 // // fTPCCorrection->SetOmegaTauT1T2(0.41,1,1.05); // Ar CO2
1207 // fTPCCorrection->InitSpaceCharge3DDistortion();
1211 //____________________________________________________________________________________
1212 Double_t AliToyMCReconstruction::GetVDrift() const
1217 return fTPCParam->GetDriftV();
1220 //____________________________________________________________________________________
1221 Double_t AliToyMCReconstruction::GetZLength(Int_t roc) const
1226 if (roc<0 || roc>71) return -1;
1227 return fTPCParam->GetZLength(roc);
1230 //____________________________________________________________________________________
1231 TTree* AliToyMCReconstruction::ConnectTrees (const char* files) {
1232 TString s=gSystem->GetFromPipe(Form("ls %s",files));
1235 TObjArray *arrFiles=s.Tokenize("\n");
1237 for (Int_t ifile=0; ifile<arrFiles->GetEntriesFast(); ++ifile){
1238 TString name(arrFiles->At(ifile)->GetName());
1240 TPRegexp reg(".*([0-9]_[0-9]_[0-9]_[0-9]{3}_[0-9]{2}).debug.root");
1241 TObjArray *arrMatch=0x0;
1242 arrMatch=reg.MatchS(name);
1244 if (arrMatch && arrMatch->At(1)) matchName=arrMatch->At(1)->GetName();
1245 else matchName=Form("%02d",ifile);
1249 TFile *f=TFile::Open(name.Data());
1251 TTree *t=(TTree*)f->Get("Tracks");
1257 t->SetName(matchName.Data());
1260 tFirst->AddFriend(Form("t%s=Tracks",matchName.Data()), name.Data());
1261 // tFirst->AddFriend(Form("t%d=Tracks",ifile), name.Data());
1265 tFirst->GetListOfFriends()->Print();
1269 //____________________________________________________________________________________
1270 Int_t AliToyMCReconstruction::LoadOuterSectors() {
1271 //-----------------------------------------------------------------
1272 // This function fills outer TPC sectors with clusters.
1273 // Copy and paste from AliTPCtracker
1274 //-----------------------------------------------------------------
1275 Int_t nrows = fOuterSectorArray->GetNRows();
1277 for (Int_t sec = 0;sec<fkNSectorOuter;sec++)
1278 for (Int_t row = 0;row<nrows;row++){
1279 AliTPCtrackerRow* tpcrow = &(fOuterSectorArray[sec%fkNSectorOuter][row]);
1280 Int_t sec2 = sec+2*fkNSectorInner;
1282 Int_t ncl = tpcrow->GetN1();
1284 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1285 index=(((sec2<<8)+row)<<16)+ncl;
1286 tpcrow->InsertCluster(c,index);
1289 ncl = tpcrow->GetN2();
1291 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1292 index=((((sec2+fkNSectorOuter)<<8)+row)<<16)+ncl;
1293 tpcrow->InsertCluster(c,index);
1296 // write indexes for fast acces
1298 for (Int_t i=0;i<510;i++)
1299 tpcrow->SetFastCluster(i,-1);
1300 for (Int_t i=0;i<tpcrow->GetN();i++){
1301 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1302 tpcrow->SetFastCluster(zi,i); // write index
1305 for (Int_t i=0;i<510;i++){
1306 if (tpcrow->GetFastCluster(i)<0)
1307 tpcrow->SetFastCluster(i,last);
1309 last = tpcrow->GetFastCluster(i);
1316 //____________________________________________________________________________________
1317 Int_t AliToyMCReconstruction::LoadInnerSectors() {
1318 //-----------------------------------------------------------------
1319 // This function fills inner TPC sectors with clusters.
1320 // Copy and paste from AliTPCtracker
1321 //-----------------------------------------------------------------
1322 Int_t nrows = fInnerSectorArray->GetNRows();
1324 for (Int_t sec = 0;sec<fkNSectorInner;sec++)
1325 for (Int_t row = 0;row<nrows;row++){
1326 AliTPCtrackerRow* tpcrow = &(fInnerSectorArray[sec%fkNSectorInner][row]);
1329 Int_t ncl = tpcrow->GetN1();
1331 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1332 index=(((sec<<8)+row)<<16)+ncl;
1333 tpcrow->InsertCluster(c,index);
1336 ncl = tpcrow->GetN2();
1338 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1339 index=((((sec+fkNSectorInner)<<8)+row)<<16)+ncl;
1340 tpcrow->InsertCluster(c,index);
1343 // write indexes for fast acces
1345 for (Int_t i=0;i<510;i++)
1346 tpcrow->SetFastCluster(i,-1);
1347 for (Int_t i=0;i<tpcrow->GetN();i++){
1348 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1349 tpcrow->SetFastCluster(zi,i); // write index
1352 for (Int_t i=0;i<510;i++){
1353 if (tpcrow->GetFastCluster(i)<0)
1354 tpcrow->SetFastCluster(i,last);
1356 last = tpcrow->GetFastCluster(i);
1363 //____________________________________________________________________________________
1364 Int_t AliToyMCReconstruction::GetSector(AliExternalTrackParam *track) {
1365 //-----------------------------------------------------------------
1366 // This function returns the sector number for a given track
1367 //-----------------------------------------------------------------
1371 // get the sector number
1372 // rotate point to global system (track is already global!)
1375 //track->Local2GlobalPosition(xd,track->GetAlpha());
1377 // use TPCParams to get the sector number
1378 Float_t xyz[3] = {xd[0],xd[1],xd[2]};
1379 Int_t i[3] = {0,0,0};
1381 sector = fTPCParam->Transform0to1(xyz,i);
1387 //____________________________________________________________________________________
1388 void AliToyMCReconstruction::FillSectorStructure(Int_t maxev) {
1389 //-----------------------------------------------------------------
1390 // This function fills the sector structure of AliToyMCReconstruction
1391 //-----------------------------------------------------------------
1393 // cluster array of all sectors
1394 fInnerSectorArray = new AliTPCtrackerSector[fkNSectorInner];
1395 fOuterSectorArray = new AliTPCtrackerSector[fkNSectorOuter];
1397 for (Int_t i=0; i<fkNSectorInner; ++i) fInnerSectorArray[i].Setup(fTPCParam,0);
1398 for (Int_t i=0; i<fkNSectorOuter; ++i) fOuterSectorArray[i].Setup(fTPCParam,1);
1400 Int_t count[72][96] = { {0} , {0} };
1402 for (Int_t iev=0; iev<maxev; ++iev){
1403 printf("============== Fill Clusters: Processing Event %6d =================\n",iev);
1404 fTree->GetEvent(iev);
1405 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
1406 printf(" > ====== Fill Clusters: Processing Track %6d ======== \n",itr);
1407 const AliToyMCTrack *tr=fEvent->GetTrack(itr);
1409 // number of clusters to loop over
1410 const Int_t ncls=(fClusterType==0)?tr->GetNumberOfSpacePoints():tr->GetNumberOfDistSpacePoints();
1412 for(Int_t icl=0; icl<ncls; ++icl){
1414 AliTPCclusterMI *cl=const_cast<AliTPCclusterMI *>(tr->GetSpacePoint(icl));
1415 if (fClusterType==1) cl=const_cast<AliTPCclusterMI *>(tr->GetDistortedSpacePoint(icl));
1418 Int_t sec = cl->GetDetector();
1419 Int_t row = cl->GetRow();
1421 // set Q of the cluster to 1, Q==0 does not work for the seeding
1424 // set cluster time to cluster Z (if not ideal tracking)
1425 if ( !fIdealTracking ) {
1426 // a 'valid' position in z is needed for the seeding procedure
1427 // cl->SetZ(cl->GetTimeBin()*GetVDrift());
1428 cl->SetZ(cl->GetTimeBin());
1430 //Printf("Fill clusters (sector %d row %d): %.2f %.2f %.2f %.2f",sec,row,cl->GetX(),cl->GetY(),cl->GetZ(),cl->GetTimeBin());
1432 // fill arrays for inner and outer sectors (A/C side handled internally)
1433 if (sec<fkNSectorInner*2){
1434 fInnerSectorArray[sec%fkNSectorInner].InsertCluster(cl, count[sec][row], fTPCParam);
1437 fOuterSectorArray[(sec-fkNSectorInner*2)%fkNSectorOuter].InsertCluster(cl, count[sec][row], fTPCParam);
1445 // fill the arrays completely
1446 // LoadOuterSectors();
1447 // LoadInnerSectors();
1449 // // check the arrays
1450 // for (Int_t i=0; i<fkNSectorInner; ++i){
1451 // for (Int_t j=0; j<fInnerSectorArray[i].GetNRows(); ++j){
1452 // if(fInnerSectorArray[i][j].GetN()>0){
1453 // Printf("Inner: Sector %d Row %d : %d",i,j,fInnerSectorArray[i][j].GetN());
1457 // for (Int_t i=0; i<fkNSectorInner; ++i){
1458 // for (Int_t j=0; j<fOuterSectorArray[i].GetNRows(); ++j){
1459 // if(fOuterSectorArray[i][j].GetN()>0){
1460 // Printf("Outer: Sector %d Row %d : %d",i,j,fOuterSectorArray[i][j].GetN());
1466 //____________________________________________________________________________________
1467 void AliToyMCReconstruction::FillSectorStructureAC(Int_t maxev) {
1468 //-----------------------------------------------------------------
1469 // This function fills the sector structure of AliToyMCReconstruction
1470 //-----------------------------------------------------------------
1473 my god is the AliTPCtrackerSector stuff complicated!!!
1474 Ok, so here we will not fill the fClusters1 and fClusters2 of AliTPCtrackerRow,
1475 using InsertCluster of AliTPCtrackerSector, but only the fClusters via InsertCluster
1476 of AliTPCtrackerRow itself which then will not be owner, but we create an array in
1477 here (fAllClusters) which owns all clusters ...
1481 // cluster array of all sectors
1482 fInnerSectorArray = new AliTPCtrackerSector[2*fkNSectorInner];
1483 fOuterSectorArray = new AliTPCtrackerSector[2*fkNSectorOuter];
1485 for (Int_t i=0; i<2*fkNSectorInner; ++i) {
1486 fInnerSectorArray[i].Setup(fTPCParam,0);
1489 for (Int_t i=0; i<2*fkNSectorOuter; ++i) {
1490 fOuterSectorArray[i].Setup(fTPCParam,1);
1493 Int_t count[72][96] = { {0} , {0} };
1495 for (Int_t iev=0; iev<maxev; ++iev){
1496 printf("============== Fill Clusters: Processing Event %6d =================\n",iev);
1497 fTree->GetEvent(iev);
1498 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
1499 printf(" > ====== Fill Clusters: Processing Track %6d ======== \n",itr);
1500 const AliToyMCTrack *tr=fEvent->GetTrack(itr);
1502 // number of clusters to loop over
1503 const Int_t ncls=(fClusterType==0)?tr->GetNumberOfSpacePoints():tr->GetNumberOfDistSpacePoints();
1505 // check if expansion of the cluster arrays is needed.
1506 if (fAllClusters.GetEntriesFast()+ncls>=fAllClusters.Capacity()) fAllClusters.Expand(2*fAllClusters.Capacity());
1507 for(Int_t icl=0; icl<ncls; ++icl){
1509 AliTPCclusterMI *cl=const_cast<AliTPCclusterMI *>(tr->GetSpacePoint(icl));
1510 if (fClusterType==1) cl=const_cast<AliTPCclusterMI *>(tr->GetDistortedSpacePoint(icl));
1513 // register copy to the cluster array
1514 cl = new(fAllClusters[fAllClusters.GetEntriesFast()]) AliTPCclusterMI(*cl);
1516 Int_t sec = cl->GetDetector();
1517 Int_t row = cl->GetRow();
1519 // set Q of the cluster to 1, Q==0 does not work for the seeding
1522 // set cluster time to cluster Z (if not ideal tracking)
1523 if ( !fIdealTracking ) {
1524 // a 'valid' position in z is needed for the seeding procedure
1525 cl->SetZ(cl->GetTimeBin()*GetVDrift());
1526 // cl->SetZ(cl->GetTimeBin());
1528 //Printf("Fill clusters (sector %d row %d): %.2f %.2f %.2f %.2f",sec,row,cl->GetX(),cl->GetY(),cl->GetZ(),cl->GetTimeBin());
1530 // fill arrays for inner and outer sectors (A/C side handled internally)
1531 if (sec<fkNSectorInner*2){
1532 fInnerSectorArray[sec][row].InsertCluster(cl, count[sec][row]);
1535 fOuterSectorArray[(sec-fkNSectorInner*2)][row].InsertCluster(cl, count[sec][row]);
1545 //____________________________________________________________________________________
1546 AliToyMCTrack *AliToyMCReconstruction::ConvertTPCSeedToToyMCTrack(const AliTPCseed &seed)
1553 AliToyMCTrack *tToy = new AliToyMCTrack(seed);
1555 for (Int_t icl=0; icl<159; ++icl){
1556 const AliTPCclusterMI *cl=seed.GetClusterFast(icl);
1558 if (fClusterType==0){
1559 tToy->AddSpacePoint(*cl);
1561 tToy->AddDistortedSpacePoint(*cl);
1568 //____________________________________________________________________________________
1569 AliExternalTrackParam* AliToyMCReconstruction::GetRefittedTrack(const AliTPCseed &seed)
1575 AliExternalTrackParam *track=0x0;
1577 const Float_t vDrift=GetVDrift();
1578 const Float_t zLength=GetZLength(0);
1579 const Double_t kMaxSnp = 0.85;
1580 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
1582 // for propagation use a copy
1583 AliExternalTrackParam t0seed(seed);
1584 AliTrackerBase::PropagateTrackTo(&t0seed,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
1585 fTime0 = t0seed.GetZ()-zLength/vDrift;
1586 fCreateT0seed = kFALSE;
1588 AliToyMCTrack *toyTrack = ConvertTPCSeedToToyMCTrack(seed);
1590 fTime0 = t0seed.GetZ()-zLength/vDrift;
1591 fCreateT0seed = kFALSE;
1592 // printf("seed (%.2g)\n",fTime0);
1593 AliExternalTrackParam *dummy = GetSeedFromTrack(toyTrack);
1595 track = GetFittedTrackFromSeed(toyTrack, dummy);
1597 // propagate seed to 0
1598 AliTrackerBase::PropagateTrackTo(track,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
1605 //____________________________________________________________________________________
1606 AliTPCclusterMI* AliToyMCReconstruction::FindMiddleCluster(const AliTPCclusterMI *clInner, const AliTPCclusterMI *clOuter,
1607 Double_t roady, Double_t roadz,
1614 const Int_t rocInner = clInner->GetDetector();
1615 const Int_t rocOuter = clOuter->GetDetector();
1617 if ( (rocInner%18) != (rocOuter%18) ){
1618 AliError("Currently only same Sector implemented");
1622 const Int_t innerDet=clInner->GetDetector();
1623 const Int_t outerDet=clOuter->GetDetector();
1624 const Int_t globalRowInner = clInner->GetRow() +(innerDet >35)*63;
1625 const Int_t globalRowOuter = clOuter->GetRow() +(outerDet >35)*63;
1627 Int_t iMiddle = (globalRowInner+globalRowOuter)/2;
1628 Int_t roc = innerDet;
1634 const AliTPCtrackerRow& krMiddle = fOuterSectorArray[roc%36][iMiddle]; // middle
1635 // initial guess use simple linear interpolation
1636 Double_t y=(clInner->GetY()+clOuter->GetY())/2;
1637 Double_t z=(clInner->GetZ()+clOuter->GetZ())/2;
1638 if (seedFit.IsValid()) {
1639 // update values once the fit was performed
1640 y=seedFit.GetYat(krMiddle.GetX());
1641 z=seedFit.GetZat(krMiddle.GetX());
1644 AliTPCclusterMI *n=krMiddle.FindNearest(y,z,roady,roadz);
1646 // printf(" Nearest cluster (%.2f, %.2f, %.2f) = m(%.2f, %.2f, %.2f : %d) i(%.2f, %.2f , %.2f : %d) o(%.2f, %.2f, %.2f : %d)\n",krMiddle.GetX(),y,z,
1647 // n->GetX(), n->GetY(),n->GetZ(),n->GetLabel(0),
1648 // clInner->GetX(), clInner->GetY(),clInner->GetZ(),clInner->GetLabel(0),
1649 // clOuter->GetX(), clOuter->GetY(),clOuter->GetZ(),clOuter->GetLabel(0)
1654 //____________________________________________________________________________________
1655 void AliToyMCReconstruction::AddMiddleClusters(AliTPCseed *seed,
1656 const AliTPCclusterMI *clInner, const AliTPCclusterMI *clOuter,
1657 Double_t roady, Double_t roadz,
1658 Int_t &nTotalClusters, AliRieman &seedFit)
1661 // Iteratively add the middle clusters
1664 // update rieman fit with every second point added
1665 AliTPCclusterMI *clMiddle=FindMiddleCluster(clInner,clOuter,roady,roadz,seedFit);
1667 // break iterative process
1668 if (!clMiddle) return;
1670 const Int_t globalRowInner = clInner->GetRow() +(clInner->GetDetector() >35)*63;
1671 const Int_t globalRowMiddle = clMiddle->GetRow()+(clMiddle->GetDetector()>35)*63;
1672 const Int_t globalRowOuter = clOuter->GetRow() +(clOuter->GetDetector() >35)*63;
1674 seed->SetClusterPointer(globalRowMiddle,clMiddle);
1676 // printf(" > Total clusters: %d\n",nTotalClusters);
1677 seedFit.AddPoint(clMiddle->GetX(), clMiddle->GetY(), clMiddle->GetZ(),
1678 TMath::Sqrt(clMiddle->GetSigmaY2()), TMath::Sqrt(clMiddle->GetSigmaZ2()));
1680 if (!(seedFit.GetN()%3)) {
1681 // printf(" call update: %d (%d)\n",seedFit.GetN(),nTotalClusters);
1682 // printf(" Riemann results: valid=%d, Chi2=%.2f, Chi2Y=%.2f, Chi2Z=%.2f\n",
1683 // seedFit.IsValid(), seedFit.GetChi2(), seedFit.GetChi2Y(), seedFit.GetChi2Z());
1686 if ( seedFit.IsValid() && seedFit.GetChi2()>1000 ) return;
1688 // Add middle clusters towards outer radius
1689 if (globalRowMiddle+1<globalRowOuter) AddMiddleClusters(seed,clMiddle,clOuter,roady,roadz,nTotalClusters,seedFit);
1691 // Add middle clusters towards innter radius
1692 if (globalRowInner+1<globalRowMiddle) AddMiddleClusters(seed,clInner,clMiddle,roady,roadz,nTotalClusters,seedFit);
1697 //____________________________________________________________________________________
1698 void AliToyMCReconstruction::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t iRowInner, Int_t iRowOuter)
1701 // find seeds in a sector, requires iRowInner < iRowOuter
1702 // iRowXXX runs from 0-159, so over IROC and OROC
1706 AliError("This function requires the sector arrays filled for AC tracking");
1710 // swap rows in case they are in the wrong order
1711 if (iRowInner>iRowOuter) {
1712 Int_t tmp=iRowInner;
1713 iRowInner=iRowOuter;
1717 // only for CookLabel
1718 AliTPCtracker tpcTracker(fTPCParam);
1720 // Define the search roads:
1721 // timeRoadCombinatorics - the maximum time difference used for the
1722 // combinatorics. Since we don't have a 'z-Vertex' estimate this will
1723 // reduce the combinatorics significantly when iterating on one TF
1724 // use a little more than one full drift length of the TPC to allow for
1727 // timeRoad - the time difference allowed when associating the cluster
1728 // in the middle of the other two used for the initial search
1730 // padRoad - the local y difference allowed when associating the middle cluster
1731 Float_t vDrift=GetVDrift();
1732 Float_t zLength=GetZLength(0);
1734 // Double_t timeRoadCombinatorics = 270./vDrift;
1735 // Double_t timeRoad = 20./vDrift;
1736 Double_t timeRoadCombinatorics = 270.;
1737 Double_t timeRoad = 20.;
1738 Double_t padRoad = 10.;
1741 // fOuterSectorArray runs from 0-95, so from iRowXXX which runs from 0-159
1742 // the number of rows in the IROC has to be subtracted
1743 const Int_t innerRows=fInnerSectorArray->GetNRows();
1744 const AliTPCtrackerRow& krOuter = fOuterSectorArray[sec][iRowOuter - innerRows]; // down
1745 const AliTPCtrackerRow& krInner = fOuterSectorArray[sec][iRowInner - innerRows]; // up
1747 AliTPCseed *seed = new AliTPCseed;
1749 const Int_t nMaxClusters=iRowOuter-iRowInner+1;
1750 // Int_t nScannedClusters = 0;
1752 // loop over all points in the firstand last search row
1753 for (Int_t iOuter=0; iOuter < krOuter; iOuter++) {
1754 const AliTPCclusterMI *clOuter = krOuter[iOuter];
1755 for (Int_t iInner=0; iInner < krInner; iInner++) {
1756 const AliTPCclusterMI *clInner = krInner[iInner];
1757 // printf("\n\n Check combination %d (%d), %d (%d)\n",iOuter, iInner, clOuter->GetLabel(0), clInner->GetLabel(0));
1758 // check maximum distance for combinatorics
1759 if (TMath::Abs(clOuter->GetZ()-clInner->GetZ())>timeRoadCombinatorics) continue;
1760 // printf(" Is inside one drift\n");
1762 // use rieman fit for seed description
1763 AliRieman seedFit(159);
1764 // add first two points
1765 seedFit.AddPoint(clInner->GetX(), clInner->GetY(), clInner->GetZ(),
1766 TMath::Sqrt(clInner->GetSigmaY2()), TMath::Sqrt(clInner->GetSigmaZ2()));
1767 seedFit.AddPoint(clOuter->GetX(), clOuter->GetY(), clOuter->GetZ(),
1768 TMath::Sqrt(clOuter->GetSigmaY2()), TMath::Sqrt(clOuter->GetSigmaZ2()));
1770 // Iteratively add all clusters in the respective middle
1771 Int_t nFoundClusters=2;
1772 AddMiddleClusters(seed,clInner,clOuter,padRoad,timeRoad,nFoundClusters,seedFit);
1773 // printf(" Clusters attached: %d\n",nFoundClusters);
1775 // printf(" Riemann results: valid=%d, Chi2=%.2f, Chi2Y=%.2f, Chi2Z=%.2f\n",
1776 // seedFit.IsValid(), seedFit.GetChi2(), seedFit.GetChi2Y(), seedFit.GetChi2Z());
1778 // check for minimum number of assigned clusters and a decent chi2
1779 if ( nFoundClusters<0.5*nMaxClusters || seedFit.GetChi2()>1000 ){
1783 // printf(" >>> Seed accepted\n");
1784 // add original outer clusters
1785 const Int_t globalRowInner = clInner->GetRow() +(clInner->GetDetector() >35)*63;
1786 const Int_t globalRowOuter = clOuter->GetRow() +(clOuter->GetDetector() >35)*63;
1788 seed->SetClusterPointer(globalRowInner,const_cast<AliTPCclusterMI*>(clInner));
1789 seed->SetClusterPointer(globalRowOuter,const_cast<AliTPCclusterMI*>(clOuter));
1791 // set parameters retrieved from AliRieman
1792 Double_t params[5]={0};
1793 Double_t covar[15]={0};
1794 const Double_t alpha=TMath::DegToRad()*(clInner->GetDetector()%18*20.+10.);
1795 const Double_t x=clInner->GetX();
1796 seedFit.GetExternalParameters(x,params,covar);
1798 seed->Set(x,alpha,params,covar);
1800 // set label of the seed. At least 60% of the clusters need the correct label
1801 tpcTracker.CookLabel(seed,.6);
1804 seed=new AliTPCseed;
1807 //delete surplus seed
1812 if (fStreamer && fTree) {
1813 //loop over all events and tracks and try to associate the seed to the track
1815 const Double_t kMaxSnp = 0.85;
1816 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
1818 for (Int_t iseed=0; iseed<arr->GetEntriesFast(); ++iseed){
1819 seed = static_cast<AliTPCseed*>(arr->UncheckedAt(iseed));
1820 AliExternalTrackParam extSeed(*seed);
1821 AliTrackerBase::PropagateTrackTo(&extSeed,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
1822 Int_t seedLabel=seed->GetLabel();
1824 // get original track
1825 Int_t iev=fMapTrackEvent.GetValue(TMath::Abs(seedLabel));
1826 Int_t itr=fMapTrackTrackInEvent.GetValue(TMath::Abs(seedLabel));
1828 fTree->GetEvent(iev);
1829 const AliToyMCTrack *toyTrack = fEvent->GetTrack(itr);
1831 AliExternalTrackParam extTrack(*toyTrack);
1833 //propagate to same reference frame
1834 extSeed.Rotate(extTrack.GetAlpha());
1835 AliTrackerBase::PropagateTrackTo(&extSeed,0,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
1837 fTime0=extSeed.GetZ()/vDrift;
1839 Float_t z0=fEvent->GetZ();
1840 Float_t t0=fEvent->GetT0();
1842 Int_t ctype(fCorrectionType);
1844 (*fStreamer) << "Seeds" <<
1848 "fTime0=" << fTime0 <<
1850 "clsType=" << fClusterType <<
1851 "corrType=" << ctype <<
1852 "seedRow=" << fSeedingRow <<
1853 "seedDist=" << fSeedingDist <<
1854 "vDrift=" << vDrift <<
1855 "zLength=" << zLength <<
1856 "track.=" << &extSeed <<
1857 "tOrig.=" << &extTrack <<
1858 "seedLabel=" << seedLabel <<
1864 //____________________________________________________________________________________
1865 void AliToyMCReconstruction::MakeSeeds(TObjArray * /*arr*/, Int_t sec, Int_t iRow1, Int_t iRow2)
1868 // Create seeds between i1 and i2 (stored in arr) with TLinearFitter
1870 // sec: sector number
1876 static TLinearFitter fitter(3,"pol2");
1878 // Get 3 padrows (iRow1,iMiddle=(iRow1+iRow2)/2,iRow2)
1879 Int_t iMiddle = (iRow1+iRow2)/2;
1880 const AliTPCtrackerRow& krd = fOuterSectorArray[sec][iRow2-fInnerSectorArray->GetNRows()]; // down
1881 const AliTPCtrackerRow& krm = fOuterSectorArray[sec][iMiddle-fInnerSectorArray->GetNRows()]; // middle
1882 const AliTPCtrackerRow& kru = fOuterSectorArray[sec][iRow1-fInnerSectorArray->GetNRows()]; // up
1884 // Loop over 3 cluster possibilities
1885 for (Int_t iu=0; iu < kru; iu++) {
1886 for (Int_t im=0; im < krm; im++) {
1887 for (Int_t id=0; id < krd; id++) {
1890 fitter.ClearPoints();
1892 // add all three points to fitter
1893 Double_t xy[2] = {kru[iu]->GetX(),kru[iu]->GetY()};
1894 Double_t z = kru[iu]->GetZ();
1895 fitter.AddPoint(xy,z);
1897 xy[0] = krm[im]->GetX();
1898 xy[1] = krm[im]->GetY();
1899 z = krm[im]->GetZ();
1900 fitter.AddPoint(xy,z);
1902 xy[0] = krd[id]->GetX();
1903 xy[1] = krd[id]->GetY();
1904 z = krd[id]->GetZ();
1905 fitter.AddPoint(xy,z);
1907 // Evaluate and get parameters
1910 // how to get the other clusters now?
1918 //____________________________________________________________________________________
1919 void AliToyMCReconstruction::InitStreamer(const char* /*addName*/, Int_t /*level*/)
1922 // initilise the debug streamer and set the logging level
1923 // use a default naming convention
1928 //____________________________________________________________________________________
1929 void AliToyMCReconstruction::ConnectInputFile(const char* file)
1932 // connect the tree and event pointer from the input file
1940 fInputFile=TFile::Open(file);
1941 if (!fInputFile || !fInputFile->IsOpen() || fInputFile->IsZombie()) {
1944 printf("ERROR: couldn't open the file '%s'\n", file);
1948 fTree=(TTree*)fInputFile->Get("toyMCtree");
1950 printf("ERROR: couldn't read the 'toyMCtree' from file '%s'\n", file);
1955 fTree->SetBranchAddress("event",&fEvent);
1962 //____________________________________________________________________________________
1963 void AliToyMCReconstruction::Cleanup()
1966 // Cleanup input data
1983 //____________________________________________________________________________________
1984 void AliToyMCReconstruction::SetupTrackMaps()
1990 fMapTrackEvent.Delete();
1991 fMapTrackTrackInEvent.Delete();
1994 AliError("Tree not connected");
1998 for (Int_t iev=0; iev<fTree->GetEntries(); ++iev) {
1999 fTree->GetEvent(iev);
2000 if (!fEvent) continue;
2002 const Int_t ntracks=fEvent->GetNumberOfTracks();
2003 if (fMapTrackEvent.GetSize()+ntracks>=fMapTrackEvent.Capacity()) fMapTrackEvent.Expand(2*fMapTrackEvent.Capacity());
2004 if (fMapTrackTrackInEvent.GetSize()+ntracks>=fMapTrackTrackInEvent.Capacity()) fMapTrackTrackInEvent.Expand(2*fMapTrackTrackInEvent.Capacity());
2006 for (Int_t itrack=0; itrack<ntracks; ++itrack){
2007 Int_t label=fEvent->GetTrack(itrack)->GetUniqueID();
2009 fMapTrackEvent.Add(label,iev);
2010 fMapTrackTrackInEvent.Add(label,itrack);