1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 Adding rekonstruction facilities
19 Piotr Krzysztof Skowronski
25 Eroor counting routines
26 Automatic combination routines improved (traps)
32 #include "AliITSMapA1.h"
33 #include "AliITSClusterFinderSSD.h"
34 #include "AliITSclusterSSD.h"
35 #include "AliITSpackageSSD.h"
40 ClassImp(AliITSClusterFinderSSD)
42 //____________________________________________________________________
45 //____________________________________________________________________
49 AliITSClusterFinderSSD::AliITSClusterFinderSSD(AliITSsegmentation *seg, TClonesArray *digits, TClonesArray *recp)
56 fMap = new AliITSMapA1(fSegmentation,fDigits);
58 fITS=(AliITS*)gAlice->GetModule("ITS");
60 fClusterP = new TClonesArray ("AliITSclusterSSD",200);
63 fClusterN= new TClonesArray ("AliITSclusterSSD",200);
66 fPackages = new TClonesArray ("AliITSpackageSSD",200); //packages
70 fDigitsIndexP = new TArrayI(300);
73 fDigitsIndexN = new TArrayI(300);
81 fPitch = fSegmentation->Dpx(0);
82 Float_t StereoP,StereoN;
83 fSegmentation->Angles(StereoP,StereoN);
84 fTanP=TMath::Tan(StereoP);
85 fTanN=TMath::Tan(StereoN);
87 fPNsignalRatio=7./8.; // warning: hard-wired number
91 //-------------------------------------------------------
92 AliITSClusterFinderSSD::~AliITSClusterFinderSSD() {
104 //-------------------------------------------------------
105 void AliITSClusterFinderSSD::InitReconstruction()
108 register Int_t i; //iterator
110 for (i=0;i<fNClusterP;i++)
112 fClusterP->RemoveAt(i);
115 for (i=0;i<fNClusterN;i++)
117 fClusterN->RemoveAt(i);
121 for (i=0;i<fNPackages;i++)
123 fPackages->RemoveAt(i);
130 Float_t StereoP,StereoN;
131 fSegmentation->Angles(StereoP,StereoN);
133 CalcStepFactor (StereoP,StereoN);
135 if (debug) cout<<"fSFF = "<<fSFF<<" fSFB = "<<fSFB<<"\n";
139 //---------------------------------------------
140 void AliITSClusterFinderSSD::FindRawClusters()
142 //Piotr Krzysztof Skowronski
143 //Warsaw University of Technology
144 //skowron@if.pw.edu.pl
146 // This function findes out all clusters belonging to one module
147 // 1. Zeroes all space after previous module reconstruction
148 // 2. Finds all neighbouring digits
149 // 3. If necesery, resolves for each group of neighbouring digits
150 // how many clusters creates it.
151 // 4. Creates packages
152 // 5. Creates clusters
154 InitReconstruction(); //ad. 1
158 FindNeighbouringDigits(); //ad. 2
159 SeparateOverlappedClusters(); //ad. 3
160 ClustersToPackages(); //ad. 4
162 PackagesToPoints(); //ad. 5
163 ReconstructNotConsumedClusters();
169 //-------------------------------------------------
170 void AliITSClusterFinderSSD::FindNeighbouringDigits()
174 //Piotr Krzysztof Skowronski
175 //Warsaw University of Technology
176 //skowron@if.pw.edu.pl
180 //If there are any digits on this side, create 1st Cluster,
181 // add to it this digit, and increment number of clusters
183 if ((fNDigitsP>0 ) && (fNDigitsN > 0 )) {
185 Int_t currentstripNo;
186 Int_t *dbuffer = new Int_t [300]; //buffer for strip numbers
187 Int_t dnumber; //curent number of digits in buffer
188 TArrayI &lDigitsIndexP = *fDigitsIndexP;
189 TArrayI &lDigitsIndexN = *fDigitsIndexN;
190 TObjArray &lDigits=*fDigits;
191 TClonesArray &lClusterP = *fClusterP;
192 TClonesArray &lClusterN = *fClusterN;
196 dbuffer[0]=lDigitsIndexP[0];
197 //If next digit is a neighbour of previous, adds to last cluster this digit
198 for (i=1; i<fNDigitsP; i++) {
200 currentstripNo = ((AliITSdigitSSD*)lDigits[lDigitsIndexP[i]])->
202 //check if it is a neighbour of a previous one
203 if ( (((AliITSdigitSSD*)lDigits[lDigitsIndexP[i-1]])->GetStripNumber())
204 == (currentstripNo-1) ) dbuffer[dnumber++]=lDigitsIndexP[i];
206 //create a new one side cluster
207 new(lClusterP[fNClusterP++]) AliITSclusterSSD(dnumber,dbuffer,fDigits,fgkSIDEP);
208 dbuffer[0]=lDigitsIndexP[i];
211 } // end loop over fNDigitsP
212 new(lClusterP[fNClusterP++]) AliITSclusterSSD(dnumber,dbuffer,fDigits,fgkSIDEP);
216 //for comments, see above
218 dbuffer[0]=lDigitsIndexN[0];
219 //If next digit is a neighbour of previous, adds to last cluster this digit
220 for (i=1; i<fNDigitsN; i++) {
221 currentstripNo = ((AliITSdigitSSD*)(lDigits[lDigitsIndexN[i]]))->
223 if ( (((AliITSdigitSSD*)lDigits[lDigitsIndexN[i-1]])->GetStripNumber())
224 == (currentstripNo-1) ) dbuffer[dnumber++]=lDigitsIndexN[i];
226 new(lClusterN[fNClusterN++]) AliITSclusterSSD(dnumber,dbuffer,fDigits,fgkSIDEN);
227 dbuffer[0]=lDigitsIndexN[i];
230 } // end loop over fNDigitsN
231 new(lClusterN[fNClusterN++]) AliITSclusterSSD(dnumber,dbuffer,fDigits,fgkSIDEN);
234 } // end condition on NDigits
236 if (debug) cout<<"\n Found clusters: fNClusterP = "<<fNClusterP<<" fNClusterN ="<<fNClusterN<<"\n";
239 /**********************************************************************/
242 void AliITSClusterFinderSSD::SeparateOverlappedClusters()
244 //************************************************
245 //Piotr Krzysztof Skowronski
246 //Warsaw University of Technology
247 //skowron@if.pw.edu.pl
249 register Int_t i; //iterator
251 Float_t factor=0.75; // How many percent must be lower signal
252 // on the middle one digit
253 // from its neighbours
254 Int_t signal0; //signal on the strip before the current one
255 Int_t signal1; //signal on the current one signal
256 Int_t signal2; //signal on the strip after the current one
257 TArrayI *splitlist; // List of splits
258 Int_t numerofsplits=0; // number of splits
259 Int_t initPsize = fNClusterP; //initial size of the arrays
260 Int_t initNsize = fNClusterN; //we have to keep it because it will grow
261 // in this function and it doasn't make
262 // sense to pass through it again
264 splitlist = new TArrayI(300);
266 for (i=0;i<initPsize;i++)
268 if (( ((AliITSclusterSSD*)(*fClusterP)[i])->GetNumOfDigits())==1) continue;
269 if (( ((AliITSclusterSSD*)(*fClusterP)[i])->GetNumOfDigits())==2) continue;
270 Int_t nj=(((AliITSclusterSSD*)(*fClusterP)[i])->GetNumOfDigits()-1);
271 for (Int_t j=1; j<nj; j++)
273 signal1=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j);
274 signal0=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j-1);
275 signal2=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j+1);
276 //if signal is less then factor*signal of its neighbours
277 if ( (signal1<(factor*signal0)) && (signal1<(factor*signal2)) )
279 (*splitlist)[numerofsplits++]=j;
281 } // end loop over number of digits
282 //split this cluster if necessary
283 if(numerofsplits>0) SplitCluster(splitlist,numerofsplits,i,fgkSIDEP);
286 //in signed places (splitlist)
287 } // end loop over clusters on Pside
289 for (i=0;i<initNsize;i++) {
290 if (( ((AliITSclusterSSD*)(*fClusterN)[i])->GetNumOfDigits())==1) continue;
291 if (( ((AliITSclusterSSD*)(*fClusterN)[i])->GetNumOfDigits())==2) continue;
292 Int_t nj=(((AliITSclusterSSD*)(*fClusterN)[i])->GetNumOfDigits()-1);
293 for (Int_t j=1; j<nj; j++)
295 signal1=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j);
296 signal0=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j-1);
297 signal2=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j+1);
298 //if signal is less then factor*signal of its neighbours
299 if ( (signal1<(factor*signal0)) && (signal1<(factor*signal2)) )
300 (*splitlist)[numerofsplits++]=j;
301 } // end loop over number of digits
302 //split this cluster into more clusters
303 if(numerofsplits>0) SplitCluster(splitlist,numerofsplits,i,fgkSIDEN);
304 numerofsplits=0; //in signed places (splitlist)
305 } // end loop over clusters on Nside
310 //-------------------------------------------------------
311 void AliITSClusterFinderSSD::SplitCluster(TArrayI *list, Int_t nsplits, Int_t index, Bool_t side)
315 //Piotr Krzysztof Skowronski
316 //Warsaw University of Technology
317 //skowron@if.pw.edu.pl
319 //This function splits one side cluster into more clusters
320 //number of splits is defined by "nsplits"
321 //Place of splits are defined in the TArray "list"
323 // For further optimisation: Replace this function by two
324 // specialised ones (each for one side)
327 //For comlete comments see AliITSclusterSSD::SplitCluster
330 register Int_t i; //iterator
332 AliITSclusterSSD* curentcluster;
333 Int_t *tmpdigits = new Int_t[100];
335 // side true means P side
337 curentcluster =((AliITSclusterSSD*)((*fClusterP)[index])) ;
338 for (i = nsplits; i>0 ;i--) {
339 NN=curentcluster->SplitCluster((*list)[(i-1)],tmpdigits);
340 new ((*fClusterP)[fNClusterP]) AliITSclusterSSD(NN,tmpdigits,fDigits,side);
341 ( (AliITSclusterSSD*)((*fClusterP)[fNClusterP]) )->
342 SetLeftNeighbour(kTRUE);
343 //if left cluster had neighbour on the right before split
344 //new should have it too
345 if ( curentcluster->GetRightNeighbour() )
346 ( (AliITSclusterSSD*)((*fClusterP)[fNClusterP]) )->
347 SetRightNeighbour(kTRUE);
348 else curentcluster->SetRightNeighbour(kTRUE);
350 } // end loop over nplits
352 curentcluster =((AliITSclusterSSD*)((*fClusterN)[index]));
353 for (i = nsplits; i>0 ;i--) {
354 NN=curentcluster->SplitCluster((*list)[(i-1)],tmpdigits);
355 new ((*fClusterN)[fNClusterN]) AliITSclusterSSD(NN,tmpdigits,fDigits,side);
356 ((AliITSclusterSSD*)((*fClusterN)[fNClusterN]))->
357 SetRightNeighbour(kTRUE);
358 if (curentcluster->GetRightNeighbour())
359 ( (AliITSclusterSSD*)( (*fClusterN)[fNClusterN]) )->
360 SetRightNeighbour(kTRUE);
361 else curentcluster->SetRightNeighbour(kTRUE);
363 } // end loop over nplits
370 //-------------------------------------------------
371 Int_t AliITSClusterFinderSSD::SortDigitsP(Int_t start, Int_t end)
375 //Piotr Krzysztof Skowronski
376 //Warsaw University of Technology
377 //skowron@if.pw.edu.pl
381 if (start != (end - 1) )
383 left=this->SortDigitsP(start,(start+end)/2);
384 right=this->SortDigitsP((start+end)/2,end);
385 return (left || right);
389 left = ((AliITSdigitSSD*)((*fDigits)[(*fDigitsIndexP)[start]]))->GetStripNumber();
390 right= ((AliITSdigitSSD*)((*fDigits)[(*fDigitsIndexP)[end]]))->GetStripNumber();
393 Int_t tmp = (*fDigitsIndexP)[start];
394 (*fDigitsIndexP)[start]=(*fDigitsIndexP)[end];
395 (*fDigitsIndexP)[end]=tmp;
403 //--------------------------------------------------
405 Int_t AliITSClusterFinderSSD::SortDigitsN(Int_t start, Int_t end)
409 //Piotr Krzysztof Skowronski
410 //Warsaw University of Technology
411 //skowron@if.pw.edu.pl
415 if (start != (end - 1))
417 left=this->SortDigitsN(start,(start+end)/2);
418 right=this->SortDigitsN((start+end)/2,end);
419 return (left || right);
423 left =((AliITSdigitSSD*)((*fDigits)[(*fDigitsIndexN)[start]]))->GetStripNumber();
424 right=((AliITSdigitSSD*)((*fDigits)[(*fDigitsIndexN)[end]]))->GetStripNumber();
427 Int_t tmp = (*fDigitsIndexN)[start];
428 (*fDigitsIndexN)[start]=(*fDigitsIndexN)[end];
429 (*fDigitsIndexN)[end]=tmp;
436 //------------------------------------------------
437 void AliITSClusterFinderSSD::FillDigitsIndex()
441 //Piotr Krzysztof Skowronski
442 //Warsaw University of Technology
443 //skowron@if.pw.edu.pl
445 //Fill the indexes of the clusters belonging to a given ITS module
446 //Created by Piotr K. Skowronski, August 7 1999
453 N = fDigits->GetEntriesFast();
455 Int_t* PSidx = new Int_t [N*sizeof(Int_t)];
456 Int_t* NSidx = new Int_t [N*sizeof(Int_t)];
457 if (fDigitsIndexP==NULL) fDigitsIndexP = new TArrayI(N);
458 if (fDigitsIndexN==NULL) fDigitsIndexN = new TArrayI(N);
462 for ( i = 0 ; i< N; i++ ) {
463 dig=(AliITSdigitSSD*)fDigits->UncheckedAt(i);
466 tmp=dig->GetStripNumber();
467 // I find this totally unnecessary - it's just a
468 // CPU consuming double check
473 if (debug) cout<<"Such a digit exists \n";
479 fDigitsIndexP->AddAt(i,fNDigitsP++);
484 tmp=dig->GetStripNumber();
490 if (debug) cout<<"Such a digit exists \n";
496 fDigitsIndexN->AddAt(i,fNDigitsN++);
503 if (debug) cout<<"Digits : P = "<<fNDigitsP<<" N = "<<fNDigitsN<<endl;
508 //-------------------------------------------
510 void AliITSClusterFinderSSD::SortDigits()
514 //Piotr Krzysztof Skowronski
515 //Warsaw University of Technology
516 //skowron@if.pw.edu.pl
522 for (i=0;i<fNDigitsP-1;i++)
523 if (SortDigitsP(0,(fNDigitsP-1-i))==0) break;
526 for (i=0;i<fNDigitsN-1;i++)
527 if(SortDigitsN(0,(fNDigitsN-1-i))==0) break;
532 //----------------------------------------------
533 void AliITSClusterFinderSSD::FillClIndexArrays(Int_t* arrayP, Int_t *arrayN)
537 //Piotr Krzysztof Skowronski
538 //Warsaw University of Technology
539 //skowron@if.pw.edu.pl
543 for (i=0; i<fNClusterP;i++)
547 for (i=0; i<fNClusterN;i++)
554 //------------------------------------------------------
555 void AliITSClusterFinderSSD::SortClusters(Int_t* arrayP, Int_t *arrayN)
559 //Piotr Krzysztof Skowronski
560 //Warsaw University of Technology
561 //skowron@if.pw.edu.pl
566 for (i=0;i<fNClusterP-1;i++)
567 if (SortClustersP(0,(fNClusterP-1),arrayP)==0) break;
571 for (i=0;i<fNClusterN-1;i++)
572 if (SortClustersN(0,(fNClusterN-1),arrayN)==0) break;
578 //---------------------------------------------------
579 Int_t AliITSClusterFinderSSD::SortClustersP(Int_t start, Int_t end, Int_t *array)
583 //Piotr Krzysztof Skowronski
584 //Warsaw University of Technology
585 //skowron@if.pw.edu.pl
591 if (start != (end - 1) ) {
592 left=this->SortClustersP(start,(start+end)/2,array);
593 right=this->SortClustersP((start+end)/2,end,array);
594 return (left || right);
596 left =((AliITSclusterSSD*)((*fClusterP)[array[start]]))->
598 right=((AliITSclusterSSD*)((*fClusterP)[array[ end ]]))->
601 Int_t tmp = array[start];
602 array[start]=array[end];
613 //-------------------------------------------------------
614 Int_t AliITSClusterFinderSSD::SortClustersN(Int_t start, Int_t end, Int_t *array)
618 //Piotr Krzysztof Skowronski
619 //Warsaw University of Technology
620 //skowron@if.pw.edu.pl
625 if (start != (end - 1) ) {
626 left=this->SortClustersN(start,(start+end)/2,array);
627 right=this->SortClustersN((start+end)/2,end,array);
628 return (left || right);
630 left =((AliITSclusterSSD*)((*fClusterN)[array[start]]))->
632 right=((AliITSclusterSSD*)((*fClusterN)[array[ end ]]))->
635 Int_t tmp = array[start];
636 array[start]=array[end];
646 //-------------------------------------------------------
647 void AliITSClusterFinderSSD::ClustersToPackages()
652 //Piotr Krzysztof Skowronski
653 //Warsaw University of Technology
654 //skowron@if.pw.edu.pl
657 Int_t *oneSclP = new Int_t[fNClusterP]; //I want to have sorted 1 S clusters
658 Int_t *oneSclN = new Int_t[fNClusterN]; //I can not sort it in TClonesArray
659 //so, I create table of indexes and
661 //I do not use TArrayI on purpose
662 // MB: well, that's not true that one
663 //cannot sort objects in TClonesArray
665 register Int_t i; //iterator
666 AliITSpackageSSD *currentpkg;
667 AliITSclusterSSD *currentP;
668 AliITSclusterSSD *currentN;
669 AliITSclusterSSD *fcurrN;
671 Int_t lastNclIndex=0; //index of last N sidecluster
672 Int_t Nclpack=0; //number of P clusters in current package
673 Int_t Pclpack=0; //number of N clusters in current package
678 Int_t tmplastNclIndex;
680 //Fills in One Side Clusters Index Array
681 FillClIndexArrays(oneSclP,oneSclN);
682 //Sorts filled Arrays
683 SortClusters(oneSclP,oneSclN);
687 new ((*fPackages)[0]) AliITSpackageSSD(fClusterP,fClusterN);
688 currentpkg = (AliITSpackageSSD*)((*fPackages)[0]);
690 //main loop on sorted P side clusters
692 for (i=0;i<fNClusterP;i++) {
693 //Take new P side cluster
694 currentP = GetPSideCluster(oneSclP[i]);
695 currentN = GetNSideCluster(oneSclN[lastNclIndex]);
696 // take a new P cluster or not ?
697 if(IsCrossing(currentP,currentN)) {
698 // don't take a new P cluster
700 currentP->AddCross(oneSclN[lastNclIndex]);
701 currentN->AddCross(oneSclP[i]);
702 currentpkg->AddPSideCluster(oneSclP[i]);
704 currentpkg->AddNSideCluster(oneSclN[lastNclIndex]);
707 //check if previous N side clusters crosses with it too
708 for(k=1;k<fSFB+1;k++) {
709 //check if we are not out of array
710 if ((lastNclIndex-k)>-1) {
711 fcurrN = GetNSideCluster( oneSclN[lastNclIndex-k] );
712 if( IsCrossing(currentP,fcurrN) ) {
713 currentP->AddCross(oneSclN[lastNclIndex-k]);
714 fcurrN->AddCross(oneSclP[i]);
715 } else break; //There is no sense to check rest of clusters
718 tmplastNclIndex=lastNclIndex;
719 //Check if next N side clusters crosses with it too
720 for (Int_t k=1;k<fSFF+1;k++) {
721 //check if we are not out of array
722 if ((tmplastNclIndex+k)<fNClusterN) {
723 fcurrN = GetNSideCluster( oneSclN[tmplastNclIndex+k] );
724 if(IsCrossing(currentP,fcurrN) ) {
726 fcurrN->AddCross(oneSclP[i]);
727 currentP->AddCross(oneSclN[tmplastNclIndex+k]);
728 currentpkg->AddNSideCluster(oneSclN[lastNclIndex]);
737 lastStripP = currentP->GetLastDigitStripNo();
738 lastStripN = currentN->GetLastDigitStripNo();
740 if((lastStripN-fSFF) < lastStripP ) {
742 if((Nclpack>0)&& (Pclpack>0)) {
743 new ((*fPackages)[fNPackages]) AliITSpackageSSD(fClusterP,fClusterN);
744 currentpkg = (AliITSpackageSSD*)((*fPackages)[fNPackages++]);
747 //so we have to take another cluster on side N and check it
748 //we have to check until taken cluster's last strip will
749 //be > last of this cluster(P)
750 //so it means that there is no corresponding cluster on side N
751 //to this cluster (P)
752 //so we have to continue main loop with new "lastNclIndex"
756 //We are not sure that next N cluter will cross with this P cluster
757 //There might one, or more, clusters that do not have any
758 //corresponding cluster on the other side
761 //Check if we are not out of array
762 if (lastNclIndex<fNClusterN) {
763 currentN = GetNSideCluster(oneSclN[lastNclIndex]);
764 if ( IsCrossing(currentP, currentN) ){
767 currentP->AddCross(oneSclN[lastNclIndex]);
768 currentN->AddCross(oneSclP[i]);
769 currentpkg->AddNSideCluster(oneSclN[lastNclIndex]);
770 currentpkg->AddPSideCluster(oneSclP[i]);
771 //Check, if next N side clusters crosses with it too
772 tmplastNclIndex=lastNclIndex;
773 for (Int_t k=1;k<fSFF+1;k++) {
774 //Check if we are not out of array
775 if ((tmplastNclIndex+k)<fNClusterN) {
776 fcurrN = GetNSideCluster(oneSclN[tmplastNclIndex+k]);
777 if( IsCrossing(currentP, fcurrN) ) {
780 currentP->AddCross(oneSclN[tmplastNclIndex+k]);
781 fcurrN->AddCross(oneSclP[i]);
782 currentpkg->AddNSideCluster(oneSclN[tmplastNclIndex+k]);
784 } else break; //we are out of array
788 firstStripP = currentP->GetFirstDigitStripNo();
789 firstStripN = currentN->GetFirstDigitStripNo();
790 if((firstStripN+fSFB)>=firstStripP) break;
793 } else goto EndOfFunction;
795 } else //EndOfPackage
798 } //else EndOfPackage
805 if ((Nclpack<1) || (Pclpack<1)) fNPackages--;
814 //-----------------------------------------------
815 void AliITSClusterFinderSSD::PackagesToPoints()
819 AliITSpackageSSD *currentpkg;
825 for (i=0;i<fNPackages;i++) {
826 //get pointer to next package
827 currentpkg = (AliITSpackageSSD*)((*fPackages)[i]);
828 NumNcl = currentpkg->GetNumOfClustersN();
829 NumPcl = currentpkg->GetNumOfClustersP();
830 if(debug) cout<<"New Package\nNumPcl ="<<NumPcl<<" NumNcl ="<<NumNcl<<"\n";
832 while(((NumPcl>=2)&&(NumNcl>2))||((NumPcl>2)&&(NumNcl>=2))) {
833 //This is case of "big" pacakage
834 //conditions see 3 lines above
835 //if in the big package exists cluster with one cross
836 //we can reconstruct this point without any geometrical ambiguities
837 if(currentpkg->GetClusterWithOneCross(clusterIndex, clusterSide) )
839 ResolveClusterWithOneCross(currentpkg, clusterIndex, clusterSide);
840 } else if (clusterIndex == -2) {
845 if ( (NumNcl==NumPcl) && (NumPcl<10)) {
846 //if there is no cluster with one cross
847 //we can resolve whole package at once
848 //by finding best combination
849 //we can make combinations when NumNcl==NumPcl
850 if (ResolvePackageBestCombin(currentpkg)) {
851 //sometimes creating combinations fail,
852 //but it happens very rarely
856 } else ResolveOneBestMatchingPoint(currentpkg);
858 ResolveOneBestMatchingPoint(currentpkg);
861 NumNcl = currentpkg->GetNumOfClustersN();
862 NumPcl = currentpkg->GetNumOfClustersP();
864 if ((NumPcl==1)&&(NumNcl==1)) {
865 ResolveSimplePackage(currentpkg);
869 ResolvePackageWithOnePSideCluster(currentpkg);
873 ResolvePackageWithOneNSideCluster(currentpkg);
876 if ((NumPcl==2)&&(NumNcl==2)) {
877 ResolveTwoForTwoPackage(currentpkg);
880 if ((NumPcl==0)&&(NumNcl>0)) { }
881 if ((NumNcl==0)&&(NumPcl>0)) { }
883 } // end loop over fNPackages
889 //----------------------------------------------------------
891 void AliITSClusterFinderSSD::
892 ResolveClusterWithOneCross(AliITSpackageSSD *currentpkg, Int_t clusterIndex, Bool_t clSide)
895 if (clSide == fgkSIDEP) ResolvePClusterWithOneCross(currentpkg,clusterIndex);
896 else ResolveNClusterWithOneCross(currentpkg,clusterIndex);
901 //---------------------------------------------------------
902 void AliITSClusterFinderSSD::
903 ResolvePClusterWithOneCross(AliITSpackageSSD *pkg, Int_t clusterIndex)
907 There is cluster (side P) which crosses with only one cluster on the other
923 AliITSclusterSSD * clusterP;
924 AliITSclusterSSD * clusterN;
926 Float_t posClusterP; //Cluster P position in strip coordinates
927 Float_t posClusterN; //Cluster N position in strip coordinates
929 Float_t posErrorClusterP;
930 Float_t posErrorClusterN;
935 Float_t sigErrorClusterP;
936 Float_t sigErrorClusterN;
944 if (debug) cout<<"ResolvePClusterWithOneCross\n";
946 clusterP=pkg->GetPSideCluster(clusterIndex);
947 posClusterP = GetClusterZ(clusterP);
948 posErrorClusterP = clusterP->GetPositionError();
949 sigClusterP = ps = clusterP->GetTotalSignal();
950 sigErrorClusterP = clusterP->GetTotalSignalError();
951 //carefully, it returns index in TClonesArray
953 clusterIdx = clusterP->GetCross(0);
954 clusterN=this->GetNSideCluster(clusterIdx);
955 ns = clusterN->GetTotalSignal();
956 posClusterN = GetClusterZ(clusterN);
957 posErrorClusterN = clusterN->GetPositionError();
958 pkg->DelCluster(clusterIndex,fgkSIDEP);
959 sigClusterN = ps/fPNsignalRatio;
960 // there is no sonse to check how signal ratio is far from perfect
961 // matching line if the if below it is true
962 if (ns < sigClusterN) {
964 if (debug) cout<<"n1 < p1/fPNsignalRatio";
965 if (debug) cout<<"Attempting to del cluster N "<<clusterIdx<<" ... \n";
966 pkg->DelClusterOI(clusterIdx,fgkSIDEN);
968 //Let's see how signal ratio is far from perfect matching line
969 Chicomb = DistToPML(ps,ns);
970 if (debug) cout<<"Chic "<<Chicomb<<"\n";
971 if (Chicomb > falpha2) {
972 //it is near, so we can risk throwing this cluster away too
973 if (debug) cout<<"Attempting to del cluster N "<<clusterIdx<<"...\n";
974 pkg->DelClusterOI(clusterIdx,fgkSIDEN);
976 clusterN->CutTotalSignal(sigClusterN);
977 if (debug) cout <<"Signal cut |||||||||||||\n";
980 sigErrorClusterN= clusterN->GetTotalSignalError();
981 CreateNewRecPoint(posClusterP,posErrorClusterP,posClusterN,posErrorClusterN,
982 sigClusterP+sigClusterN, sigErrorClusterN+sigErrorClusterP,
983 clusterP, clusterN, 0.75);
988 //------------------------------------------------------
989 void AliITSClusterFinderSSD::
990 ResolveNClusterWithOneCross(AliITSpackageSSD *pkg, Int_t clusterIndex)
993 AliITSclusterSSD * clusterP;
994 AliITSclusterSSD * clusterN;
996 Float_t posClusterP; //Cluster P position in strip coordinates
997 Float_t posClusterN; //Cluster N position in strip coordinates
999 Float_t posErrorClusterP;
1000 Float_t posErrorClusterN;
1002 Float_t sigClusterP;
1003 Float_t sigClusterN;
1005 Float_t sigErrorClusterP;
1006 Float_t sigErrorClusterN;
1014 if (debug) cout<<"ResolveNClusterWithOneCross\n";
1016 clusterN=pkg->GetNSideCluster(clusterIndex);
1017 posClusterN = GetClusterZ(clusterN);
1018 posErrorClusterN = clusterN->GetPositionError();
1019 sigClusterN = ns = clusterN->GetTotalSignal();
1020 sigErrorClusterN = clusterN->GetTotalSignalError();
1021 //carefully, it returns index in TClonesArray
1022 clusterIdx = clusterN->GetCross(0);
1023 clusterP=this->GetPSideCluster(clusterIdx);
1024 ps = clusterP->GetTotalSignal();
1025 posClusterP = GetClusterZ(clusterP);
1026 posErrorClusterP = clusterP->GetPositionError();
1027 pkg->DelCluster(clusterIndex,fgkSIDEN);
1028 sigClusterP=ns*fPNsignalRatio;
1029 // there is no sonse to check how signal ratio is far from perfect
1030 // matching line if the if below it is true
1031 if (ps < sigClusterP) {
1033 if (debug) cout<<"ps < ns*fPNsignalRatio";
1034 if (debug) cout<<"Attempting to del cluster P "<<clusterIdx<<" ... \n";
1035 pkg->DelClusterOI(clusterIdx,fgkSIDEP);
1037 //Let's see how signal ratio is far from perfect matching line
1038 Chicomb = DistToPML(ps,ns);
1039 if (debug) cout<<"Chic "<<Chicomb<<"\n";
1040 if (Chicomb > falpha2) {
1041 //it is near, so we can risk frowing this cluster away too
1042 if (debug) cout<<"Attempting to del cluster P "<<clusterIdx<<"...\n";
1043 pkg->DelClusterOI(clusterIdx,fgkSIDEP);
1045 clusterN->CutTotalSignal(sigClusterP);
1046 if (debug) cout <<"Signal cut ------------\n";
1049 sigErrorClusterP= clusterP->GetTotalSignalError();
1050 CreateNewRecPoint( posClusterP,posErrorClusterP,posClusterN,posErrorClusterN,
1051 sigClusterP+sigClusterN,sigErrorClusterN+sigErrorClusterP,
1052 clusterP, clusterN, 0.75);
1059 //-------------------------------------------------------
1061 Bool_t AliITSClusterFinderSSD::
1062 ResolvePackageBestCombin(AliITSpackageSSD *pkg)
1064 if (debug) cout<<"NumNcl==NumPcl ("<<pkg->GetNumOfClustersN()
1065 <<"=="<<pkg->GetNumOfClustersP()<<"); Generating combinations ... \n";
1068 AliITSclusterSSD * clusterP;
1069 AliITSclusterSSD * clusterN;
1071 Int_t Ncombin; //Number of combinations
1072 Int_t itera; //iterator
1073 Int_t sizet=1; //size of array to allocate
1075 Int_t NP = pkg->GetNumOfClustersP();
1076 for (itera =2; itera <= NP ;itera ++) {
1078 if (sizet > 10000) {
1084 Int_t** combin = new Int_t*[sizet]; //2D array to keep combinations in
1086 for (itera =0; itera <sizet;itera++) {
1087 combin[itera] = new Int_t[NP+1];
1090 pkg->GetAllCombinations(combin,Ncombin,sizet);
1093 if (debug) cout<<"No combin Error";
1096 //calculate which combination fits the best to perfect matching line
1097 Int_t bc = GetBestComb(combin,Ncombin,NP,pkg);
1098 if (debug) cout<<" bc "<<bc <<"\n";
1100 for (itera =0; itera < NP; itera ++) {
1101 clusterP = pkg->GetPSideCluster(itera);
1103 //becase AliITSclusterSSD::GetCross returns index in
1104 //AliITSmoduleSSD.fClusterP, which is put to "combin"
1105 clusterN = GetNSideCluster(combin[bc][itera]);
1106 CreateNewRecPoint(clusterP, clusterN, 0.75);
1109 for (itera =0; itera <sizet;itera++) {
1110 delete [](combin[itera]);
1118 //----------------------------------------------------
1119 void AliITSClusterFinderSSD::
1120 ResolveOneBestMatchingPoint(AliITSpackageSSD *pkg)
1126 Int_t nextP, nextN=0;
1129 AliITSclusterSSD * clusterP;
1130 AliITSclusterSSD * clusterN;
1132 Bool_t split = kFALSE;
1134 if (debug) cout<<"ResolveOneBestMatchingPoint \n";
1136 GetBestMatchingPoint(pi, ni, pkg);
1138 clusterP = GetPSideCluster(pi);
1139 clusterN = GetNSideCluster(ni);
1141 CreateNewRecPoint(clusterP, clusterN, 0.75);
1143 if ((nextP=pkg->GetNextPIdx(pi))!=-1)
1144 if ((nextN=pkg->GetNextNIdx(ni))!=-1)
1145 if ((prvP=pkg->GetPrvPIdx(pi))!=-1)
1146 if ((prvN=pkg->GetPrvNIdx(ni))!=-1)
1147 if( !(GetPSideCluster(prvP)->IsCrossingWith(nextN)))
1148 if( !(GetPSideCluster(nextP)->IsCrossingWith(prvN)))
1154 pkg->DelClusterOI(pi, fgkSIDEP);
1155 pkg->DelClusterOI(ni, fgkSIDEN);
1158 if (debug) cout<<"spltting package ...\n";
1159 new ((*fPackages)[fNPackages]) AliITSpackageSSD(fClusterP,fClusterN);
1161 SplitPackage(nextP,nextN,(AliITSpackageSSD*)((*fPackages)[fNPackages++]));
1167 //--------------------------------------------------
1168 void AliITSClusterFinderSSD::ResolveSimplePackage(AliITSpackageSSD *pkg)
1171 AliITSclusterSSD * clusterP;
1172 AliITSclusterSSD * clusterN;
1174 clusterP = pkg->GetPSideCluster(0);
1176 clusterN = pkg->GetNSideCluster(0);
1178 CreateNewRecPoint(clusterP, clusterN, 1.0);
1184 //--------------------------------------------------
1185 void AliITSClusterFinderSSD:: ResolvePackageWithOnePSideCluster(AliITSpackageSSD *pkg) {
1201 /************************/
1202 /**************************/
1203 /*XP SP itg jest tylko jeden nie musi byc tablica i w peetli nie trzeba po niej iterowcac*/
1204 /***************************/
1208 AliITSclusterSSD * clusterP;
1209 AliITSclusterSSD * clusterN;
1211 Int_t NN=pkg->GetNumOfClustersN();
1217 Float_t * XN = new Float_t[NN];
1218 Float_t * XNerr = new Float_t[NN];
1220 Float_t * SP = new Float_t[NN];
1221 Float_t * SN = new Float_t[NN];
1223 Float_t * SPerr = new Float_t[NN];
1224 Float_t * SNerr = new Float_t[NN];
1229 clusterP = pkg->GetPSideCluster(0);
1230 p1 = clusterP->GetTotalSignal();
1232 XP = GetClusterZ(clusterP);
1233 XPerr = clusterP->GetPositionError();
1234 p1err = clusterP->GetTotalSignalError();
1236 for (k=0;k<NN;k++) {
1237 SN[k] = pkg->GetNSideCluster(k)->GetTotalSignal();
1238 SNerr[k] = pkg->GetNSideCluster(k)->GetTotalSignalError();
1241 for (k=0;k<NN;k++) {
1242 clusterN = pkg->GetNSideCluster(k);
1243 SP[k]= p1*SN[k]/sumsig;
1244 SPerr[k] = p1err*SN[k]/sumsig;
1245 XN[k]=GetClusterZ(clusterN);
1246 XNerr[k]= clusterN->GetPositionError();
1247 CreateNewRecPoint(XP,XPerr, XN[k],XNerr[k], SP[k]+SN[k], SPerr[k]+SNerr[k], clusterP, clusterN, 1.0);
1254 //---------------------------------------------------------
1255 void AliITSClusterFinderSSD::ResolvePackageWithOneNSideCluster(AliITSpackageSSD *pkg) {
1272 AliITSclusterSSD * clusterP;
1273 AliITSclusterSSD * clusterN;
1275 Int_t NP=pkg->GetNumOfClustersP();
1278 Float_t * XP = new Float_t[NP];
1279 Float_t * XPerr = new Float_t[NP];
1284 Float_t * SP = new Float_t[NP];
1285 Float_t * SN = new Float_t[NP];
1287 Float_t * SPerr = new Float_t[NP];
1288 Float_t * SNerr = new Float_t[NP];
1293 clusterN = pkg->GetNSideCluster(0);
1294 n1 = clusterN->GetTotalSignal();
1296 XN = GetClusterZ(clusterN);
1297 XNerr = clusterN->GetPositionError();
1299 n1err=clusterN->GetTotalSignalError();
1301 for (k=0;k<NP;k++) {
1302 SP[k] = pkg->GetPSideCluster(k)->GetTotalSignal();
1304 SPerr[k] = pkg->GetPSideCluster(k)->GetTotalSignalError();
1307 for (k=0;k<NP;k++) {
1308 clusterP = pkg->GetPSideCluster(k);
1309 SN[k]= n1*SP[k]/sumsig;
1310 XP[k]=GetClusterZ(clusterP);
1311 XPerr[k]= clusterP->GetPositionError();
1312 SNerr[k] = n1err*SP[k]/sumsig;
1313 CreateNewRecPoint(XP[k],XPerr[k], XN,XNerr, SP[k]+SN[k], SPerr[k]+SNerr[k],clusterP, clusterN, 1.0);
1319 /**********************************************************************/
1320 /********* 2 X 2 *********************************************/
1321 /**********************************************************************/
1323 void AliITSClusterFinderSSD::
1324 ResolveTwoForTwoPackage(AliITSpackageSSD *pkg)
1327 AliITSclusterSSD *clusterP1 = pkg->GetPSideCluster(0);
1328 AliITSclusterSSD *clusterP2 = pkg->GetPSideCluster(1);
1329 AliITSclusterSSD *clusterN1 = pkg->GetNSideCluster(0);
1330 AliITSclusterSSD *clusterN2 = pkg->GetNSideCluster(1);
1332 AliITSclusterSSD *tmp;
1359 if(clusterP1->GetDigitStripNo(0) > clusterP2->GetDigitStripNo(0)) {
1360 if (debug) cout<<"P strips flip\n";
1362 clusterP1 = clusterP2;
1365 if(clusterN1->GetDigitStripNo(0) > clusterN2->GetDigitStripNo(0)) {
1366 if (debug) cout<<"N strips flip\n";
1368 clusterN1 = clusterN2;
1371 p1sig = clusterP1->GetTotalSignal();
1372 p2sig = clusterP2->GetTotalSignal();
1373 n1sig = clusterN1->GetTotalSignal();
1374 n2sig = clusterN2->GetTotalSignal();
1377 p1sigErr = clusterP1->GetTotalSignalError();
1378 n1sigErr = clusterN1->GetTotalSignalError();
1379 p2sigErr = clusterP2->GetTotalSignalError();
1380 n2sigErr = clusterN2->GetTotalSignalError();
1382 ZposP1 = clusterP1->GetPosition();
1383 ZposN1 = clusterN1->GetPosition();
1384 ZposP2 = clusterP2->GetPosition();
1385 ZposN2 = clusterN2->GetPosition();
1387 ZposErrP1 = clusterP1->GetPositionError();
1388 ZposErrN1 = clusterN1->GetPositionError();
1389 ZposErrP2 = clusterP2->GetPositionError();
1390 ZposErrN2 = clusterN2->GetPositionError();
1392 //in this may be two types:
1393 // 1.When each cluster crosses with 2 clusters on the other side
1394 // gives 2 ghosts and 2 real points
1396 // 2.When two clusters (one an each side) crosses with only one on
1397 // the other side and two crosses (one on the each side) with
1398 // two on the other gives 2 or 3 points,
1400 if (debug) cout<<"2 for 2 ambiguity ...";
1401 /***************************/
1402 /*First sort of combination*/
1403 /***************************/
1405 if((clusterP1->GetCrossNo()==2) && (clusterN1->GetCrossNo()==2)) {
1406 if (debug) cout<<"All clusters has 2 crosses\n";
1407 D12 = TMath::Sqrt((Float_t)((p1sig -p2sig)*(p1sig -p2sig) + (n1sig -n2sig)*(n1sig -n2sig)));
1409 if(debug) cout<<"Distance between points in P(N) plane D12 = "<<D12<<"\n";
1411 /*********************************************/
1412 /*resolving ambiguities: */
1413 /*we count Chicomb's and we take combination */
1414 /*giving lower Chicomb as a real points */
1415 /*Keep only better combinantion */
1416 /*********************************************/
1418 if (D12 > (falpha3*17.8768)) {
1419 if (debug) cout<<"decided to take only one pair \n";
1420 Chicomb1 = DistToPML(p1sig,n1sig) + DistToPML(p2sig,n2sig);
1421 Chicomb2 = DistToPML(p2sig,n1sig) + DistToPML(p1sig,n2sig);
1423 cout<<" 00 11 combination : "<<Chicomb1<<" 01 10 combination : "<<Chicomb2<<" \n";
1424 cout<<"p1 = "<<p1sig<<" n1 = "<<n1sig<<" p2 = "<<p2sig<<" n2 = "<<n2sig<<"\n";
1426 if (Chicomb1 < Chicomb2) {
1427 if (debug) cout<<"00 11";
1428 CreateNewRecPoint(ZposP1,ZposErrP1, ZposN1,ZposErrN1, p1sig+n1sig, p1sigErr+n1sigErr, clusterP1, clusterN1, 0.75);
1429 CreateNewRecPoint(ZposP2,ZposErrP2, ZposN2,ZposErrN2, p2sig+n2sig, p2sigErr+n2sigErr, clusterP2, clusterN2, 0.75);
1432 //second cominantion
1434 if (debug) cout<<"01 10";
1435 CreateNewRecPoint(ZposP1,0, ZposN2,0, p1sig+n2sig, p1sigErr+n2sigErr, clusterP1, clusterN2, 0.75);
1436 CreateNewRecPoint(ZposP2,0, ZposN1,0, p2sig+n1sig, p2sigErr+n1sigErr, clusterP2, clusterN1, 0.75);
1437 } //end second combinantion
1438 //if (D12 > falpha3*17.8768)
1439 //keep all combinations
1441 if (debug) cout<<"We decide to take all points\n";
1442 CreateNewRecPoint(ZposP1,ZposErrP1, ZposN1,ZposErrN1, p1sig+n1sig, p1sigErr+n1sigErr, clusterP1, clusterN1, 0.5);
1443 CreateNewRecPoint(ZposP2,ZposErrP2, ZposN2,ZposErrN2, p2sig+n2sig, p2sigErr+n2sigErr, clusterP2, clusterN2, 0.5);
1444 CreateNewRecPoint(ZposP1,ZposErrP1, ZposN2,ZposErrN2, p1sig+n2sig, p1sigErr+n2sigErr, clusterP1, clusterN2, 0.5);
1445 CreateNewRecPoint(ZposP2,ZposErrP2, ZposN1,ZposErrN1, p2sig+n1sig, p2sigErr+n1sigErr, clusterP2, clusterN1, 0.5);
1448 // ad.2 Second type of combination
1450 Chicomb1 = DistToPML(p1sig,n1sig) + DistToPML(p2sig,n2sig);
1451 if (debug) cout<<"\nhere can be reconstructed 3 points: chicomb = "<<Chicomb1<<"\n";
1453 if (Chicomb1<falpha1) {
1454 if (debug) cout<<"\nWe decided to take 3rd point";
1455 if (clusterP1->GetCrossNo()==1) {
1456 if (debug) cout<<"... P1 has one cross\n";
1457 n1sig = p1sig/fPNsignalRatio;
1458 p2sig = n2sig*fPNsignalRatio;
1460 clusterN1->CutTotalSignal(n1sig);
1461 clusterP2->CutTotalSignal(p2sig);
1463 CreateNewRecPoint(ZposP2,ZposErrP2, ZposN1,ZposErrN1, p2sig+n1sig, p2sigErr+n1sigErr, clusterP2, clusterN1, 0.5);
1465 n1sig = clusterN1->GetTotalSignal();
1466 p2sig = clusterP2->GetTotalSignal();
1469 if (debug) cout<<"... N1 has one cross\n";
1471 n2sig=p2sig/fPNsignalRatio;
1472 p1sig=n1sig*fPNsignalRatio;
1474 clusterN2->CutTotalSignal(n2sig);
1475 clusterP1->CutTotalSignal(p1sig);
1477 CreateNewRecPoint(ZposP1,ZposErrP1, ZposN2,ZposErrN2, p1sig+n2sig, p1sigErr+n2sigErr, clusterP1, clusterN2, 0.5);
1479 n2sig=clusterN2->GetTotalSignal();
1480 p1sig=clusterP1->GetTotalSignal();
1483 if (debug) cout<<"\nWe decided NOT to take 3rd point\n";
1486 CreateNewRecPoint(ZposP1,ZposErrP1, ZposN1,ZposErrN1, p1sig+n1sig, p1sigErr+n1sigErr, clusterP1, clusterN1, 1.0);
1487 CreateNewRecPoint(ZposP2,ZposErrP2, ZposN2,ZposErrN2, p2sig+n2sig, p2sigErr+n2sigErr, clusterP2, clusterN2, 1.0);
1495 //------------------------------------------------------
1496 Bool_t AliITSClusterFinderSSD::
1497 CreateNewRecPoint(Float_t P, Float_t dP, Float_t N, Float_t dN,
1498 Float_t Sig,Float_t dSig,
1499 AliITSclusterSSD *clusterP, AliITSclusterSSD *clusterN,
1503 const Float_t kdEdXtoQ = 2.778e+8;
1504 const Float_t kconv = 1.0e-4;
1505 const Float_t kRMSx = 20.0*kconv; // microns->cm ITS TDR Table 1.3
1506 const Float_t kRMSz = 830.0*kconv; // microns->cm ITS TDR Table 1.3
1511 Int_t stripP, stripN;
1513 AliITSdigitSSD *digP, *digN;
1514 if (GetCrossing(P,N)) {
1515 GetCrossingError(dP,dN);
1516 AliITSRawClusterSSD cnew;
1517 Int_t nstripsP=clusterP->GetNumOfDigits();
1518 Int_t nstripsN=clusterN->GetNumOfDigits();
1519 cnew.fMultiplicity=nstripsP;
1520 cnew.fMultiplicityN=nstripsN;
1522 if (nstripsP > 100) {
1523 printf("multiplicity > 100 - increase the dimension of the arrays %d\n",nstripsP);
1526 for(int i=0;i<nstripsP;i++) {
1527 // check if 'clusterP->GetDigitStripNo(i)' returns the digit index
1528 cnew.fIndexMap[i] = clusterP->GetDigitStripNo(i);
1530 if (nstripsN > 100) {
1531 printf("multiplicity > 100 - increase the dimension of the arrays %d\n",nstripsN);
1534 for(int i=0;i<nstripsN;i++) {
1535 // check if 'clusterN->GetDigitStripNo(i)' returns the digit index
1536 cnew.fIndexMapN[i] = clusterN->GetDigitStripNo(i);
1540 //cnew.fProbability=(float)prob;
1541 fITS->AddCluster(2,&cnew);
1542 fSegmentation->GetPadIxz(P,N,stripP,stripN);
1543 digP = (AliITSdigitSSD*)fMap->GetHit(1,stripP);
1544 digN = (AliITSdigitSSD*)fMap->GetHit(0,stripN);
1545 sigP = digP->fSignal;
1546 sigN = digN->fSignal;
1547 // add the rec point info
1548 AliITSRecPoint rnew;
1552 rnew.SetdEdX(Sig/kdEdXtoQ);
1553 rnew.SetSigmaX2( kRMSx* kRMSx);
1554 rnew.SetSigmaZ2( kRMSz* kRMSz);
1555 rnew.SetProbability((float)prob);
1557 rnew.fTracks[0]=digP->fTracks[0];
1558 rnew.fTracks[1]=digP->fTracks[1];
1559 rnew.fTracks[2]=digP->fTracks[2];
1561 rnew.fTracks[0]=digN->fTracks[0];
1562 rnew.fTracks[1]=digN->fTracks[1];
1563 rnew.fTracks[2]=digN->fTracks[2];
1565 fITS->AddRecPoint(rnew);
1568 fPointsM->AddLast( (TObject*)
1569 new AliITSRecPointSSD(P,dP,0,0,N,dN,Sig,dSig,fLayer,fLad,fDet,clusterP,clusterN,prob) );
1572 if(debug) cout<<"\n"<<": ImpactPoint Created: X = "<<P<<" Z = "<<N<<"; P = "<<p<<" N = "<<n<<"\n";
1576 cout<<"\n"<<": ATENTION : stupid ImpactPoit Point X = "<<P<<" Z = "<<N<<"; P = "<<p<<" N = "<<n<<"\n";
1584 /**********************************************************************/
1585 Bool_t AliITSClusterFinderSSD::
1586 CreateNewRecPoint(AliITSclusterSSD *clusterP, AliITSclusterSSD *clusterN, Stat_t prob)
1588 Float_t posClusterP; //Cluster P position in strip coordinates
1589 Float_t posClusterN; //Cluster N position in strip coordinates
1591 Float_t posErrorClusterP;
1592 Float_t posErrorClusterN;
1594 Float_t sigClusterP;
1595 Float_t sigClusterN;
1597 Float_t sigErrorClusterP;
1598 Float_t sigErrorClusterN;
1600 posClusterP = clusterP->GetPosition();
1601 posErrorClusterP = clusterP->GetPositionError();
1602 sigClusterP = clusterP->GetTotalSignal();
1603 sigErrorClusterP = clusterP->GetTotalSignalError();
1605 posClusterN = clusterN->GetPosition();
1606 posErrorClusterN = clusterN->GetPositionError();
1607 sigClusterN = clusterN->GetTotalSignal();
1608 sigErrorClusterN = clusterN->GetTotalSignalError();
1610 return CreateNewRecPoint( posClusterP,posErrorClusterP, posClusterN,posErrorClusterN,
1611 sigClusterP+sigClusterN, sigErrorClusterN+sigErrorClusterP,
1612 clusterP, clusterN, prob);
1616 //--------------------------------------------------
1617 Bool_t AliITSClusterFinderSSD::IsCrossing(AliITSclusterSSD* p, AliITSclusterSSD* n)
1619 Float_t x = p->GetPosition();
1620 Float_t y = n->GetPosition();
1621 return GetCrossing(x,y);
1625 //----------------------------------------------
1626 Bool_t AliITSClusterFinderSSD::Strip2Local( Float_t stripP, Float_t stripN, Float_t &Z,Float_t &X)
1630 //Piotr Krzysztof Skowronski
1631 //Warsaw University of Technology
1632 //skowron@if.pw.edu.pl
1635 Z = (stripN-stripP)*fFactorOne;
1636 X = (stripN + stripP - fStripZeroOffset)*fFactorTwo;
1645 if (debug) cout<<"P="<<stripP<<" N="<<stripN<<" X = "<<X<<" Z = "<<Z<<"\n";
1646 if ((Z<2.1)&&(Z>-2.1)&&(X<3.65)&&(X>-3.65)) return kTRUE;
1652 //-----------------------------------------------------------
1653 Float_t AliITSClusterFinderSSD::GetClusterZ(AliITSclusterSSD* clust)
1656 return clust->GetPosition();
1660 //-------------------------------------------------------------
1661 Int_t AliITSClusterFinderSSD::GetBestComb
1662 (Int_t** comb,Int_t Ncomb, Int_t Ncl, AliITSpackageSSD * pkg)
1666 //Piotr Krzysztof Skowronski
1667 //Warsaw University of Technology
1668 //skowron@if.pw.edu.pl
1670 //returns index of best combination in "comb"
1671 //comb : sets of combinations
1672 // in given combination on place "n" is index of
1673 // Nside cluster coresponding to "n" P side cluster
1675 //Ncomb : number of combinations == number of rows in "comb"
1677 //Ncl : number of clusters in each row == number of columns in "comb"
1682 Float_t currbval=-1; //current best value,
1683 //starting value is set to number negative,
1684 //to be changed in first loop turn automatically
1686 Int_t curridx=0; //index of combination giving currently the best chi^2
1688 Float_t ps, ns; //signal of P cluster and N cluster
1690 for (Int_t i=0;i<Ncomb;i++)
1694 for (Int_t j=0;j<Ncl;j++)
1696 ps = pkg->GetPSideCluster(j)->GetTotalSignal(); //carrefully here, different functions
1697 ns = GetNSideCluster(comb[i][j])->GetTotalSignal();
1698 chi+=DistToPML(ps,ns);
1701 if (currbval==-1) currbval = chi;
1714 //--------------------------------------------------
1715 void AliITSClusterFinderSSD::GetBestMatchingPoint
1716 (Int_t & ip, Int_t & in, AliITSpackageSSD* pkg )
1720 //Piotr Krzysztof Skowronski
1721 //Warsaw University of Technology
1722 //skowron@if.pw.edu.pl
1724 if (debug) pkg->PrintClusters();
1726 Float_t ps, ns; //signals on side p & n
1728 Int_t nc; // number of crosses in given p side cluster
1730 AliITSclusterSSD *curPcl, *curNcl; //current p side cluster
1731 Float_t bestchi, chi;
1732 ip=p=pkg->GetPSideClusterIdx(0);
1733 in=n=pkg->GetNSideClusterIdx(0);
1735 bestchi=DistToPML( pkg->GetPSideCluster(0)->GetTotalSignal(),
1736 pkg->GetNSideCluster(0)->GetTotalSignal() );
1737 for (Int_t i = 0; i< pkg->GetNumOfClustersP(); i++)
1740 p = pkg->GetPSideClusterIdx(i);
1741 curPcl= GetPSideCluster(p);
1742 nc=curPcl->GetCrossNo();
1743 ps=curPcl->GetTotalSignal();
1745 for (Int_t j = 0; j< nc; j++)
1747 n=curPcl->GetCross(j);
1748 curNcl= GetNSideCluster(n);
1749 ns=curNcl->GetTotalSignal();
1750 chi = DistToPML(ps, ns);
1764 //------------------------------------------------------
1765 void AliITSClusterFinderSSD::CalcStepFactor(Float_t Psteo, Float_t Nsteo )
1769 //Piotr Krzysztof Skowronski
1770 //Warsaw University of Technology
1771 //skowron@if.pw.edu.pl
1774 // 95 is the pitch, 4000 - dimension along z ?
1776 fSFF = ( (Int_t) (Psteo*40000/95 ) );// +1;
1777 fSFB = ( (Int_t) (Nsteo*40000/95 ) );// +1;
1781 Float_t dz=fSegmentation->Dz();
1783 fSFF = ( (Int_t) (Psteo*dz/fPitch ) );// +1;
1784 fSFB = ( (Int_t) (Nsteo*dz/fPitch ) );// +1;
1789 //-----------------------------------------------------------
1790 AliITSclusterSSD* AliITSClusterFinderSSD::GetPSideCluster(Int_t idx)
1794 //Piotr Krzysztof Skowronski
1795 //Warsaw University of Technology
1796 //skowron@if.pw.edu.pl
1800 if((idx<0)||(idx>=fNClusterP))
1802 printf("AliITSClusterFinderSSD::GetPSideCluster : index out of range\n");
1807 return (AliITSclusterSSD*)((*fClusterP)[idx]);
1811 //-------------------------------------------------------
1812 AliITSclusterSSD* AliITSClusterFinderSSD::GetNSideCluster(Int_t idx)
1816 //Piotr Krzysztof Skowronski
1817 //Warsaw University of Technology
1818 //skowron@if.pw.edu.pl
1820 if((idx<0)||(idx>=fNClusterN))
1822 printf("AliITSClusterFinderSSD::GetNSideCluster : index out of range\n");
1827 return (AliITSclusterSSD*)((*fClusterN)[idx]);
1831 //--------------------------------------------------------
1832 AliITSclusterSSD* AliITSClusterFinderSSD::GetCluster(Int_t idx, Bool_t side)
1836 //Piotr Krzysztof Skowronski
1837 //Warsaw University of Technology
1838 //skowron@if.pw.edu.pl
1840 return (side) ? GetPSideCluster(idx) : GetNSideCluster(idx);
1844 //--------------------------------------------------------
1845 void AliITSClusterFinderSSD::ConsumeClusters()
1849 for ( Int_t i=0;i<fNPackages;i++)
1851 ((AliITSpackageSSD*)((*fPackages)[i]))->ConsumeClusters();
1857 //--------------------------------------------------------
1858 void AliITSClusterFinderSSD::ReconstructNotConsumedClusters()
1861 AliITSclusterSSD *cluster;
1865 Float_t x1,x2,z1,z2;
1867 Float_t Dx = fSegmentation->Dx();
1868 Float_t Dz = fSegmentation->Dz();
1870 const Float_t kdEdXtoQ = 2.778e+8; // GeV -> number of e-hole pairs
1871 const Float_t kconv = 1.0e-4;
1872 const Float_t kRMSx = 20.0*kconv; // microns->cm ITS TDR Table 1.3
1873 const Float_t kRMSz = 830.0*kconv; // microns->cm ITS TDR Table 1.3
1875 Int_t stripP,stripN;
1876 AliITSdigitSSD *dig;
1877 for (i=0;i<fNClusterP;i++)
1879 cluster = GetPSideCluster(i);
1880 if (!cluster->IsConsumed())
1882 if( (pos = cluster->GetPosition()) < fSFB)
1884 sig = cluster->GetTotalSignal();
1886 sig += sig/fPNsignalRatio;
1888 sigerr = cluster->GetTotalSignalError();
1889 x1 = -Dx/2 + pos *fPitch;
1894 GetCrossing (x2,z2);
1895 AliITSRawClusterSSD cnew;
1896 Int_t nstripsP=cluster->GetNumOfDigits();
1897 cnew.fMultiplicity=nstripsP;
1898 cnew.fMultiplicityN=0;
1900 if (nstripsP > 100) {
1901 printf("multiplicity > 100 - increase the dimension of the arrays %d\n",nstripsP);
1904 for(int k=0;k<nstripsP;k++) {
1905 // check if 'clusterP->GetDigitStripNo(i)' returns
1906 // the digit index and not smth else
1907 cnew.fIndexMap[k] = cluster->GetDigitStripNo(k);
1911 //cnew.fProbability=0.75;
1912 fITS->AddCluster(2,&cnew);
1913 fSegmentation->GetPadIxz((x1+x2)/2,(z1+z2)/2,stripP,stripN);
1914 dig = (AliITSdigitSSD*)fMap->GetHit(1,stripP);
1915 // add the rec point info
1916 AliITSRecPoint rnew;
1917 rnew.SetX(kconv*(x1+x2)/2);
1918 rnew.SetZ(kconv*(z1+z2)/2);
1920 rnew.SetdEdX(sig/kdEdXtoQ);
1921 rnew.SetSigmaX2( kRMSx* kRMSx);
1922 rnew.SetSigmaZ2( kRMSz* kRMSz);
1923 rnew.SetProbability(0.75);
1924 rnew.fTracks[0]=dig->fTracks[0];
1925 rnew.fTracks[1]=dig->fTracks[1];
1926 rnew.fTracks[2]=dig->fTracks[2];
1927 fITS->AddRecPoint(rnew);
1929 fPointsM->AddLast( (TObject*)
1930 new AliITSRecPointSSD((x1+x2)/2 ,0,0,0,(z1+z2)/2,0,sig,sigerr,fLayer,fLad,fDet,cluster, 0.75) );
1933 if(debug) cout<<"\n"<<": SINGLE SIDE ImpactPoint Created: X = "
1934 <<(x1+x2)/2<<" Z = "<<(z1+z2)/2<<"; Pos = "<<pos;
1939 for (i=0;i<fNClusterN;i++)
1941 cluster = GetNSideCluster(i);
1942 if (!cluster->IsConsumed())
1944 if( (pos = cluster->GetPosition()) < fSFF)
1946 sig = cluster->GetTotalSignal();
1948 sig += sig*fPNsignalRatio;
1950 sigerr = cluster->GetTotalSignalError();
1952 x1 = -Dx/2 + pos *fPitch;
1958 GetCrossing (x2,z2);
1959 AliITSRawClusterSSD cnew;
1960 Int_t nstripsN=cluster->GetNumOfDigits();
1961 cnew.fMultiplicity=0;
1962 cnew.fMultiplicityN=nstripsN;
1964 if (nstripsN > 100) {
1965 printf("multiplicity > 100 - increase the dimension of the arrays %d\n",nstripsN);
1968 for(int k=0;k<nstripsN;k++) {
1969 // check if 'clusterP->GetDigitStripNo(i)' returns
1970 // the digit index and not smth else
1971 cnew.fIndexMapN[k] = cluster->GetDigitStripNo(k);
1975 //cnew.fProbability=0.75;
1976 fITS->AddCluster(2,&cnew);
1977 // add the rec point info
1978 fSegmentation->GetPadIxz((x1+x2)/2,(z1+z2)/2,stripP,stripN);
1979 dig = (AliITSdigitSSD*)fMap->GetHit(0,stripN);
1980 AliITSRecPoint rnew;
1981 rnew.SetX(kconv*(x1+x2)/2);
1982 rnew.SetZ(kconv*(z1+z2)/2);
1984 rnew.SetdEdX(sig/kdEdXtoQ);
1985 rnew.SetSigmaX2( kRMSx* kRMSx);
1986 rnew.SetSigmaZ2( kRMSz* kRMSz);
1987 rnew.SetProbability(0.75);
1988 rnew.fTracks[0]=dig->fTracks[0];
1989 rnew.fTracks[1]=dig->fTracks[1];
1990 rnew.fTracks[2]=dig->fTracks[2];
1991 fITS->AddRecPoint(rnew);
1993 fPointsM->AddLast( (TObject*)
1994 new AliITSRecPointSSD((x1+x2)/2 ,0,0,0,(z1+z2)/2,0,sig,sigerr,fLayer,fLad,fDet,cluster, 0.75) );
1997 if(debug) cout<<"\n"<<": SINGLE SIDE ImpactPoint Created: X = "
1998 <<(x1+x2)/2<<" Z = "<<(z1+z2)/2<<"; Pos = "<<pos;
2007 //_______________________________________________________________________
2009 Bool_t AliITSClusterFinderSSD::GetCrossing (Float_t &P, Float_t &N)
2012 Float_t Dx = fSegmentation->Dx();
2013 Float_t Dz = fSegmentation->Dz();
2022 //P = (kZ * fTan + N + P)/2.0; // x coordinate
2023 //N = kZ - (P-N)/fTan; // z coordinate
2025 if(fTanP + fTanN == 0) return kFALSE;
2027 N = (N - P + fTanN * Dz) / (fTanP + fTanN); // X coordinate
2028 P = P + fTanP * N; // Y coordinate
2033 // N = -(N - P + kZ/2*(fTanP + fTanN))/(fTanP + fTanN);
2034 // P = (fTanP*(N-kX/2-kZ*fTanN/2) + fTanN*(P-kX/2-kZ*fTanP/2) )/(fTanP + fTanN);
2036 if ( ( N < -(Dz/2+dx) ) || ( N > (Dz/2+dx) ) ) return kFALSE;
2037 if ( ( P < -(Dx/2+dx) ) || ( P > (Dx/2+dx) ) ) return kFALSE;
2043 //_________________________________________________________________________
2045 void AliITSClusterFinderSSD::GetCrossingError(Float_t& dP, Float_t& dN)
2049 dz = TMath::Abs(( dP + dN )*fPitch/(fTanP + fTanN) );
2050 dx = fPitch*(TMath::Abs(dP*(1 - fTanP/(fTanP + fTanN))) +
2051 TMath::Abs(dN *fTanP/(fTanP + fTanN) ));