2 #include <TDatabasePDG.h>
10 #include <AliExternalTrackParam.h>
11 #include <AliTPCcalibDB.h>
12 #include <AliTPCclusterMI.h>
13 #include <AliTPCCorrection.h>
14 #include <AliTrackerBase.h>
15 #include <AliTrackPointArray.h>
17 #include <AliTPCParam.h>
18 #include <AliTPCROC.h>
19 #include <TTreeStream.h>
20 #include <AliTPCReconstructor.h>
21 #include <AliTPCTransform.h>
22 #include <AliTPCseed.h>
23 #include <AliTPCtracker.h>
24 #include <AliTPCtrackerSector.h>
25 #include <AliRieman.h>
27 #include "AliToyMCTrack.h"
28 #include "AliToyMCEvent.h"
30 #include "AliToyMCReconstruction.h"
38 //____________________________________________________________________________________
39 AliToyMCReconstruction::AliToyMCReconstruction() : TObject()
43 , fCorrectionType(kNoCorrection)
45 , fUseMaterial(kFALSE)
46 , fIdealTracking(kFALSE)
49 , fCreateT0seed(kFALSE)
51 , fFillClusterRes(kFALSE)
62 , fkNSectorInner(18) // hard-coded to avoid loading the parameters before
63 , fInnerSectorArray(0x0)
64 , fkNSectorOuter(18) // hard-coded to avoid loading the parameters before
65 , fOuterSectorArray(0x0)
66 , fAllClusters("AliTPCclusterMI",10000)
67 , fMapTrackEvent(10000)
68 , fMapTrackTrackInEvent(10000)
75 fTPCParam=AliTPCcalibDB::Instance()->GetParameters();
79 //____________________________________________________________________________________
80 AliToyMCReconstruction::~AliToyMCReconstruction()
89 //____________________________________________________________________________________
90 void AliToyMCReconstruction::RunReco(const char* file, Int_t nmaxEv)
93 // Recostruction from associated clusters
96 ConnectInputFile(file, nmaxEv);
99 Int_t maxev=fTree->GetEntries();
100 if (nmaxEv>0&&nmaxEv<maxev) maxev=nmaxEv;
102 InitStreamer(".debug");
106 static AliExternalTrackParam resetParam;
108 AliExternalTrackParam t0seed;
109 AliExternalTrackParam seed;
110 AliExternalTrackParam track;
111 AliExternalTrackParam tOrig;
114 AliExternalTrackParam tOrigITS; // ideal track
115 AliExternalTrackParam tRealITS; // ITS track with realistic space point resolution
116 AliExternalTrackParam trackITS; // TPC refitted track
118 //between TPC inner wall and ITS
119 AliExternalTrackParam tOrigITS1;
120 AliExternalTrackParam tRealITS1;
121 AliExternalTrackParam trackITS1;
124 AliExternalTrackParam tOrigITS2;
125 AliExternalTrackParam tRealITS2;
126 AliExternalTrackParam trackITS2;
128 AliExternalTrackParam *dummy;
130 // prepare list of T0s
131 TVectorF t0list(maxev);
132 TVectorF z0list(maxev);
133 if (fUseT0list || fUseZ0list) {
134 for (Int_t iev=0; iev<maxev; ++iev){
135 fTree->GetEvent(iev);
136 const Float_t t0=fEvent->GetT0();
137 const Float_t z0=fEvent->GetZ();
143 // array with cluster residuals
144 TClonesArray *arrClustRes=0x0;
145 if (fFillClusterRes){
146 arrClustRes=new TClonesArray("AliTPCclusterMI",160);
149 const Double_t lastLayerITS = 43.0; // same as in AliToyMCEventGenerator::MakeITSClusters (hard coded)
150 const Double_t iFCRadius = 83.5; //radius constants found in AliTPCCorrection.cxx
151 const Double_t betweeTPCITS = (lastLayerITS+iFCRadius)/2.; // its track propgated to inner TPC wall
153 const Double_t kMaxSnp = 0.85;
154 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
159 // binning r, phi, z, delta
161 Int_t bins[nbins] = {16, 18*5, 50, 80};
162 Double_t xmin[nbins] = {86. , 0., -250., -2.};
163 Double_t xmax[nbins] = {250., 2*TMath::Pi(), 250., 2.};
164 fHnDelta = new THnF("hn", "hn", nbins, bins, xmin, xmax);
167 Bool_t fillStreamer=(fStreamer!=0x0);
168 if (fRecoInfo>-1 && ((fRecoInfo&kFillNoTrackInfo)==kFillNoTrackInfo)) fillStreamer=kFALSE;
170 for (Int_t iev=0; iev<maxev; ++iev){
171 printf("============== Processing Event %6d =================\n",iev);
172 fTree->GetEvent(iev);
174 Float_t z0=fEvent->GetZ();
175 Float_t t0=fEvent->GetT0();
177 // set SC scaling factor
178 fTPCCorrection->SetCorrScaleFactor(fEvent->GetSCscale());
180 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
181 // printf(" > ====== Processing Track %6d ======== \n",itr);
182 const AliToyMCTrack *tr=fEvent->GetTrack(itr);
185 // propagate original track to ITS comparison points
186 if (fRecoInfo<0 || (fRecoInfo&kFillITS) ==kFillITS ) {
188 AliTrackerBase::PropagateTrackTo(&tOrigITS, lastLayerITS,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
189 tRealITS = resetParam;
191 if (fRecoInfo<0 || (fRecoInfo&kFillITS1)==kFillITS1 ) {
193 AliTrackerBase::PropagateTrackTo(&tOrigITS1,betweeTPCITS,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
194 tRealITS1 = resetParam;
196 if (fRecoInfo<0 || (fRecoInfo&kFillITS2)==kFillITS2 ) {
198 AliTrackerBase::PropagateTrackTo(&tOrigITS2,iFCRadius, kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
199 tRealITS2 = resetParam;
202 // realistic ITS track propagated to reference points
203 dummy = GetTrackRefit(tr,kITS);
205 // propagate realistic track to ITS comparison points
206 if (fRecoInfo<0 || (fRecoInfo&kFillITS) ==kFillITS ) {
208 AliTrackerBase::PropagateTrackTo(&tRealITS, lastLayerITS,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
210 if (fRecoInfo<0 || (fRecoInfo&kFillITS1)==kFillITS1 ) {
212 AliTrackerBase::PropagateTrackTo(&tRealITS1,betweeTPCITS,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
214 if (fRecoInfo<0 || (fRecoInfo&kFillITS2)==kFillITS2 ) {
216 AliTrackerBase::PropagateTrackTo(&tRealITS2,iFCRadius, kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
230 if (fRecoInfo<0 || (fRecoInfo&kFillITS) ==kFillITS ) trackITS = resetParam;
231 if (fRecoInfo<0 || (fRecoInfo&kFillITS1)==kFillITS1 ) trackITS1 = resetParam;
232 if (fRecoInfo<0 || (fRecoInfo&kFillITS2)==kFillITS2 ) trackITS2 = resetParam;
234 Float_t vDrift=GetVDrift();
235 Float_t zLength=GetZLength(0);
237 // crate time0 seed, steered by fCreateT0seed
238 // printf("t0 seed\n");
241 dummy = GetSeedFromTrack(tr);
249 dummy = GetFittedTrackFromSeed(tr,&t0seed);
254 // set the T0 from the seed
255 // in case the match with the real T0 infor is requested, find the
256 // closes T0 from the list of T0s
257 fTime0 = t0seed.GetZ()-zLength/vDrift;
258 if (fUseT0list || fUseZ0list) {
259 fTime0 = FindClosestT0(t0list, z0list, t0seed);
261 // create real seed using the time 0 from the first seed
262 // set fCreateT0seed now to false to get the seed in z coordinates
263 fCreateT0seed = kFALSE;
264 // printf("seed (%.2g)\n",fTime0);
265 dummy = GetSeedFromTrack(tr);
271 // create fitted track
273 // printf("track\n");
274 dummy = GetFittedTrackFromSeed(tr, &seed, arrClustRes);
280 // propagate seed to 0
281 AliTrackerBase::PropagateTrackTo(&seed,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
287 // rotate fitted track to the frame of the original track and propagate to same reference
288 if (fRecoInfo<0 || (fRecoInfo&kFillITS) ==kFillITS ){
290 AliTrackerBase::PropagateTrackTo(&trackITS,lastLayerITS,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
291 trackITS.Rotate(tOrigITS.GetAlpha());
292 AliTrackerBase::PropagateTrackTo(&trackITS,lastLayerITS,kMass,1,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
295 // rotate fitted track to the frame of the original track and propagate to same reference
296 if (fRecoInfo<0 || (fRecoInfo&kFillITS1)==kFillITS1 ){
298 AliTrackerBase::PropagateTrackTo(&trackITS1,betweeTPCITS,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
299 trackITS1.Rotate(tOrigITS1.GetAlpha());
300 AliTrackerBase::PropagateTrackTo(&trackITS1,betweeTPCITS,kMass,1,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
303 // rotate fitted track to the frame of the original track and propagate to same reference
304 if (fRecoInfo<0 || (fRecoInfo&kFillITS2)==kFillITS2 ){
306 AliTrackerBase::PropagateTrackTo(&trackITS2,iFCRadius,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
307 trackITS2.Rotate(tOrigITS2.GetAlpha());
308 AliTrackerBase::PropagateTrackTo(&trackITS2,iFCRadius,kMass,1,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
313 Int_t ctype(fCorrectionType);
316 (*fStreamer) << "Tracks" <<
320 "lastt0=" << lastT0 <<
321 "fTime0=" << fTime0 <<
323 "clsType=" << fClusterType <<
324 "corrType=" << ctype <<
325 "seedRow=" << fSeedingRow <<
326 "seedDist=" << fSeedingDist <<
327 "vDrift=" << vDrift <<
328 "zLength=" << zLength <<
329 "t0seed.=" << &t0seed <<
332 "tOrig.=" << &tOrig <<
337 if (fRecoInfo<0 || (fRecoInfo&kFillITS) ==kFillITS ){
338 (*fStreamer) << "Tracks" <<
339 "tOrigITS.=" << &tOrigITS <<
340 "tRealITS.=" << &tRealITS <<
341 "trackITS.=" << &trackITS;
344 if (fRecoInfo<0 || (fRecoInfo&kFillITS1) ==kFillITS1 ){
345 (*fStreamer) << "Tracks" <<
346 "tOrigITS1.=" << &tOrigITS1 <<
347 "tRealITS1.=" << &tRealITS1 <<
348 "trackITS1.=" << &trackITS1;
351 if (fRecoInfo<0 || (fRecoInfo&kFillITS) ==kFillITS ){
352 (*fStreamer) << "Tracks" <<
353 "tOrigITS2.=" << &tOrigITS2 <<
354 "tRealITS2.=" << &tRealITS2 <<
355 "trackITS2.=" << &trackITS2;
359 const Int_t nCl=arrClustRes->GetEntriesFast();
360 // fracktion of outliers from track extrapolation
361 // for 3, 3.5, 4, 4.5 and 5 sigma of the cluster resolution (~1mm)
362 Float_t fracY[5]={0.};
363 Float_t fracZ[5]={0.};
365 for (Int_t icl=0; icl<nCl; ++icl) {
366 AliTPCclusterMI *cl=static_cast<AliTPCclusterMI*>(arrClustRes->At(icl));
367 // const Float_t sigmaY=TMath::Sqrt(cl->GetSigmaY2());
368 // const Float_t sigmaZ=TMath::Sqrt(cl->GetSigmaZ2());
369 for (Int_t inSig=0; inSig<5; ++inSig) {
370 fracY[inSig] += cl->GetY()>(3+inSig*.5)/**sigmaY*/;
371 fracZ[inSig] += cl->GetZ()>(3+inSig*.5)/**sigmaZ*/;
376 for (Int_t inSig=0; inSig<5; ++inSig) {
382 (*fStreamer) << "Tracks" <<
383 "clustRes.=" << arrClustRes;
384 for (Int_t inSig=0; inSig<5; ++inSig) {
385 const char* fracYname=Form("clFracY%02d=", 30+inSig*5);
386 const char* fracZname=Form("clFracZ%02d=", 30+inSig*5);
387 (*fStreamer) << "Tracks" <<
388 fracYname << fracY[inSig] <<
389 fracZname << fracZ[inSig];
393 (*fStreamer) << "Tracks" <<
402 fStreamer->GetFile()->cd();
410 //____________________________________________________________________________________
411 void AliToyMCReconstruction::RunRecoAllClusters(const char* file, Int_t nmaxEv)
414 // Reconstruction for seed from associated clusters, but array of clusters:
415 // Step 1) Filling of cluster arrays
416 // Step 2) Seeding from clusters associated to tracks
417 // Step 3) Free track reconstruction using all clusters
421 if (!f.IsOpen() || f.IsZombie()) {
422 printf("ERROR: couldn't open the file '%s'\n", file);
426 fTree=(TTree*)f.Get("toyMCtree");
428 printf("ERROR: couldn't read the 'toyMCtree' from file '%s'\n", file);
433 fTree->SetBranchAddress("event",&fEvent);
435 // read spacecharge from the Userinfo ot the tree
438 TString debugName=file;
439 debugName.ReplaceAll(".root","");
440 debugName.Append(Form(".%1d.%1d_%1d_%1d_%03d_%02d",
441 fUseMaterial,fIdealTracking,fClusterType,
442 Int_t(fCorrectionType),fSeedingRow,fSeedingDist));
443 debugName.Append(".allClusters.debug.root");
445 gSystem->Exec(Form("test -f %s && rm %s", debugName.Data(), debugName.Data()));
446 if (!fStreamer) fStreamer=new TTreeSRedirector(debugName.Data());
450 static AliExternalTrackParam dummySeedT0;
451 static AliExternalTrackParam dummySeed;
452 static AliExternalTrackParam dummyTrack;
454 AliExternalTrackParam t0seed;
455 AliExternalTrackParam seed;
456 AliExternalTrackParam track;
457 AliExternalTrackParam tOrig;
459 AliExternalTrackParam *dummy;
461 Int_t maxev=fTree->GetEntries();
462 if (nmaxEv>0&&nmaxEv<maxev) maxev=nmaxEv;
464 // ===========================================================================================
465 // Loop 1: Fill AliTPCtrackerSector structure
466 // ===========================================================================================
467 FillSectorStructure(maxev);
469 // settings (TODO: find the correct settings)
470 AliTPCRecoParam *tpcRecoParam = new AliTPCRecoParam();
471 tpcRecoParam->SetDoKinks(kFALSE);
472 AliTPCcalibDB::Instance()->GetTransform()->SetCurrentRecoParam(tpcRecoParam);
473 //tpcRecoParam->Print();
475 // need AliTPCReconstructor for parameter settings in AliTPCtracker
476 AliTPCReconstructor *tpcRec = new AliTPCReconstructor();
477 tpcRec->SetRecoParam(tpcRecoParam);
480 // ===========================================================================================
481 // Loop 2: Seeding from clusters associated to tracks
482 // TODO: Implement tracking from given seed!
483 // ===========================================================================================
484 for (Int_t iev=0; iev<maxev; ++iev){
485 printf("============== Processing Event %6d =================\n",iev);
486 fTree->GetEvent(iev);
487 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
488 printf(" > ====== Processing Track %6d ======== \n",itr);
489 const AliToyMCTrack *tr=fEvent->GetTrack(itr);
494 t0seed = dummySeedT0;
498 Float_t z0=fEvent->GetZ();
499 Float_t t0=fEvent->GetT0();
501 Float_t vDrift=GetVDrift();
502 Float_t zLength=GetZLength(0);
506 // crate time0 seed, steered by fCreateT0seed
510 dummy = GetSeedFromTrack(tr);
516 // crate real seed using the time 0 from the first seed
517 // set fCreateT0seed now to false to get the seed in z coordinates
518 fTime0 = t0seed.GetZ()-zLength/vDrift;
519 fCreateT0seed = kFALSE;
520 printf("seed (%.2g)\n",fTime0);
521 dummy = GetSeedFromTrack(tr);
526 // create fitted track
529 dummy = GetFittedTrackFromSeedAllClusters(tr, &seed,nClus);
534 // propagate seed to 0
535 const Double_t kMaxSnp = 0.85;
536 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
537 AliTrackerBase::PropagateTrackTo(&seed,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,kFALSE);
542 Int_t ctype(fCorrectionType);
545 (*fStreamer) << "Tracks" <<
549 "fTime0=" << fTime0 <<
551 "clsType=" << fClusterType <<
552 "corrType=" << ctype <<
553 "seedRow=" << fSeedingRow <<
554 "seedDist=" << fSeedingDist <<
555 "vDrift=" << vDrift <<
556 "zLength=" << zLength <<
558 "t0seed.=" << &t0seed <<
560 "track.=" << &track <<
561 "tOrig.=" << &tOrig <<
581 //____________________________________________________________________________________
582 void AliToyMCReconstruction::RunRecoAllClustersStandardTracking(const char* file, Int_t nmaxEv)
585 // Reconstruction for seed from associated clusters, but array of clusters
586 // Step 1) Filling of cluster arrays
587 // Step 2) Use the standard tracking: AliTPCtracker::Clusters2Tracks();
591 if (!f.IsOpen() || f.IsZombie()) {
592 printf("ERROR: couldn't open the file '%s'\n", file);
596 fTree=(TTree*)f.Get("toyMCtree");
598 printf("ERROR: couldn't read the 'toyMCtree' from file '%s'\n", file);
603 fTree->SetBranchAddress("event",&fEvent);
605 // read spacecharge from the Userinfo ot the tree
608 TString debugName=file;
609 debugName.ReplaceAll(".root","");
610 debugName.Append(Form(".%1d.%1d_%1d_%1d_%03d_%02d",
611 fUseMaterial,fIdealTracking,fClusterType,
612 Int_t(fCorrectionType),fSeedingRow,fSeedingDist));
613 debugName.Append(".allClusters.debug.root");
615 gSystem->Exec(Form("test -f %s && rm %s", debugName.Data(), debugName.Data()));
616 if (!fStreamer) fStreamer=new TTreeSRedirector(debugName.Data());
620 AliExternalTrackParam t0seed;
621 AliExternalTrackParam seed;
622 AliExternalTrackParam track;
623 AliExternalTrackParam tOrig;
624 AliToyMCTrack tOrigToy;
626 AliExternalTrackParam *dummy;
627 AliTPCseed *seedBest;
629 AliTPCclusterMI *cluster;
631 Int_t maxev=fTree->GetEntries();
632 if (nmaxEv>0&&nmaxEv<maxev) maxev=nmaxEv;
635 // ===========================================================================================
636 // Loop 1: Fill AliTPCtrackerSector structure
637 // ===========================================================================================
638 FillSectorStructure(maxev);
640 // ===========================================================================================
641 // Loop 2: Use the TPC tracker for seeding (MakeSeeds3)
642 // TODO: - check tracking configuration
643 // - add clusters and original tracks to output (how?)
644 // ===========================================================================================
646 // settings (TODO: find the correct settings)
647 AliTPCRecoParam *tpcRecoParam = new AliTPCRecoParam();
648 tpcRecoParam->SetDoKinks(kFALSE);
649 AliTPCcalibDB::Instance()->GetTransform()->SetCurrentRecoParam(tpcRecoParam);
650 //tpcRecoParam->Print();
652 // need AliTPCReconstructor for parameter settings in AliTPCtracker
653 AliTPCReconstructor *tpcRec = new AliTPCReconstructor();
654 tpcRec->SetRecoParam(tpcRecoParam);
657 AliTPCtracker *tpcTracker = new AliTPCtracker(fTPCParam);
658 tpcTracker->SetDebug(10);
661 tpcTracker->SetTPCtrackerSectors(fInnerSectorArray,fOuterSectorArray);
662 tpcTracker->LoadInnerSectors();
663 tpcTracker->LoadOuterSectors();
666 static TObjArray arrTracks;
667 TObjArray * arr = &arrTracks;
668 TObjArray * seeds = new TObjArray;
672 // cuts[0]=0.0070; // cuts[0] - fP4 cut
673 // cuts[1] = 1.5; // cuts[1] - tan(phi) cut
674 // cuts[2] = 3.; // cuts[2] - zvertex cut
675 // cuts[3] = 3.; // cuts[3] - fP3 cut
678 Int_t lowerRow = fSeedingRow;
679 Int_t upperRow = fSeedingRow+2*fSeedingDist;
680 const AliTPCROC * roc = AliTPCROC::Instance();
681 const Int_t kNRowsInnerTPC = roc->GetNRows(0);
682 const Int_t kNRowsTPC = kNRowsInnerTPC + roc->GetNRows(36);
683 if(lowerRow < kNRowsInnerTPC){
684 Printf("Seeding row requested (%d) is lower than kNRowsInnerTPC --> use %d",lowerRow,kNRowsInnerTPC);
685 lowerRow = kNRowsInnerTPC;
686 upperRow = lowerRow + 20;
688 if(upperRow >= kNRowsTPC){
689 Printf("Seeding row requested (%d) is larger than kNRowsTPC --> use %d",upperRow,kNRowsTPC-1);
690 upperRow = kNRowsTPC-1;
691 lowerRow = upperRow-20;
695 for (Int_t sec=0;sec<fkNSectorOuter;sec++){
697 //tpcTracker->MakeSeeds3(arr, sec,upperRow,lowerRow,cuts,-1,1);
698 MakeSeeds(arr, sec,upperRow,lowerRow); // own function (based on TLinearFitter)
699 //tpcTracker->SumTracks(seeds,arr);
700 //tpcTracker->SignClusters(seeds,3.0,3.0);
704 Printf("After seeding we have %d tracks",seeds->GetEntriesFast());
707 tpcTracker->SetSeeds(seeds);
708 tpcTracker->PropagateForward();
709 Printf("After trackinging we have %d tracks",seeds->GetEntriesFast());
712 // Loop over all input tracks and connect to found seeds
713 for (Int_t iev=0; iev<maxev; ++iev){
714 printf("============== Fill Tracks: Processing Event %6d =================\n",iev);
715 fTree->GetEvent(iev);
716 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
717 printf(" > ====== Fill Tracks: Processing Track %6d ======== \n",itr);
718 const AliToyMCTrack *tr=fEvent->GetTrack(itr);
722 Float_t z0=fEvent->GetZ();
723 Float_t t0=fEvent->GetT0();
724 Float_t vDrift=GetVDrift();
725 Float_t zLength=GetZLength(0);
727 // find the corresponding seed (and track)
728 Int_t trackID = tr->GetUniqueID();
729 Int_t nClustersMC = tr->GetNumberOfSpacePoints(); // number of findable clusters (ideal)
731 nClustersMC = tr->GetNumberOfDistSpacePoints(); // number of findable clusters (distorted)
732 // Int_t idxSeed = 0; // index of best seed (best is with maximum number of clusters with correct ID)
733 Int_t nSeeds = 0; // number of seeds for MC track
734 Int_t nSeedClusters = 0; // number of clusters for best seed
735 Int_t nSeedClustersTmp = 0; // number of clusters for current seed
736 Int_t nSeedClustersID = 0; // number of clusters with correct ID for best seed
737 Int_t nSeedClustersIDTmp = 0; // number of clusters with correct ID for current seed
738 for(Int_t iSeeds = 0; iSeeds < seeds->GetEntriesFast(); ++iSeeds){
740 // set current seed and reset counters
741 seedTmp = (AliTPCseed*)(seeds->At(iSeeds));
742 nSeedClustersTmp = 0;
743 nSeedClustersIDTmp = 0;
745 if(!seedTmp) continue;
747 // loop over all rows
748 for(Int_t iRow = seedTmp->GetRow(); iRow < seedTmp->GetRow() + seedTmp->GetNumberOfClustersIndices(); iRow++ ){
750 // get cluster and increment counters
751 cluster = seedTmp->GetClusterFast(iRow);
754 if(cluster->GetLabel(0)==trackID){
755 nSeedClustersIDTmp++;
760 // if number of corresponding clusters > 0,
762 if(nSeedClustersTmp > 0){
766 // if number of corresponding clusters bigger than current nSeedClusters,
767 // take this seed as the best one
768 if(nSeedClustersIDTmp > nSeedClustersID){
771 nSeedClusters = nSeedClustersTmp; // number of correctly assigned clusters
772 nSeedClustersID = nSeedClustersIDTmp; // number of all clusters
777 // cluster to track association (commented out, when used standard tracking)
778 if (nSeeds>0&&nSeedClusters>0) {
779 t0seed = (AliExternalTrackParam)*seedBest;
780 // fTime0 = t0seed.GetZ()-zLength/vDrift;
781 // get the refitted track from the seed
782 // this will also set the fTime0 from the seed extrapolation
783 dummy=GetRefittedTrack(*seedBest);
786 //printf("seed (%.2g): %d seeds with %d clusters\n",fTime0,nSeeds,nSeedClusters);
788 // // cluster to track association for all good seeds
789 // // set fCreateT0seed to true to get the seed in time coordinates
790 // fCreateT0seed = kTRUE;
791 // dummy = ClusterToTrackAssociation(seedBest,trackID,nClus);
793 //// propagate track to 0
794 //const Double_t kMaxSnp = 0.85;
795 //const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
796 //AliTrackerBase::PropagateTrackTo(&track,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,kFALSE);
800 Int_t ctype(fCorrectionType);
803 (*fStreamer) << "Tracks" <<
807 "fTime0=" << fTime0 <<
809 "clsType=" << fClusterType <<
810 "corrType=" << ctype <<
811 "seedRow=" << fSeedingRow <<
812 "seedDist=" << fSeedingDist <<
813 "vDrift=" << vDrift <<
814 "zLength=" << zLength <<
815 "nClustersMC=" << nClustersMC <<
816 "nSeeds=" << nSeeds <<
817 "nSeedClusters=" << nSeedClusters <<
818 "nSeedClustersID=" << nSeedClustersID <<
819 "t0seed.=" << &t0seed <<
820 "track.=" << &track <<
821 "tOrig.=" << &tOrig <<
822 "tOrigToy.=" << &tOrigToy <<
841 //____________________________________________________________________________________
842 void AliToyMCReconstruction::RunFullTracking(const char* file, Int_t nmaxEv)
848 ConnectInputFile(file,nmaxEv);
851 InitStreamer(".fullTracking");
853 FillSectorStructureAC();
855 AliTPCReconstructor::SetStreamLevel(0);
861 if (lowerRow>upperRow){
868 // NOTE: the z position is set to GetTimeBin*vDrift
869 // therefore it is not possible to simply propagate
870 // the track using AliTrackerBase::Propagate, since a
871 // wrong B-Field will be assinged...
872 printf("Run Seeding in %3d - %3d\n",lowerRow,upperRow);
873 for (Int_t sec=0;sec<36;sec++){
874 printf(" in sector: %d\n",sec);
875 Int_t nAdded=MakeSeeds2(&seeds, sec,lowerRow,upperRow);
876 printf(" -> Added Seeds: %d\n",nAdded);
877 nAdded=MakeSeeds2(&seeds, sec,lowerRow-2,upperRow-2);
878 printf(" -> Added Seeds: %d\n",nAdded);
879 nAdded=MakeSeeds2(&seeds, sec,lowerRow-4,upperRow-4);
880 printf(" -> Added Seeds: %d\n",nAdded);
883 printf("Run Tracking in %3d - %3d\n",lowerRow,upperRow);
885 for (Int_t iseed=firstSeed; iseed<seeds.GetEntriesFast();++iseed) ClusterToTrackAssociation(*(AliTPCseed*)seeds.UncheckedAt(iseed));
886 //first seed is used to not run the tracking twice on a seed
887 firstSeed=seeds.GetEntriesFast();
888 // DumpTrackInfo(&seeds);
893 printf("Run Seeding in %3d - %3d\n",lowerRow,upperRow);
894 for (Int_t sec=0;sec<36;sec++){
895 printf(" in sector: %d\n",sec);
896 Int_t nAdded=MakeSeeds2(&seeds, sec,lowerRow,upperRow);
897 printf(" -> Added Seeds: %d\n",nAdded);
899 printf("Run Tracking in %3d - %3d\n",lowerRow,upperRow);
900 for (Int_t iseed=firstSeed; iseed<seeds.GetEntriesFast();++iseed) ClusterToTrackAssociation(*(AliTPCseed*)seeds.UncheckedAt(iseed));
901 firstSeed=seeds.GetEntriesFast();
903 //now seeding also at more central rows with shorter seeds
907 printf("Run Seeding in %3d - %3d\n",lowerRow,upperRow);
908 for (Int_t sec=0;sec<36;sec++){
909 printf(" in sector: %d\n",sec);
910 Int_t nAdded=MakeSeeds2(&seeds, sec,lowerRow,upperRow);
911 printf(" -> Added Seeds: %d\n",nAdded);
913 printf("Run Tracking in %3d - %3d\n",lowerRow,upperRow);
914 for (Int_t iseed=firstSeed; iseed<seeds.GetEntriesFast();++iseed) ClusterToTrackAssociation(*(AliTPCseed*)seeds.UncheckedAt(iseed));
915 firstSeed=seeds.GetEntriesFast();
918 Int_t startUpper=upperRow-10;
919 Int_t startLower=lowerRow-5;
920 for (Int_t sec=0;sec<36;sec++){
923 printf(" in sector: %d\n",sec);
925 printf("Run Seeding in %3d - %3d\n",lowerRow,upperRow);
926 Int_t nAdded=MakeSeeds2(&seeds, sec,lowerRow,upperRow);
927 printf(" -> Added Seeds: %d\n",nAdded);
928 for (Int_t iseed=firstSeed; iseed<seeds.GetEntriesFast();++iseed) ClusterToTrackAssociation(*(AliTPCseed*)seeds.UncheckedAt(iseed));
929 firstSeed=seeds.GetEntriesFast();
937 DumpTrackInfo(&seeds);
939 // TObjArray seedsCentral2;
943 // for (Int_t sec=0;sec<36;sec++){
944 // Int_t nAdded=MakeSeeds2(&seedsCentral2, sec,lowerRow,upperRow);
945 // printf(" -> Added Seeds: %d\n",nAdded);
946 // nAdded=MakeSeeds2(&seedsCentral2, sec,lowerRow-2,upperRow-2);
947 // printf(" -> Added Seeds: %d\n",nAdded);
948 // nAdded=MakeSeeds2(&seedsCentral2, sec,lowerRow-4,upperRow-4);
949 // printf(" -> Added Seeds: %d\n",nAdded);
951 // for (Int_t iseed=0; iseed<seedsCentral2.GetEntriesFast();++iseed) ClusterToTrackAssociation(*(AliTPCseed*)seedsCentral2.UncheckedAt(iseed));
952 // DumpTrackInfo(&seedsCentral2);
955 // (*fStreamer) << "clusters" <<
956 // "cl.=" << &fAllClusters << "\n";
961 //____________________________________________________________________________________
962 AliExternalTrackParam* AliToyMCReconstruction::GetSeedFromTrackIdeal(const AliToyMCTrack * const tr, EDet det )
965 // crate a seed from the track points of the respective detector
967 AliTrackPoint seedPoint[3];
972 npoints=tr->GetNumberOfITSPoints();
975 npoints=(fClusterType == 0)?tr->GetNumberOfSpacePoints():tr->GetNumberOfDistSpacePoints();
978 npoints=tr->GetNumberOfTRDPoints();
982 if (npoints<3) return 0x0;
984 Int_t pos[3]={0,npoints/2,npoints-1};
985 const AliCluster *cl=0x0;
987 for (Int_t ipoint=0;ipoint<3;++ipoint){
988 Int_t cluster=pos[ipoint];
991 seedPoint[ipoint]=(*tr->GetITSPoint(cluster));
994 cl=tr->GetSpacePoint(cluster);
995 if (fClusterType == 1) cl=tr->GetDistortedSpacePoint(cluster);
996 AliTPCclusterMI::SetGlobalTrackPoint(*cl,seedPoint[ipoint]);
999 seedPoint[ipoint]=(*tr->GetTRDPoint(cluster));
1004 AliExternalTrackParam *seed = AliTrackerBase::MakeSeed(seedPoint[0], seedPoint[1], seedPoint[2]);
1005 seed->ResetCovariance(10);
1010 //____________________________________________________________________________________
1011 AliExternalTrackParam* AliToyMCReconstruction::GetSeedFromTrack(const AliToyMCTrack * const tr, Bool_t forceSeed)
1014 // if we don't have a valid time0 informaion (fTime0) available yet
1015 // assume we create a seed for the time0 estimate
1018 // seed point informaion
1019 AliTrackPoint seedPoint[3];
1020 const AliTPCclusterMI *seedCluster[3]={0x0,0x0,0x0};
1022 // number of clusters to loop over
1023 const Int_t ncls=(fClusterType==0)?tr->GetNumberOfSpacePoints():tr->GetNumberOfDistSpacePoints();
1025 AliError(Form("Not enough points to create a seed: %d",ncls));
1028 UChar_t nextSeedRow=fSeedingRow;
1031 //assumes sorted clusters
1033 // force the seed creation, using the first, middle and last cluster
1034 Int_t npoints[3]={0,ncls/2,ncls-1};
1035 for (Int_t icl=0;icl<3;++icl){
1036 const AliTPCclusterMI *cl=tr->GetSpacePoint(npoints[icl]);
1037 if (fClusterType==1) cl=tr->GetDistortedSpacePoint(npoints[icl]);
1038 seedCluster[nseeds]=cl;
1039 SetTrackPointFromCluster(cl, seedPoint[nseeds]);
1043 // create seeds according to the reco settings
1044 for (Int_t icl=0;icl<ncls;++icl) {
1045 const AliTPCclusterMI *cl=tr->GetSpacePoint(icl);
1046 if (fClusterType==1) cl=tr->GetDistortedSpacePoint(icl);
1048 // use row in sector
1049 const UChar_t row=cl->GetRow() + 63*(cl->GetDetector()>35);
1050 // skip clusters without proper pad row
1051 if (row>200) continue;
1054 // if we are in the last row and still miss a seed we use the last row
1055 // even if the row spacing will not be equal
1056 if (row>=nextSeedRow || icl==ncls-1){
1057 seedCluster[nseeds]=cl;
1058 SetTrackPointFromCluster(cl, seedPoint[nseeds]);
1060 nextSeedRow+=fSeedingDist;
1062 if (nseeds==3) break;
1067 // check we really have 3 seeds
1069 AliError(Form("Seeding failed for parameters %d, %d\n",fSeedingDist,fSeedingRow));
1073 // determine preliminary theta
1074 Float_t xyz1[3]={0,0,0};
1075 Float_t xyz2[3]={0,0,0};
1076 seedPoint[0].GetXYZ(xyz1);
1077 seedPoint[2].GetXYZ(xyz2);
1078 Float_t prelDeltaR = TMath::Sqrt(xyz2[0]*xyz2[0]+xyz2[1]*xyz2[1]) - TMath::Sqrt(xyz1[0]*xyz1[0]+xyz1[1]*xyz1[1]) ;
1079 Float_t prelDeltaZ = ( seedCluster[0]->GetTimeBin() - seedCluster[2]->GetTimeBin() ) * GetVDrift();
1080 Float_t prelTheta = TMath::ATan(prelDeltaR/prelDeltaZ);
1081 if(prelTheta > TMath::Pi()/2) prelTheta = TMath::Pi() - prelTheta;
1083 // do cluster correction for fCorrectionType:
1084 // 0 - no correction
1088 // 4 - preliminary eta (needs fixing!!! Not yet in full code!!!)
1089 // assign the cluster abs time as z component to all seeds
1090 for (Int_t iseed=0; iseed<3; ++iseed) {
1091 Float_t xyz[3]={0,0,0};
1092 seedPoint[iseed].GetXYZ(xyz);
1093 const Float_t r=TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
1095 const Int_t sector=seedCluster[iseed]->GetDetector();
1096 const Int_t sign=1-2*((sector/18)%2);
1098 Float_t zBeforeCorr = xyz[2];
1100 if ( (fClusterType == 1) && (fCorrectionType != kNoCorrection) ) {
1101 // the settings below are for the T0 seed
1102 // for known T0 the z position is already calculated in SetTrackPointFromCluster
1103 if ( fCreateT0seed ){
1104 if ( fCorrectionType == kTPCCenter ) xyz[2] = 125.*sign;
1105 //!!! TODO: is this the correct association?
1106 if ( fCorrectionType == kAverageEta ) xyz[2] = TMath::Tan(45./2.*TMath::DegToRad())*r*sign;
1107 if ( fCorrectionType == kPreliminaryEta ) xyz[2] = r/TMath::Tan(prelTheta)*sign;//(needs fixing!!! Not yet in full code!!!)
1110 if ( fCorrectionType == kIdeal ) xyz[2] = seedCluster[iseed]->GetZ();
1112 // Store xyz only here!!! To get the Delta z from the correction...
1113 zBeforeCorr = xyz[2];
1115 //!!! TODO: to be replaced with the proper correction
1116 fTPCCorrection->CorrectPoint(xyz, seedCluster[iseed]->GetDetector());
1119 // after the correction set the time bin as z-Position in case of a T0 seed
1120 if ( fCreateT0seed )
1121 xyz[2]=seedCluster[iseed]->GetTimeBin() + sign*( zBeforeCorr - xyz[2] )/GetVDrift();
1123 seedPoint[iseed].SetXYZ(xyz);
1126 const Double_t kMaxSnp = 0.85;
1127 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
1129 AliExternalTrackParam *seed = AliTrackerBase::MakeSeed(seedPoint[0], seedPoint[1], seedPoint[2]);
1131 if (fCreateT0seed&&!fLongT0seed){
1132 // only propagate to vertex if we don't create a long seed
1133 // if fTime0 < 0 we assume that we create a seed for the T0 estimate
1134 Int_t ret=AliTrackerBase::PropagateTrackTo2(seed,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,kFALSE);
1135 if (TMath::Abs(seed->GetX())>3) {
1136 // printf("Could not propagate track to 0, x:%.2f, a:%.2f (%.2f), snp:%.2f (%.2f), pt:%.2f (%.2f), %d\n",seed->GetX(),seed->GetAlpha(),tr->GetAlpha(), seed->GetSnp(), tr->GetSnp(), seed->Pt(), tr->Pt(), ret);
1139 seed->Rotate(tr->GetAlpha());
1140 AliTrackerBase::PropagateTrackTo2(seed,0,kMass,1.,kFALSE,kMaxSnp,0,kFALSE,kFALSE);
1144 seed->ResetCovariance(10);
1149 //____________________________________________________________________________________
1150 AliExternalTrackParam* AliToyMCReconstruction::GetTrackRefit(const AliToyMCTrack * const tr, EDet det)
1153 // Get the ITS or TRD track refitted from the toy track
1154 // type: 0=ITS; 1=TRD
1157 AliExternalTrackParam *track=GetSeedFromTrackIdeal(tr,det);
1158 if (!track) return 0x0;
1160 const Double_t kMaxSnp = 0.85;
1161 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
1166 npoints=tr->GetNumberOfITSPoints();
1169 npoints=(fClusterType == 0)?tr->GetNumberOfSpacePoints():tr->GetNumberOfDistSpacePoints();
1172 npoints=tr->GetNumberOfTRDPoints();
1176 const AliCluster *cl=0x0;
1178 for (Int_t ipoint=0; ipoint<npoints; ++ipoint) {
1183 pIn=(*tr->GetITSPoint(ipoint));
1186 cl=tr->GetSpacePoint(ipoint);
1187 if (fClusterType == 1) cl=tr->GetDistortedSpacePoint(ipoint);
1188 AliTPCclusterMI::SetGlobalTrackPoint(*cl,pIn);
1191 pIn=(*tr->GetTRDPoint(ipoint));
1196 const Double_t angle=pIn.GetAngle();
1197 track->Rotate(angle);
1198 AliTrackPoint prot = pIn.Rotate(track->GetAlpha()); // rotate to the local frame - non distoted point
1200 if (!AliTrackerBase::PropagateTrackTo(track,prot.GetX(),kMass,5,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial)) {
1201 AliInfo(Form("Could not propagate track to x=%.2f (a=%.2f) for det %d",prot.GetX(),angle,det));
1205 Double_t pointPos[2]={0,0};
1206 Double_t pointCov[3]={0,0,0};
1207 pointPos[0]=prot.GetY();//local y
1208 pointPos[1]=prot.GetZ();//local z
1209 pointCov[0]=prot.GetCov()[3];//simay^2
1210 pointCov[1]=prot.GetCov()[4];//sigmayz
1211 pointCov[2]=prot.GetCov()[5];//sigmaz^2
1213 if (!track->Update(pointPos,pointCov)) {
1214 AliInfo(Form("no update: det: %d",det));
1224 //____________________________________________________________________________________
1225 void AliToyMCReconstruction::SetTrackPointFromCluster(const AliTPCclusterMI *cl, AliTrackPoint &p )
1228 // make AliTrackPoint out of AliTPCclusterMI
1232 Float_t xyz[3]={0.,0.,0.};
1233 // ClusterToSpacePoint(cl,xyz);
1234 // cl->GetGlobalCov(cov);
1235 //TODO: what to do with the covariance matrix???
1236 //TODO: the problem is that it is used in GetAngle in AliTrackPoint
1237 //TODO: which is used by AliTrackerBase::MakeSeed to get alpha correct ...
1238 //TODO: for the moment simply assign 1 permill squared
1239 // in AliTrackPoint the cov is xx, xy, xz, yy, yz, zz
1240 // Float_t cov[6]={xyz[0]*xyz[0]*1e-6,xyz[0]*xyz[1]*1e-6,xyz[0]*xyz[2]*1e-6,
1241 // xyz[1]*xyz[1]*1e-6,xyz[1]*xyz[2]*1e-6,xyz[2]*xyz[2]*1e-6};
1242 // cl->GetGlobalXYZ(xyz);
1243 // cl->GetGlobalCov(cov);
1244 // voluem ID to add later ....
1247 // AliTrackPoint *tp=const_cast<AliTPCclusterMI*>(cl)->MakePoint(p);
1250 // const_cast<AliTPCclusterMI*>(cl)->MakePoint(p);
1251 AliTPCclusterMI::SetGlobalTrackPoint(*cl,p);
1254 p.SetVolumeID(cl->GetDetector());
1257 if ( !fCreateT0seed && !fIdealTracking ) {
1259 const Int_t sector=cl->GetDetector();
1260 const Int_t sign=1-2*((sector/18)%2);
1261 const Float_t zT0=( GetZLength(sector) - (cl->GetTimeBin()-fTime0)*GetVDrift() )*sign;
1262 // printf(" z: %.2f %.2f\n",xyz[2],zT0);
1268 // p.Rotate(p.GetAngle()).Print();
1271 //____________________________________________________________________________________
1272 void AliToyMCReconstruction::ClusterToSpacePoint(const AliTPCclusterMI *cl, Float_t xyz[3])
1275 // convert the cluster to a space point in global coordinates
1278 xyz[0]=cl->GetRow();
1279 xyz[1]=cl->GetPad();
1280 xyz[2]=cl->GetTimeBin(); // this will not be correct at all
1281 Int_t i[3]={0,cl->GetDetector(),cl->GetRow()};
1282 // printf("%.2f, %.2f, %.2f - %d, %d, %d\n",xyz[0],xyz[1],xyz[2],i[0],i[1],i[2]);
1283 fTPCParam->Transform8to4(xyz,i);
1284 // printf("%.2f, %.2f, %.2f - %d, %d, %d\n",xyz[0],xyz[1],xyz[2],i[0],i[1],i[2]);
1285 fTPCParam->Transform4to3(xyz,i);
1286 // printf("%.2f, %.2f, %.2f - %d, %d, %d\n",xyz[0],xyz[1],xyz[2],i[0],i[1],i[2]);
1287 fTPCParam->Transform2to1(xyz,i);
1288 // printf("%.2f, %.2f, %.2f - %d, %d, %d\n",xyz[0],xyz[1],xyz[2],i[0],i[1],i[2]);
1291 //____________________________________________________________________________________
1292 AliExternalTrackParam* AliToyMCReconstruction::GetFittedTrackFromSeed(const AliToyMCTrack *tr, const AliExternalTrackParam *seed, TClonesArray *arrClustRes)
1299 arrClustRes->Clear();
1303 AliExternalTrackParam *track = new AliExternalTrackParam(*seed);
1304 // track copy for propagation
1305 AliExternalTrackParam trCopy(*tr);
1307 Int_t ncls=(fClusterType == 0)?tr->GetNumberOfSpacePoints():tr->GetNumberOfDistSpacePoints();
1309 const AliTPCROC * roc = AliTPCROC::Instance();
1311 const Double_t kRTPC0 = roc->GetPadRowRadii(0,0);
1312 const Double_t kRTPC1 = roc->GetPadRowRadii(36,roc->GetNRows(36)-1);
1313 const Double_t kMaxSnp = 0.85;
1314 const Double_t kMaxR = 500.;
1315 const Double_t kMaxZ = 500.;
1317 // const Double_t kMaxZ0=220;
1318 // const Double_t kZcut=3;
1320 const Double_t refX = tr->GetX();
1322 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
1324 // parametrised track resolution
1325 Double_t trackRes=gRandom->Gaus();
1327 // loop over all other points and add to the track
1328 for (Int_t ipoint=ncls-1; ipoint>=0; --ipoint){
1330 const AliTPCclusterMI *cl=tr->GetSpacePoint(ipoint);
1331 if (fClusterType == 1) cl=tr->GetDistortedSpacePoint(ipoint);
1332 const Int_t globalRow = cl->GetRow() +(cl->GetDetector() >35)*63;
1333 if ( fCreateT0seed ){
1334 if ( globalRow<fSeedingRow || globalRow>fSeedingRow+2*fSeedingDist ) continue;
1337 SetTrackPointFromCluster(cl, pIn);
1339 Float_t xyz[3]={0,0,0};
1341 Float_t zBeforeCorr = xyz[2];
1343 const Int_t sector=cl->GetDetector();
1344 const Int_t sign=1-2*((sector/18)%2);
1346 if (fCorrectionType != kNoCorrection){
1348 const Float_t r=TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
1350 if ( fCreateT0seed ){
1351 if ( fCorrectionType == kTPCCenter ) xyz[2] = 125.*sign;
1352 //!!! TODO: is this the correct association?
1353 if ( fCorrectionType == kAverageEta ) xyz[2] = TMath::Tan(45./2.*TMath::DegToRad())*r*sign;
1354 if ( fCorrectionType == kIdeal ) xyz[2] = cl->GetZ();
1357 // Store xyz only here!!! To get the Delta z from the correction...
1358 zBeforeCorr = xyz[2];
1360 fTPCCorrection->CorrectPoint(xyz, cl->GetDetector());
1363 if ( fCreateT0seed )
1364 xyz[2]=cl->GetTimeBin() + sign*( zBeforeCorr - xyz[2] )/GetVDrift();
1365 // xyz[2]=cl->GetTimeBin();
1368 // rotate the cluster to the local detector frame
1369 track->Rotate(((cl->GetDetector()%18)*20+10)*TMath::DegToRad());
1370 AliTrackPoint prot = pIn.Rotate(track->GetAlpha()); // rotate to the local frame - non distoted point
1371 if (TMath::Abs(prot.GetX())<kRTPC0) continue;
1372 if (TMath::Abs(prot.GetX())>kRTPC1) continue;
1374 Bool_t res=AliTrackerBase::PropagateTrackTo(track,prot.GetX(),kMass,5,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
1378 if (TMath::Abs(track->GetZ())>kMaxZ) break;
1379 if (TMath::Abs(track->GetX())>kMaxR) break;
1380 // if (TMath::Abs(track->GetZ())<kZcut)continue;
1385 TClonesArray &arrDummy=*arrClustRes;
1386 AliTPCclusterMI *clRes = new(arrDummy[arrDummy.GetEntriesFast()]) AliTPCclusterMI(*cl);
1387 clRes->SetX(prot.GetX());
1388 // residuals in terms of sigma cl and track
1389 clRes->SetY((track->GetY()-prot.GetY())/( sqrt ( prot.GetCov()[3] + track->GetSigmaY2()) ) );
1390 clRes->SetZ((track->GetZ()-prot.GetZ())/( sqrt ( prot.GetCov()[5] + track->GetSigmaZ2()) ) );
1393 // fill cluster residuals to ideal track for calibration studies
1394 // ideal cluster position
1395 // require at least 2 TRD points
1396 if (fRecoInfo<0 || (fRecoInfo&kFillDeltas) ==kFillDeltas ) {
1397 trCopy.Rotate(track->GetAlpha());
1398 AliTrackerBase::PropagateTrackTo(&trCopy,prot.GetX(),kMass,5,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
1399 // binning r, phi, z, delta (0=rphi, 1=z)
1400 // resolution parametrisation
1401 Float_t soneOverPt= trCopy.GetSigned1Pt();
1402 Float_t oneOverPt = TMath::Abs(soneOverPt);
1403 Float_t radius = trCopy.GetX();
1404 Float_t trackY = trCopy.GetY();
1405 Float_t trackZ = trCopy.GetZ();
1406 Float_t trackPhi = trCopy.Phi();
1407 Float_t alpha = trCopy.GetAlpha();
1409 Float_t pointY = prot.GetY();
1410 Float_t pointZ = prot.GetZ();
1412 Float_t resRphi = 0.004390 + oneOverPt*(-0.136403) + oneOverPt*radius*(0.002266) + oneOverPt*radius*radius*(-0.000006);
1414 Float_t resRphiRandom = resRphi*trackRes;
1415 Float_t deviation = trackY+resRphiRandom-pointY;
1416 Short_t npTRD = tr->GetNumberOfTRDPoints();
1419 Double_t xx[4]={radius, trackPhi, trackZ ,deviation};
1424 Short_t event=fTree->GetReadEntry();
1427 (*fStreamer) << "delta" <<
1428 "soneOverPt=" << soneOverPt <<
1430 "trackPhi=" << trackPhi <<
1431 "trackY=" << trackY <<
1432 "trackZ=" << trackZ <<
1433 "alpha=" << alpha <<
1434 "resRphi=" << resRphi <<
1435 "trackRes=" << trackRes <<
1436 "pointY=" << pointY <<
1437 "pointZ=" << pointZ <<
1438 "npTRD=" << npTRD <<
1439 "event=" << event <<
1441 // "point.=" << &prot <<
1442 // "track.=" << track <<
1446 Double_t pointPos[2]={0,0};
1447 Double_t pointCov[3]={0,0,0};
1448 pointPos[0]=prot.GetY();//local y
1449 pointPos[1]=prot.GetZ();//local z
1450 pointCov[0]=prot.GetCov()[3];//simay^2
1451 pointCov[1]=prot.GetCov()[4];//sigmayz
1452 pointCov[2]=prot.GetCov()[5];//sigmaz^2
1454 if (!track->Update(pointPos,pointCov)) {printf("no update\n"); break;}
1457 AliTrackerBase::PropagateTrackTo2(track,refX,kMass,5.,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
1459 if (!fCreateT0seed || fForceAlpha){
1460 // rotate fittet track to the frame of the original track and propagate to same reference
1461 track->Rotate(tr->GetAlpha());
1463 AliTrackerBase::PropagateTrackTo2(track,refX,kMass,1.,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
1469 //____________________________________________________________________________________
1470 AliExternalTrackParam* AliToyMCReconstruction::GetFittedTrackFromSeedAllClusters(const AliToyMCTrack *tr, const AliExternalTrackParam *seed, Int_t &nClus)
1473 // Tracking for given seed on an array of clusters
1477 AliExternalTrackParam *track = new AliExternalTrackParam(*seed);
1479 const AliTPCROC * roc = AliTPCROC::Instance();
1481 const Double_t kRTPC0 = roc->GetPadRowRadii(0,0);
1482 const Double_t kRTPC1 = roc->GetPadRowRadii(36,roc->GetNRows(36)-1);
1483 const Int_t kNRowsTPC = roc->GetNRows(0) + roc->GetNRows(36) - 1;
1484 const Int_t kIRowsTPC = roc->GetNRows(0) - 1;
1485 const Double_t kMaxSnp = 0.85;
1486 const Double_t kMaxR = 500.;
1487 const Double_t kMaxZ = 500.;
1488 const Double_t roady = 100.;
1489 const Double_t roadz = 100.;
1491 const Double_t refX = tr->GetX();
1493 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
1496 UInt_t indexCur = 0;
1497 Double_t xCur, yCur, zCur = 0.;
1499 Float_t vDrift = GetVDrift();
1501 // first propagate seed to outermost row
1502 AliTrackerBase::PropagateTrackTo(track,kRTPC1,kMass,5,kFALSE,kMaxSnp);
1504 // Loop over rows and find the cluster candidates
1505 for( Int_t iRow = kNRowsTPC; iRow >= 0; --iRow ){
1507 // inner or outer sector
1508 Bool_t bInnerSector = kTRUE;
1509 if(iRow > kIRowsTPC) bInnerSector = kFALSE;
1511 // nearest track point/cluster (to be found)
1512 AliTrackPoint nearestPoint;
1513 AliTPCclusterMI *nearestCluster = NULL;
1518 // Propagate to center of pad row and extract parameters
1519 AliTrackerBase::PropagateTrackTo(track,roc->GetPadRowRadii(0,iRow),kMass,5,kFALSE,kMaxSnp);
1520 xCur = track->GetX();
1521 yCur = track->GetY();
1522 zCur = track->GetZ();
1523 if ( !fIdealTracking ) {
1524 zCur = zCur/vDrift + fTime0; // Look at time, not at z!
1526 secCur = GetSector(track);
1528 // Find the nearest cluster (TODO: correct road settings!)
1529 Printf("inner tracking here: x = %.2f, y = %.2f, z = %.2f (Row %d Sector %d)",xCur,yCur,zCur,iRow,secCur);
1530 nearestCluster = fInnerSectorArray[secCur%fkNSectorInner][iRow].FindNearest2(yCur,zCur,roady,roadz,indexCur);
1532 // Move to next row if now cluster found
1533 if(!nearestCluster) continue;
1534 //Printf("Nearest Clusters = %d (of %d) ",indexCur,fInnerSectorArray[secCur%fkNSectorInner][iRow].GetN());
1541 // Propagate to center of pad row and extract parameters
1542 AliTrackerBase::PropagateTrackTo(track,roc->GetPadRowRadii(36,iRow-kIRowsTPC-1),kMass,5,kFALSE,kMaxSnp);
1543 xCur = track->GetX();
1544 yCur = track->GetY();
1545 zCur = track->GetZ();
1546 if ( !fIdealTracking ) {
1547 zCur = zCur/vDrift + fTime0; // Look at time, not at z!
1549 secCur = GetSector(track);
1551 // Find the nearest cluster (TODO: correct road settings!)
1552 Printf("outer tracking here: x = %.2f, y = %.2f, z = %.2f (Row %d Sector %d)",xCur,yCur,zCur,iRow,secCur);
1553 nearestCluster = fOuterSectorArray[(secCur-fkNSectorInner*2)%fkNSectorOuter][iRow-kIRowsTPC-1].FindNearest2(yCur,zCur,roady,roadz,indexCur);
1555 // Move to next row if now cluster found
1556 if(!nearestCluster) continue;
1557 //Printf("Nearest Clusters = %d (of %d)",indexCur,fOuterSectorArray[(secCur-fkNSectorInner*2)%fkNSectorOuter][iRow-kIRowsTPC-1].GetN());
1561 // create track point from cluster
1562 SetTrackPointFromCluster(nearestCluster,nearestPoint);
1564 //Printf("Track point = %.2f %.2f %.2f",nearestPoint.GetX(),nearestPoint.GetY(),nearestPoint.GetZ());
1567 // TODO: also correction when looking for the next cluster?
1568 if (fCorrectionType != kNoCorrection){
1569 Float_t xyz[3]={0,0,0};
1570 nearestPoint.GetXYZ(xyz);
1571 fTPCCorrection->CorrectPoint(xyz, nearestCluster->GetDetector());
1572 nearestPoint.SetXYZ(xyz);
1575 // rotate the cluster to the local detector frame
1576 track->Rotate(((nearestCluster->GetDetector()%18)*20+10)*TMath::DegToRad());
1577 AliTrackPoint prot = nearestPoint.Rotate(track->GetAlpha()); // rotate to the local frame - non distoted point
1578 if (TMath::Abs(prot.GetX())<kRTPC0) continue;
1579 if (TMath::Abs(prot.GetX())>kRTPC1) continue;
1582 //Printf("Rotated Track point = %.2f %.2f %.2f",prot.GetX(),prot.GetY(),prot.GetZ());
1584 // update track with the nearest track point
1585 Bool_t res=AliTrackerBase::PropagateTrackTo(track,prot.GetX(),kMass,5,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
1589 if (TMath::Abs(track->GetZ())>kMaxZ) break;
1590 if (TMath::Abs(track->GetX())>kMaxR) break;
1591 //if (TMath::Abs(track->GetZ())<kZcut)continue;
1593 Double_t pointPos[2]={0,0};
1594 Double_t pointCov[3]={0,0,0};
1595 pointPos[0]=prot.GetY();//local y
1596 pointPos[1]=prot.GetZ();//local z
1597 pointCov[0]=prot.GetCov()[3];//simay^2
1598 pointCov[1]=prot.GetCov()[4];//sigmayz
1599 pointCov[2]=prot.GetCov()[5];//sigmaz^2
1601 if (!track->Update(pointPos,pointCov)) {printf("no update\n");}
1607 // propagation to refX
1608 AliTrackerBase::PropagateTrackTo(track,refX,kMass,5.,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
1610 // rotate fittet track to the frame of the original track and propagate to same reference
1611 track->Rotate(tr->GetAlpha());
1613 AliTrackerBase::PropagateTrackTo(track,refX,kMass,1.,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
1615 Printf("We have %d clusters in this track!",nClus);
1620 //____________________________________________________________________________________
1621 AliExternalTrackParam* AliToyMCReconstruction::ClusterToTrackAssociation(const AliTPCseed *seed, Int_t trackID, Int_t &nClus)
1624 // Cluster to track association for given seed on an array of clusters
1628 AliExternalTrackParam *track = new AliExternalTrackParam(*seed);
1630 const AliTPCROC * roc = AliTPCROC::Instance();
1632 const Double_t kRTPC0 = roc->GetPadRowRadii(0,0);
1633 const Double_t kRTPC1 = roc->GetPadRowRadii(36,roc->GetNRows(36)-1);
1634 const Int_t kNRowsTPC = roc->GetNRows(0) + roc->GetNRows(36) - 1;
1635 const Int_t kIRowsTPC = roc->GetNRows(0) - 1;
1636 const Double_t kMaxSnp = 0.85;
1637 const Double_t kMaxR = 500.;
1638 const Double_t kMaxZ = 500.;
1639 const Double_t roady = 0.1;
1640 const Double_t roadz = 0.01;
1642 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
1644 Int_t secCur, secOld = -1;
1645 UInt_t indexCur = 0;
1646 Double_t xCur, yCur, zCur = 0.;
1648 // Float_t vDrift = GetVDrift();
1650 // first propagate seed to outermost row
1651 Bool_t res0=AliTrackerBase::PropagateTrackTo(track,kRTPC1,kMass,5,kFALSE,kMaxSnp);
1653 // Loop over rows and find the cluster candidates
1654 for( Int_t iRow = kNRowsTPC; iRow >= 0; --iRow ){
1656 // inner or outer sector
1657 Bool_t bInnerSector = kTRUE;
1658 if(iRow > kIRowsTPC) bInnerSector = kFALSE;
1660 // nearest track point/cluster (to be found)
1661 AliTrackPoint nearestPoint;
1662 AliTPCclusterMI *nearestCluster = NULL;
1667 // Propagate to center of pad row and extract parameters
1668 AliTrackerBase::PropagateTrackTo(track,roc->GetPadRowRadii(0,iRow),kMass,5,kFALSE,kMaxSnp);
1669 xCur = track->GetX();
1670 yCur = track->GetY();
1671 zCur = track->GetZ();
1672 secCur = GetSector(track);
1674 // Find the nearest cluster (TODO: correct road settings!)
1675 //Printf("inner tracking here: x = %.2f, y = %.2f, z = %.6f (Row %d Sector %d)",xCur,yCur,zCur,iRow,secCur);
1676 nearestCluster = fInnerSectorArray[secCur%fkNSectorInner][iRow].FindNearest2(yCur,zCur,roady,roadz,indexCur);
1678 // Look again at -y if nothing found here and the sector changed with respect to the last found cluster
1679 // Increase also the road in this case
1680 if(!nearestCluster && secCur != secOld && secOld > -1){
1681 //Printf("inner tracking here 2: x = %.2f, y = %.2f, z = %.6f (Row %d Sector %d)",xCur,-yCur,zCur,iRow,secCur);
1682 nearestCluster = fInnerSectorArray[secCur%fkNSectorInner][iRow].FindNearest2(-yCur,zCur,roady*100,roadz,indexCur);
1685 // Move to next row if now cluster found
1686 if(!nearestCluster) continue;
1687 //Printf("Nearest Clusters = %d (of %d) ",indexCur,fInnerSectorArray[secCur%fkNSectorInner][iRow].GetN());
1694 // Propagate to center of pad row and extract parameters
1695 AliTrackerBase::PropagateTrackTo(track,roc->GetPadRowRadii(36,iRow-kIRowsTPC-1),kMass,5,kFALSE,kMaxSnp);
1696 xCur = track->GetX();
1697 yCur = track->GetY();
1698 zCur = track->GetZ();
1699 secCur = GetSector(track);
1701 // Find the nearest cluster (TODO: correct road settings!)
1702 Printf("res0 = %d, outer tracking here: x = %.2f, y = %.2f, z = %.6f (Row %d Sector %d)",res0,xCur,yCur,zCur,iRow,secCur);
1703 nearestCluster = fOuterSectorArray[(secCur-fkNSectorInner*2)%fkNSectorOuter][iRow-kIRowsTPC-1].FindNearest2(yCur,zCur,roady,roadz,indexCur);
1705 // Look again at -y if nothing found here and the sector changed with respect to the last found cluster
1706 // Increase also the road in this case
1707 if(!nearestCluster && secCur != secOld && secOld > -1){
1708 Printf("outer tracking here 2: x = %.2f, y = %.2f, z = %.6f (Row %d Sector %d)",xCur,-yCur,zCur,iRow,secCur);
1709 nearestCluster = fOuterSectorArray[(secCur-fkNSectorInner*2)%fkNSectorOuter][iRow-kIRowsTPC-1].FindNearest2(-yCur,zCur,roady*100,roadz,indexCur);
1713 // Move to next row if now cluster found
1714 if(!nearestCluster) continue;
1715 Printf("Nearest Clusters = %d (of %d)",indexCur,fOuterSectorArray[(secCur-fkNSectorInner*2)%fkNSectorOuter][iRow-kIRowsTPC-1].GetN());
1719 // create track point from cluster
1720 SetTrackPointFromCluster(nearestCluster,nearestPoint);
1722 //Printf("Track point = %.2f %.2f %.2f",nearestPoint.GetX(),nearestPoint.GetY(),nearestPoint.GetZ());
1724 // rotate the cluster to the local detector frame
1725 track->Rotate(((nearestCluster->GetDetector()%18)*20+10)*TMath::DegToRad());
1726 AliTrackPoint prot = nearestPoint.Rotate(track->GetAlpha()); // rotate to the local frame - non distoted point
1727 if (TMath::Abs(prot.GetX())<kRTPC0) continue;
1728 if (TMath::Abs(prot.GetX())>kRTPC1) continue;
1731 //Printf("Rotated Track point = %.2f %.2f %.2f",prot.GetX(),prot.GetY(),prot.GetZ());
1733 // update track with the nearest track point
1734 Bool_t res=AliTrackerBase::PropagateTrackTo(track,prot.GetX(),kMass,5,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
1738 if (TMath::Abs(track->GetZ())>kMaxZ) break;
1739 if (TMath::Abs(track->GetX())>kMaxR) break;
1740 //if (TMath::Abs(track->GetZ())<kZcut)continue;
1742 Double_t pointPos[2]={0,0};
1743 Double_t pointCov[3]={0,0,0};
1744 pointPos[0]=prot.GetY();//local y
1745 pointPos[1]=prot.GetZ();//local z
1746 pointCov[0]=prot.GetCov()[3];//simay^2
1747 pointCov[1]=prot.GetCov()[4];//sigmayz
1748 pointCov[2]=prot.GetCov()[5];//sigmaz^2
1750 if (!track->Update(pointPos,pointCov)) {printf("no update\n");}
1753 //Printf("Cluster belongs to track = %d",nearestCluster->GetLabel(0));
1755 // only count as associate cluster if it belongs to correct track!
1756 if(nearestCluster->GetLabel(0) == trackID)
1760 Printf("We have %d clusters in this track!",nClus);
1765 //____________________________________________________________________________________
1766 void AliToyMCReconstruction::AssociateClusters(AliTPCseed &seed, Int_t firstRow, Int_t lastRow, Bool_t direction)
1769 // do cluster to track association from first to last row
1770 // direction 0: outwards; 1: inwards
1776 AliRieman rieman1(160);
1777 AliRieman rieman2(160);
1778 SetRieman(seed,rieman1);
1779 CopyRieman(rieman1,rieman2);
1781 Int_t sec=seed.GetSector();
1782 Int_t noLastPoint=0;
1783 //TODO: change to inward and outwar search?
1784 // -> better handling of non consecutive points
1790 //always from inside out
1791 if (firstRow>lastRow){
1797 for (Int_t row=firstRow; row<=lastRow && noLastPoint<3;++row) {
1798 Int_t iRow=TMath::Abs(row);
1799 const AliTPCclusterMI *cl=seed.GetClusterPointer(iRow);
1802 const Int_t secrow = iRow<63?iRow:iRow-63;
1804 AliTPCtrackerSector *arrSec=(iRow<63)?fInnerSectorArray:fOuterSectorArray;
1805 const AliTPCtrackerRow& kr = arrSec[sec%36][secrow];
1806 const Double_t maxy=arrSec[sec%36].GetMaxY(secrow);
1808 Double_t y=rieman1.GetYat(kr.GetX());
1809 Double_t z=rieman1.GetZat(kr.GetX());
1811 if (TMath::Abs(y)>maxy) {
1812 AliError("Tracking over sector boundaries not implemented, yet");
1816 AliTPCclusterMI *n=kr.FindNearest(y,z,roady,roadz);
1817 if (!n || n->IsUsed()) {
1821 // check for quality of the cluster
1823 rieman2.AddPoint(n->GetX(), n->GetY(), n->GetZ(),
1824 TMath::Sqrt(n->GetSigmaY2()), TMath::Sqrt(n->GetSigmaZ2()));
1826 // printf(" Riemann results: row=%d valid=%d, Chi2=%.2f (%.2f) %d (%d)",
1827 // iRow, rieman2.IsValid(), rieman2.GetChi2(), rieman1.GetChi2(), n->GetLabel(0),seed.GetLabel());
1828 Double_t limit=2*rieman1.GetChi2();
1829 if (fClusterType==0) limit=1000;
1830 if (rieman2.GetChi2()>limit) {
1831 CopyRieman(rieman1,rieman2);
1836 // printf(" +++ \n");
1840 rieman1.AddPoint(n->GetX(), n->GetY(), n->GetZ(),
1841 TMath::Sqrt(n->GetSigmaY2()), TMath::Sqrt(n->GetSigmaZ2()));
1844 seed.SetClusterPointer(iRow,n);
1845 // if (iRow<seed.GetSeed1()) seed.SetSeed1(iRow);
1846 // if (iRow>seed.GetSeed2()) seed.SetSeed2(iRow);
1852 //____________________________________________________________________________________
1853 void AliToyMCReconstruction::ClusterToTrackAssociation(AliTPCseed &seed)
1859 // printf("\n ============ \nnext Seed: %d\n",seed.GetLabel());
1860 //assume seed is within one sector
1861 Int_t iMiddle=(seed.GetSeed1()+seed.GetSeed2())/2;
1863 AssociateClusters(seed,iMiddle+1,158,kFALSE);
1865 AssociateClusters(seed,0,iMiddle,kTRUE);
1866 seed.SetIsSeeding(kFALSE);
1868 CookLabel(&seed,.6);
1872 //____________________________________________________________________________________
1873 void AliToyMCReconstruction::InitSpaceCharge()
1876 // Init the space charge map
1879 // TString filename="$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2_eps5_50kHz_precal.root";
1882 TList *l=fTree->GetUserInfo();
1883 for (Int_t i=0; i<l->GetEntries(); ++i) {
1884 TObject *o=l->At(i);
1885 if (o->IsA() == TObjString::Class()){
1886 TString s(o->GetName());
1887 if (s.Contains("lookup.root")) {
1895 if (filename.IsNull()) {
1896 AliFatal("No SC map provided in the Userinfo of the simulation tree");
1900 AliInfo(Form("Initialising the space charge map using the file: '%s'\n",filename.Data()));
1901 TFile f(filename.Data());
1902 fTPCCorrection=(AliTPCCorrection*)f.Get("map");
1904 // fTPCCorrection = new AliTPCSpaceCharge3D();
1905 // fTPCCorrection->SetSCDataFileName("$ALICE_ROOT/TPC/Calib/maps/SC_NeCO2_eps10_50kHz.root");
1906 // fTPCCorrection->SetOmegaTauT1T2(0.325,1,1); // Ne CO2
1907 // // fTPCCorrection->SetOmegaTauT1T2(0.41,1,1.05); // Ar CO2
1908 // fTPCCorrection->InitSpaceCharge3DDistortion();
1912 //____________________________________________________________________________________
1913 Double_t AliToyMCReconstruction::GetVDrift() const
1918 return fTPCParam->GetDriftV();
1921 //____________________________________________________________________________________
1922 Double_t AliToyMCReconstruction::GetZLength(Int_t roc) const
1927 if (roc<0 || roc>71) return -1;
1928 return fTPCParam->GetZLength(roc);
1931 //____________________________________________________________________________________
1932 TTree* AliToyMCReconstruction::ConnectTrees (const char* files) {
1933 TString s=gSystem->GetFromPipe(Form("ls %s",files));
1936 TObjArray *arrFiles=s.Tokenize("\n");
1938 for (Int_t ifile=0; ifile<arrFiles->GetEntriesFast(); ++ifile){
1939 TString name(arrFiles->At(ifile)->GetName());
1941 TPRegexp reg(".*([0-9]_[0-9]_[0-9]_[0-9]{3}_[0-9]{2}).debug.root");
1942 TObjArray *arrMatch=0x0;
1943 arrMatch=reg.MatchS(name);
1945 if (arrMatch && arrMatch->At(1)) matchName=arrMatch->At(1)->GetName();
1946 else matchName=Form("%02d",ifile);
1950 TFile *f=TFile::Open(name.Data());
1952 TTree *t=(TTree*)f->Get("Tracks");
1958 t->SetName(matchName.Data());
1961 tFirst->AddFriend(Form("t%s=Tracks",matchName.Data()), name.Data());
1962 // tFirst->AddFriend(Form("t%d=Tracks",ifile), name.Data());
1966 if (tFirst->GetListOfFriends()) tFirst->GetListOfFriends()->Print();
1970 //____________________________________________________________________________________
1971 Int_t AliToyMCReconstruction::LoadOuterSectors() {
1972 //-----------------------------------------------------------------
1973 // This function fills outer TPC sectors with clusters.
1974 // Copy and paste from AliTPCtracker
1975 //-----------------------------------------------------------------
1976 Int_t nrows = fOuterSectorArray->GetNRows();
1978 for (Int_t sec = 0;sec<fkNSectorOuter;sec++)
1979 for (Int_t row = 0;row<nrows;row++){
1980 AliTPCtrackerRow* tpcrow = &(fOuterSectorArray[sec%fkNSectorOuter][row]);
1981 Int_t sec2 = sec+2*fkNSectorInner;
1983 Int_t ncl = tpcrow->GetN1();
1985 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1986 index=(((sec2<<8)+row)<<16)+ncl;
1987 tpcrow->InsertCluster(c,index);
1990 ncl = tpcrow->GetN2();
1992 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1993 index=((((sec2+fkNSectorOuter)<<8)+row)<<16)+ncl;
1994 tpcrow->InsertCluster(c,index);
1997 // write indexes for fast acces
1999 for (Int_t i=0;i<510;i++)
2000 tpcrow->SetFastCluster(i,-1);
2001 for (Int_t i=0;i<tpcrow->GetN();i++){
2002 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
2003 tpcrow->SetFastCluster(zi,i); // write index
2006 for (Int_t i=0;i<510;i++){
2007 if (tpcrow->GetFastCluster(i)<0)
2008 tpcrow->SetFastCluster(i,last);
2010 last = tpcrow->GetFastCluster(i);
2017 //____________________________________________________________________________________
2018 Int_t AliToyMCReconstruction::LoadInnerSectors() {
2019 //-----------------------------------------------------------------
2020 // This function fills inner TPC sectors with clusters.
2021 // Copy and paste from AliTPCtracker
2022 //-----------------------------------------------------------------
2023 Int_t nrows = fInnerSectorArray->GetNRows();
2025 for (Int_t sec = 0;sec<fkNSectorInner;sec++)
2026 for (Int_t row = 0;row<nrows;row++){
2027 AliTPCtrackerRow* tpcrow = &(fInnerSectorArray[sec%fkNSectorInner][row]);
2030 Int_t ncl = tpcrow->GetN1();
2032 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
2033 index=(((sec<<8)+row)<<16)+ncl;
2034 tpcrow->InsertCluster(c,index);
2037 ncl = tpcrow->GetN2();
2039 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
2040 index=((((sec+fkNSectorInner)<<8)+row)<<16)+ncl;
2041 tpcrow->InsertCluster(c,index);
2044 // write indexes for fast acces
2046 for (Int_t i=0;i<510;i++)
2047 tpcrow->SetFastCluster(i,-1);
2048 for (Int_t i=0;i<tpcrow->GetN();i++){
2049 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
2050 tpcrow->SetFastCluster(zi,i); // write index
2053 for (Int_t i=0;i<510;i++){
2054 if (tpcrow->GetFastCluster(i)<0)
2055 tpcrow->SetFastCluster(i,last);
2057 last = tpcrow->GetFastCluster(i);
2064 //____________________________________________________________________________________
2065 Int_t AliToyMCReconstruction::GetSector(AliExternalTrackParam *track) {
2066 //-----------------------------------------------------------------
2067 // This function returns the sector number for a given track
2068 //-----------------------------------------------------------------
2072 // get the sector number
2073 // rotate point to global system (track is already global!)
2076 //track->Local2GlobalPosition(xd,track->GetAlpha());
2078 // use TPCParams to get the sector number
2079 Float_t xyz[3] = {static_cast<Float_t>(xd[0]),static_cast<Float_t>(xd[1]),static_cast<Float_t>(xd[2])};
2080 Int_t i[3] = {0,0,0};
2082 sector = fTPCParam->Transform0to1(xyz,i);
2088 //____________________________________________________________________________________
2089 void AliToyMCReconstruction::FillSectorStructure(Int_t maxev) {
2090 //-----------------------------------------------------------------
2091 // This function fills the sector structure of AliToyMCReconstruction
2092 //-----------------------------------------------------------------
2094 // cluster array of all sectors
2095 fInnerSectorArray = new AliTPCtrackerSector[fkNSectorInner];
2096 fOuterSectorArray = new AliTPCtrackerSector[fkNSectorOuter];
2098 for (Int_t i=0; i<fkNSectorInner; ++i) fInnerSectorArray[i].Setup(fTPCParam,0);
2099 for (Int_t i=0; i<fkNSectorOuter; ++i) fOuterSectorArray[i].Setup(fTPCParam,1);
2101 Int_t count[72][96] = { {0} , {0} };
2103 for (Int_t iev=0; iev<maxev; ++iev){
2104 printf("============== Fill Clusters: Processing Event %6d =================\n",iev);
2105 fTree->GetEvent(iev);
2106 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
2107 printf(" > ====== Fill Clusters: Processing Track %6d ======== \n",itr);
2108 const AliToyMCTrack *tr=fEvent->GetTrack(itr);
2110 // number of clusters to loop over
2111 const Int_t ncls=(fClusterType==0)?tr->GetNumberOfSpacePoints():tr->GetNumberOfDistSpacePoints();
2113 for(Int_t icl=0; icl<ncls; ++icl){
2115 AliTPCclusterMI *cl=const_cast<AliTPCclusterMI *>(tr->GetSpacePoint(icl));
2116 if (fClusterType==1) cl=const_cast<AliTPCclusterMI *>(tr->GetDistortedSpacePoint(icl));
2119 Int_t sec = cl->GetDetector();
2120 Int_t row = cl->GetRow();
2122 // set Q of the cluster to 1, Q==0 does not work for the seeding
2125 // set cluster time to cluster Z (if not ideal tracking)
2126 if ( !fIdealTracking ) {
2127 // a 'valid' position in z is needed for the seeding procedure
2128 // cl->SetZ(cl->GetTimeBin()*GetVDrift());
2129 cl->SetZ(cl->GetTimeBin());
2131 //Printf("Fill clusters (sector %d row %d): %.2f %.2f %.2f %.2f",sec,row,cl->GetX(),cl->GetY(),cl->GetZ(),cl->GetTimeBin());
2133 // fill arrays for inner and outer sectors (A/C side handled internally)
2134 if (sec<fkNSectorInner*2){
2135 fInnerSectorArray[sec%fkNSectorInner].InsertCluster(cl, count[sec][row], fTPCParam);
2138 fOuterSectorArray[(sec-fkNSectorInner*2)%fkNSectorOuter].InsertCluster(cl, count[sec][row], fTPCParam);
2146 // fill the arrays completely
2147 // LoadOuterSectors();
2148 // LoadInnerSectors();
2150 // // check the arrays
2151 // for (Int_t i=0; i<fkNSectorInner; ++i){
2152 // for (Int_t j=0; j<fInnerSectorArray[i].GetNRows(); ++j){
2153 // if(fInnerSectorArray[i][j].GetN()>0){
2154 // Printf("Inner: Sector %d Row %d : %d",i,j,fInnerSectorArray[i][j].GetN());
2158 // for (Int_t i=0; i<fkNSectorInner; ++i){
2159 // for (Int_t j=0; j<fOuterSectorArray[i].GetNRows(); ++j){
2160 // if(fOuterSectorArray[i][j].GetN()>0){
2161 // Printf("Outer: Sector %d Row %d : %d",i,j,fOuterSectorArray[i][j].GetN());
2167 //____________________________________________________________________________________
2168 void AliToyMCReconstruction::FillSectorStructureAC() {
2169 //-----------------------------------------------------------------
2170 // This function fills the sector structure of AliToyMCReconstruction
2171 //-----------------------------------------------------------------
2174 my god is the AliTPCtrackerSector stuff complicated!!!
2175 Ok, so here we will not fill the fClusters1 and fClusters2 of AliTPCtrackerRow,
2176 using InsertCluster of AliTPCtrackerSector, but only the fClusters via InsertCluster
2177 of AliTPCtrackerRow itself which then will not be owner, but we create an array in
2178 here (fAllClusters) which owns all clusters ...
2182 // cluster array of all sectors
2183 fInnerSectorArray = new AliTPCtrackerSector[2*fkNSectorInner];
2184 fOuterSectorArray = new AliTPCtrackerSector[2*fkNSectorOuter];
2186 for (Int_t i=0; i<2*fkNSectorInner; ++i) {
2187 fInnerSectorArray[i].Setup(fTPCParam,0);
2190 for (Int_t i=0; i<2*fkNSectorOuter; ++i) {
2191 fOuterSectorArray[i].Setup(fTPCParam,1);
2194 Int_t count[72][96] = { {0} , {0} };
2196 for (Int_t iev=0; iev<fNmaxEvents; ++iev){
2197 printf("============== Fill Clusters: Processing Event %6d =================\n",iev);
2198 fTree->GetEvent(iev);
2199 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks(); ++itr){
2200 // printf(" > ====== Fill Clusters: Processing Track %6d ======== \n",itr);
2201 const AliToyMCTrack *tr=fEvent->GetTrack(itr);
2203 // number of clusters to loop over
2204 const Int_t ncls=(fClusterType==0)?tr->GetNumberOfSpacePoints():tr->GetNumberOfDistSpacePoints();
2206 // check if expansion of the cluster arrays is needed.
2207 if (fAllClusters.GetEntriesFast()+ncls>=fAllClusters.Capacity()) fAllClusters.Expand(2*fAllClusters.Capacity());
2208 for(Int_t icl=0; icl<ncls; ++icl){
2210 AliTPCclusterMI *cl=const_cast<AliTPCclusterMI *>(tr->GetSpacePoint(icl));
2211 if (fClusterType==1) cl=const_cast<AliTPCclusterMI *>(tr->GetDistortedSpacePoint(icl));
2214 // register copy to the cluster array
2215 cl = new(fAllClusters[fAllClusters.GetEntriesFast()]) AliTPCclusterMI(*cl);
2217 Int_t sec = cl->GetDetector();
2218 Int_t row = cl->GetRow();
2220 // set Q of the cluster to 1, Q==0 does not work for the seeding
2223 // set cluster time to cluster Z (if not ideal tracking)
2224 if ( !fIdealTracking ) {
2225 // a 'valid' position in z is needed for the seeding procedure
2227 if (((sec/18)%2)==1) sign=-1;
2228 cl->SetZ(cl->GetTimeBin()*GetVDrift());
2229 //mark cluster to be time*vDrift by setting the type to 1
2231 // cl->SetZ(cl->GetTimeBin());
2233 //Printf("Fill clusters (sector %d row %d): %.2f %.2f %.2f %.2f",sec,row,cl->GetX(),cl->GetY(),cl->GetZ(),cl->GetTimeBin());
2235 // fill arrays for inner and outer sectors (A/C side handled internally)
2236 if (sec<fkNSectorInner*2){
2237 fInnerSectorArray[sec][row].InsertCluster(cl, count[sec][row]);
2240 fOuterSectorArray[(sec-fkNSectorInner*2)][row].InsertCluster(cl, count[sec][row]);
2250 //____________________________________________________________________________________
2251 AliToyMCTrack *AliToyMCReconstruction::ConvertTPCSeedToToyMCTrack(const AliTPCseed &seed)
2258 AliToyMCTrack *tToy = new AliToyMCTrack(seed);
2260 for (Int_t icl=0; icl<159; ++icl){
2261 const AliTPCclusterMI *cl=seed.GetClusterFast(icl);
2263 if (fClusterType==0){
2264 tToy->AddSpacePoint(*cl);
2266 tToy->AddDistortedSpacePoint(*cl);
2273 //____________________________________________________________________________________
2274 AliExternalTrackParam* AliToyMCReconstruction::GetRefittedTrack(const AliTPCseed &seed)
2280 AliExternalTrackParam *track=0x0;
2282 const Float_t vDrift=GetVDrift();
2283 const Float_t zLength=GetZLength(0);
2284 const Double_t kMaxSnp = 0.85;
2285 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
2287 AliToyMCTrack *toyTrack = ConvertTPCSeedToToyMCTrack(seed);
2292 fCreateT0seed = kTRUE;
2293 AliExternalTrackParam *t0seed = GetSeedFromTrack(toyTrack,kTRUE);
2294 if (!t0seed) return 0x0;
2296 fTime0 = t0seed->GetZ()-zLength/vDrift;
2300 fCreateT0seed = kFALSE;
2301 AliExternalTrackParam *dummy = GetSeedFromTrack(toyTrack,kTRUE);
2302 track = GetFittedTrackFromSeed(toyTrack, dummy);
2304 // propagate seed to 0
2305 AliTrackerBase::PropagateTrackTo(track,0,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
2310 //____________________________________________________________________________________
2311 AliTPCclusterMI* AliToyMCReconstruction::FindMiddleCluster(const AliTPCclusterMI *clInner, const AliTPCclusterMI *clOuter,
2312 Double_t roady, Double_t roadz,
2319 const Int_t rocInner = clInner->GetDetector();
2320 const Int_t rocOuter = clOuter->GetDetector();
2322 if ( (rocInner%18) != (rocOuter%18) ){
2323 AliError("Currently only same Sector implemented");
2327 const Int_t innerDet=clInner->GetDetector();
2328 const Int_t outerDet=clOuter->GetDetector();
2329 const Int_t globalRowInner = clInner->GetRow() +(innerDet >35)*63;
2330 const Int_t globalRowOuter = clOuter->GetRow() +(outerDet >35)*63;
2332 AliTPCclusterMI *n=0x0;
2334 // allow flexibility of +- nRowsGrace Rows to find a middle cluster
2335 const Int_t nRowsGrace = 0;
2336 for (Int_t iter=0; iter<2*nRowsGrace+1; ++iter){
2337 Int_t iMiddle = (globalRowInner+globalRowOuter)/2;
2338 iMiddle+=((iter+1)/2)*(1-2*((iter+1)%2));
2340 Int_t localRow=iMiddle;
2341 Int_t roc = innerDet;
2347 AliTPCtrackerSector *arrRow=(iMiddle<63)?fInnerSectorArray:fOuterSectorArray;
2348 const AliTPCtrackerRow& krMiddle = arrRow[roc%36][localRow]; // middle
2349 // initial guess use simple linear interpolation
2350 Double_t y=(clInner->GetY()+clOuter->GetY())/2;
2351 Double_t z=(clInner->GetZ()+clOuter->GetZ())/2;
2352 if (seedFit.IsValid()) {
2353 // update values once the fit was performed
2354 y=seedFit.GetYat(krMiddle.GetX());
2355 z=seedFit.GetZat(krMiddle.GetX());
2358 n=krMiddle.FindNearest(y,z,roady,roadz);
2363 // 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,
2364 // n->GetX(), n->GetY(),n->GetZ(),n->GetLabel(0),
2365 // clInner->GetX(), clInner->GetY(),clInner->GetZ(),clInner->GetLabel(0),
2366 // clOuter->GetX(), clOuter->GetY(),clOuter->GetZ(),clOuter->GetLabel(0)
2371 //____________________________________________________________________________________
2372 void AliToyMCReconstruction::AddMiddleClusters(AliTPCseed *seed,
2373 const AliTPCclusterMI *clInner, const AliTPCclusterMI *clOuter,
2374 Double_t roady, Double_t roadz,
2375 Int_t &nTotalClusters, AliRieman &seedFit)
2378 // Iteratively add the middle clusters
2381 // update rieman fit with every second point added
2382 AliTPCclusterMI *clMiddle=FindMiddleCluster(clInner,clOuter,roady,roadz,seedFit);
2384 // break iterative process
2385 if (!clMiddle || clMiddle->IsUsed()) return;
2387 const Int_t globalRowInner = clInner->GetRow() +(clInner->GetDetector() >35)*63;
2388 const Int_t globalRowMiddle = clMiddle->GetRow()+(clMiddle->GetDetector()>35)*63;
2389 const Int_t globalRowOuter = clOuter->GetRow() +(clOuter->GetDetector() >35)*63;
2391 seed->SetClusterPointer(globalRowMiddle,clMiddle);
2393 // printf(" > Total clusters: %d\n",nTotalClusters);
2394 seedFit.AddPoint(clMiddle->GetX(), clMiddle->GetY(), clMiddle->GetZ(),
2395 TMath::Sqrt(clMiddle->GetSigmaY2()), TMath::Sqrt(clMiddle->GetSigmaZ2()));
2397 if (seedFit.GetN()>3) {
2398 // printf(" call update: %d (%d)\n",seedFit.GetN(),nTotalClusters);
2399 // printf(" Riemann results: valid=%d, Chi2=%.2f, Chi2Y=%.2f, Chi2Z=%.2f -- %d\n",
2400 // seedFit.IsValid(), seedFit.GetChi2(), seedFit.GetChi2Y(), seedFit.GetChi2Z(), clMiddle->GetLabel(0));
2403 if ( seedFit.IsValid() && seedFit.GetChi2()>1000 ) return;
2405 // Add middle clusters towards outer radius
2406 if (globalRowMiddle+1<globalRowOuter) AddMiddleClusters(seed,clMiddle,clOuter,roady,roadz,nTotalClusters,seedFit);
2408 // Add middle clusters towards innter radius
2409 if (globalRowInner+1<globalRowMiddle) AddMiddleClusters(seed,clInner,clMiddle,roady,roadz,nTotalClusters,seedFit);
2414 //____________________________________________________________________________________
2415 Int_t AliToyMCReconstruction::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t iRowInner, Int_t iRowOuter)
2418 // find seeds in a sector, requires iRowInner < iRowOuter
2419 // iRowXXX runs from 0-159, so over IROC and OROC
2423 AliError("This function requires the sector arrays filled for AC tracking");
2427 // swap rows in case they are in the wrong order
2428 if (iRowInner>iRowOuter) {
2429 Int_t tmp=iRowInner;
2430 iRowInner=iRowOuter;
2434 if (iRowOuter>158) iRowOuter=158;
2435 if (iRowInner<0) iRowInner=0;
2437 // Define the search roads:
2438 // timeRoadCombinatorics - the maximum time difference used for the
2439 // combinatorics. Since we don't have a 'z-Vertex' estimate this will
2440 // reduce the combinatorics significantly when iterating on one TF
2441 // use a little more than one full drift length of the TPC to allow for
2444 // timeRoad - the time difference allowed when associating the cluster
2445 // in the middle of the other two used for the initial search
2447 // padRoad - the local y difference allowed when associating the middle cluster
2449 // Double_t timeRoadCombinatorics = 270./vDrift;
2450 // Double_t timeRoad = 20./vDrift;
2451 Double_t timeRoadCombinatorics = 270.;
2452 Double_t timeRoad = 10.;
2453 Double_t padRoad = 5.;
2456 // fOuterSectorArray runs from 0-95, so from iRowXXX which runs from 0-159
2457 // the number of rows in the IROC has to be subtracted
2458 const Int_t innerRows=fInnerSectorArray->GetNRows();
2460 AliTPCtrackerSector *arrInnerRow=(iRowInner<63)?fInnerSectorArray:fOuterSectorArray;
2461 AliTPCtrackerSector *arrOuterRow=(iRowOuter<63)?fInnerSectorArray:fOuterSectorArray;
2463 const AliTPCtrackerRow& krInner = arrInnerRow[sec][iRowInner - (iRowInner>62)*innerRows]; // up
2464 const AliTPCtrackerRow& krOuter = arrOuterRow[sec][iRowOuter - (iRowOuter>62)*innerRows]; // down
2466 AliTPCseed *seed = new AliTPCseed;
2468 const Int_t nMaxClusters=iRowOuter-iRowInner+1;
2469 // Int_t nScannedClusters = 0;
2472 // loop over all points in the firstand last search row
2473 for (Int_t iOuter=0; iOuter < krOuter; iOuter++) {
2474 const AliTPCclusterMI *clOuter = krOuter[iOuter];
2475 if (clOuter->IsUsed()) continue;
2476 for (Int_t iInner=0; iInner < krInner; iInner++) {
2477 const AliTPCclusterMI *clInner = krInner[iInner];
2478 if (clInner->IsUsed()) continue;
2479 // printf("\n\n Check combination %d (%d), %d (%d) -- %d (%d) -- %d\n",iOuter, iInner, clOuter->GetLabel(0), clInner->GetLabel(0),iRowOuter,iRowInner,sec);
2480 // check maximum distance for combinatorics
2481 if (TMath::Abs(clOuter->GetZ()-clInner->GetZ())>timeRoadCombinatorics) continue;
2482 // printf(" Is inside one drift\n");
2484 // use rieman fit for seed description
2485 AliRieman seedFit(159);
2486 // add first two points
2487 seedFit.AddPoint(clInner->GetX(), clInner->GetY(), clInner->GetZ(),
2488 TMath::Sqrt(clInner->GetSigmaY2()), TMath::Sqrt(clInner->GetSigmaZ2()));
2489 seedFit.AddPoint(clOuter->GetX(), clOuter->GetY(), clOuter->GetZ(),
2490 TMath::Sqrt(clOuter->GetSigmaY2()), TMath::Sqrt(clOuter->GetSigmaZ2()));
2492 // Iteratively add all clusters in the respective middle
2493 Int_t nFoundClusters=2;
2494 AddMiddleClusters(seed,clInner,clOuter,padRoad,timeRoad,nFoundClusters,seedFit);
2495 // printf(" Clusters attached: %d\n",nFoundClusters);
2496 if (nFoundClusters>2) seedFit.Update();
2497 // printf(" Riemann results: valid=%d, Chi2=%.2f, Chi2Y=%.2f, Chi2Z=%.2f\n",
2498 // seedFit.IsValid(), seedFit.GetChi2(), seedFit.GetChi2Y(), seedFit.GetChi2Z());
2500 // check for minimum number of assigned clusters and a decent chi2
2501 if ( nFoundClusters<0.5*nMaxClusters || seedFit.GetChi2()>1000 ){
2505 // printf(" >>> Seed accepted\n");
2506 // add original outer clusters
2507 const Int_t globalRowInner = clInner->GetRow() +(clInner->GetDetector() >35)*63;
2508 const Int_t globalRowOuter = clOuter->GetRow() +(clOuter->GetDetector() >35)*63;
2510 seed->SetClusterPointer(globalRowInner,const_cast<AliTPCclusterMI*>(clInner));
2511 seed->SetClusterPointer(globalRowOuter,const_cast<AliTPCclusterMI*>(clOuter));
2513 // set parameters retrieved from AliRieman
2514 Double_t params[5]={0};
2515 Double_t covar[15]={0};
2516 const Double_t alpha=TMath::DegToRad()*(clInner->GetDetector()%18*20.+10.);
2517 const Double_t x=clInner->GetX();
2518 seedFit.GetExternalParameters(x,params,covar);
2520 seed->Set(x,alpha,params,covar);
2522 // set label of the seed. At least 60% of the clusters need the correct label
2524 // printf(" - Label: %d\n",seed->GetLabel());
2525 // mark clusters as being used
2526 MarkClustersUsed(seed);
2528 seed->SetSeed1(iRowInner);
2529 seed->SetSeed2(iRowOuter);
2530 seed->SetSector(sec);
2533 seed->SetUniqueID(arr->GetEntriesFast());
2534 seed->SetIsSeeding(kTRUE);
2537 seed=new AliTPCseed;
2542 //delete surplus seed
2548 //____________________________________________________________________________________
2549 void AliToyMCReconstruction::MakeSeeds(TObjArray * /*arr*/, Int_t sec, Int_t iRow1, Int_t iRow2)
2552 // Create seeds between i1 and i2 (stored in arr) with TLinearFitter
2554 // sec: sector number
2560 static TLinearFitter fitter(3,"pol2");
2562 // Get 3 padrows (iRow1,iMiddle=(iRow1+iRow2)/2,iRow2)
2563 Int_t iMiddle = (iRow1+iRow2)/2;
2564 const AliTPCtrackerRow& krd = fOuterSectorArray[sec][iRow2-fInnerSectorArray->GetNRows()]; // down
2565 const AliTPCtrackerRow& krm = fOuterSectorArray[sec][iMiddle-fInnerSectorArray->GetNRows()]; // middle
2566 const AliTPCtrackerRow& kru = fOuterSectorArray[sec][iRow1-fInnerSectorArray->GetNRows()]; // up
2568 // Loop over 3 cluster possibilities
2569 for (Int_t iu=0; iu < kru; iu++) {
2570 for (Int_t im=0; im < krm; im++) {
2571 for (Int_t id=0; id < krd; id++) {
2574 fitter.ClearPoints();
2576 // add all three points to fitter
2577 Double_t xy[2] = {kru[iu]->GetX(),kru[iu]->GetY()};
2578 Double_t z = kru[iu]->GetZ();
2579 fitter.AddPoint(xy,z);
2581 xy[0] = krm[im]->GetX();
2582 xy[1] = krm[im]->GetY();
2583 z = krm[im]->GetZ();
2584 fitter.AddPoint(xy,z);
2586 xy[0] = krd[id]->GetX();
2587 xy[1] = krd[id]->GetY();
2588 z = krd[id]->GetZ();
2589 fitter.AddPoint(xy,z);
2591 // Evaluate and get parameters
2594 // how to get the other clusters now?
2602 //____________________________________________________________________________________
2603 void AliToyMCReconstruction::InitStreamer(TString addName, Int_t level)
2606 // initilise the debug streamer and set the logging level
2607 // use a default naming convention
2613 if (addName.IsNull()) addName=".dummy";
2617 TString debugName=gSystem->BaseName(fInputFile->GetName());
2618 debugName.ReplaceAll(".root","");
2619 debugName.Append(Form(".%1d.%1d_%1d_%1d_%03d_%02d",
2620 fUseMaterial,fIdealTracking,fClusterType,
2621 Int_t(fCorrectionType),fSeedingRow,fSeedingDist));
2622 debugName.Append(addName);
2623 debugName.Append(".root");
2625 gSystem->Exec(Form("test -f %s && rm %s", debugName.Data(), debugName.Data()));
2626 fStreamer=new TTreeSRedirector(debugName.Data());
2627 fStreamer->SetUniqueID(level);
2632 //____________________________________________________________________________________
2633 void AliToyMCReconstruction::ConnectInputFile(const char* file, Int_t nmaxEv)
2636 // connect the tree and event pointer from the input file
2644 fInputFile=TFile::Open(file);
2645 if (!fInputFile || !fInputFile->IsOpen() || fInputFile->IsZombie()) {
2648 AliError(Form("ERROR: couldn't open the file '%s'\n", file));
2652 fTree=(TTree*)fInputFile->Get("toyMCtree");
2654 AliError(Form("ERROR: couldn't read the 'toyMCtree' from file '%s'\n", file));
2659 fTree->SetBranchAddress("event",&fEvent);
2663 fNmaxEvents=fTree->GetEntries();
2664 if (nmaxEv>-1) fNmaxEvents=TMath::Min(nmaxEv,fNmaxEvents);
2666 // setup space charge map from Userinfo of the tree
2669 // setup the track maps
2673 //____________________________________________________________________________________
2674 void AliToyMCReconstruction::Cleanup()
2677 // Cleanup input data
2680 if (fStreamer) delete fStreamer;
2696 //____________________________________________________________________________________
2697 void AliToyMCReconstruction::SetupTrackMaps()
2703 fMapTrackEvent.Delete();
2704 fMapTrackTrackInEvent.Delete();
2707 AliError("Tree not connected");
2711 Int_t nmaxEv=fTree->GetEntries();
2712 if (fNmaxEvents>-1) nmaxEv=fNmaxEvents;
2714 for (Int_t iev=0; iev<nmaxEv; ++iev) {
2715 fTree->GetEvent(iev);
2716 if (!fEvent) continue;
2718 const Int_t ntracks=fEvent->GetNumberOfTracks();
2719 if (fMapTrackEvent.GetSize()+ntracks>=fMapTrackEvent.Capacity()) fMapTrackEvent.Expand(2*fMapTrackEvent.Capacity());
2720 if (fMapTrackTrackInEvent.GetSize()+ntracks>=fMapTrackTrackInEvent.Capacity()) fMapTrackTrackInEvent.Expand(2*fMapTrackTrackInEvent.Capacity());
2722 for (Int_t itrack=0; itrack<ntracks; ++itrack){
2723 Int_t label=fEvent->GetTrack(itrack)->GetUniqueID();
2725 fMapTrackEvent.Add(label,iev);
2726 fMapTrackTrackInEvent.Add(label,itrack);
2732 //____________________________________________________________________________________
2733 void AliToyMCReconstruction::CookLabel(AliTPCseed *seed, Double_t fraction, Int_t info[5])
2739 Int_t labels[159]={0};
2740 // Long64_t posMaxLabel=-1;
2741 Int_t nMaxLabel=0; // clusters from maximum label
2742 Int_t nMaxLabel2=0; // clusters from second maximum
2744 Int_t maxLabel=-1; // label with most clusters
2745 Int_t maxLabel2=-1; // label with second most clusters
2747 TExMap labelMap(159);
2749 for (Int_t icl=0; icl<159; ++icl) {
2750 const AliTPCclusterMI *cl=seed->GetClusterPointer(icl);
2754 const Int_t clLabel=cl->GetLabel(0);
2755 // a not assinged value returns 0, so we need to add 1 and subtract it afterwards
2756 Long64_t labelPos=labelMap.GetValue(clLabel);
2760 labelMap.Add(clLabel,labelPos);
2765 const Int_t nCurrentLabel=++labels[labelPos];
2766 if (nCurrentLabel>nMaxLabel) {
2767 nMaxLabel2=nMaxLabel;
2768 nMaxLabel=nCurrentLabel;
2769 // posMaxLabel=labelPos;
2775 if (Double_t(nMaxLabel)/nclusters<fraction) maxLabel=-maxLabel;
2777 seed->SetLabel(maxLabel);
2789 //____________________________________________________________________________________
2790 void AliToyMCReconstruction::DumpSeedInfo(TObjArray *arr)
2794 if (!fStreamer || !fTree) return;
2795 // swap rows in case they are in the wrong order
2796 AliInfo(Form("Number of Seeds: %d (out of %d tracks)",arr->GetEntriesFast(),fMapTrackEvent.GetSize()));
2798 //loop over all events and tracks and try to associate the seed to the track
2799 for (Int_t iseed=0; iseed<arr->GetEntriesFast(); ++iseed){
2800 AliTPCseed *seed = static_cast<AliTPCseed*>(arr->UncheckedAt(iseed));
2802 // get original track
2803 Int_t seedLabel=seed->GetLabel();
2804 Int_t iev=fMapTrackEvent.GetValue(TMath::Abs(seedLabel));
2805 Int_t itr=fMapTrackTrackInEvent.GetValue(TMath::Abs(seedLabel));
2807 fTree->GetEvent(iev);
2808 const AliToyMCTrack *toyTrack = fEvent->GetTrack(itr);
2810 DumpSeedInfo(toyTrack,seed);
2814 //____________________________________________________________________________________
2815 void AliToyMCReconstruction::DumpTrackInfo(TObjArray *arr)
2819 if (!fStreamer || !fTree) return;
2820 // swap rows in case they are in the wrong order
2821 AliInfo(Form("Number of Seeds: %d (out of %d tracks)",arr->GetEntriesFast(),fMapTrackEvent.GetSize()));
2823 //loop over all events and tracks and try to associate the seed to the track
2824 AliTPCseed dummySeed;
2825 for (Int_t iev=0; iev<fNmaxEvents; ++iev) {
2826 fTree->GetEvent(iev);
2827 const Int_t ntracks=fEvent->GetNumberOfTracks();
2828 for (Int_t itr=0; itr<ntracks; ++itr) {
2829 const AliToyMCTrack *toyTrack = fEvent->GetTrack(itr);
2831 Bool_t foundSeed=kFALSE;
2832 for (Int_t iseed=0; iseed<arr->GetEntriesFast(); ++iseed) {
2833 AliTPCseed *seed = static_cast<AliTPCseed*>(arr->UncheckedAt(iseed));
2834 const UInt_t tmpLabel=TMath::Abs(seed->GetLabel());
2835 if (toyTrack->GetUniqueID()!=tmpLabel) continue;
2837 // dump all seeds with the correct label
2838 DumpSeedInfo(toyTrack,seed);
2842 if (!foundSeed) DumpSeedInfo(toyTrack,&dummySeed);
2848 //____________________________________________________________________________________
2849 void AliToyMCReconstruction::DumpSeedInfo(const AliToyMCTrack *toyTrack, AliTPCseed *seed)
2855 const Double_t kMaxSnp = 0.85;
2856 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
2857 Float_t vDrift=GetVDrift();
2858 Float_t zLength=GetZLength(0);
2860 AliExternalTrackParam tOrig(*toyTrack);
2861 AliExternalTrackParam tOrigITS(*toyTrack);
2863 // propagate original track to ITS last layer
2864 // Double_t lastLayerITS = 43.0; // same as in AliToyMCEventGenerator::MakeITSClusters (hard coded)
2865 const Double_t iFCRadius = 83.5; //radius constants found in AliTPCCorrection.cxx
2866 Double_t lastLayerITS = iFCRadius; // its track propgated to inner TPC wall
2867 AliTrackerBase::PropagateTrackTo(&tOrigITS,lastLayerITS,kMass,1,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
2869 AliExternalTrackParam dummyParam;
2870 Bool_t isDummy=kFALSE;
2871 //create refitted track, this will also set the fTime0
2872 AliExternalTrackParam *track=GetRefittedTrack(*seed);
2877 AliTrackerBase::PropagateTrackTo(track,0,kMass,5.,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
2878 track->Rotate(tOrig.GetAlpha());
2879 AliTrackerBase::PropagateTrackTo(track,0,kMass,1.,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
2881 // rotate fitted track to the frame of the original track and propagate to same reference
2882 AliExternalTrackParam trackITS(*track);
2883 AliTrackerBase::PropagateTrackTo(&trackITS,lastLayerITS,kMass,5,kTRUE,kMaxSnp,0,kFALSE,fUseMaterial);
2884 trackITS.Rotate(tOrigITS.GetAlpha());
2885 AliTrackerBase::PropagateTrackTo(&trackITS,lastLayerITS,kMass,1,kFALSE,kMaxSnp,0,kFALSE,fUseMaterial);
2887 Int_t seedSec=seed->GetSector();
2888 Int_t seedID =seed->GetUniqueID();
2890 //count findable and found clusters in the seed
2892 Int_t iRowInner=seed->GetSeed1();
2893 Int_t iRowOuter=seed->GetSeed2();
2895 Int_t nClustersSeedMax=iRowOuter-iRowInner+1;
2896 Int_t nClustersFindable=0;
2897 Int_t nClustersSeed=0;
2899 Int_t ncls=(fClusterType==0)?toyTrack->GetNumberOfSpacePoints():toyTrack->GetNumberOfDistSpacePoints();
2901 Int_t rowInner=iRowInner-(iRowInner>62)*63;
2902 Int_t rowOuter=iRowOuter-(iRowOuter>62)*63;
2904 //findable in the current seed sector
2907 Int_t nCrossedROCs=0;
2914 for (Int_t icl=0; icl<ncls; ++icl) {
2915 const AliTPCclusterMI *cl=(fClusterType==0)?toyTrack->GetSpacePoint(icl):toyTrack->GetDistortedSpacePoint(icl);
2916 const Int_t roc=cl->GetDetector();
2917 const Int_t row=cl->GetRow();
2918 const Int_t rowGlobal=row+(roc>35)*63;
2920 AliTPCclusterMI *seedCl = seed->GetClusterPointer(rowGlobal);
2922 AliTPCclusterMI *clc=const_cast<AliTPCclusterMI*>(cl);
2923 if (seedCl->GetDetector()==roc&&seedCl->IsUsed()) clc->Use();
2924 clc->SetLabel(seedID,1);
2928 // if (row1<0) row1=rowGlobal;
2930 if ( (roc%36) != (lastROC%36)) {
2932 if (nclROC>nMaxClROC) {
2945 if ( (roc%36)!=(seedSec%36) ) continue;
2946 // if ( (row<rowInner) || (row>rowOuter) ) continue;
2947 ++nClustersFindable;
2951 if (nclROC>nMaxClROC) {
2960 Int_t nClustersInTrack=0;
2962 for (Int_t icl=0; icl<159; ++icl) {
2963 const AliTPCclusterMI *cl=seed->GetClusterPointer(icl);
2966 const Int_t row=cl->GetRow();
2967 const Int_t rowGlobal=row+(cl->GetDetector()>35)*63;
2968 if (rowGlobal>lastRow) lastRow=rowGlobal;
2969 if (rowGlobal<firstRow) firstRow=rowGlobal;
2970 if ( (row<rowInner) || (row>rowOuter) ) continue;
2974 Float_t z0=fEvent->GetZ();
2975 Float_t t0=fEvent->GetT0();
2977 Int_t ctype(fCorrectionType);
2980 CookLabel(seed,.6,info);
2981 Int_t seedLabel=seed->GetLabel();
2983 Int_t labelOrig=toyTrack->GetUniqueID();
2985 AliToyMCTrack *tr2 = const_cast<AliToyMCTrack*>(toyTrack);
2987 (*fStreamer) << "Seeds" <<
2989 // "iseed=" << iseed <<
2993 "vDrift=" << vDrift <<
2994 "zLength=" << zLength <<
2995 "fTime0=" << fTime0 <<
2996 "clsType=" << fClusterType <<
2997 "corrType=" << ctype <<
2999 "tOrig.=" << &tOrig <<
3000 "tOrigITS.=" << &tOrigITS <<
3002 "to.nclFindable=" << nClustersFindable <<
3003 "to.nclTot=" << ncls <<
3004 "to.label=" << labelOrig <<
3005 "to.nCrossedROCs="<< nCrossedROCs <<
3006 "to.rocMax=" << rocMaxCl <<
3007 "to.rocMaxNcl=" << nMaxClROC <<
3008 "to.row1Max=" << row1Maxcl <<
3009 "to.row2Max=" << row2Maxcl <<
3011 "track.=" << track <<
3012 "trackITS.=" << &trackITS <<
3014 "s.RowInner=" << iRowInner <<
3015 "s.RowOuter=" << iRowOuter <<
3016 "s.nclMax=" << nClustersSeedMax <<
3017 "s.ncl=" << nClustersSeed <<
3018 "s.ID=" << seedID <<
3020 "tr.firstClRow=" << firstRow <<
3021 "tr.lastClRow=" << lastRow <<
3022 "tr.ncl=" << nClustersInTrack <<
3023 "tr.label=" << seedLabel <<
3025 "tr.LabelNcl=" << info[0] <<
3026 "tr.Label2Ncl=" << info[1] <<
3027 "tr.Label2=" << info[2] <<
3028 "tr.nclTot=" << info[3] <<
3029 "tr.Nlabels=" << info[4] <<
3031 "tr.Sec=" << seedSec <<
3034 "toyTrack.=" << tr2 <<
3037 if (!isDummy) delete track;
3040 //____________________________________________________________________________________
3041 void AliToyMCReconstruction::MarkClustersUsed(AliTPCseed *seed)
3047 for (Int_t icl=0; icl<159; ++icl) {
3048 AliTPCclusterMI *cl=seed->GetClusterPointer(icl);
3053 //____________________________________________________________________________________
3054 void AliToyMCReconstruction::ResetClustersZtoTime(AliTPCseed *seed)
3060 for (Int_t icl=0; icl<159; ++icl) {
3061 AliTPCclusterMI *cl=seed->GetClusterPointer(icl);
3062 if (cl) cl->SetZ(cl->GetTimeBin());
3066 //____________________________________________________________________________________
3067 void AliToyMCReconstruction::DumpTracksToTree(const char* file)
3072 ConnectInputFile(file);
3078 TString debugName=fInputFile->GetName();
3079 debugName.ReplaceAll(".root",".AllTracks.root");
3081 gSystem->Exec(Form("test -f %s && rm %s", debugName.Data(), debugName.Data()));
3082 fStreamer=new TTreeSRedirector(debugName.Data());
3084 for (Int_t iev=0;iev<fNmaxEvents;++iev){
3085 fTree->GetEvent(iev);
3086 for (Int_t itr=0; itr<fEvent->GetNumberOfTracks();++itr){
3087 AliToyMCTrack *toyTrack=const_cast<AliToyMCTrack*>(fEvent->GetTrack(itr));
3088 Int_t trackID=toyTrack->GetUniqueID();
3090 (*fStreamer) << "Tracks" <<
3093 "trackID=" << trackID <<
3094 "track.=" << toyTrack <<
3103 //____________________________________________________________________________________
3104 void AliToyMCReconstruction::SetRieman(const AliTPCseed &seed, AliRieman &rieman)
3111 for (Int_t icl=0; icl<159; ++icl) {
3112 const AliTPCclusterMI *cl=seed.GetClusterPointer(icl);
3114 rieman.AddPoint(cl->GetX(), cl->GetY(), cl->GetZ(),
3115 TMath::Sqrt(cl->GetSigmaY2()), TMath::Sqrt(cl->GetSigmaZ2()));
3120 //____________________________________________________________________________________
3121 void AliToyMCReconstruction::CopyRieman(const AliRieman &from, AliRieman &to)
3127 if (to.GetCapacity()<from.GetCapacity()) return;
3130 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]);
3133 //____________________________________________________________________________________
3134 Float_t AliToyMCReconstruction::FindClosestT0(const TVectorF &t0list, const TVectorF &z0list, AliExternalTrackParam &t0seed)
3137 // find closes T0 in a list of T0s
3140 Long64_t size=t0list.GetNrows();
3141 const Float_t *array=t0list.GetMatrixArray();
3143 Float_t vDrift=GetVDrift();
3144 Float_t zLength=GetZLength(0);
3146 Float_t sign=(1-2*(t0seed.GetTgl()>0));
3149 Float_t t0=t0seed.GetZ()-zLength/vDrift;
3152 Float_t minDist=1e20;
3153 for (Int_t it0=0; it0<size; ++it0) {
3154 if (fUseZ0list) vtxCorr=sign*z0list[it0]/vDrift;
3155 // printf("vtxcorr %d: %.2g, %.2g\n",it0, vtxCorr, z0list[it0]);
3156 const Float_t dist=TMath::Abs(t0list[it0]-t0-vtxCorr);
3163 return array[index];