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)
48 , fCreateT0seed(kFALSE)
55 , fkNSectorInner(18) // hard-coded to avoid loading the parameters before
56 , fInnerSectorArray(0x0)
57 , fkNSectorOuter(18) // hard-coded to avoid loading the parameters before
58 , fOuterSectorArray(0x0)
59 , fAllClusters("AliTPCclusterMI",10000)
60 , fMapTrackEvent(10000)
61 , fMapTrackTrackInEvent(10000)
67 fTPCParam=AliTPCcalibDB::Instance()->GetParameters();
71 //____________________________________________________________________________________
72 AliToyMCReconstruction::~AliToyMCReconstruction()
81 //____________________________________________________________________________________
82 void AliToyMCReconstruction::RunReco(const char* file, Int_t nmaxEv)
85 // Recostruction from associated clusters
88 ConnectInputFile(file, nmaxEv);
91 InitStreamer(".debug");
95 static AliExternalTrackParam dummySeedT0;
96 static AliExternalTrackParam dummySeed;
97 static AliExternalTrackParam dummyTrack;
99 AliExternalTrackParam t0seed;
100 AliExternalTrackParam seed;
101 AliExternalTrackParam track;
102 AliExternalTrackParam trackITS;
103 AliExternalTrackParam tOrig;
104 AliExternalTrackParam tOrigITS;
106 AliExternalTrackParam *dummy;
108 Int_t maxev=fTree->GetEntries();
109 if (nmaxEv>0&&nmaxEv<maxev) maxev=nmaxEv;
111 for (Int_t iev=0; iev<maxev; ++iev){
112 printf("============== Processing Event %6d =================\n",iev);
113 fTree->GetEvent(iev);
114 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
115 // printf(" > ====== Processing Track %6d ======== \n",itr);
116 const AliToyMCTrack *tr=fEvent->GetTrack(itr);
121 t0seed = dummySeedT0;
125 Float_t z0=fEvent->GetZ();
126 Float_t t0=fEvent->GetT0();
128 Float_t vDrift=GetVDrift();
129 Float_t zLength=GetZLength(0);
131 // crate time0 seed, steered by fCreateT0seed
132 // printf("t0 seed\n");
135 dummy = GetSeedFromTrack(tr);
141 // crate real seed using the time 0 from the first seed
142 // set fCreateT0seed now to false to get the seed in z coordinates
143 fTime0 = t0seed.GetZ()-zLength/vDrift;
144 fCreateT0seed = kFALSE;
145 // printf("seed (%.2g)\n",fTime0);
146 dummy = GetSeedFromTrack(tr);
151 // create fitted track
153 // printf("track\n");
154 dummy = GetFittedTrackFromSeed(tr, &seed);
159 // Copy original track and fitted track
160 // for extrapolation to ITS last layer
164 // propagate seed to 0
165 const Double_t kMaxSnp = 0.85;
166 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
167 AliTrackerBase::PropagateTrackTo(&seed,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
169 // propagate original track to ITS last layer
170 Double_t lastLayerITS = 43.0; // same as in AliToyMCEventGenerator::MakeITSClusters (hard coded)
171 AliTrackerBase::PropagateTrackTo(&tOrigITS,lastLayerITS,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
173 // rotate fitted track to the frame of the original track and propagate to same reference
174 AliTrackerBase::PropagateTrackTo(&trackITS,lastLayerITS,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
175 trackITS.Rotate(tOrigITS.GetAlpha());
176 AliTrackerBase::PropagateTrackTo(&trackITS,lastLayerITS,kMass,1,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
182 Int_t ctype(fCorrectionType);
185 (*fStreamer) << "Tracks" <<
189 "fTime0=" << fTime0 <<
191 "clsType=" << fClusterType <<
192 "corrType=" << ctype <<
193 "seedRow=" << fSeedingRow <<
194 "seedDist=" << fSeedingDist <<
195 "vDrift=" << vDrift <<
196 "zLength=" << zLength <<
197 "t0seed.=" << &t0seed <<
199 "track.=" << &track <<
200 "tOrig.=" << &tOrig <<
201 "trackITS.=" << &trackITS <<
202 "tOrigITS.=" << &tOrigITS <<
214 //____________________________________________________________________________________
215 void AliToyMCReconstruction::RunRecoAllClusters(const char* file, Int_t nmaxEv)
218 // Reconstruction for seed from associated clusters, but array of clusters:
219 // Step 1) Filling of cluster arrays
220 // Step 2) Seeding from clusters associated to tracks
221 // Step 3) Free track reconstruction using all clusters
225 if (!f.IsOpen() || f.IsZombie()) {
226 printf("ERROR: couldn't open the file '%s'\n", file);
230 fTree=(TTree*)f.Get("toyMCtree");
232 printf("ERROR: couldn't read the 'toyMCtree' from file '%s'\n", file);
237 fTree->SetBranchAddress("event",&fEvent);
239 // read spacecharge from the Userinfo ot the tree
242 TString debugName=file;
243 debugName.ReplaceAll(".root","");
244 debugName.Append(Form(".%1d.%1d_%1d_%1d_%03d_%02d",
245 fUseMaterial,fIdealTracking,fClusterType,
246 Int_t(fCorrectionType),fSeedingRow,fSeedingDist));
247 debugName.Append(".allClusters.debug.root");
249 gSystem->Exec(Form("test -f %s && rm %s", debugName.Data(), debugName.Data()));
250 if (!fStreamer) fStreamer=new TTreeSRedirector(debugName.Data());
254 static AliExternalTrackParam dummySeedT0;
255 static AliExternalTrackParam dummySeed;
256 static AliExternalTrackParam dummyTrack;
258 AliExternalTrackParam t0seed;
259 AliExternalTrackParam seed;
260 AliExternalTrackParam track;
261 AliExternalTrackParam tOrig;
263 AliExternalTrackParam *dummy;
265 Int_t maxev=fTree->GetEntries();
266 if (nmaxEv>0&&nmaxEv<maxev) maxev=nmaxEv;
268 // ===========================================================================================
269 // Loop 1: Fill AliTPCtrackerSector structure
270 // ===========================================================================================
271 FillSectorStructure(maxev);
273 // settings (TODO: find the correct settings)
274 AliTPCRecoParam *tpcRecoParam = new AliTPCRecoParam();
275 tpcRecoParam->SetDoKinks(kFALSE);
276 AliTPCcalibDB::Instance()->GetTransform()->SetCurrentRecoParam(tpcRecoParam);
277 //tpcRecoParam->Print();
279 // need AliTPCReconstructor for parameter settings in AliTPCtracker
280 AliTPCReconstructor *tpcRec = new AliTPCReconstructor();
281 tpcRec->SetRecoParam(tpcRecoParam);
284 // ===========================================================================================
285 // Loop 2: Seeding from clusters associated to tracks
286 // TODO: Implement tracking from given seed!
287 // ===========================================================================================
288 for (Int_t iev=0; iev<maxev; ++iev){
289 printf("============== Processing Event %6d =================\n",iev);
290 fTree->GetEvent(iev);
291 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
292 printf(" > ====== Processing Track %6d ======== \n",itr);
293 const AliToyMCTrack *tr=fEvent->GetTrack(itr);
298 t0seed = dummySeedT0;
302 Float_t z0=fEvent->GetZ();
303 Float_t t0=fEvent->GetT0();
305 Float_t vDrift=GetVDrift();
306 Float_t zLength=GetZLength(0);
310 // crate time0 seed, steered by fCreateT0seed
314 dummy = GetSeedFromTrack(tr);
320 // crate real seed using the time 0 from the first seed
321 // set fCreateT0seed now to false to get the seed in z coordinates
322 fTime0 = t0seed.GetZ()-zLength/vDrift;
323 fCreateT0seed = kFALSE;
324 printf("seed (%.2g)\n",fTime0);
325 dummy = GetSeedFromTrack(tr);
330 // create fitted track
333 dummy = GetFittedTrackFromSeedAllClusters(tr, &seed,nClus);
338 // propagate seed to 0
339 const Double_t kMaxSnp = 0.85;
340 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
341 AliTrackerBase::PropagateTrackTo(&seed,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,kFALSE);
346 Int_t ctype(fCorrectionType);
349 (*fStreamer) << "Tracks" <<
353 "fTime0=" << fTime0 <<
355 "clsType=" << fClusterType <<
356 "corrType=" << ctype <<
357 "seedRow=" << fSeedingRow <<
358 "seedDist=" << fSeedingDist <<
359 "vDrift=" << vDrift <<
360 "zLength=" << zLength <<
362 "t0seed.=" << &t0seed <<
364 "track.=" << &track <<
365 "tOrig.=" << &tOrig <<
385 //____________________________________________________________________________________
386 void AliToyMCReconstruction::RunRecoAllClustersStandardTracking(const char* file, Int_t nmaxEv)
389 // Reconstruction for seed from associated clusters, but array of clusters
390 // Step 1) Filling of cluster arrays
391 // Step 2) Use the standard tracking: AliTPCtracker::Clusters2Tracks();
395 if (!f.IsOpen() || f.IsZombie()) {
396 printf("ERROR: couldn't open the file '%s'\n", file);
400 fTree=(TTree*)f.Get("toyMCtree");
402 printf("ERROR: couldn't read the 'toyMCtree' from file '%s'\n", file);
407 fTree->SetBranchAddress("event",&fEvent);
409 // read spacecharge from the Userinfo ot the tree
412 TString debugName=file;
413 debugName.ReplaceAll(".root","");
414 debugName.Append(Form(".%1d.%1d_%1d_%1d_%03d_%02d",
415 fUseMaterial,fIdealTracking,fClusterType,
416 Int_t(fCorrectionType),fSeedingRow,fSeedingDist));
417 debugName.Append(".allClusters.debug.root");
419 gSystem->Exec(Form("test -f %s && rm %s", debugName.Data(), debugName.Data()));
420 if (!fStreamer) fStreamer=new TTreeSRedirector(debugName.Data());
424 AliExternalTrackParam t0seed;
425 AliExternalTrackParam seed;
426 AliExternalTrackParam track;
427 AliExternalTrackParam tOrig;
428 AliToyMCTrack tOrigToy;
430 AliExternalTrackParam *dummy;
431 AliTPCseed *seedBest;
433 AliTPCclusterMI *cluster;
435 Int_t maxev=fTree->GetEntries();
436 if (nmaxEv>0&&nmaxEv<maxev) maxev=nmaxEv;
439 // ===========================================================================================
440 // Loop 1: Fill AliTPCtrackerSector structure
441 // ===========================================================================================
442 FillSectorStructure(maxev);
444 // ===========================================================================================
445 // Loop 2: Use the TPC tracker for seeding (MakeSeeds3)
446 // TODO: - check tracking configuration
447 // - add clusters and original tracks to output (how?)
448 // ===========================================================================================
450 // settings (TODO: find the correct settings)
451 AliTPCRecoParam *tpcRecoParam = new AliTPCRecoParam();
452 tpcRecoParam->SetDoKinks(kFALSE);
453 AliTPCcalibDB::Instance()->GetTransform()->SetCurrentRecoParam(tpcRecoParam);
454 //tpcRecoParam->Print();
456 // need AliTPCReconstructor for parameter settings in AliTPCtracker
457 AliTPCReconstructor *tpcRec = new AliTPCReconstructor();
458 tpcRec->SetRecoParam(tpcRecoParam);
461 AliTPCtracker *tpcTracker = new AliTPCtracker(fTPCParam);
462 tpcTracker->SetDebug(10);
465 tpcTracker->SetTPCtrackerSectors(fInnerSectorArray,fOuterSectorArray);
466 tpcTracker->LoadInnerSectors();
467 tpcTracker->LoadOuterSectors();
470 static TObjArray arrTracks;
471 TObjArray * arr = &arrTracks;
472 TObjArray * seeds = new TObjArray;
476 // cuts[0]=0.0070; // cuts[0] - fP4 cut
477 // cuts[1] = 1.5; // cuts[1] - tan(phi) cut
478 // cuts[2] = 3.; // cuts[2] - zvertex cut
479 // cuts[3] = 3.; // cuts[3] - fP3 cut
482 Int_t lowerRow = fSeedingRow;
483 Int_t upperRow = fSeedingRow+2*fSeedingDist;
484 const AliTPCROC * roc = AliTPCROC::Instance();
485 const Int_t kNRowsInnerTPC = roc->GetNRows(0);
486 const Int_t kNRowsTPC = kNRowsInnerTPC + roc->GetNRows(36);
487 if(lowerRow < kNRowsInnerTPC){
488 Printf("Seeding row requested (%d) is lower than kNRowsInnerTPC --> use %d",lowerRow,kNRowsInnerTPC);
489 lowerRow = kNRowsInnerTPC;
490 upperRow = lowerRow + 20;
492 if(upperRow >= kNRowsTPC){
493 Printf("Seeding row requested (%d) is larger than kNRowsTPC --> use %d",upperRow,kNRowsTPC-1);
494 upperRow = kNRowsTPC-1;
495 lowerRow = upperRow-20;
499 for (Int_t sec=0;sec<fkNSectorOuter;sec++){
501 //tpcTracker->MakeSeeds3(arr, sec,upperRow,lowerRow,cuts,-1,1);
502 MakeSeeds(arr, sec,upperRow,lowerRow); // own function (based on TLinearFitter)
503 //tpcTracker->SumTracks(seeds,arr);
504 //tpcTracker->SignClusters(seeds,3.0,3.0);
508 Printf("After seeding we have %d tracks",seeds->GetEntriesFast());
511 tpcTracker->SetSeeds(seeds);
512 tpcTracker->PropagateForward();
513 Printf("After trackinging we have %d tracks",seeds->GetEntriesFast());
516 // Loop over all input tracks and connect to found seeds
517 for (Int_t iev=0; iev<maxev; ++iev){
518 printf("============== Fill Tracks: Processing Event %6d =================\n",iev);
519 fTree->GetEvent(iev);
520 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
521 printf(" > ====== Fill Tracks: Processing Track %6d ======== \n",itr);
522 const AliToyMCTrack *tr=fEvent->GetTrack(itr);
526 Float_t z0=fEvent->GetZ();
527 Float_t t0=fEvent->GetT0();
528 Float_t vDrift=GetVDrift();
529 Float_t zLength=GetZLength(0);
531 // find the corresponding seed (and track)
532 Int_t trackID = tr->GetUniqueID();
533 Int_t nClustersMC = tr->GetNumberOfSpacePoints(); // number of findable clusters (ideal)
535 nClustersMC = tr->GetNumberOfDistSpacePoints(); // number of findable clusters (distorted)
536 // Int_t idxSeed = 0; // index of best seed (best is with maximum number of clusters with correct ID)
537 Int_t nSeeds = 0; // number of seeds for MC track
538 Int_t nSeedClusters = 0; // number of clusters for best seed
539 Int_t nSeedClustersTmp = 0; // number of clusters for current seed
540 Int_t nSeedClustersID = 0; // number of clusters with correct ID for best seed
541 Int_t nSeedClustersIDTmp = 0; // number of clusters with correct ID for current seed
542 for(Int_t iSeeds = 0; iSeeds < seeds->GetEntriesFast(); ++iSeeds){
544 // set current seed and reset counters
545 seedTmp = (AliTPCseed*)(seeds->At(iSeeds));
546 nSeedClustersTmp = 0;
547 nSeedClustersIDTmp = 0;
549 if(!seedTmp) continue;
551 // loop over all rows
552 for(Int_t iRow = seedTmp->GetRow(); iRow < seedTmp->GetRow() + seedTmp->GetNumberOfClustersIndices(); iRow++ ){
554 // get cluster and increment counters
555 cluster = seedTmp->GetClusterFast(iRow);
558 if(cluster->GetLabel(0)==trackID){
559 nSeedClustersIDTmp++;
564 // if number of corresponding clusters > 0,
566 if(nSeedClustersTmp > 0){
570 // if number of corresponding clusters bigger than current nSeedClusters,
571 // take this seed as the best one
572 if(nSeedClustersIDTmp > nSeedClustersID){
575 nSeedClusters = nSeedClustersTmp; // number of correctly assigned clusters
576 nSeedClustersID = nSeedClustersIDTmp; // number of all clusters
581 // cluster to track association (commented out, when used standard tracking)
582 if (nSeeds>0&&nSeedClusters>0) {
583 t0seed = (AliExternalTrackParam)*seedBest;
584 // fTime0 = t0seed.GetZ()-zLength/vDrift;
585 // get the refitted track from the seed
586 // this will also set the fTime0 from the seed extrapolation
587 dummy=GetRefittedTrack(*seedBest);
590 //printf("seed (%.2g): %d seeds with %d clusters\n",fTime0,nSeeds,nSeedClusters);
592 // // cluster to track association for all good seeds
593 // // set fCreateT0seed to true to get the seed in time coordinates
594 // fCreateT0seed = kTRUE;
595 // dummy = ClusterToTrackAssociation(seedBest,trackID,nClus);
597 //// propagate track to 0
598 //const Double_t kMaxSnp = 0.85;
599 //const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
600 //AliTrackerBase::PropagateTrackTo(&track,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,kFALSE);
604 Int_t ctype(fCorrectionType);
607 (*fStreamer) << "Tracks" <<
611 "fTime0=" << fTime0 <<
613 "clsType=" << fClusterType <<
614 "corrType=" << ctype <<
615 "seedRow=" << fSeedingRow <<
616 "seedDist=" << fSeedingDist <<
617 "vDrift=" << vDrift <<
618 "zLength=" << zLength <<
619 "nClustersMC=" << nClustersMC <<
620 "nSeeds=" << nSeeds <<
621 "nSeedClusters=" << nSeedClusters <<
622 "nSeedClustersID=" << nSeedClustersID <<
623 "t0seed.=" << &t0seed <<
624 "track.=" << &track <<
625 "tOrig.=" << &tOrig <<
626 "tOrigToy.=" << &tOrigToy <<
645 //____________________________________________________________________________________
646 void AliToyMCReconstruction::RunFullTracking(const char* file, Int_t nmaxEv)
652 ConnectInputFile(file,nmaxEv);
655 InitStreamer(".fullTracking");
657 FillSectorStructureAC();
659 AliTPCReconstructor::SetStreamLevel(0);
665 if (lowerRow>upperRow){
672 // NOTE: the z position is set to GetTimeBin*vDrift
673 // therefore it is not possible to simply propagate
674 // the track using AliTrackerBase::Propagate, since a
675 // wrong B-Field will be assinged...
676 printf("Run Seeding in %3d - %3d\n",lowerRow,upperRow);
677 for (Int_t sec=0;sec<36;sec++){
678 printf(" in sector: %d\n",sec);
679 Int_t nAdded=MakeSeeds2(&seeds, sec,lowerRow,upperRow);
680 printf(" -> Added Seeds: %d\n",nAdded);
681 nAdded=MakeSeeds2(&seeds, sec,lowerRow-2,upperRow-2);
682 printf(" -> Added Seeds: %d\n",nAdded);
683 nAdded=MakeSeeds2(&seeds, sec,lowerRow-4,upperRow-4);
684 printf(" -> Added Seeds: %d\n",nAdded);
687 printf("Run Tracking in %3d - %3d\n",lowerRow,upperRow);
689 for (Int_t iseed=firstSeed; iseed<seeds.GetEntriesFast();++iseed) ClusterToTrackAssociation(*(AliTPCseed*)seeds.UncheckedAt(iseed));
690 //first seed is used to not run the tracking twice on a seed
691 firstSeed=seeds.GetEntriesFast();
692 // DumpTrackInfo(&seeds);
697 printf("Run Seeding in %3d - %3d\n",lowerRow,upperRow);
698 for (Int_t sec=0;sec<36;sec++){
699 printf(" in sector: %d\n",sec);
700 Int_t nAdded=MakeSeeds2(&seeds, sec,lowerRow,upperRow);
701 printf(" -> Added Seeds: %d\n",nAdded);
703 printf("Run Tracking in %3d - %3d\n",lowerRow,upperRow);
704 for (Int_t iseed=firstSeed; iseed<seeds.GetEntriesFast();++iseed) ClusterToTrackAssociation(*(AliTPCseed*)seeds.UncheckedAt(iseed));
705 firstSeed=seeds.GetEntriesFast();
707 //now seeding also at more central rows with shorter seeds
711 printf("Run Seeding in %3d - %3d\n",lowerRow,upperRow);
712 for (Int_t sec=0;sec<36;sec++){
713 printf(" in sector: %d\n",sec);
714 Int_t nAdded=MakeSeeds2(&seeds, sec,lowerRow,upperRow);
715 printf(" -> Added Seeds: %d\n",nAdded);
717 printf("Run Tracking in %3d - %3d\n",lowerRow,upperRow);
718 for (Int_t iseed=firstSeed; iseed<seeds.GetEntriesFast();++iseed) ClusterToTrackAssociation(*(AliTPCseed*)seeds.UncheckedAt(iseed));
719 firstSeed=seeds.GetEntriesFast();
722 Int_t startUpper=upperRow-10;
723 Int_t startLower=lowerRow-5;
724 for (Int_t sec=0;sec<36;sec++){
727 printf(" in sector: %d\n",sec);
729 printf("Run Seeding in %3d - %3d\n",lowerRow,upperRow);
730 Int_t nAdded=MakeSeeds2(&seeds, sec,lowerRow,upperRow);
731 printf(" -> Added Seeds: %d\n",nAdded);
732 for (Int_t iseed=firstSeed; iseed<seeds.GetEntriesFast();++iseed) ClusterToTrackAssociation(*(AliTPCseed*)seeds.UncheckedAt(iseed));
733 firstSeed=seeds.GetEntriesFast();
741 DumpTrackInfo(&seeds);
743 // TObjArray seedsCentral2;
747 // for (Int_t sec=0;sec<36;sec++){
748 // Int_t nAdded=MakeSeeds2(&seedsCentral2, sec,lowerRow,upperRow);
749 // printf(" -> Added Seeds: %d\n",nAdded);
750 // nAdded=MakeSeeds2(&seedsCentral2, sec,lowerRow-2,upperRow-2);
751 // printf(" -> Added Seeds: %d\n",nAdded);
752 // nAdded=MakeSeeds2(&seedsCentral2, sec,lowerRow-4,upperRow-4);
753 // printf(" -> Added Seeds: %d\n",nAdded);
755 // for (Int_t iseed=0; iseed<seedsCentral2.GetEntriesFast();++iseed) ClusterToTrackAssociation(*(AliTPCseed*)seedsCentral2.UncheckedAt(iseed));
756 // DumpTrackInfo(&seedsCentral2);
759 (*fStreamer) << "clusters" <<
760 "cl.=" << &fAllClusters << "\n";
765 //____________________________________________________________________________________
766 AliExternalTrackParam* AliToyMCReconstruction::GetSeedFromTrack(const AliToyMCTrack * const tr, Bool_t forceSeed)
769 // if we don't have a valid time0 informaion (fTime0) available yet
770 // assume we create a seed for the time0 estimate
773 // seed point informaion
774 AliTrackPoint seedPoint[3];
775 const AliTPCclusterMI *seedCluster[3]={0x0,0x0,0x0};
777 // number of clusters to loop over
778 const Int_t ncls=(fClusterType==0)?tr->GetNumberOfSpacePoints():tr->GetNumberOfDistSpacePoints();
780 AliError(Form("Not enough points to create a seed: %d",ncls));
783 UChar_t nextSeedRow=fSeedingRow;
786 //assumes sorted clusters
788 // force the seed creation, using the first, middle and last cluster
789 Int_t npoints[3]={0,ncls/2,ncls-1};
790 for (Int_t icl=0;icl<3;++icl){
791 const AliTPCclusterMI *cl=tr->GetSpacePoint(npoints[icl]);
792 if (fClusterType==1) cl=tr->GetDistortedSpacePoint(npoints[icl]);
793 seedCluster[nseeds]=cl;
794 SetTrackPointFromCluster(cl, seedPoint[nseeds]);
798 // create seeds according to the reco settings
799 for (Int_t icl=0;icl<ncls;++icl) {
800 const AliTPCclusterMI *cl=tr->GetSpacePoint(icl);
801 if (fClusterType==1) cl=tr->GetDistortedSpacePoint(icl);
804 const UChar_t row=cl->GetRow() + 63*(cl->GetDetector()>35);
805 // skip clusters without proper pad row
806 if (row>200) continue;
809 // if we are in the last row and still miss a seed we use the last row
810 // even if the row spacing will not be equal
811 if (row>=nextSeedRow || icl==ncls-1){
812 seedCluster[nseeds]=cl;
813 SetTrackPointFromCluster(cl, seedPoint[nseeds]);
815 nextSeedRow+=fSeedingDist;
817 if (nseeds==3) break;
822 // check we really have 3 seeds
824 AliError(Form("Seeding failed for parameters %d, %d\n",fSeedingDist,fSeedingRow));
828 // do cluster correction for fCorrectionType:
833 // assign the cluster abs time as z component to all seeds
834 for (Int_t iseed=0; iseed<3; ++iseed) {
835 Float_t xyz[3]={0,0,0};
836 seedPoint[iseed].GetXYZ(xyz);
837 const Float_t r=TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
839 const Int_t sector=seedCluster[iseed]->GetDetector();
840 const Int_t sign=1-2*((sector/18)%2);
842 if ( (fClusterType == 1) && (fCorrectionType != kNoCorrection) ) {
843 // printf("correction type: %d\n",(Int_t)fCorrectionType);
845 // the settings below are for the T0 seed
846 // for known T0 the z position is already calculated in SetTrackPointFromCluster
847 if ( fCreateT0seed ){
848 if ( fCorrectionType == kTPCCenter ) xyz[2] = 125.*sign;
849 //!!! TODO: is this the correct association?
850 if ( fCorrectionType == kAverageEta ) xyz[2] = TMath::Tan(45./2.*TMath::DegToRad())*r*sign;
853 if ( fCorrectionType == kIdeal ) xyz[2] = seedCluster[iseed]->GetZ();
855 //!!! TODO: to be replaced with the proper correction
856 fTPCCorrection->CorrectPoint(xyz, seedCluster[iseed]->GetDetector());
859 // after the correction set the time bin as z-Position in case of a T0 seed
861 xyz[2]=seedCluster[iseed]->GetTimeBin();
863 seedPoint[iseed].SetXYZ(xyz);
866 const Double_t kMaxSnp = 0.85;
867 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
869 AliExternalTrackParam *seed = AliTrackerBase::MakeSeed(seedPoint[0], seedPoint[1], seedPoint[2]);
870 seed->ResetCovariance(10);
873 // if fTime0 < 0 we assume that we create a seed for the T0 estimate
874 AliTrackerBase::PropagateTrackTo(seed,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,kFALSE);
875 if (TMath::Abs(seed->GetX())>3) {
876 // printf("Could not propagate track to 0, %.2f, %.2f, %.2f\n",seed->GetX(),seed->GetAlpha(),seed->Pt());
885 //____________________________________________________________________________________
886 void AliToyMCReconstruction::SetTrackPointFromCluster(const AliTPCclusterMI *cl, AliTrackPoint &p )
889 // make AliTrackPoint out of AliTPCclusterMI
893 Float_t xyz[3]={0.,0.,0.};
894 // ClusterToSpacePoint(cl,xyz);
895 // cl->GetGlobalCov(cov);
896 //TODO: what to do with the covariance matrix???
897 //TODO: the problem is that it is used in GetAngle in AliTrackPoint
898 //TODO: which is used by AliTrackerBase::MakeSeed to get alpha correct ...
899 //TODO: for the moment simply assign 1 permill squared
900 // in AliTrackPoint the cov is xx, xy, xz, yy, yz, zz
901 // Float_t cov[6]={xyz[0]*xyz[0]*1e-6,xyz[0]*xyz[1]*1e-6,xyz[0]*xyz[2]*1e-6,
902 // xyz[1]*xyz[1]*1e-6,xyz[1]*xyz[2]*1e-6,xyz[2]*xyz[2]*1e-6};
903 // cl->GetGlobalXYZ(xyz);
904 // cl->GetGlobalCov(cov);
905 // voluem ID to add later ....
908 // AliTrackPoint *tp=const_cast<AliTPCclusterMI*>(cl)->MakePoint(p);
911 const_cast<AliTPCclusterMI*>(cl)->MakePoint(p);
914 p.SetVolumeID(cl->GetDetector());
917 if ( !fCreateT0seed && !fIdealTracking ) {
919 const Int_t sector=cl->GetDetector();
920 const Int_t sign=1-2*((sector/18)%2);
921 const Float_t zT0=( GetZLength(sector) - (cl->GetTimeBin()-fTime0)*GetVDrift() )*sign;
922 // printf(" z: %.2f %.2f\n",xyz[2],zT0);
928 // p.Rotate(p.GetAngle()).Print();
931 //____________________________________________________________________________________
932 void AliToyMCReconstruction::ClusterToSpacePoint(const AliTPCclusterMI *cl, Float_t xyz[3])
935 // convert the cluster to a space point in global coordinates
940 xyz[2]=cl->GetTimeBin(); // this will not be correct at all
941 Int_t i[3]={0,cl->GetDetector(),cl->GetRow()};
942 // printf("%.2f, %.2f, %.2f - %d, %d, %d\n",xyz[0],xyz[1],xyz[2],i[0],i[1],i[2]);
943 fTPCParam->Transform8to4(xyz,i);
944 // printf("%.2f, %.2f, %.2f - %d, %d, %d\n",xyz[0],xyz[1],xyz[2],i[0],i[1],i[2]);
945 fTPCParam->Transform4to3(xyz,i);
946 // printf("%.2f, %.2f, %.2f - %d, %d, %d\n",xyz[0],xyz[1],xyz[2],i[0],i[1],i[2]);
947 fTPCParam->Transform2to1(xyz,i);
948 // printf("%.2f, %.2f, %.2f - %d, %d, %d\n",xyz[0],xyz[1],xyz[2],i[0],i[1],i[2]);
951 //____________________________________________________________________________________
952 AliExternalTrackParam* AliToyMCReconstruction::GetFittedTrackFromSeed(const AliToyMCTrack *tr, const AliExternalTrackParam *seed)
959 AliExternalTrackParam *track = new AliExternalTrackParam(*seed);
961 Int_t ncls=(fClusterType == 0)?tr->GetNumberOfSpacePoints():tr->GetNumberOfDistSpacePoints();
963 const AliTPCROC * roc = AliTPCROC::Instance();
965 const Double_t kRTPC0 = roc->GetPadRowRadii(0,0);
966 const Double_t kRTPC1 = roc->GetPadRowRadii(36,roc->GetNRows(36)-1);
967 const Double_t kMaxSnp = 0.85;
968 const Double_t kMaxR = 500.;
969 const Double_t kMaxZ = 500.;
971 // const Double_t kMaxZ0=220;
972 // const Double_t kZcut=3;
974 const Double_t refX = tr->GetX();
976 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
978 // loop over all other points and add to the track
979 for (Int_t ipoint=ncls-1; ipoint>=0; --ipoint){
981 const AliTPCclusterMI *cl=tr->GetSpacePoint(ipoint);
982 if (fClusterType == 1) cl=tr->GetDistortedSpacePoint(ipoint);
983 SetTrackPointFromCluster(cl, pIn);
984 if (fCorrectionType != kNoCorrection){
985 Float_t xyz[3]={0,0,0};
987 // if ( fCorrectionType == kIdeal ) xyz[2] = cl->GetZ();
988 fTPCCorrection->CorrectPoint(xyz, cl->GetDetector());
991 // rotate the cluster to the local detector frame
992 track->Rotate(((cl->GetDetector()%18)*20+10)*TMath::DegToRad());
993 AliTrackPoint prot = pIn.Rotate(track->GetAlpha()); // rotate to the local frame - non distoted point
994 if (TMath::Abs(prot.GetX())<kRTPC0) continue;
995 if (TMath::Abs(prot.GetX())>kRTPC1) continue;
997 Bool_t res=AliTrackerBase::PropagateTrackTo(track,prot.GetX(),kMass,5,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
1001 if (TMath::Abs(track->GetZ())>kMaxZ) break;
1002 if (TMath::Abs(track->GetX())>kMaxR) break;
1003 // if (TMath::Abs(track->GetZ())<kZcut)continue;
1005 Double_t pointPos[2]={0,0};
1006 Double_t pointCov[3]={0,0,0};
1007 pointPos[0]=prot.GetY();//local y
1008 pointPos[1]=prot.GetZ();//local z
1009 pointCov[0]=prot.GetCov()[3];//simay^2
1010 pointCov[1]=prot.GetCov()[4];//sigmayz
1011 pointCov[2]=prot.GetCov()[5];//sigmaz^2
1013 if (!track->Update(pointPos,pointCov)) {printf("no update\n"); break;}
1016 AliTrackerBase::PropagateTrackTo2(track,refX,kMass,5.,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
1018 // rotate fittet track to the frame of the original track and propagate to same reference
1019 track->Rotate(tr->GetAlpha());
1021 AliTrackerBase::PropagateTrackTo2(track,refX,kMass,1.,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
1027 //____________________________________________________________________________________
1028 AliExternalTrackParam* AliToyMCReconstruction::GetFittedTrackFromSeedAllClusters(const AliToyMCTrack *tr, const AliExternalTrackParam *seed, Int_t &nClus)
1031 // Tracking for given seed on an array of clusters
1035 AliExternalTrackParam *track = new AliExternalTrackParam(*seed);
1037 const AliTPCROC * roc = AliTPCROC::Instance();
1039 const Double_t kRTPC0 = roc->GetPadRowRadii(0,0);
1040 const Double_t kRTPC1 = roc->GetPadRowRadii(36,roc->GetNRows(36)-1);
1041 const Int_t kNRowsTPC = roc->GetNRows(0) + roc->GetNRows(36) - 1;
1042 const Int_t kIRowsTPC = roc->GetNRows(0) - 1;
1043 const Double_t kMaxSnp = 0.85;
1044 const Double_t kMaxR = 500.;
1045 const Double_t kMaxZ = 500.;
1046 const Double_t roady = 100.;
1047 const Double_t roadz = 100.;
1049 const Double_t refX = tr->GetX();
1051 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
1054 UInt_t indexCur = 0;
1055 Double_t xCur, yCur, zCur = 0.;
1057 Float_t vDrift = GetVDrift();
1059 // first propagate seed to outermost row
1060 AliTrackerBase::PropagateTrackTo(track,kRTPC1,kMass,5,kFALSE,kMaxSnp);
1062 // Loop over rows and find the cluster candidates
1063 for( Int_t iRow = kNRowsTPC; iRow >= 0; --iRow ){
1065 // inner or outer sector
1066 Bool_t bInnerSector = kTRUE;
1067 if(iRow > kIRowsTPC) bInnerSector = kFALSE;
1069 // nearest track point/cluster (to be found)
1070 AliTrackPoint nearestPoint;
1071 AliTPCclusterMI *nearestCluster = NULL;
1076 // Propagate to center of pad row and extract parameters
1077 AliTrackerBase::PropagateTrackTo(track,roc->GetPadRowRadii(0,iRow),kMass,5,kFALSE,kMaxSnp);
1078 xCur = track->GetX();
1079 yCur = track->GetY();
1080 zCur = track->GetZ();
1081 if ( !fIdealTracking ) {
1082 zCur = zCur/vDrift + fTime0; // Look at time, not at z!
1084 secCur = GetSector(track);
1086 // Find the nearest cluster (TODO: correct road settings!)
1087 Printf("inner tracking here: x = %.2f, y = %.2f, z = %.2f (Row %d Sector %d)",xCur,yCur,zCur,iRow,secCur);
1088 nearestCluster = fInnerSectorArray[secCur%fkNSectorInner][iRow].FindNearest2(yCur,zCur,roady,roadz,indexCur);
1090 // Move to next row if now cluster found
1091 if(!nearestCluster) continue;
1092 //Printf("Nearest Clusters = %d (of %d) ",indexCur,fInnerSectorArray[secCur%fkNSectorInner][iRow].GetN());
1099 // Propagate to center of pad row and extract parameters
1100 AliTrackerBase::PropagateTrackTo(track,roc->GetPadRowRadii(36,iRow-kIRowsTPC-1),kMass,5,kFALSE,kMaxSnp);
1101 xCur = track->GetX();
1102 yCur = track->GetY();
1103 zCur = track->GetZ();
1104 if ( !fIdealTracking ) {
1105 zCur = zCur/vDrift + fTime0; // Look at time, not at z!
1107 secCur = GetSector(track);
1109 // Find the nearest cluster (TODO: correct road settings!)
1110 Printf("outer tracking here: x = %.2f, y = %.2f, z = %.2f (Row %d Sector %d)",xCur,yCur,zCur,iRow,secCur);
1111 nearestCluster = fOuterSectorArray[(secCur-fkNSectorInner*2)%fkNSectorOuter][iRow-kIRowsTPC-1].FindNearest2(yCur,zCur,roady,roadz,indexCur);
1113 // Move to next row if now cluster found
1114 if(!nearestCluster) continue;
1115 //Printf("Nearest Clusters = %d (of %d)",indexCur,fOuterSectorArray[(secCur-fkNSectorInner*2)%fkNSectorOuter][iRow-kIRowsTPC-1].GetN());
1119 // create track point from cluster
1120 SetTrackPointFromCluster(nearestCluster,nearestPoint);
1122 //Printf("Track point = %.2f %.2f %.2f",nearestPoint.GetX(),nearestPoint.GetY(),nearestPoint.GetZ());
1125 // TODO: also correction when looking for the next cluster?
1126 if (fCorrectionType != kNoCorrection){
1127 Float_t xyz[3]={0,0,0};
1128 nearestPoint.GetXYZ(xyz);
1129 fTPCCorrection->CorrectPoint(xyz, nearestCluster->GetDetector());
1130 nearestPoint.SetXYZ(xyz);
1133 // rotate the cluster to the local detector frame
1134 track->Rotate(((nearestCluster->GetDetector()%18)*20+10)*TMath::DegToRad());
1135 AliTrackPoint prot = nearestPoint.Rotate(track->GetAlpha()); // rotate to the local frame - non distoted point
1136 if (TMath::Abs(prot.GetX())<kRTPC0) continue;
1137 if (TMath::Abs(prot.GetX())>kRTPC1) continue;
1140 //Printf("Rotated Track point = %.2f %.2f %.2f",prot.GetX(),prot.GetY(),prot.GetZ());
1142 // update track with the nearest track point
1143 Bool_t res=AliTrackerBase::PropagateTrackTo(track,prot.GetX(),kMass,5,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
1147 if (TMath::Abs(track->GetZ())>kMaxZ) break;
1148 if (TMath::Abs(track->GetX())>kMaxR) break;
1149 //if (TMath::Abs(track->GetZ())<kZcut)continue;
1151 Double_t pointPos[2]={0,0};
1152 Double_t pointCov[3]={0,0,0};
1153 pointPos[0]=prot.GetY();//local y
1154 pointPos[1]=prot.GetZ();//local z
1155 pointCov[0]=prot.GetCov()[3];//simay^2
1156 pointCov[1]=prot.GetCov()[4];//sigmayz
1157 pointCov[2]=prot.GetCov()[5];//sigmaz^2
1159 if (!track->Update(pointPos,pointCov)) {printf("no update\n");}
1165 // propagation to refX
1166 AliTrackerBase::PropagateTrackTo(track,refX,kMass,5.,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
1168 // rotate fittet track to the frame of the original track and propagate to same reference
1169 track->Rotate(tr->GetAlpha());
1171 AliTrackerBase::PropagateTrackTo(track,refX,kMass,1.,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
1173 Printf("We have %d clusters in this track!",nClus);
1178 //____________________________________________________________________________________
1179 AliExternalTrackParam* AliToyMCReconstruction::ClusterToTrackAssociation(const AliTPCseed *seed, Int_t trackID, Int_t &nClus)
1182 // Cluster to track association for given seed on an array of clusters
1186 AliExternalTrackParam *track = new AliExternalTrackParam(*seed);
1188 const AliTPCROC * roc = AliTPCROC::Instance();
1190 const Double_t kRTPC0 = roc->GetPadRowRadii(0,0);
1191 const Double_t kRTPC1 = roc->GetPadRowRadii(36,roc->GetNRows(36)-1);
1192 const Int_t kNRowsTPC = roc->GetNRows(0) + roc->GetNRows(36) - 1;
1193 const Int_t kIRowsTPC = roc->GetNRows(0) - 1;
1194 const Double_t kMaxSnp = 0.85;
1195 const Double_t kMaxR = 500.;
1196 const Double_t kMaxZ = 500.;
1197 const Double_t roady = 0.1;
1198 const Double_t roadz = 0.01;
1200 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
1202 Int_t secCur, secOld = -1;
1203 UInt_t indexCur = 0;
1204 Double_t xCur, yCur, zCur = 0.;
1206 // Float_t vDrift = GetVDrift();
1208 // first propagate seed to outermost row
1209 Bool_t res0=AliTrackerBase::PropagateTrackTo(track,kRTPC1,kMass,5,kFALSE,kMaxSnp);
1211 // Loop over rows and find the cluster candidates
1212 for( Int_t iRow = kNRowsTPC; iRow >= 0; --iRow ){
1214 // inner or outer sector
1215 Bool_t bInnerSector = kTRUE;
1216 if(iRow > kIRowsTPC) bInnerSector = kFALSE;
1218 // nearest track point/cluster (to be found)
1219 AliTrackPoint nearestPoint;
1220 AliTPCclusterMI *nearestCluster = NULL;
1225 // Propagate to center of pad row and extract parameters
1226 AliTrackerBase::PropagateTrackTo(track,roc->GetPadRowRadii(0,iRow),kMass,5,kFALSE,kMaxSnp);
1227 xCur = track->GetX();
1228 yCur = track->GetY();
1229 zCur = track->GetZ();
1230 secCur = GetSector(track);
1232 // Find the nearest cluster (TODO: correct road settings!)
1233 //Printf("inner tracking here: x = %.2f, y = %.2f, z = %.6f (Row %d Sector %d)",xCur,yCur,zCur,iRow,secCur);
1234 nearestCluster = fInnerSectorArray[secCur%fkNSectorInner][iRow].FindNearest2(yCur,zCur,roady,roadz,indexCur);
1236 // Look again at -y if nothing found here and the sector changed with respect to the last found cluster
1237 // Increase also the road in this case
1238 if(!nearestCluster && secCur != secOld && secOld > -1){
1239 //Printf("inner tracking here 2: x = %.2f, y = %.2f, z = %.6f (Row %d Sector %d)",xCur,-yCur,zCur,iRow,secCur);
1240 nearestCluster = fInnerSectorArray[secCur%fkNSectorInner][iRow].FindNearest2(-yCur,zCur,roady*100,roadz,indexCur);
1243 // Move to next row if now cluster found
1244 if(!nearestCluster) continue;
1245 //Printf("Nearest Clusters = %d (of %d) ",indexCur,fInnerSectorArray[secCur%fkNSectorInner][iRow].GetN());
1252 // Propagate to center of pad row and extract parameters
1253 AliTrackerBase::PropagateTrackTo(track,roc->GetPadRowRadii(36,iRow-kIRowsTPC-1),kMass,5,kFALSE,kMaxSnp);
1254 xCur = track->GetX();
1255 yCur = track->GetY();
1256 zCur = track->GetZ();
1257 secCur = GetSector(track);
1259 // Find the nearest cluster (TODO: correct road settings!)
1260 Printf("res0 = %d, outer tracking here: x = %.2f, y = %.2f, z = %.6f (Row %d Sector %d)",res0,xCur,yCur,zCur,iRow,secCur);
1261 nearestCluster = fOuterSectorArray[(secCur-fkNSectorInner*2)%fkNSectorOuter][iRow-kIRowsTPC-1].FindNearest2(yCur,zCur,roady,roadz,indexCur);
1263 // Look again at -y if nothing found here and the sector changed with respect to the last found cluster
1264 // Increase also the road in this case
1265 if(!nearestCluster && secCur != secOld && secOld > -1){
1266 Printf("outer tracking here 2: x = %.2f, y = %.2f, z = %.6f (Row %d Sector %d)",xCur,-yCur,zCur,iRow,secCur);
1267 nearestCluster = fOuterSectorArray[(secCur-fkNSectorInner*2)%fkNSectorOuter][iRow-kIRowsTPC-1].FindNearest2(-yCur,zCur,roady*100,roadz,indexCur);
1271 // Move to next row if now cluster found
1272 if(!nearestCluster) continue;
1273 Printf("Nearest Clusters = %d (of %d)",indexCur,fOuterSectorArray[(secCur-fkNSectorInner*2)%fkNSectorOuter][iRow-kIRowsTPC-1].GetN());
1277 // create track point from cluster
1278 SetTrackPointFromCluster(nearestCluster,nearestPoint);
1280 //Printf("Track point = %.2f %.2f %.2f",nearestPoint.GetX(),nearestPoint.GetY(),nearestPoint.GetZ());
1282 // rotate the cluster to the local detector frame
1283 track->Rotate(((nearestCluster->GetDetector()%18)*20+10)*TMath::DegToRad());
1284 AliTrackPoint prot = nearestPoint.Rotate(track->GetAlpha()); // rotate to the local frame - non distoted point
1285 if (TMath::Abs(prot.GetX())<kRTPC0) continue;
1286 if (TMath::Abs(prot.GetX())>kRTPC1) continue;
1289 //Printf("Rotated Track point = %.2f %.2f %.2f",prot.GetX(),prot.GetY(),prot.GetZ());
1291 // update track with the nearest track point
1292 Bool_t res=AliTrackerBase::PropagateTrackTo(track,prot.GetX(),kMass,5,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
1296 if (TMath::Abs(track->GetZ())>kMaxZ) break;
1297 if (TMath::Abs(track->GetX())>kMaxR) break;
1298 //if (TMath::Abs(track->GetZ())<kZcut)continue;
1300 Double_t pointPos[2]={0,0};
1301 Double_t pointCov[3]={0,0,0};
1302 pointPos[0]=prot.GetY();//local y
1303 pointPos[1]=prot.GetZ();//local z
1304 pointCov[0]=prot.GetCov()[3];//simay^2
1305 pointCov[1]=prot.GetCov()[4];//sigmayz
1306 pointCov[2]=prot.GetCov()[5];//sigmaz^2
1308 if (!track->Update(pointPos,pointCov)) {printf("no update\n");}
1311 //Printf("Cluster belongs to track = %d",nearestCluster->GetLabel(0));
1313 // only count as associate cluster if it belongs to correct track!
1314 if(nearestCluster->GetLabel(0) == trackID)
1318 Printf("We have %d clusters in this track!",nClus);
1323 //____________________________________________________________________________________
1324 void AliToyMCReconstruction::AssociateClusters(AliTPCseed &seed, Int_t firstRow, Int_t lastRow, Bool_t direction)
1327 // do cluster to track association from first to last row
1328 // direction 0: outwards; 1: inwards
1334 AliRieman rieman1(160);
1335 AliRieman rieman2(160);
1336 SetRieman(seed,rieman1);
1337 CopyRieman(rieman1,rieman2);
1339 Int_t sec=seed.GetSector();
1340 Int_t noLastPoint=0;
1341 //TODO: change to inward and outwar search?
1342 // -> better handling of non consecutive points
1348 //always from inside out
1349 if (firstRow>lastRow){
1355 for (Int_t row=firstRow; row<=lastRow && noLastPoint<3;++row) {
1356 Int_t iRow=TMath::Abs(row);
1357 const AliTPCclusterMI *cl=seed.GetClusterPointer(iRow);
1360 const Int_t secrow = iRow<63?iRow:iRow-63;
1362 AliTPCtrackerSector *arrSec=(iRow<63)?fInnerSectorArray:fOuterSectorArray;
1363 const AliTPCtrackerRow& kr = arrSec[sec%36][secrow];
1364 const Double_t maxy=arrSec[sec%36].GetMaxY(secrow);
1366 Double_t y=rieman1.GetYat(kr.GetX());
1367 Double_t z=rieman1.GetZat(kr.GetX());
1369 if (TMath::Abs(y)>maxy) {
1370 AliError("Tracking over sector boundaries not implemented, yet");
1374 AliTPCclusterMI *n=kr.FindNearest(y,z,roady,roadz);
1375 if (!n || n->IsUsed()) {
1379 // check for quality of the cluster
1381 rieman2.AddPoint(n->GetX(), n->GetY(), n->GetZ(),
1382 TMath::Sqrt(n->GetSigmaY2()), TMath::Sqrt(n->GetSigmaZ2()));
1384 // printf(" Riemann results: row=%d valid=%d, Chi2=%.2f (%.2f) %d (%d)",
1385 // iRow, rieman2.IsValid(), rieman2.GetChi2(), rieman1.GetChi2(), n->GetLabel(0),seed.GetLabel());
1386 Double_t limit=2*rieman1.GetChi2();
1387 if (fClusterType==0) limit=1000;
1388 if (rieman2.GetChi2()>limit) {
1389 CopyRieman(rieman1,rieman2);
1394 // printf(" +++ \n");
1398 rieman1.AddPoint(n->GetX(), n->GetY(), n->GetZ(),
1399 TMath::Sqrt(n->GetSigmaY2()), TMath::Sqrt(n->GetSigmaZ2()));
1402 seed.SetClusterPointer(iRow,n);
1403 // if (iRow<seed.GetSeed1()) seed.SetSeed1(iRow);
1404 // if (iRow>seed.GetSeed2()) seed.SetSeed2(iRow);
1410 //____________________________________________________________________________________
1411 void AliToyMCReconstruction::ClusterToTrackAssociation(AliTPCseed &seed)
1417 // printf("\n ============ \nnext Seed: %d\n",seed.GetLabel());
1418 //assume seed is within one sector
1419 Int_t iMiddle=(seed.GetSeed1()+seed.GetSeed2())/2;
1421 AssociateClusters(seed,iMiddle+1,158,kFALSE);
1423 AssociateClusters(seed,0,iMiddle,kTRUE);
1424 seed.SetIsSeeding(kFALSE);
1426 CookLabel(&seed,.6);
1430 //____________________________________________________________________________________
1431 void AliToyMCReconstruction::InitSpaceCharge()
1434 // Init the space charge map
1437 TString filename="$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2_eps5_50kHz_precal.root";
1439 TList *l=fTree->GetUserInfo();
1440 for (Int_t i=0; i<l->GetEntries(); ++i) {
1441 TString s(l->At(i)->GetName());
1442 if (s.Contains("SC_")) {
1449 printf("Initialising the space charge map using the file: '%s'\n",filename.Data());
1450 TFile f(filename.Data());
1451 fTPCCorrection=(AliTPCCorrection*)f.Get("map");
1453 // fTPCCorrection = new AliTPCSpaceCharge3D();
1454 // fTPCCorrection->SetSCDataFileName("$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2_eps10_50kHz.root");
1455 // fTPCCorrection->SetOmegaTauT1T2(0.325,1,1); // Ne CO2
1456 // // fTPCCorrection->SetOmegaTauT1T2(0.41,1,1.05); // Ar CO2
1457 // fTPCCorrection->InitSpaceCharge3DDistortion();
1461 //____________________________________________________________________________________
1462 Double_t AliToyMCReconstruction::GetVDrift() const
1467 return fTPCParam->GetDriftV();
1470 //____________________________________________________________________________________
1471 Double_t AliToyMCReconstruction::GetZLength(Int_t roc) const
1476 if (roc<0 || roc>71) return -1;
1477 return fTPCParam->GetZLength(roc);
1480 //____________________________________________________________________________________
1481 TTree* AliToyMCReconstruction::ConnectTrees (const char* files) {
1482 TString s=gSystem->GetFromPipe(Form("ls %s",files));
1485 TObjArray *arrFiles=s.Tokenize("\n");
1487 for (Int_t ifile=0; ifile<arrFiles->GetEntriesFast(); ++ifile){
1488 TString name(arrFiles->At(ifile)->GetName());
1490 TPRegexp reg(".*([0-9]_[0-9]_[0-9]_[0-9]{3}_[0-9]{2}).debug.root");
1491 TObjArray *arrMatch=0x0;
1492 arrMatch=reg.MatchS(name);
1494 if (arrMatch && arrMatch->At(1)) matchName=arrMatch->At(1)->GetName();
1495 else matchName=Form("%02d",ifile);
1499 TFile *f=TFile::Open(name.Data());
1501 TTree *t=(TTree*)f->Get("Tracks");
1507 t->SetName(matchName.Data());
1510 tFirst->AddFriend(Form("t%s=Tracks",matchName.Data()), name.Data());
1511 // tFirst->AddFriend(Form("t%d=Tracks",ifile), name.Data());
1515 tFirst->GetListOfFriends()->Print();
1519 //____________________________________________________________________________________
1520 Int_t AliToyMCReconstruction::LoadOuterSectors() {
1521 //-----------------------------------------------------------------
1522 // This function fills outer TPC sectors with clusters.
1523 // Copy and paste from AliTPCtracker
1524 //-----------------------------------------------------------------
1525 Int_t nrows = fOuterSectorArray->GetNRows();
1527 for (Int_t sec = 0;sec<fkNSectorOuter;sec++)
1528 for (Int_t row = 0;row<nrows;row++){
1529 AliTPCtrackerRow* tpcrow = &(fOuterSectorArray[sec%fkNSectorOuter][row]);
1530 Int_t sec2 = sec+2*fkNSectorInner;
1532 Int_t ncl = tpcrow->GetN1();
1534 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1535 index=(((sec2<<8)+row)<<16)+ncl;
1536 tpcrow->InsertCluster(c,index);
1539 ncl = tpcrow->GetN2();
1541 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1542 index=((((sec2+fkNSectorOuter)<<8)+row)<<16)+ncl;
1543 tpcrow->InsertCluster(c,index);
1546 // write indexes for fast acces
1548 for (Int_t i=0;i<510;i++)
1549 tpcrow->SetFastCluster(i,-1);
1550 for (Int_t i=0;i<tpcrow->GetN();i++){
1551 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1552 tpcrow->SetFastCluster(zi,i); // write index
1555 for (Int_t i=0;i<510;i++){
1556 if (tpcrow->GetFastCluster(i)<0)
1557 tpcrow->SetFastCluster(i,last);
1559 last = tpcrow->GetFastCluster(i);
1566 //____________________________________________________________________________________
1567 Int_t AliToyMCReconstruction::LoadInnerSectors() {
1568 //-----------------------------------------------------------------
1569 // This function fills inner TPC sectors with clusters.
1570 // Copy and paste from AliTPCtracker
1571 //-----------------------------------------------------------------
1572 Int_t nrows = fInnerSectorArray->GetNRows();
1574 for (Int_t sec = 0;sec<fkNSectorInner;sec++)
1575 for (Int_t row = 0;row<nrows;row++){
1576 AliTPCtrackerRow* tpcrow = &(fInnerSectorArray[sec%fkNSectorInner][row]);
1579 Int_t ncl = tpcrow->GetN1();
1581 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1582 index=(((sec<<8)+row)<<16)+ncl;
1583 tpcrow->InsertCluster(c,index);
1586 ncl = tpcrow->GetN2();
1588 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1589 index=((((sec+fkNSectorInner)<<8)+row)<<16)+ncl;
1590 tpcrow->InsertCluster(c,index);
1593 // write indexes for fast acces
1595 for (Int_t i=0;i<510;i++)
1596 tpcrow->SetFastCluster(i,-1);
1597 for (Int_t i=0;i<tpcrow->GetN();i++){
1598 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1599 tpcrow->SetFastCluster(zi,i); // write index
1602 for (Int_t i=0;i<510;i++){
1603 if (tpcrow->GetFastCluster(i)<0)
1604 tpcrow->SetFastCluster(i,last);
1606 last = tpcrow->GetFastCluster(i);
1613 //____________________________________________________________________________________
1614 Int_t AliToyMCReconstruction::GetSector(AliExternalTrackParam *track) {
1615 //-----------------------------------------------------------------
1616 // This function returns the sector number for a given track
1617 //-----------------------------------------------------------------
1621 // get the sector number
1622 // rotate point to global system (track is already global!)
1625 //track->Local2GlobalPosition(xd,track->GetAlpha());
1627 // use TPCParams to get the sector number
1628 Float_t xyz[3] = {xd[0],xd[1],xd[2]};
1629 Int_t i[3] = {0,0,0};
1631 sector = fTPCParam->Transform0to1(xyz,i);
1637 //____________________________________________________________________________________
1638 void AliToyMCReconstruction::FillSectorStructure(Int_t maxev) {
1639 //-----------------------------------------------------------------
1640 // This function fills the sector structure of AliToyMCReconstruction
1641 //-----------------------------------------------------------------
1643 // cluster array of all sectors
1644 fInnerSectorArray = new AliTPCtrackerSector[fkNSectorInner];
1645 fOuterSectorArray = new AliTPCtrackerSector[fkNSectorOuter];
1647 for (Int_t i=0; i<fkNSectorInner; ++i) fInnerSectorArray[i].Setup(fTPCParam,0);
1648 for (Int_t i=0; i<fkNSectorOuter; ++i) fOuterSectorArray[i].Setup(fTPCParam,1);
1650 Int_t count[72][96] = { {0} , {0} };
1652 for (Int_t iev=0; iev<maxev; ++iev){
1653 printf("============== Fill Clusters: Processing Event %6d =================\n",iev);
1654 fTree->GetEvent(iev);
1655 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
1656 printf(" > ====== Fill Clusters: Processing Track %6d ======== \n",itr);
1657 const AliToyMCTrack *tr=fEvent->GetTrack(itr);
1659 // number of clusters to loop over
1660 const Int_t ncls=(fClusterType==0)?tr->GetNumberOfSpacePoints():tr->GetNumberOfDistSpacePoints();
1662 for(Int_t icl=0; icl<ncls; ++icl){
1664 AliTPCclusterMI *cl=const_cast<AliTPCclusterMI *>(tr->GetSpacePoint(icl));
1665 if (fClusterType==1) cl=const_cast<AliTPCclusterMI *>(tr->GetDistortedSpacePoint(icl));
1668 Int_t sec = cl->GetDetector();
1669 Int_t row = cl->GetRow();
1671 // set Q of the cluster to 1, Q==0 does not work for the seeding
1674 // set cluster time to cluster Z (if not ideal tracking)
1675 if ( !fIdealTracking ) {
1676 // a 'valid' position in z is needed for the seeding procedure
1677 // cl->SetZ(cl->GetTimeBin()*GetVDrift());
1678 cl->SetZ(cl->GetTimeBin());
1680 //Printf("Fill clusters (sector %d row %d): %.2f %.2f %.2f %.2f",sec,row,cl->GetX(),cl->GetY(),cl->GetZ(),cl->GetTimeBin());
1682 // fill arrays for inner and outer sectors (A/C side handled internally)
1683 if (sec<fkNSectorInner*2){
1684 fInnerSectorArray[sec%fkNSectorInner].InsertCluster(cl, count[sec][row], fTPCParam);
1687 fOuterSectorArray[(sec-fkNSectorInner*2)%fkNSectorOuter].InsertCluster(cl, count[sec][row], fTPCParam);
1695 // fill the arrays completely
1696 // LoadOuterSectors();
1697 // LoadInnerSectors();
1699 // // check the arrays
1700 // for (Int_t i=0; i<fkNSectorInner; ++i){
1701 // for (Int_t j=0; j<fInnerSectorArray[i].GetNRows(); ++j){
1702 // if(fInnerSectorArray[i][j].GetN()>0){
1703 // Printf("Inner: Sector %d Row %d : %d",i,j,fInnerSectorArray[i][j].GetN());
1707 // for (Int_t i=0; i<fkNSectorInner; ++i){
1708 // for (Int_t j=0; j<fOuterSectorArray[i].GetNRows(); ++j){
1709 // if(fOuterSectorArray[i][j].GetN()>0){
1710 // Printf("Outer: Sector %d Row %d : %d",i,j,fOuterSectorArray[i][j].GetN());
1716 //____________________________________________________________________________________
1717 void AliToyMCReconstruction::FillSectorStructureAC() {
1718 //-----------------------------------------------------------------
1719 // This function fills the sector structure of AliToyMCReconstruction
1720 //-----------------------------------------------------------------
1723 my god is the AliTPCtrackerSector stuff complicated!!!
1724 Ok, so here we will not fill the fClusters1 and fClusters2 of AliTPCtrackerRow,
1725 using InsertCluster of AliTPCtrackerSector, but only the fClusters via InsertCluster
1726 of AliTPCtrackerRow itself which then will not be owner, but we create an array in
1727 here (fAllClusters) which owns all clusters ...
1731 // cluster array of all sectors
1732 fInnerSectorArray = new AliTPCtrackerSector[2*fkNSectorInner];
1733 fOuterSectorArray = new AliTPCtrackerSector[2*fkNSectorOuter];
1735 for (Int_t i=0; i<2*fkNSectorInner; ++i) {
1736 fInnerSectorArray[i].Setup(fTPCParam,0);
1739 for (Int_t i=0; i<2*fkNSectorOuter; ++i) {
1740 fOuterSectorArray[i].Setup(fTPCParam,1);
1743 Int_t count[72][96] = { {0} , {0} };
1745 for (Int_t iev=0; iev<fNmaxEvents; ++iev){
1746 printf("============== Fill Clusters: Processing Event %6d =================\n",iev);
1747 fTree->GetEvent(iev);
1748 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
1749 // printf(" > ====== Fill Clusters: Processing Track %6d ======== \n",itr);
1750 const AliToyMCTrack *tr=fEvent->GetTrack(itr);
1752 // number of clusters to loop over
1753 const Int_t ncls=(fClusterType==0)?tr->GetNumberOfSpacePoints():tr->GetNumberOfDistSpacePoints();
1755 // check if expansion of the cluster arrays is needed.
1756 if (fAllClusters.GetEntriesFast()+ncls>=fAllClusters.Capacity()) fAllClusters.Expand(2*fAllClusters.Capacity());
1757 for(Int_t icl=0; icl<ncls; ++icl){
1759 AliTPCclusterMI *cl=const_cast<AliTPCclusterMI *>(tr->GetSpacePoint(icl));
1760 if (fClusterType==1) cl=const_cast<AliTPCclusterMI *>(tr->GetDistortedSpacePoint(icl));
1763 // register copy to the cluster array
1764 cl = new(fAllClusters[fAllClusters.GetEntriesFast()]) AliTPCclusterMI(*cl);
1766 Int_t sec = cl->GetDetector();
1767 Int_t row = cl->GetRow();
1769 // set Q of the cluster to 1, Q==0 does not work for the seeding
1772 // set cluster time to cluster Z (if not ideal tracking)
1773 if ( !fIdealTracking ) {
1774 // a 'valid' position in z is needed for the seeding procedure
1776 if (((sec/18)%2)==1) sign=-1;
1777 cl->SetZ(cl->GetTimeBin()*GetVDrift()*sign);
1778 //mark cluster to be time*vDrift by setting the type to 1
1780 // cl->SetZ(cl->GetTimeBin());
1782 //Printf("Fill clusters (sector %d row %d): %.2f %.2f %.2f %.2f",sec,row,cl->GetX(),cl->GetY(),cl->GetZ(),cl->GetTimeBin());
1784 // fill arrays for inner and outer sectors (A/C side handled internally)
1785 if (sec<fkNSectorInner*2){
1786 fInnerSectorArray[sec][row].InsertCluster(cl, count[sec][row]);
1789 fOuterSectorArray[(sec-fkNSectorInner*2)][row].InsertCluster(cl, count[sec][row]);
1799 //____________________________________________________________________________________
1800 AliToyMCTrack *AliToyMCReconstruction::ConvertTPCSeedToToyMCTrack(const AliTPCseed &seed)
1807 AliToyMCTrack *tToy = new AliToyMCTrack(seed);
1809 for (Int_t icl=0; icl<159; ++icl){
1810 const AliTPCclusterMI *cl=seed.GetClusterFast(icl);
1812 if (fClusterType==0){
1813 tToy->AddSpacePoint(*cl);
1815 tToy->AddDistortedSpacePoint(*cl);
1822 //____________________________________________________________________________________
1823 AliExternalTrackParam* AliToyMCReconstruction::GetRefittedTrack(const AliTPCseed &seed)
1829 AliExternalTrackParam *track=0x0;
1831 const Float_t vDrift=GetVDrift();
1832 const Float_t zLength=GetZLength(0);
1833 const Double_t kMaxSnp = 0.85;
1834 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
1836 AliToyMCTrack *toyTrack = ConvertTPCSeedToToyMCTrack(seed);
1841 fCreateT0seed = kTRUE;
1842 AliExternalTrackParam *t0seed = GetSeedFromTrack(toyTrack,kTRUE);
1843 if (!t0seed) return 0x0;
1845 fTime0 = t0seed->GetZ()-zLength/vDrift;
1849 fCreateT0seed = kFALSE;
1850 AliExternalTrackParam *dummy = GetSeedFromTrack(toyTrack,kTRUE);
1851 track = GetFittedTrackFromSeed(toyTrack, dummy);
1853 // propagate seed to 0
1854 AliTrackerBase::PropagateTrackTo(track,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
1859 //____________________________________________________________________________________
1860 AliTPCclusterMI* AliToyMCReconstruction::FindMiddleCluster(const AliTPCclusterMI *clInner, const AliTPCclusterMI *clOuter,
1861 Double_t roady, Double_t roadz,
1868 const Int_t rocInner = clInner->GetDetector();
1869 const Int_t rocOuter = clOuter->GetDetector();
1871 if ( (rocInner%18) != (rocOuter%18) ){
1872 AliError("Currently only same Sector implemented");
1876 const Int_t innerDet=clInner->GetDetector();
1877 const Int_t outerDet=clOuter->GetDetector();
1878 const Int_t globalRowInner = clInner->GetRow() +(innerDet >35)*63;
1879 const Int_t globalRowOuter = clOuter->GetRow() +(outerDet >35)*63;
1881 AliTPCclusterMI *n=0x0;
1883 // allow flexibility of +- nRowsGrace Rows to find a middle cluster
1884 const Int_t nRowsGrace = 0;
1885 for (Int_t iter=0; iter<2*nRowsGrace+1; ++iter){
1886 Int_t iMiddle = (globalRowInner+globalRowOuter)/2;
1887 iMiddle+=((iter+1)/2)*(1-2*((iter+1)%2));
1889 Int_t localRow=iMiddle;
1890 Int_t roc = innerDet;
1896 AliTPCtrackerSector *arrRow=(iMiddle<63)?fInnerSectorArray:fOuterSectorArray;
1897 const AliTPCtrackerRow& krMiddle = arrRow[roc%36][localRow]; // middle
1898 // initial guess use simple linear interpolation
1899 Double_t y=(clInner->GetY()+clOuter->GetY())/2;
1900 Double_t z=(clInner->GetZ()+clOuter->GetZ())/2;
1901 if (seedFit.IsValid()) {
1902 // update values once the fit was performed
1903 y=seedFit.GetYat(krMiddle.GetX());
1904 z=seedFit.GetZat(krMiddle.GetX());
1907 n=krMiddle.FindNearest(y,z,roady,roadz);
1912 // 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,
1913 // n->GetX(), n->GetY(),n->GetZ(),n->GetLabel(0),
1914 // clInner->GetX(), clInner->GetY(),clInner->GetZ(),clInner->GetLabel(0),
1915 // clOuter->GetX(), clOuter->GetY(),clOuter->GetZ(),clOuter->GetLabel(0)
1920 //____________________________________________________________________________________
1921 void AliToyMCReconstruction::AddMiddleClusters(AliTPCseed *seed,
1922 const AliTPCclusterMI *clInner, const AliTPCclusterMI *clOuter,
1923 Double_t roady, Double_t roadz,
1924 Int_t &nTotalClusters, AliRieman &seedFit)
1927 // Iteratively add the middle clusters
1930 // update rieman fit with every second point added
1931 AliTPCclusterMI *clMiddle=FindMiddleCluster(clInner,clOuter,roady,roadz,seedFit);
1933 // break iterative process
1934 if (!clMiddle || clMiddle->IsUsed()) return;
1936 const Int_t globalRowInner = clInner->GetRow() +(clInner->GetDetector() >35)*63;
1937 const Int_t globalRowMiddle = clMiddle->GetRow()+(clMiddle->GetDetector()>35)*63;
1938 const Int_t globalRowOuter = clOuter->GetRow() +(clOuter->GetDetector() >35)*63;
1940 seed->SetClusterPointer(globalRowMiddle,clMiddle);
1942 // printf(" > Total clusters: %d\n",nTotalClusters);
1943 seedFit.AddPoint(clMiddle->GetX(), clMiddle->GetY(), clMiddle->GetZ(),
1944 TMath::Sqrt(clMiddle->GetSigmaY2()), TMath::Sqrt(clMiddle->GetSigmaZ2()));
1946 if (seedFit.GetN()>3) {
1947 // printf(" call update: %d (%d)\n",seedFit.GetN(),nTotalClusters);
1948 // printf(" Riemann results: valid=%d, Chi2=%.2f, Chi2Y=%.2f, Chi2Z=%.2f -- %d\n",
1949 // seedFit.IsValid(), seedFit.GetChi2(), seedFit.GetChi2Y(), seedFit.GetChi2Z(), clMiddle->GetLabel(0));
1952 if ( seedFit.IsValid() && seedFit.GetChi2()>1000 ) return;
1954 // Add middle clusters towards outer radius
1955 if (globalRowMiddle+1<globalRowOuter) AddMiddleClusters(seed,clMiddle,clOuter,roady,roadz,nTotalClusters,seedFit);
1957 // Add middle clusters towards innter radius
1958 if (globalRowInner+1<globalRowMiddle) AddMiddleClusters(seed,clInner,clMiddle,roady,roadz,nTotalClusters,seedFit);
1963 //____________________________________________________________________________________
1964 Int_t AliToyMCReconstruction::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t iRowInner, Int_t iRowOuter)
1967 // find seeds in a sector, requires iRowInner < iRowOuter
1968 // iRowXXX runs from 0-159, so over IROC and OROC
1972 AliError("This function requires the sector arrays filled for AC tracking");
1976 // swap rows in case they are in the wrong order
1977 if (iRowInner>iRowOuter) {
1978 Int_t tmp=iRowInner;
1979 iRowInner=iRowOuter;
1983 if (iRowOuter>158) iRowOuter=158;
1984 if (iRowInner<0) iRowInner=0;
1986 // Define the search roads:
1987 // timeRoadCombinatorics - the maximum time difference used for the
1988 // combinatorics. Since we don't have a 'z-Vertex' estimate this will
1989 // reduce the combinatorics significantly when iterating on one TF
1990 // use a little more than one full drift length of the TPC to allow for
1993 // timeRoad - the time difference allowed when associating the cluster
1994 // in the middle of the other two used for the initial search
1996 // padRoad - the local y difference allowed when associating the middle cluster
1998 // Double_t timeRoadCombinatorics = 270./vDrift;
1999 // Double_t timeRoad = 20./vDrift;
2000 Double_t timeRoadCombinatorics = 270.;
2001 Double_t timeRoad = 10.;
2002 Double_t padRoad = 5.;
2005 // fOuterSectorArray runs from 0-95, so from iRowXXX which runs from 0-159
2006 // the number of rows in the IROC has to be subtracted
2007 const Int_t innerRows=fInnerSectorArray->GetNRows();
2009 AliTPCtrackerSector *arrInnerRow=(iRowInner<63)?fInnerSectorArray:fOuterSectorArray;
2010 AliTPCtrackerSector *arrOuterRow=(iRowOuter<63)?fInnerSectorArray:fOuterSectorArray;
2012 const AliTPCtrackerRow& krInner = arrInnerRow[sec][iRowInner - (iRowInner>62)*innerRows]; // up
2013 const AliTPCtrackerRow& krOuter = arrOuterRow[sec][iRowOuter - (iRowOuter>62)*innerRows]; // down
2015 AliTPCseed *seed = new AliTPCseed;
2017 const Int_t nMaxClusters=iRowOuter-iRowInner+1;
2018 // Int_t nScannedClusters = 0;
2021 // loop over all points in the firstand last search row
2022 for (Int_t iOuter=0; iOuter < krOuter; iOuter++) {
2023 const AliTPCclusterMI *clOuter = krOuter[iOuter];
2024 if (clOuter->IsUsed()) continue;
2025 for (Int_t iInner=0; iInner < krInner; iInner++) {
2026 const AliTPCclusterMI *clInner = krInner[iInner];
2027 if (clInner->IsUsed()) continue;
2028 // printf("\n\n Check combination %d (%d), %d (%d) -- %d (%d) -- %d\n",iOuter, iInner, clOuter->GetLabel(0), clInner->GetLabel(0),iRowOuter,iRowInner,sec);
2029 // check maximum distance for combinatorics
2030 if (TMath::Abs(clOuter->GetZ()-clInner->GetZ())>timeRoadCombinatorics) continue;
2031 // printf(" Is inside one drift\n");
2033 // use rieman fit for seed description
2034 AliRieman seedFit(159);
2035 // add first two points
2036 seedFit.AddPoint(clInner->GetX(), clInner->GetY(), clInner->GetZ(),
2037 TMath::Sqrt(clInner->GetSigmaY2()), TMath::Sqrt(clInner->GetSigmaZ2()));
2038 seedFit.AddPoint(clOuter->GetX(), clOuter->GetY(), clOuter->GetZ(),
2039 TMath::Sqrt(clOuter->GetSigmaY2()), TMath::Sqrt(clOuter->GetSigmaZ2()));
2041 // Iteratively add all clusters in the respective middle
2042 Int_t nFoundClusters=2;
2043 AddMiddleClusters(seed,clInner,clOuter,padRoad,timeRoad,nFoundClusters,seedFit);
2044 // printf(" Clusters attached: %d\n",nFoundClusters);
2045 if (nFoundClusters>2) seedFit.Update();
2046 // printf(" Riemann results: valid=%d, Chi2=%.2f, Chi2Y=%.2f, Chi2Z=%.2f\n",
2047 // seedFit.IsValid(), seedFit.GetChi2(), seedFit.GetChi2Y(), seedFit.GetChi2Z());
2049 // check for minimum number of assigned clusters and a decent chi2
2050 if ( nFoundClusters<0.5*nMaxClusters || seedFit.GetChi2()>1000 ){
2054 // printf(" >>> Seed accepted\n");
2055 // add original outer clusters
2056 const Int_t globalRowInner = clInner->GetRow() +(clInner->GetDetector() >35)*63;
2057 const Int_t globalRowOuter = clOuter->GetRow() +(clOuter->GetDetector() >35)*63;
2059 seed->SetClusterPointer(globalRowInner,const_cast<AliTPCclusterMI*>(clInner));
2060 seed->SetClusterPointer(globalRowOuter,const_cast<AliTPCclusterMI*>(clOuter));
2062 // set parameters retrieved from AliRieman
2063 Double_t params[5]={0};
2064 Double_t covar[15]={0};
2065 const Double_t alpha=TMath::DegToRad()*(clInner->GetDetector()%18*20.+10.);
2066 const Double_t x=clInner->GetX();
2067 seedFit.GetExternalParameters(x,params,covar);
2069 seed->Set(x,alpha,params,covar);
2071 // set label of the seed. At least 60% of the clusters need the correct label
2073 // printf(" - Label: %d\n",seed->GetLabel());
2074 // mark clusters as being used
2075 MarkClustersUsed(seed);
2077 seed->SetSeed1(iRowInner);
2078 seed->SetSeed2(iRowOuter);
2079 seed->SetSector(sec);
2082 seed->SetUniqueID(arr->GetEntriesFast());
2083 seed->SetIsSeeding(kTRUE);
2086 seed=new AliTPCseed;
2091 //delete surplus seed
2097 //____________________________________________________________________________________
2098 void AliToyMCReconstruction::MakeSeeds(TObjArray * /*arr*/, Int_t sec, Int_t iRow1, Int_t iRow2)
2101 // Create seeds between i1 and i2 (stored in arr) with TLinearFitter
2103 // sec: sector number
2109 static TLinearFitter fitter(3,"pol2");
2111 // Get 3 padrows (iRow1,iMiddle=(iRow1+iRow2)/2,iRow2)
2112 Int_t iMiddle = (iRow1+iRow2)/2;
2113 const AliTPCtrackerRow& krd = fOuterSectorArray[sec][iRow2-fInnerSectorArray->GetNRows()]; // down
2114 const AliTPCtrackerRow& krm = fOuterSectorArray[sec][iMiddle-fInnerSectorArray->GetNRows()]; // middle
2115 const AliTPCtrackerRow& kru = fOuterSectorArray[sec][iRow1-fInnerSectorArray->GetNRows()]; // up
2117 // Loop over 3 cluster possibilities
2118 for (Int_t iu=0; iu < kru; iu++) {
2119 for (Int_t im=0; im < krm; im++) {
2120 for (Int_t id=0; id < krd; id++) {
2123 fitter.ClearPoints();
2125 // add all three points to fitter
2126 Double_t xy[2] = {kru[iu]->GetX(),kru[iu]->GetY()};
2127 Double_t z = kru[iu]->GetZ();
2128 fitter.AddPoint(xy,z);
2130 xy[0] = krm[im]->GetX();
2131 xy[1] = krm[im]->GetY();
2132 z = krm[im]->GetZ();
2133 fitter.AddPoint(xy,z);
2135 xy[0] = krd[id]->GetX();
2136 xy[1] = krd[id]->GetY();
2137 z = krd[id]->GetZ();
2138 fitter.AddPoint(xy,z);
2140 // Evaluate and get parameters
2143 // how to get the other clusters now?
2151 //____________________________________________________________________________________
2152 void AliToyMCReconstruction::InitStreamer(TString addName, Int_t level)
2155 // initilise the debug streamer and set the logging level
2156 // use a default naming convention
2162 if (addName.IsNull()) addName=".dummy";
2166 TString debugName=fInputFile->GetName();
2167 debugName.ReplaceAll(".root","");
2168 debugName.Append(Form(".%1d.%1d_%1d_%1d_%03d_%02d",
2169 fUseMaterial,fIdealTracking,fClusterType,
2170 Int_t(fCorrectionType),fSeedingRow,fSeedingDist));
2171 debugName.Append(addName);
2172 debugName.Append(".root");
2174 gSystem->Exec(Form("test -f %s && rm %s", debugName.Data(), debugName.Data()));
2175 fStreamer=new TTreeSRedirector(debugName.Data());
2176 fStreamer->SetUniqueID(level);
2181 //____________________________________________________________________________________
2182 void AliToyMCReconstruction::ConnectInputFile(const char* file, Int_t nmaxEv)
2185 // connect the tree and event pointer from the input file
2193 fInputFile=TFile::Open(file);
2194 if (!fInputFile || !fInputFile->IsOpen() || fInputFile->IsZombie()) {
2197 AliError(Form("ERROR: couldn't open the file '%s'\n", file));
2201 fTree=(TTree*)fInputFile->Get("toyMCtree");
2203 AliError(Form("ERROR: couldn't read the 'toyMCtree' from file '%s'\n", file));
2208 fTree->SetBranchAddress("event",&fEvent);
2212 fNmaxEvents=fTree->GetEntries();
2213 if (nmaxEv>-1) fNmaxEvents=TMath::Min(nmaxEv,fNmaxEvents);
2215 // setup space charge map from Userinfo of the tree
2218 // setup the track maps
2222 //____________________________________________________________________________________
2223 void AliToyMCReconstruction::Cleanup()
2226 // Cleanup input data
2229 if (fStreamer) delete fStreamer;
2243 //____________________________________________________________________________________
2244 void AliToyMCReconstruction::SetupTrackMaps()
2250 fMapTrackEvent.Delete();
2251 fMapTrackTrackInEvent.Delete();
2254 AliError("Tree not connected");
2258 Int_t nmaxEv=fTree->GetEntries();
2259 if (fNmaxEvents>-1) nmaxEv=fNmaxEvents;
2261 for (Int_t iev=0; iev<nmaxEv; ++iev) {
2262 fTree->GetEvent(iev);
2263 if (!fEvent) continue;
2265 const Int_t ntracks=fEvent->GetNumberOfTracks();
2266 if (fMapTrackEvent.GetSize()+ntracks>=fMapTrackEvent.Capacity()) fMapTrackEvent.Expand(2*fMapTrackEvent.Capacity());
2267 if (fMapTrackTrackInEvent.GetSize()+ntracks>=fMapTrackTrackInEvent.Capacity()) fMapTrackTrackInEvent.Expand(2*fMapTrackTrackInEvent.Capacity());
2269 for (Int_t itrack=0; itrack<ntracks; ++itrack){
2270 Int_t label=fEvent->GetTrack(itrack)->GetUniqueID();
2272 fMapTrackEvent.Add(label,iev);
2273 fMapTrackTrackInEvent.Add(label,itrack);
2279 //____________________________________________________________________________________
2280 void AliToyMCReconstruction::CookLabel(AliTPCseed *seed, Double_t fraction, Int_t info[5])
2286 Int_t labels[159]={0};
2287 // Long64_t posMaxLabel=-1;
2288 Int_t nMaxLabel=0; // clusters from maximum label
2289 Int_t nMaxLabel2=0; // clusters from second maximum
2291 Int_t maxLabel=-1; // label with most clusters
2292 Int_t maxLabel2=-1; // label with second most clusters
2294 TExMap labelMap(159);
2296 for (Int_t icl=0; icl<159; ++icl) {
2297 const AliTPCclusterMI *cl=seed->GetClusterPointer(icl);
2301 const Int_t clLabel=cl->GetLabel(0);
2302 // a not assinged value returns 0, so we need to add 1 and subtract it afterwards
2303 Long64_t labelPos=labelMap.GetValue(clLabel);
2307 labelMap.Add(clLabel,labelPos);
2312 const Int_t nCurrentLabel=++labels[labelPos];
2313 if (nCurrentLabel>nMaxLabel) {
2314 nMaxLabel2=nMaxLabel;
2315 nMaxLabel=nCurrentLabel;
2316 // posMaxLabel=labelPos;
2322 if (Double_t(nMaxLabel)/nclusters<fraction) maxLabel=-maxLabel;
2324 seed->SetLabel(maxLabel);
2336 //____________________________________________________________________________________
2337 void AliToyMCReconstruction::DumpSeedInfo(TObjArray *arr)
2341 if (!fStreamer || !fTree) return;
2342 // swap rows in case they are in the wrong order
2343 AliInfo(Form("Number of Seeds: %d (out of %d tracks)",arr->GetEntriesFast(),fMapTrackEvent.GetSize()));
2345 //loop over all events and tracks and try to associate the seed to the track
2346 for (Int_t iseed=0; iseed<arr->GetEntriesFast(); ++iseed){
2347 AliTPCseed *seed = static_cast<AliTPCseed*>(arr->UncheckedAt(iseed));
2349 // get original track
2350 Int_t seedLabel=seed->GetLabel();
2351 Int_t iev=fMapTrackEvent.GetValue(TMath::Abs(seedLabel));
2352 Int_t itr=fMapTrackTrackInEvent.GetValue(TMath::Abs(seedLabel));
2354 fTree->GetEvent(iev);
2355 const AliToyMCTrack *toyTrack = fEvent->GetTrack(itr);
2357 DumpSeedInfo(toyTrack,seed);
2361 //____________________________________________________________________________________
2362 void AliToyMCReconstruction::DumpTrackInfo(TObjArray *arr)
2366 if (!fStreamer || !fTree) return;
2367 // swap rows in case they are in the wrong order
2368 AliInfo(Form("Number of Seeds: %d (out of %d tracks)",arr->GetEntriesFast(),fMapTrackEvent.GetSize()));
2370 //loop over all events and tracks and try to associate the seed to the track
2371 AliTPCseed dummySeed;
2372 for (Int_t iev=0; iev<fNmaxEvents; ++iev) {
2373 fTree->GetEvent(iev);
2374 const Int_t ntracks=fEvent->GetNumberOfTracks();
2375 for (Int_t itr=0; itr<ntracks; ++itr) {
2376 const AliToyMCTrack *toyTrack = fEvent->GetTrack(itr);
2378 Bool_t foundSeed=kFALSE;
2379 for (Int_t iseed=0; iseed<arr->GetEntriesFast(); ++iseed) {
2380 AliTPCseed *seed = static_cast<AliTPCseed*>(arr->UncheckedAt(iseed));
2381 const UInt_t tmpLabel=TMath::Abs(seed->GetLabel());
2382 if (toyTrack->GetUniqueID()!=tmpLabel) continue;
2384 // dump all seeds with the correct label
2385 DumpSeedInfo(toyTrack,seed);
2389 if (!foundSeed) DumpSeedInfo(toyTrack,&dummySeed);
2395 //____________________________________________________________________________________
2396 void AliToyMCReconstruction::DumpSeedInfo(const AliToyMCTrack *toyTrack, AliTPCseed *seed)
2402 const Double_t kMaxSnp = 0.85;
2403 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
2404 Float_t vDrift=GetVDrift();
2405 Float_t zLength=GetZLength(0);
2407 AliExternalTrackParam tOrig(*toyTrack);
2408 AliExternalTrackParam tOrigITS(*toyTrack);
2410 // propagate original track to ITS last layer
2411 Double_t lastLayerITS = 43.0; // same as in AliToyMCEventGenerator::MakeITSClusters (hard coded)
2412 AliTrackerBase::PropagateTrackTo(&tOrigITS,lastLayerITS,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
2414 AliExternalTrackParam dummyParam;
2415 Bool_t isDummy=kFALSE;
2416 //create refitted track, this will also set the fTime0
2417 AliExternalTrackParam *track=GetRefittedTrack(*seed);
2422 AliTrackerBase::PropagateTrackTo(track,0,kMass,5.,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
2423 track->Rotate(tOrig.GetAlpha());
2424 AliTrackerBase::PropagateTrackTo(track,0,kMass,1.,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
2426 // rotate fitted track to the frame of the original track and propagate to same reference
2427 AliExternalTrackParam trackITS(*track);
2428 AliTrackerBase::PropagateTrackTo(&trackITS,lastLayerITS,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
2429 trackITS.Rotate(tOrigITS.GetAlpha());
2430 AliTrackerBase::PropagateTrackTo(&trackITS,lastLayerITS,kMass,1,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
2432 Int_t seedSec=seed->GetSector();
2433 Int_t seedID =seed->GetUniqueID();
2435 //count findable and found clusters in the seed
2437 Int_t iRowInner=seed->GetSeed1();
2438 Int_t iRowOuter=seed->GetSeed2();
2440 Int_t nClustersSeedMax=iRowOuter-iRowInner+1;
2441 Int_t nClustersFindable=0;
2442 Int_t nClustersSeed=0;
2444 Int_t ncls=(fClusterType==0)?toyTrack->GetNumberOfSpacePoints():toyTrack->GetNumberOfDistSpacePoints();
2446 Int_t rowInner=iRowInner-(iRowInner>62)*63;
2447 Int_t rowOuter=iRowOuter-(iRowOuter>62)*63;
2449 //findable in the current seed sector
2452 Int_t nCrossedROCs=0;
2459 for (Int_t icl=0; icl<ncls; ++icl) {
2460 const AliTPCclusterMI *cl=(fClusterType==0)?toyTrack->GetSpacePoint(icl):toyTrack->GetDistortedSpacePoint(icl);
2461 const Int_t roc=cl->GetDetector();
2462 const Int_t row=cl->GetRow();
2463 const Int_t rowGlobal=row+(roc>35)*63;
2465 AliTPCclusterMI *seedCl = seed->GetClusterPointer(rowGlobal);
2467 AliTPCclusterMI *clc=const_cast<AliTPCclusterMI*>(cl);
2468 if (seedCl->GetDetector()==roc&&seedCl->IsUsed()) clc->Use();
2469 clc->SetLabel(seedID,1);
2473 // if (row1<0) row1=rowGlobal;
2475 if ( (roc%36) != (lastROC%36)) {
2477 if (nclROC>nMaxClROC) {
2490 if ( (roc%36)!=(seedSec%36) ) continue;
2491 // if ( (row<rowInner) || (row>rowOuter) ) continue;
2492 ++nClustersFindable;
2496 if (nclROC>nMaxClROC) {
2505 Int_t nClustersInTrack=0;
2507 for (Int_t icl=0; icl<159; ++icl) {
2508 const AliTPCclusterMI *cl=seed->GetClusterPointer(icl);
2511 const Int_t row=cl->GetRow();
2512 const Int_t rowGlobal=row+(cl->GetDetector()>35)*63;
2513 if (rowGlobal>lastRow) lastRow=rowGlobal;
2514 if (rowGlobal<firstRow) firstRow=rowGlobal;
2515 if ( (row<rowInner) || (row>rowOuter) ) continue;
2519 Float_t z0=fEvent->GetZ();
2520 Float_t t0=fEvent->GetT0();
2522 Int_t ctype(fCorrectionType);
2525 CookLabel(seed,.6,info);
2526 Int_t seedLabel=seed->GetLabel();
2528 Int_t labelOrig=toyTrack->GetUniqueID();
2530 AliToyMCTrack *tr2 = const_cast<AliToyMCTrack*>(toyTrack);
2532 (*fStreamer) << "Seeds" <<
2534 // "iseed=" << iseed <<
2538 "vDrift=" << vDrift <<
2539 "zLength=" << zLength <<
2540 "fTime0=" << fTime0 <<
2541 "clsType=" << fClusterType <<
2542 "corrType=" << ctype <<
2544 "tOrig.=" << &tOrig <<
2545 "tOrigITS.=" << &tOrigITS <<
2547 "to.nclFindable=" << nClustersFindable <<
2548 "to.nclTot=" << ncls <<
2549 "to.label=" << labelOrig <<
2550 "to.nCrossedROCs="<< nCrossedROCs <<
2551 "to.rocMax=" << rocMaxCl <<
2552 "to.rocMaxNcl=" << nMaxClROC <<
2553 "to.row1Max=" << row1Maxcl <<
2554 "to.row2Max=" << row2Maxcl <<
2556 "track.=" << track <<
2557 "trackITS.=" << &trackITS <<
2559 "s.RowInner=" << iRowInner <<
2560 "s.RowOuter=" << iRowOuter <<
2561 "s.nclMax=" << nClustersSeedMax <<
2562 "s.ncl=" << nClustersSeed <<
2563 "s.ID=" << seedID <<
2565 "tr.firstClRow=" << firstRow <<
2566 "tr.lastClRow=" << lastRow <<
2567 "tr.ncl=" << nClustersInTrack <<
2568 "tr.label=" << seedLabel <<
2570 "tr.LabelNcl=" << info[0] <<
2571 "tr.Label2Ncl=" << info[1] <<
2572 "tr.Label2=" << info[2] <<
2573 "tr.nclTot=" << info[3] <<
2574 "tr.Nlabels=" << info[4] <<
2576 "tr.Sec=" << seedSec <<
2579 "toyTrack.=" << tr2 <<
2582 if (!isDummy) delete track;
2585 //____________________________________________________________________________________
2586 void AliToyMCReconstruction::MarkClustersUsed(AliTPCseed *seed)
2592 for (Int_t icl=0; icl<159; ++icl) {
2593 AliTPCclusterMI *cl=seed->GetClusterPointer(icl);
2598 //____________________________________________________________________________________
2599 void AliToyMCReconstruction::ResetClustersZtoTime(AliTPCseed *seed)
2605 for (Int_t icl=0; icl<159; ++icl) {
2606 AliTPCclusterMI *cl=seed->GetClusterPointer(icl);
2607 if (cl) cl->SetZ(cl->GetTimeBin());
2611 //____________________________________________________________________________________
2612 void AliToyMCReconstruction::DumpTracksToTree(const char* file)
2617 ConnectInputFile(file);
2623 TString debugName=fInputFile->GetName();
2624 debugName.ReplaceAll(".root",".AllTracks.root");
2626 gSystem->Exec(Form("test -f %s && rm %s", debugName.Data(), debugName.Data()));
2627 fStreamer=new TTreeSRedirector(debugName.Data());
2629 for (Int_t iev=0;iev<fNmaxEvents;++iev){
2630 fTree->GetEvent(iev);
2631 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks();++itr){
2632 AliToyMCTrack *toyTrack=const_cast<AliToyMCTrack*>(fEvent->GetTrack(itr));
2633 Int_t trackID=toyTrack->GetUniqueID();
2635 (*fStreamer) << "Tracks" <<
2638 "trackID=" << trackID <<
2639 "track.=" << toyTrack <<
2648 //____________________________________________________________________________________
2649 void AliToyMCReconstruction::SetRieman(const AliTPCseed &seed, AliRieman &rieman)
2656 for (Int_t icl=0; icl<159; ++icl) {
2657 const AliTPCclusterMI *cl=seed.GetClusterPointer(icl);
2659 rieman.AddPoint(cl->GetX(), cl->GetY(), cl->GetZ(),
2660 TMath::Sqrt(cl->GetSigmaY2()), TMath::Sqrt(cl->GetSigmaZ2()));
2665 //____________________________________________________________________________________
2666 void AliToyMCReconstruction::CopyRieman(const AliRieman &from, AliRieman &to)
2672 if (to.GetCapacity()<from.GetCapacity()) return;
2675 for (Int_t i=0;i<from.GetN();++i) to.AddPoint(from.GetX()[i],from.GetY()[i],from.GetZ()[i],from.GetSy()[i],from.GetSz()[i]);