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
22 //Piotr Krzysztof Skowronski
23 //Warsaw University of Technology
24 //skowron@if.pw.edu.pl
30 Eroor counting routines
31 Automatic combination routines improved (traps)
41 #include "AliITSdigit.h"
42 #include "AliITSRawCluster.h"
43 #include "AliITSRecPoint.h"
44 #include "AliITSMapA1.h"
45 #include "AliITSClusterFinderSSD.h"
46 #include "AliITSclusterSSD.h"
47 #include "AliITSpackageSSD.h"
48 #include "AliITSsegmentation.h"
50 const Bool_t AliITSClusterFinderSSD::fgkSIDEP=kTRUE;
51 const Bool_t AliITSClusterFinderSSD::fgkSIDEN=kFALSE;
55 ClassImp(AliITSClusterFinderSSD)
57 //____________________________________________________________________
60 //____________________________________________________________________
64 AliITSClusterFinderSSD::AliITSClusterFinderSSD(AliITSsegmentation *seg, TClonesArray *digits)
66 //Standard constructor
71 fMap = new AliITSMapA1(fSegmentation,fDigits);
73 fITS=(AliITS*)gAlice->GetModule("ITS");
75 fClusterP = new TClonesArray ("AliITSclusterSSD",200);
78 fClusterN= new TClonesArray ("AliITSclusterSSD",200);
81 fPackages = new TClonesArray ("AliITSpackageSSD",200); //packages
85 fDigitsIndexP = new TArrayI(300);
88 fDigitsIndexN = new TArrayI(300);
96 fPitch = fSegmentation->Dpx(0);
97 Float_t StereoP,StereoN;
98 fSegmentation->Angles(StereoP,StereoN);
99 fTanP=TMath::Tan(StereoP);
100 fTanN=TMath::Tan(StereoN);
102 fPNsignalRatio=7./8.; // warning: hard-wired number
106 //-------------------------------------------------------
107 AliITSClusterFinderSSD::~AliITSClusterFinderSSD() {
108 // Default destructor
113 delete fDigitsIndexP;
114 delete fDigitsIndexN;
120 //-------------------------------------------------------
121 void AliITSClusterFinderSSD::InitReconstruction()
123 // initialization of the cluster finder
125 register Int_t i; //iterator
127 for (i=0;i<fNClusterP;i++)
129 fClusterP->RemoveAt(i);
132 for (i=0;i<fNClusterN;i++)
134 fClusterN->RemoveAt(i);
138 for (i=0;i<fNPackages;i++)
140 fPackages->RemoveAt(i);
147 Float_t StereoP,StereoN;
148 fSegmentation->Angles(StereoP,StereoN);
150 CalcStepFactor (StereoP,StereoN);
152 if (debug) cout<<"fSFF = "<<fSFF<<" fSFB = "<<fSFB<<"\n";
156 //---------------------------------------------
157 void AliITSClusterFinderSSD::FindRawClusters()
159 // This function findes out all clusters belonging to one module
160 // 1. Zeroes all space after previous module reconstruction
161 // 2. Finds all neighbouring digits
162 // 3. If necesery, resolves for each group of neighbouring digits
163 // how many clusters creates it.
164 // 4. Creates packages
165 // 5. Creates clusters
167 InitReconstruction(); //ad. 1
171 FindNeighbouringDigits(); //ad. 2
172 SeparateOverlappedClusters(); //ad. 3
173 ClustersToPackages(); //ad. 4
175 PackagesToPoints(); //ad. 5
176 ReconstructNotConsumedClusters();
182 //-------------------------------------------------
183 void AliITSClusterFinderSSD::FindNeighbouringDigits()
185 //If there are any digits on this side, create 1st Cluster,
186 // add to it this digit, and increment number of clusters
192 if ((fNDigitsP>0 ) && (fNDigitsN > 0 )) {
194 Int_t currentstripNo;
195 Int_t *dbuffer = new Int_t [300]; //buffer for strip numbers
196 Int_t dnumber; //curent number of digits in buffer
197 TArrayI &lDigitsIndexP = *fDigitsIndexP;
198 TArrayI &lDigitsIndexN = *fDigitsIndexN;
199 TObjArray &lDigits = *(Digits());
200 TClonesArray &lClusterP = *fClusterP;
201 TClonesArray &lClusterN = *fClusterN;
205 dbuffer[0]=lDigitsIndexP[0];
206 //If next digit is a neighbour of previous, adds to last cluster this digit
207 for (i=1; i<fNDigitsP; i++) {
209 currentstripNo = ((AliITSdigitSSD*)lDigits[lDigitsIndexP[i]])->
211 //check if it is a neighbour of a previous one
212 if ( (((AliITSdigitSSD*)lDigits[lDigitsIndexP[i-1]])->GetStripNumber())
213 == (currentstripNo-1) ) dbuffer[dnumber++]=lDigitsIndexP[i];
215 //create a new one side cluster
216 new(lClusterP[fNClusterP++]) AliITSclusterSSD(dnumber,dbuffer,Digits(),fgkSIDEP);
217 dbuffer[0]=lDigitsIndexP[i];
220 } // end loop over fNDigitsP
221 new(lClusterP[fNClusterP++]) AliITSclusterSSD(dnumber,dbuffer,Digits(),fgkSIDEP);
225 //for comments, see above
227 dbuffer[0]=lDigitsIndexN[0];
228 //If next digit is a neighbour of previous, adds to last cluster this digit
229 for (i=1; i<fNDigitsN; i++) {
230 currentstripNo = ((AliITSdigitSSD*)(lDigits[lDigitsIndexN[i]]))->
232 if ( (((AliITSdigitSSD*)lDigits[lDigitsIndexN[i-1]])->GetStripNumber())
233 == (currentstripNo-1) ) dbuffer[dnumber++]=lDigitsIndexN[i];
235 new(lClusterN[fNClusterN++]) AliITSclusterSSD(dnumber,dbuffer,Digits(),fgkSIDEN);
236 dbuffer[0]=lDigitsIndexN[i];
239 } // end loop over fNDigitsN
240 new(lClusterN[fNClusterN++]) AliITSclusterSSD(dnumber,dbuffer,Digits(),fgkSIDEN);
243 } // end condition on NDigits
245 if (debug) cout<<"\n Found clusters: fNClusterP = "<<fNClusterP<<" fNClusterN ="<<fNClusterN<<"\n";
248 /**********************************************************************/
251 void AliITSClusterFinderSSD::SeparateOverlappedClusters()
253 // overlapped clusters separation
255 register Int_t i; //iterator
257 Float_t factor=0.75; // How many percent must be lower signal
258 // on the middle one digit
259 // from its neighbours
260 Int_t signal0; //signal on the strip before the current one
261 Int_t signal1; //signal on the current one signal
262 Int_t signal2; //signal on the strip after the current one
263 TArrayI *splitlist; // List of splits
264 Int_t numerofsplits=0; // number of splits
265 Int_t initPsize = fNClusterP; //initial size of the arrays
266 Int_t initNsize = fNClusterN; //we have to keep it because it will grow
267 // in this function and it doasn't make
268 // sense to pass through it again
270 splitlist = new TArrayI(300);
272 for (i=0;i<initPsize;i++)
274 if (( ((AliITSclusterSSD*)(*fClusterP)[i])->GetNumOfDigits())==1) continue;
275 if (( ((AliITSclusterSSD*)(*fClusterP)[i])->GetNumOfDigits())==2) continue;
276 Int_t nj=(((AliITSclusterSSD*)(*fClusterP)[i])->GetNumOfDigits()-1);
277 for (Int_t j=1; j<nj; j++)
279 signal1=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j);
280 signal0=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j-1);
281 signal2=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j+1);
282 //if signal is less then factor*signal of its neighbours
283 if ( (signal1<(factor*signal0)) && (signal1<(factor*signal2)) )
285 (*splitlist)[numerofsplits++]=j;
287 } // end loop over number of digits
288 //split this cluster if necessary
289 if(numerofsplits>0) SplitCluster(splitlist,numerofsplits,i,fgkSIDEP);
292 //in signed places (splitlist)
293 } // end loop over clusters on Pside
295 for (i=0;i<initNsize;i++) {
296 if (( ((AliITSclusterSSD*)(*fClusterN)[i])->GetNumOfDigits())==1) continue;
297 if (( ((AliITSclusterSSD*)(*fClusterN)[i])->GetNumOfDigits())==2) continue;
298 Int_t nj=(((AliITSclusterSSD*)(*fClusterN)[i])->GetNumOfDigits()-1);
299 for (Int_t j=1; j<nj; j++)
301 signal1=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j);
302 signal0=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j-1);
303 signal2=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j+1);
304 //if signal is less then factor*signal of its neighbours
305 if ( (signal1<(factor*signal0)) && (signal1<(factor*signal2)) )
306 (*splitlist)[numerofsplits++]=j;
307 } // end loop over number of digits
308 //split this cluster into more clusters
309 if(numerofsplits>0) SplitCluster(splitlist,numerofsplits,i,fgkSIDEN);
310 numerofsplits=0; //in signed places (splitlist)
311 } // end loop over clusters on Nside
316 //-------------------------------------------------------
317 void AliITSClusterFinderSSD::SplitCluster(TArrayI *list, Int_t nsplits, Int_t index, Bool_t side)
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,Digits(),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,Digits(),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)
373 // sort digits on the P side
378 if (start != (end - 1) )
380 left=this->SortDigitsP(start,(start+end)/2);
381 right=this->SortDigitsP((start+end)/2,end);
382 return (left || right);
386 left = ((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexP)[start]]))->GetStripNumber();
387 right= ((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexP)[end]]))->GetStripNumber();
390 Int_t tmp = (*fDigitsIndexP)[start];
391 (*fDigitsIndexP)[start]=(*fDigitsIndexP)[end];
392 (*fDigitsIndexP)[end]=tmp;
400 //--------------------------------------------------
402 Int_t AliITSClusterFinderSSD::SortDigitsN(Int_t start, Int_t end)
404 // sort digits on the N side
408 if (start != (end - 1))
410 left=this->SortDigitsN(start,(start+end)/2);
411 right=this->SortDigitsN((start+end)/2,end);
412 return (left || right);
416 left =((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexN)[start]]))->GetStripNumber();
417 right=((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexN)[end]]))->GetStripNumber();
420 Int_t tmp = (*fDigitsIndexN)[start];
421 (*fDigitsIndexN)[start]=(*fDigitsIndexN)[end];
422 (*fDigitsIndexN)[end]=tmp;
429 //------------------------------------------------
430 void AliITSClusterFinderSSD::FillDigitsIndex()
432 //Fill the indexes of the clusters belonging to a given ITS module
439 N = fDigits->GetEntriesFast();
441 Int_t* PSidx = new Int_t [N*sizeof(Int_t)];
442 Int_t* NSidx = new Int_t [N*sizeof(Int_t)];
443 if (fDigitsIndexP==NULL) fDigitsIndexP = new TArrayI(N);
444 if (fDigitsIndexN==NULL) fDigitsIndexN = new TArrayI(N);
448 for ( i = 0 ; i< N; i++ ) {
449 dig = (AliITSdigitSSD*)GetDigit(i);
452 tmp=dig->GetStripNumber();
453 // I find this totally unnecessary - it's just a
454 // CPU consuming double check
459 if (debug) cout<<"Such a digit exists \n";
465 fDigitsIndexP->AddAt(i,fNDigitsP++);
470 tmp=dig->GetStripNumber();
476 if (debug) cout<<"Such a digit exists \n";
482 fDigitsIndexN->AddAt(i,fNDigitsN++);
491 if (debug) cout<<"Digits : P = "<<fNDigitsP<<" N = "<<fNDigitsN<<endl;
496 //-------------------------------------------
498 void AliITSClusterFinderSSD::SortDigits()
504 for (i=0;i<fNDigitsP-1;i++)
505 if (SortDigitsP(0,(fNDigitsP-1-i))==0) break;
508 for (i=0;i<fNDigitsN-1;i++)
509 if(SortDigitsN(0,(fNDigitsN-1-i))==0) break;
514 //----------------------------------------------
515 void AliITSClusterFinderSSD::FillClIndexArrays(Int_t* arrayP, Int_t *arrayN)
517 // fill cluster index array
520 for (i=0; i<fNClusterP;i++)
524 for (i=0; i<fNClusterN;i++)
531 //------------------------------------------------------
532 void AliITSClusterFinderSSD::SortClusters(Int_t* arrayP, Int_t *arrayN)
538 for (i=0;i<fNClusterP-1;i++)
539 if (SortClustersP(0,(fNClusterP-1),arrayP)==0) break;
543 for (i=0;i<fNClusterN-1;i++)
544 if (SortClustersN(0,(fNClusterN-1),arrayN)==0) break;
550 //---------------------------------------------------
551 Int_t AliITSClusterFinderSSD::SortClustersP(Int_t start, Int_t end, Int_t *array)
553 //Sort P side clusters
558 if (start != (end - 1) ) {
559 left=this->SortClustersP(start,(start+end)/2,array);
560 right=this->SortClustersP((start+end)/2,end,array);
561 return (left || right);
563 left =((AliITSclusterSSD*)((*fClusterP)[array[start]]))->
565 right=((AliITSclusterSSD*)((*fClusterP)[array[ end ]]))->
568 Int_t tmp = array[start];
569 array[start]=array[end];
580 //-------------------------------------------------------
581 Int_t AliITSClusterFinderSSD::SortClustersN(Int_t start, Int_t end, Int_t *array)
583 //Sort N side clusters
589 if (start != (end - 1) ) {
590 left=this->SortClustersN(start,(start+end)/2,array);
591 right=this->SortClustersN((start+end)/2,end,array);
592 return (left || right);
594 left =((AliITSclusterSSD*)((*fClusterN)[array[start]]))->
596 right=((AliITSclusterSSD*)((*fClusterN)[array[ end ]]))->
599 Int_t tmp = array[start];
600 array[start]=array[end];
610 //-------------------------------------------------------
611 void AliITSClusterFinderSSD::ClustersToPackages()
615 Int_t *oneSclP = new Int_t[fNClusterP]; //I want to have sorted 1 S clusters
616 Int_t *oneSclN = new Int_t[fNClusterN]; //I can not sort it in TClonesArray
617 //so, I create table of indexes and
619 //I do not use TArrayI on purpose
620 // MB: well, that's not true that one
621 //cannot sort objects in TClonesArray
623 register Int_t i; //iterator
624 AliITSpackageSSD *currentpkg;
625 AliITSclusterSSD *currentP;
626 AliITSclusterSSD *currentN;
627 AliITSclusterSSD *fcurrN;
629 Int_t lastNclIndex=0; //index of last N sidecluster
630 Int_t Nclpack=0; //number of P clusters in current package
631 Int_t Pclpack=0; //number of N clusters in current package
636 Int_t tmplastNclIndex;
638 //Fills in One Side Clusters Index Array
639 FillClIndexArrays(oneSclP,oneSclN);
640 //Sorts filled Arrays
641 SortClusters(oneSclP,oneSclN);
645 new ((*fPackages)[0]) AliITSpackageSSD(fClusterP,fClusterN);
646 currentpkg = (AliITSpackageSSD*)((*fPackages)[0]);
648 //main loop on sorted P side clusters
650 for (i=0;i<fNClusterP;i++) {
651 //Take new P side cluster
652 currentP = GetPSideCluster(oneSclP[i]);
653 currentN = GetNSideCluster(oneSclN[lastNclIndex]);
654 // take a new P cluster or not ?
655 if(IsCrossing(currentP,currentN)) {
656 // don't take a new P cluster
658 currentP->AddCross(oneSclN[lastNclIndex]);
659 currentN->AddCross(oneSclP[i]);
660 currentpkg->AddPSideCluster(oneSclP[i]);
662 currentpkg->AddNSideCluster(oneSclN[lastNclIndex]);
665 //check if previous N side clusters crosses with it too
666 for(k=1;k<fSFB+1;k++) {
667 //check if we are not out of array
668 if ((lastNclIndex-k)>-1) {
669 fcurrN = GetNSideCluster( oneSclN[lastNclIndex-k] );
670 if( IsCrossing(currentP,fcurrN) ) {
671 currentP->AddCross(oneSclN[lastNclIndex-k]);
672 fcurrN->AddCross(oneSclP[i]);
673 } else break; //There is no sense to check rest of clusters
676 tmplastNclIndex=lastNclIndex;
677 //Check if next N side clusters crosses with it too
678 for (Int_t k=1;k<fSFF+1;k++) {
679 //check if we are not out of array
680 if ((tmplastNclIndex+k)<fNClusterN) {
681 fcurrN = GetNSideCluster( oneSclN[tmplastNclIndex+k] );
682 if(IsCrossing(currentP,fcurrN) ) {
684 fcurrN->AddCross(oneSclP[i]);
685 currentP->AddCross(oneSclN[tmplastNclIndex+k]);
686 currentpkg->AddNSideCluster(oneSclN[lastNclIndex]);
695 lastStripP = currentP->GetLastDigitStripNo();
696 lastStripN = currentN->GetLastDigitStripNo();
698 if((lastStripN-fSFF) < lastStripP ) {
700 if((Nclpack>0)&& (Pclpack>0)) {
701 new ((*fPackages)[fNPackages]) AliITSpackageSSD(fClusterP,fClusterN);
702 currentpkg = (AliITSpackageSSD*)((*fPackages)[fNPackages++]);
705 //so we have to take another cluster on side N and check it
706 //we have to check until taken cluster's last strip will
707 //be > last of this cluster(P)
708 //so it means that there is no corresponding cluster on side N
709 //to this cluster (P)
710 //so we have to continue main loop with new "lastNclIndex"
714 //We are not sure that next N cluter will cross with this P cluster
715 //There might one, or more, clusters that do not have any
716 //corresponding cluster on the other side
719 //Check if we are not out of array
720 if (lastNclIndex<fNClusterN) {
721 currentN = GetNSideCluster(oneSclN[lastNclIndex]);
722 if ( IsCrossing(currentP, currentN) ){
725 currentP->AddCross(oneSclN[lastNclIndex]);
726 currentN->AddCross(oneSclP[i]);
727 currentpkg->AddNSideCluster(oneSclN[lastNclIndex]);
728 currentpkg->AddPSideCluster(oneSclP[i]);
729 //Check, if next N side clusters crosses with it too
730 tmplastNclIndex=lastNclIndex;
731 for (Int_t k=1;k<fSFF+1;k++) {
732 //Check if we are not out of array
733 if ((tmplastNclIndex+k)<fNClusterN) {
734 fcurrN = GetNSideCluster(oneSclN[tmplastNclIndex+k]);
735 if( IsCrossing(currentP, fcurrN) ) {
738 currentP->AddCross(oneSclN[tmplastNclIndex+k]);
739 fcurrN->AddCross(oneSclP[i]);
740 currentpkg->AddNSideCluster(oneSclN[tmplastNclIndex+k]);
742 } else break; //we are out of array
746 firstStripP = currentP->GetFirstDigitStripNo();
747 firstStripN = currentN->GetFirstDigitStripNo();
748 if((firstStripN+fSFB)>=firstStripP) break;
751 } else goto EndOfFunction;
753 } else //EndOfPackage
756 } //else EndOfPackage
763 if ((Nclpack<1) || (Pclpack<1)) fNPackages--;
772 //-----------------------------------------------
773 void AliITSClusterFinderSSD::PackagesToPoints()
775 // find recpoints from packages
778 AliITSpackageSSD *currentpkg;
784 for (i=0;i<fNPackages;i++) {
785 //get pointer to next package
786 currentpkg = (AliITSpackageSSD*)((*fPackages)[i]);
787 NumNcl = currentpkg->GetNumOfClustersN();
788 NumPcl = currentpkg->GetNumOfClustersP();
789 if(debug) cout<<"New Package\nNumPcl ="<<NumPcl<<" NumNcl ="<<NumNcl<<"\n";
791 while(((NumPcl>=2)&&(NumNcl>2))||((NumPcl>2)&&(NumNcl>=2))) {
792 //This is case of "big" pacakage
793 //conditions see 3 lines above
794 //if in the big package exists cluster with one cross
795 //we can reconstruct this point without any geometrical ambiguities
796 if(currentpkg->GetClusterWithOneCross(clusterIndex, clusterSide) )
798 ResolveClusterWithOneCross(currentpkg, clusterIndex, clusterSide);
799 } else if (clusterIndex == -2) {
804 if ( (NumNcl==NumPcl) && (NumPcl<10)) {
805 //if there is no cluster with one cross
806 //we can resolve whole package at once
807 //by finding best combination
808 //we can make combinations when NumNcl==NumPcl
809 if (ResolvePackageBestCombin(currentpkg)) {
810 //sometimes creating combinations fail,
811 //but it happens very rarely
815 } else ResolveOneBestMatchingPoint(currentpkg);
817 ResolveOneBestMatchingPoint(currentpkg);
820 NumNcl = currentpkg->GetNumOfClustersN();
821 NumPcl = currentpkg->GetNumOfClustersP();
823 if ((NumPcl==1)&&(NumNcl==1)) {
824 ResolveSimplePackage(currentpkg);
828 ResolvePackageWithOnePSideCluster(currentpkg);
832 ResolvePackageWithOneNSideCluster(currentpkg);
835 if ((NumPcl==2)&&(NumNcl==2)) {
836 ResolveTwoForTwoPackage(currentpkg);
839 if ((NumPcl==0)&&(NumNcl>0)) { }
840 if ((NumNcl==0)&&(NumPcl>0)) { }
842 } // end loop over fNPackages
848 //----------------------------------------------------------
850 void AliITSClusterFinderSSD::
851 ResolveClusterWithOneCross(AliITSpackageSSD *currentpkg, Int_t clusterIndex, Bool_t clSide)
853 // resolve clusters with one cross
870 if (clSide == fgkSIDEP) ResolvePClusterWithOneCross(currentpkg,clusterIndex);
871 else ResolveNClusterWithOneCross(currentpkg,clusterIndex);
876 //---------------------------------------------------------
877 void AliITSClusterFinderSSD::
878 ResolvePClusterWithOneCross(AliITSpackageSSD *pkg, Int_t clusterIndex)
880 // resolve clusters with one cross on P side
882 There is cluster (side P) which crosses with only one cluster on the other
898 AliITSclusterSSD * clusterP;
899 AliITSclusterSSD * clusterN;
901 Float_t posClusterP; //Cluster P position in strip coordinates
902 Float_t posClusterN; //Cluster N position in strip coordinates
904 Float_t posErrorClusterP;
905 Float_t posErrorClusterN;
910 Float_t sigErrorClusterP;
911 Float_t sigErrorClusterN;
919 if (debug) cout<<"ResolvePClusterWithOneCross\n";
921 clusterP=pkg->GetPSideCluster(clusterIndex);
922 posClusterP = GetClusterZ(clusterP);
923 posErrorClusterP = clusterP->GetPositionError();
924 sigClusterP = ps = clusterP->GetTotalSignal();
925 sigErrorClusterP = clusterP->GetTotalSignalError();
926 //carefully, it returns index in TClonesArray
928 clusterIdx = clusterP->GetCross(0);
929 clusterN=this->GetNSideCluster(clusterIdx);
930 ns = clusterN->GetTotalSignal();
931 posClusterN = GetClusterZ(clusterN);
932 posErrorClusterN = clusterN->GetPositionError();
933 pkg->DelCluster(clusterIndex,fgkSIDEP);
934 sigClusterN = ps/fPNsignalRatio;
935 // there is no sonse to check how signal ratio is far from perfect
936 // matching line if the if below it is true
937 if (ns < sigClusterN) {
939 if (debug) cout<<"n1 < p1/fPNsignalRatio";
940 if (debug) cout<<"Attempting to del cluster N "<<clusterIdx<<" ... \n";
941 pkg->DelClusterOI(clusterIdx,fgkSIDEN);
943 //Let's see how signal ratio is far from perfect matching line
944 Chicomb = DistToPML(ps,ns);
945 if (debug) cout<<"Chic "<<Chicomb<<"\n";
946 if (Chicomb > fAlpha2) {
947 //it is near, so we can risk throwing this cluster away too
948 if (debug) cout<<"Attempting to del cluster N "<<clusterIdx<<"...\n";
949 pkg->DelClusterOI(clusterIdx,fgkSIDEN);
951 clusterN->CutTotalSignal(sigClusterN);
952 if (debug) cout <<"Signal cut |||||||||||||\n";
955 sigErrorClusterN= clusterN->GetTotalSignalError();
956 CreateNewRecPoint(posClusterP,posErrorClusterP,posClusterN,posErrorClusterN,
957 sigClusterP+sigClusterN, sigErrorClusterN+sigErrorClusterP,
958 clusterP, clusterN, 0.75);
963 //------------------------------------------------------
964 void AliITSClusterFinderSSD::
965 ResolveNClusterWithOneCross(AliITSpackageSSD *pkg, Int_t clusterIndex)
967 // resolve clusters with one cross on N side
970 AliITSclusterSSD * clusterP;
971 AliITSclusterSSD * clusterN;
973 Float_t posClusterP; //Cluster P position in strip coordinates
974 Float_t posClusterN; //Cluster N position in strip coordinates
976 Float_t posErrorClusterP;
977 Float_t posErrorClusterN;
982 Float_t sigErrorClusterP;
983 Float_t sigErrorClusterN;
991 if (debug) cout<<"ResolveNClusterWithOneCross\n";
993 clusterN=pkg->GetNSideCluster(clusterIndex);
994 posClusterN = GetClusterZ(clusterN);
995 posErrorClusterN = clusterN->GetPositionError();
996 sigClusterN = ns = clusterN->GetTotalSignal();
997 sigErrorClusterN = clusterN->GetTotalSignalError();
998 //carefully, it returns index in TClonesArray
999 clusterIdx = clusterN->GetCross(0);
1000 clusterP=this->GetPSideCluster(clusterIdx);
1001 ps = clusterP->GetTotalSignal();
1002 posClusterP = GetClusterZ(clusterP);
1003 posErrorClusterP = clusterP->GetPositionError();
1004 pkg->DelCluster(clusterIndex,fgkSIDEN);
1005 sigClusterP=ns*fPNsignalRatio;
1006 // there is no sonse to check how signal ratio is far from perfect
1007 // matching line if the if below it is true
1008 if (ps < sigClusterP) {
1010 if (debug) cout<<"ps < ns*fPNsignalRatio";
1011 if (debug) cout<<"Attempting to del cluster P "<<clusterIdx<<" ... \n";
1012 pkg->DelClusterOI(clusterIdx,fgkSIDEP);
1014 //Let's see how signal ratio is far from perfect matching line
1015 Chicomb = DistToPML(ps,ns);
1016 if (debug) cout<<"Chic "<<Chicomb<<"\n";
1017 if (Chicomb > fAlpha2) {
1018 //it is near, so we can risk frowing this cluster away too
1019 if (debug) cout<<"Attempting to del cluster P "<<clusterIdx<<"...\n";
1020 pkg->DelClusterOI(clusterIdx,fgkSIDEP);
1022 clusterN->CutTotalSignal(sigClusterP);
1023 if (debug) cout <<"Signal cut ------------\n";
1026 sigErrorClusterP= clusterP->GetTotalSignalError();
1027 CreateNewRecPoint( posClusterP,posErrorClusterP,posClusterN,posErrorClusterN,
1028 sigClusterP+sigClusterN,sigErrorClusterN+sigErrorClusterP,
1029 clusterP, clusterN, 0.75);
1036 //-------------------------------------------------------
1038 Bool_t AliITSClusterFinderSSD::
1039 ResolvePackageBestCombin(AliITSpackageSSD *pkg)
1041 //find best combination
1043 if (debug) cout<<"NumNcl==NumPcl ("<<pkg->GetNumOfClustersN()
1044 <<"=="<<pkg->GetNumOfClustersP()<<"); Generating combinations ... \n";
1047 AliITSclusterSSD * clusterP;
1048 AliITSclusterSSD * clusterN;
1050 Int_t Ncombin; //Number of combinations
1051 Int_t itera; //iterator
1052 Int_t sizet=1; //size of array to allocate
1054 Int_t NP = pkg->GetNumOfClustersP();
1055 for (itera =2; itera <= NP ;itera ++) {
1057 if (sizet > 10000) {
1063 Int_t** combin = new Int_t*[sizet]; //2D array to keep combinations in
1065 for (itera =0; itera <sizet;itera++) {
1066 combin[itera] = new Int_t[NP+1];
1069 pkg->GetAllCombinations(combin,Ncombin,sizet);
1072 if (debug) cout<<"No combin Error";
1075 //calculate which combination fits the best to perfect matching line
1076 Int_t bc = GetBestComb(combin,Ncombin,NP,pkg);
1077 if (debug) cout<<" bc "<<bc <<"\n";
1079 for (itera =0; itera < NP; itera ++) {
1080 clusterP = pkg->GetPSideCluster(itera);
1082 //becase AliITSclusterSSD::GetCross returns index in
1083 //AliITSmoduleSSD.fClusterP, which is put to "combin"
1084 clusterN = GetNSideCluster(combin[bc][itera]);
1085 CreateNewRecPoint(clusterP, clusterN, 0.75);
1088 for (itera =0; itera <sizet;itera++) {
1089 delete [](combin[itera]);
1097 //----------------------------------------------------
1098 void AliITSClusterFinderSSD::
1099 ResolveOneBestMatchingPoint(AliITSpackageSSD *pkg)
1101 // find best matching point
1106 Int_t nextP, nextN=0;
1109 AliITSclusterSSD * clusterP;
1110 AliITSclusterSSD * clusterN;
1112 Bool_t split = kFALSE;
1114 if (debug) cout<<"ResolveOneBestMatchingPoint \n";
1116 GetBestMatchingPoint(pi, ni, pkg);
1118 clusterP = GetPSideCluster(pi);
1119 clusterN = GetNSideCluster(ni);
1121 CreateNewRecPoint(clusterP, clusterN, 0.75);
1123 if ((nextP=pkg->GetNextPIdx(pi))!=-1)
1124 if ((nextN=pkg->GetNextNIdx(ni))!=-1)
1125 if ((prvP=pkg->GetPrvPIdx(pi))!=-1)
1126 if ((prvN=pkg->GetPrvNIdx(ni))!=-1)
1127 if( !(GetPSideCluster(prvP)->IsCrossingWith(nextN)))
1128 if( !(GetPSideCluster(nextP)->IsCrossingWith(prvN)))
1134 pkg->DelClusterOI(pi, fgkSIDEP);
1135 pkg->DelClusterOI(ni, fgkSIDEN);
1138 if (debug) cout<<"spltting package ...\n";
1139 new ((*fPackages)[fNPackages]) AliITSpackageSSD(fClusterP,fClusterN);
1141 SplitPackage(nextP,nextN,(AliITSpackageSSD*)((*fPackages)[fNPackages++]));
1147 //--------------------------------------------------
1148 void AliITSClusterFinderSSD::ResolveSimplePackage(AliITSpackageSSD *pkg)
1150 // resolve simple package
1152 AliITSclusterSSD * clusterP;
1153 AliITSclusterSSD * clusterN;
1155 clusterP = pkg->GetPSideCluster(0);
1157 clusterN = pkg->GetNSideCluster(0);
1159 CreateNewRecPoint(clusterP, clusterN, 1.0);
1165 //--------------------------------------------------
1166 void AliITSClusterFinderSSD:: ResolvePackageWithOnePSideCluster(AliITSpackageSSD *pkg) {
1167 // resolve P side clusters from packages
1182 /************************/
1183 /**************************/
1184 /*XP SP itg jest tylko jeden nie musi byc tablica i w peetli nie trzeba po niej iterowcac*/
1185 /***************************/
1189 AliITSclusterSSD * clusterP;
1190 AliITSclusterSSD * clusterN;
1192 Int_t NN=pkg->GetNumOfClustersN();
1198 Float_t * XN = new Float_t[NN];
1199 Float_t * XNerr = new Float_t[NN];
1201 Float_t * SP = new Float_t[NN];
1202 Float_t * SN = new Float_t[NN];
1204 Float_t * SPerr = new Float_t[NN];
1205 Float_t * SNerr = new Float_t[NN];
1210 clusterP = pkg->GetPSideCluster(0);
1211 p1 = clusterP->GetTotalSignal();
1213 XP = GetClusterZ(clusterP);
1214 XPerr = clusterP->GetPositionError();
1215 p1err = clusterP->GetTotalSignalError();
1217 for (k=0;k<NN;k++) {
1218 SN[k] = pkg->GetNSideCluster(k)->GetTotalSignal();
1219 SNerr[k] = pkg->GetNSideCluster(k)->GetTotalSignalError();
1222 for (k=0;k<NN;k++) {
1223 clusterN = pkg->GetNSideCluster(k);
1224 SP[k]= p1*SN[k]/sumsig;
1225 SPerr[k] = p1err*SN[k]/sumsig;
1226 XN[k]=GetClusterZ(clusterN);
1227 XNerr[k]= clusterN->GetPositionError();
1228 CreateNewRecPoint(XP,XPerr, XN[k],XNerr[k], SP[k]+SN[k], SPerr[k]+SNerr[k], clusterP, clusterN, 1.0);
1243 //---------------------------------------------------------
1244 void AliITSClusterFinderSSD::ResolvePackageWithOneNSideCluster(AliITSpackageSSD *pkg) {
1245 // resolve N side clusters from packages
1261 AliITSclusterSSD * clusterP;
1262 AliITSclusterSSD * clusterN;
1264 Int_t NP=pkg->GetNumOfClustersP();
1267 Float_t * XP = new Float_t[NP];
1268 Float_t * XPerr = new Float_t[NP];
1273 Float_t * SP = new Float_t[NP];
1274 Float_t * SN = new Float_t[NP];
1276 Float_t * SPerr = new Float_t[NP];
1277 Float_t * SNerr = new Float_t[NP];
1282 clusterN = pkg->GetNSideCluster(0);
1283 n1 = clusterN->GetTotalSignal();
1285 XN = GetClusterZ(clusterN);
1286 XNerr = clusterN->GetPositionError();
1288 n1err=clusterN->GetTotalSignalError();
1290 for (k=0;k<NP;k++) {
1291 SP[k] = pkg->GetPSideCluster(k)->GetTotalSignal();
1293 SPerr[k] = pkg->GetPSideCluster(k)->GetTotalSignalError();
1296 for (k=0;k<NP;k++) {
1297 clusterP = pkg->GetPSideCluster(k);
1298 SN[k]= n1*SP[k]/sumsig;
1299 XP[k]=GetClusterZ(clusterP);
1300 XPerr[k]= clusterP->GetPositionError();
1301 SNerr[k] = n1err*SP[k]/sumsig;
1302 CreateNewRecPoint(XP[k],XPerr[k], XN,XNerr, SP[k]+SN[k], SPerr[k]+SNerr[k],clusterP, clusterN, 1.0);
1314 /**********************************************************************/
1315 /********* 2 X 2 *********************************************/
1316 /**********************************************************************/
1318 void AliITSClusterFinderSSD::
1319 ResolveTwoForTwoPackage(AliITSpackageSSD *pkg)
1321 // resolve 2x2 packages
1323 AliITSclusterSSD *clusterP1 = pkg->GetPSideCluster(0);
1324 AliITSclusterSSD *clusterP2 = pkg->GetPSideCluster(1);
1325 AliITSclusterSSD *clusterN1 = pkg->GetNSideCluster(0);
1326 AliITSclusterSSD *clusterN2 = pkg->GetNSideCluster(1);
1328 AliITSclusterSSD *tmp;
1355 if(clusterP1->GetDigitStripNo(0) > clusterP2->GetDigitStripNo(0)) {
1356 if (debug) cout<<"P strips flip\n";
1358 clusterP1 = clusterP2;
1361 if(clusterN1->GetDigitStripNo(0) > clusterN2->GetDigitStripNo(0)) {
1362 if (debug) cout<<"N strips flip\n";
1364 clusterN1 = clusterN2;
1367 p1sig = clusterP1->GetTotalSignal();
1368 p2sig = clusterP2->GetTotalSignal();
1369 n1sig = clusterN1->GetTotalSignal();
1370 n2sig = clusterN2->GetTotalSignal();
1373 p1sigErr = clusterP1->GetTotalSignalError();
1374 n1sigErr = clusterN1->GetTotalSignalError();
1375 p2sigErr = clusterP2->GetTotalSignalError();
1376 n2sigErr = clusterN2->GetTotalSignalError();
1378 ZposP1 = clusterP1->GetPosition();
1379 ZposN1 = clusterN1->GetPosition();
1380 ZposP2 = clusterP2->GetPosition();
1381 ZposN2 = clusterN2->GetPosition();
1383 ZposErrP1 = clusterP1->GetPositionError();
1384 ZposErrN1 = clusterN1->GetPositionError();
1385 ZposErrP2 = clusterP2->GetPositionError();
1386 ZposErrN2 = clusterN2->GetPositionError();
1388 //in this may be two types:
1389 // 1.When each cluster crosses with 2 clusters on the other side
1390 // gives 2 ghosts and 2 real points
1392 // 2.When two clusters (one an each side) crosses with only one on
1393 // the other side and two crosses (one on the each side) with
1394 // two on the other gives 2 or 3 points,
1396 if (debug) cout<<"2 for 2 ambiguity ...";
1397 /***************************/
1398 /*First sort of combination*/
1399 /***************************/
1401 if((clusterP1->GetCrossNo()==2) && (clusterN1->GetCrossNo()==2)) {
1402 if (debug) cout<<"All clusters has 2 crosses\n";
1403 D12 = TMath::Sqrt((Float_t)((p1sig -p2sig)*(p1sig -p2sig) + (n1sig -n2sig)*(n1sig -n2sig)));
1405 if(debug) cout<<"Distance between points in P(N) plane D12 = "<<D12<<"\n";
1407 /*********************************************/
1408 /*resolving ambiguities: */
1409 /*we count Chicomb's and we take combination */
1410 /*giving lower Chicomb as a real points */
1411 /*Keep only better combinantion */
1412 /*********************************************/
1414 if (D12 > (fAlpha3*17.8768)) {
1415 if (debug) cout<<"decided to take only one pair \n";
1416 Chicomb1 = DistToPML(p1sig,n1sig) + DistToPML(p2sig,n2sig);
1417 Chicomb2 = DistToPML(p2sig,n1sig) + DistToPML(p1sig,n2sig);
1419 cout<<" 00 11 combination : "<<Chicomb1<<" 01 10 combination : "<<Chicomb2<<" \n";
1420 cout<<"p1 = "<<p1sig<<" n1 = "<<n1sig<<" p2 = "<<p2sig<<" n2 = "<<n2sig<<"\n";
1422 if (Chicomb1 < Chicomb2) {
1423 if (debug) cout<<"00 11";
1424 CreateNewRecPoint(ZposP1,ZposErrP1, ZposN1,ZposErrN1, p1sig+n1sig, p1sigErr+n1sigErr, clusterP1, clusterN1, 0.75);
1425 CreateNewRecPoint(ZposP2,ZposErrP2, ZposN2,ZposErrN2, p2sig+n2sig, p2sigErr+n2sigErr, clusterP2, clusterN2, 0.75);
1428 //second cominantion
1430 if (debug) cout<<"01 10";
1431 CreateNewRecPoint(ZposP1,0, ZposN2,0, p1sig+n2sig, p1sigErr+n2sigErr, clusterP1, clusterN2, 0.75);
1432 CreateNewRecPoint(ZposP2,0, ZposN1,0, p2sig+n1sig, p2sigErr+n1sigErr, clusterP2, clusterN1, 0.75);
1433 } //end second combinantion
1434 //if (D12 > fAlpha3*17.8768)
1435 //keep all combinations
1437 if (debug) cout<<"We decide to take all points\n";
1438 CreateNewRecPoint(ZposP1,ZposErrP1, ZposN1,ZposErrN1, p1sig+n1sig, p1sigErr+n1sigErr, clusterP1, clusterN1, 0.5);
1439 CreateNewRecPoint(ZposP2,ZposErrP2, ZposN2,ZposErrN2, p2sig+n2sig, p2sigErr+n2sigErr, clusterP2, clusterN2, 0.5);
1440 CreateNewRecPoint(ZposP1,ZposErrP1, ZposN2,ZposErrN2, p1sig+n2sig, p1sigErr+n2sigErr, clusterP1, clusterN2, 0.5);
1441 CreateNewRecPoint(ZposP2,ZposErrP2, ZposN1,ZposErrN1, p2sig+n1sig, p2sigErr+n1sigErr, clusterP2, clusterN1, 0.5);
1444 // ad.2 Second type of combination
1446 Chicomb1 = DistToPML(p1sig,n1sig) + DistToPML(p2sig,n2sig);
1447 if (debug) cout<<"\nhere can be reconstructed 3 points: chicomb = "<<Chicomb1<<"\n";
1449 if (Chicomb1<fAlpha1) {
1450 if (debug) cout<<"\nWe decided to take 3rd point";
1451 if (clusterP1->GetCrossNo()==1) {
1452 if (debug) cout<<"... P1 has one cross\n";
1453 n1sig = p1sig/fPNsignalRatio;
1454 p2sig = n2sig*fPNsignalRatio;
1456 clusterN1->CutTotalSignal(n1sig);
1457 clusterP2->CutTotalSignal(p2sig);
1459 CreateNewRecPoint(ZposP2,ZposErrP2, ZposN1,ZposErrN1, p2sig+n1sig, p2sigErr+n1sigErr, clusterP2, clusterN1, 0.5);
1461 n1sig = clusterN1->GetTotalSignal();
1462 p2sig = clusterP2->GetTotalSignal();
1465 if (debug) cout<<"... N1 has one cross\n";
1467 n2sig=p2sig/fPNsignalRatio;
1468 p1sig=n1sig*fPNsignalRatio;
1470 clusterN2->CutTotalSignal(n2sig);
1471 clusterP1->CutTotalSignal(p1sig);
1473 CreateNewRecPoint(ZposP1,ZposErrP1, ZposN2,ZposErrN2, p1sig+n2sig, p1sigErr+n2sigErr, clusterP1, clusterN2, 0.5);
1475 n2sig=clusterN2->GetTotalSignal();
1476 p1sig=clusterP1->GetTotalSignal();
1479 if (debug) cout<<"\nWe decided NOT to take 3rd point\n";
1482 CreateNewRecPoint(ZposP1,ZposErrP1, ZposN1,ZposErrN1, p1sig+n1sig, p1sigErr+n1sigErr, clusterP1, clusterN1, 1.0);
1483 CreateNewRecPoint(ZposP2,ZposErrP2, ZposN2,ZposErrN2, p2sig+n2sig, p2sigErr+n2sigErr, clusterP2, clusterN2, 1.0);
1491 //------------------------------------------------------
1492 Bool_t AliITSClusterFinderSSD::
1493 CreateNewRecPoint(Float_t P, Float_t dP, Float_t N, Float_t dN,
1494 Float_t Sig,Float_t dSig,
1495 AliITSclusterSSD *clusterP, AliITSclusterSSD *clusterN,
1498 // create the recpoints
1501 const Float_t kdEdXtoQ = 2.778e+8;
1502 const Float_t kconv = 1.0e-4;
1503 const Float_t kRMSx = 20.0*kconv; // microns->cm ITS TDR Table 1.3
1504 const Float_t kRMSz = 830.0*kconv; // microns->cm ITS TDR Table 1.3
1509 Int_t stripP, stripN;
1511 AliITSdigitSSD *digP, *digN;
1512 if (GetCrossing(P,N)) {
1513 GetCrossingError(dP,dN);
1514 AliITSRawClusterSSD cnew;
1515 Int_t nstripsP=clusterP->GetNumOfDigits();
1516 Int_t nstripsN=clusterN->GetNumOfDigits();
1517 cnew.fMultiplicity=nstripsP;
1518 cnew.fMultiplicityN=nstripsN;
1520 if (nstripsP > 100) {
1521 printf("multiplicity > 100 - increase the dimension of the arrays %d\n",nstripsP);
1524 for(int i=0;i<nstripsP;i++) {
1525 // check if 'clusterP->GetDigitStripNo(i)' returns the digit index
1526 cnew.fIndexMap[i] = clusterP->GetDigitStripNo(i);
1528 if (nstripsN > 100) {
1529 printf("multiplicity > 100 - increase the dimension of the arrays %d\n",nstripsN);
1532 for(int i=0;i<nstripsN;i++) {
1533 // check if 'clusterN->GetDigitStripNo(i)' returns the digit index
1534 cnew.fIndexMapN[i] = clusterN->GetDigitStripNo(i);
1538 //cnew.fProbability=(float)prob;
1539 fITS->AddCluster(2,&cnew);
1540 fSegmentation->GetPadIxz(P,N,stripP,stripN);
1541 digP = (AliITSdigitSSD*)fMap->GetHit(1,stripP);
1542 digN = (AliITSdigitSSD*)fMap->GetHit(0,stripN);
1543 //printf("SSD: digP digN %p %p\n",digP,digN);
1544 if(digP) sigP = digP->fSignal;
1546 if(digN) sigN = digN->fSignal;
1548 if (!digP && !digN) {
1549 Error("CreateNewRecPoint","cannot find the digit!");
1552 // add the rec point info
1553 AliITSRecPoint rnew;
1557 rnew.SetdEdX(Sig/kdEdXtoQ);
1558 rnew.SetSigmaX2( kRMSx* kRMSx);
1559 rnew.SetSigmaZ2( kRMSz* kRMSz);
1560 //rnew.SetProbability((float)prob);
1562 rnew.fTracks[0]=digP->fTracks[0];
1563 rnew.fTracks[1]=digP->fTracks[1];
1564 rnew.fTracks[2]=digP->fTracks[2];
1565 //printf("sigP>sigN: %d %d %d\n",digP->fTracks[0],digP->fTracks[1],digP->fTracks[2]);
1567 rnew.fTracks[0]=digN->fTracks[0];
1568 rnew.fTracks[1]=digN->fTracks[1];
1569 rnew.fTracks[2]=digN->fTracks[2];
1570 //printf("sigN>sigP: %d %d %d\n",digN->fTracks[0],digN->fTracks[1],digN->fTracks[2]);
1572 //printf("SSD: track1 track2 track3 X Z %d %d %d %f %f\n",rnew.fTracks[0],rnew.fTracks[1],rnew.fTracks[2],P*kconv,N*kconv);
1573 fITS->AddRecPoint(rnew);
1576 fPointsM->AddLast( (TObject*)
1577 new AliITSRecPointSSD(P,dP,0,0,N,dN,Sig,dSig,fLayer,fLad,fDet,clusterP,clusterN,prob) );
1580 if(debug) cout<<"\n"<<": ImpactPoint Created: X = "<<P<<" Z = "<<N<<"; P = "<<p<<" N = "<<n<<"\n";
1584 cout<<"\n"<<": ATENTION : stupid ImpactPoit Point X = "<<P<<" Z = "<<N<<"; P = "<<p<<" N = "<<n<<"\n";
1592 /**********************************************************************/
1593 Bool_t AliITSClusterFinderSSD::
1594 CreateNewRecPoint(AliITSclusterSSD *clusterP, AliITSclusterSSD *clusterN, Stat_t prob)
1598 Float_t posClusterP; //Cluster P position in strip coordinates
1599 Float_t posClusterN; //Cluster N position in strip coordinates
1601 Float_t posErrorClusterP;
1602 Float_t posErrorClusterN;
1604 Float_t sigClusterP;
1605 Float_t sigClusterN;
1607 Float_t sigErrorClusterP;
1608 Float_t sigErrorClusterN;
1610 posClusterP = clusterP->GetPosition();
1611 posErrorClusterP = clusterP->GetPositionError();
1612 sigClusterP = clusterP->GetTotalSignal();
1613 sigErrorClusterP = clusterP->GetTotalSignalError();
1615 posClusterN = clusterN->GetPosition();
1616 posErrorClusterN = clusterN->GetPositionError();
1617 sigClusterN = clusterN->GetTotalSignal();
1618 sigErrorClusterN = clusterN->GetTotalSignalError();
1620 return CreateNewRecPoint( posClusterP,posErrorClusterP, posClusterN,posErrorClusterN,
1621 sigClusterP+sigClusterN, sigErrorClusterN+sigErrorClusterP,
1622 clusterP, clusterN, prob);
1626 //--------------------------------------------------
1627 Bool_t AliITSClusterFinderSSD::IsCrossing(AliITSclusterSSD* p, AliITSclusterSSD* n)
1629 // check for crossings
1631 Float_t x = p->GetPosition();
1632 Float_t y = n->GetPosition();
1633 return GetCrossing(x,y);
1637 //----------------------------------------------
1638 Bool_t AliITSClusterFinderSSD::Strip2Local( Float_t stripP, Float_t stripN, Float_t &Z,Float_t &X)
1640 // convert between strip numbers and local coordinates
1643 Z = (stripN-stripP)*fFactorOne;
1644 X = (stripN + stripP - fStripZeroOffset)*fFactorTwo;
1653 if (debug) cout<<"P="<<stripP<<" N="<<stripN<<" X = "<<X<<" Z = "<<Z<<"\n";
1654 if ((Z<2.1)&&(Z>-2.1)&&(X<3.65)&&(X>-3.65)) return kTRUE;
1660 //-----------------------------------------------------------
1661 Float_t AliITSClusterFinderSSD::GetClusterZ(AliITSclusterSSD* clust)
1663 // get Z coordinate of the cluster
1665 return clust->GetPosition();
1669 //-------------------------------------------------------------
1670 Int_t AliITSClusterFinderSSD::GetBestComb
1671 (Int_t** comb,Int_t Ncomb, Int_t Ncl, AliITSpackageSSD * pkg)
1673 //returns index of best combination in "comb"
1674 //comb : sets of combinations
1675 // in given combination on place "n" is index of
1676 // Nside cluster coresponding to "n" P side cluster
1678 //Ncomb : number of combinations == number of rows in "comb"
1680 //Ncl : number of clusters in each row == number of columns in "comb"
1685 Float_t currbval=-1; //current best value,
1686 //starting value is set to number negative,
1687 //to be changed in first loop turn automatically
1689 Int_t curridx=0; //index of combination giving currently the best chi^2
1691 Float_t ps, ns; //signal of P cluster and N cluster
1693 for (Int_t i=0;i<Ncomb;i++)
1697 for (Int_t j=0;j<Ncl;j++)
1699 ps = pkg->GetPSideCluster(j)->GetTotalSignal(); //carrefully here, different functions
1700 ns = GetNSideCluster(comb[i][j])->GetTotalSignal();
1701 chi+=DistToPML(ps,ns);
1704 if (currbval==-1) currbval = chi;
1717 //--------------------------------------------------
1718 void AliITSClusterFinderSSD::GetBestMatchingPoint
1719 (Int_t & ip, Int_t & in, AliITSpackageSSD* pkg )
1721 // find the best matching point
1723 if (debug) pkg->PrintClusters();
1725 Float_t ps, ns; //signals on side p & n
1727 Int_t nc; // number of crosses in given p side cluster
1729 AliITSclusterSSD *curPcl, *curNcl; //current p side cluster
1730 Float_t bestchi, chi;
1731 ip=p=pkg->GetPSideClusterIdx(0);
1732 in=n=pkg->GetNSideClusterIdx(0);
1734 bestchi=DistToPML( pkg->GetPSideCluster(0)->GetTotalSignal(),
1735 pkg->GetNSideCluster(0)->GetTotalSignal() );
1736 for (Int_t i = 0; i< pkg->GetNumOfClustersP(); i++)
1739 p = pkg->GetPSideClusterIdx(i);
1740 curPcl= GetPSideCluster(p);
1741 nc=curPcl->GetCrossNo();
1742 ps=curPcl->GetTotalSignal();
1744 for (Int_t j = 0; j< nc; j++)
1746 n=curPcl->GetCross(j);
1747 curNcl= GetNSideCluster(n);
1748 ns=curNcl->GetTotalSignal();
1749 chi = DistToPML(ps, ns);
1763 //------------------------------------------------------
1764 void AliITSClusterFinderSSD::CalcStepFactor(Float_t Psteo, Float_t Nsteo )
1766 // calculate the step factor for matching clusters
1769 // 95 is the pitch, 4000 - dimension along z ?
1771 fSFF = ( (Int_t) (Psteo*40000/95 ) );// +1;
1772 fSFB = ( (Int_t) (Nsteo*40000/95 ) );// +1;
1776 Float_t dz=fSegmentation->Dz();
1778 fSFF = ( (Int_t) (Psteo*dz/fPitch ) );// +1;
1779 fSFB = ( (Int_t) (Nsteo*dz/fPitch ) );// +1;
1784 //-----------------------------------------------------------
1785 AliITSclusterSSD* AliITSClusterFinderSSD::GetPSideCluster(Int_t idx)
1787 // get P side clusters
1792 if((idx<0)||(idx>=fNClusterP))
1794 printf("AliITSClusterFinderSSD::GetPSideCluster : index out of range\n");
1799 return (AliITSclusterSSD*)((*fClusterP)[idx]);
1803 //-------------------------------------------------------
1804 AliITSclusterSSD* AliITSClusterFinderSSD::GetNSideCluster(Int_t idx)
1806 // get N side clusters
1808 if((idx<0)||(idx>=fNClusterN))
1810 printf("AliITSClusterFinderSSD::GetNSideCluster : index out of range\n");
1815 return (AliITSclusterSSD*)((*fClusterN)[idx]);
1819 //--------------------------------------------------------
1820 AliITSclusterSSD* AliITSClusterFinderSSD::GetCluster(Int_t idx, Bool_t side)
1824 return (side) ? GetPSideCluster(idx) : GetNSideCluster(idx);
1828 //--------------------------------------------------------
1829 void AliITSClusterFinderSSD::ConsumeClusters()
1831 // remove clusters from the list of unmatched clusters
1833 for ( Int_t i=0;i<fNPackages;i++)
1835 ((AliITSpackageSSD*)((*fPackages)[i]))->ConsumeClusters();
1841 //--------------------------------------------------------
1842 void AliITSClusterFinderSSD::ReconstructNotConsumedClusters()
1844 // reconstruct remaining non-crossing clusters
1846 //printf("ReconstructNotConsumedClusters !!!\n");
1849 AliITSclusterSSD *cluster;
1853 Float_t x1,x2,z1,z2;
1855 Float_t Dx = fSegmentation->Dx();
1856 Float_t Dz = fSegmentation->Dz();
1858 const Float_t kdEdXtoQ = 2.778e+8; // GeV -> number of e-hole pairs
1859 const Float_t kconv = 1.0e-4;
1860 const Float_t kRMSx = 20.0*kconv; // microns->cm ITS TDR Table 1.3
1861 const Float_t kRMSz = 830.0*kconv; // microns->cm ITS TDR Table 1.3
1863 Int_t stripP,stripN;
1864 AliITSdigitSSD *dig;
1865 for (i=0;i<fNClusterP;i++)
1867 //printf("P side cluster: cluster number %d\n",i);
1868 cluster = GetPSideCluster(i);
1869 if (!cluster->IsConsumed())
1871 if( (pos = cluster->GetPosition()) < fSFB)
1873 sig = cluster->GetTotalSignal();
1875 sig += sig/fPNsignalRatio;
1877 sigerr = cluster->GetTotalSignalError();
1878 x1 = -Dx/2 + pos *fPitch;
1883 GetCrossing (x2,z2);
1884 fSegmentation->GetPadIxz((x1+x2)/2,(z1+z2)/2,stripP,stripN);
1885 dig = (AliITSdigitSSD*)fMap->GetHit(1,stripP);
1886 //printf("dig %p\n",dig);
1887 if (!dig) printf("SSD: check the digit! dig %p\n",dig);
1889 AliITSRawClusterSSD cnew;
1890 Int_t nstripsP=cluster->GetNumOfDigits();
1891 cnew.fMultiplicity=nstripsP;
1892 cnew.fMultiplicityN=0;
1894 if (nstripsP > 100) {
1895 printf("multiplicity > 100 - increase the dimension of the arrays %d\n",nstripsP);
1898 for(int k=0;k<nstripsP;k++) {
1899 // check if 'clusterP->GetDigitStripNo(i)' returns
1900 // the digit index and not smth else
1901 cnew.fIndexMap[k] = cluster->GetDigitStripNo(k);
1905 //cnew.fProbability=0.75;
1906 //printf("AddCluster: %p nstripsP %d\n",&cnew,nstripsP);
1907 fITS->AddCluster(2,&cnew);
1908 // add the rec point info
1909 AliITSRecPoint rnew;
1910 rnew.SetX(kconv*(x1+x2)/2);
1911 rnew.SetZ(kconv*(z1+z2)/2);
1913 rnew.SetdEdX(sig/kdEdXtoQ);
1914 rnew.SetSigmaX2( kRMSx* kRMSx);
1915 rnew.SetSigmaZ2( kRMSz* kRMSz);
1916 //rnew.SetProbability(0.75);
1917 rnew.fTracks[0]=dig->fTracks[0];
1918 rnew.fTracks[1]=dig->fTracks[1];
1919 rnew.fTracks[2]=dig->fTracks[2];
1920 //printf("digP: %d %d %d\n",dig->fTracks[0],dig->fTracks[1],dig->fTracks[2]);
1921 //printf("SSD - P : track1 track2 track3 X Z %d %d %d %f %f\n",rnew.fTracks[0],rnew.fTracks[1],rnew.fTracks[2],kconv*(x1+x2)/2,kconv*(z1+z2)/2);
1922 fITS->AddRecPoint(rnew);
1924 fPointsM->AddLast( (TObject*)
1925 new AliITSRecPointSSD((x1+x2)/2 ,0,0,0,(z1+z2)/2,0,sig,sigerr,fLayer,fLad,fDet,cluster, 0.75) );
1928 if(debug) cout<<"\n"<<": SINGLE SIDE ImpactPoint Created: X = "
1929 <<(x1+x2)/2<<" Z = "<<(z1+z2)/2<<"; Pos = "<<pos;
1934 for (i=0;i<fNClusterN;i++)
1936 //printf("N side cluster: cluster number %d\n",i);
1937 cluster = GetNSideCluster(i);
1938 if (!cluster->IsConsumed())
1940 if( (pos = cluster->GetPosition()) < fSFF)
1942 sig = cluster->GetTotalSignal();
1944 sig += sig*fPNsignalRatio;
1946 sigerr = cluster->GetTotalSignalError();
1948 x1 = -Dx/2 + pos *fPitch;
1954 GetCrossing (x2,z2);
1955 fSegmentation->GetPadIxz((x1+x2)/2,(z1+z2)/2,stripP,stripN);
1956 dig = (AliITSdigitSSD*)fMap->GetHit(0,stripN);
1957 if (!dig) printf("SSD: check the digit! dig %p\n",dig);
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 AliITSRecPoint rnew;
1978 rnew.SetX(kconv*(x1+x2)/2);
1979 rnew.SetZ(kconv*(z1+z2)/2);
1981 rnew.SetdEdX(sig/kdEdXtoQ);
1982 rnew.SetSigmaX2( kRMSx* kRMSx);
1983 rnew.SetSigmaZ2( kRMSz* kRMSz);
1984 //rnew.SetProbability(0.75);
1985 rnew.fTracks[0]=dig->fTracks[0];
1986 rnew.fTracks[1]=dig->fTracks[1];
1987 rnew.fTracks[2]=dig->fTracks[2];
1988 //printf("digN: %d %d %d\n",dig->fTracks[0],dig->fTracks[1],dig->fTracks[2]);
1989 //printf("SSD -N : track1 track2 track3 X Z %d %d %d %f %f\n",rnew.fTracks[0],rnew.fTracks[1],rnew.fTracks[2],kconv*(x1+x2)/2,kconv*(z1+z2)/2);
1990 fITS->AddRecPoint(rnew);
1992 fPointsM->AddLast( (TObject*)
1993 new AliITSRecPointSSD((x1+x2)/2 ,0,0,0,(z1+z2)/2,0,sig,sigerr,fLayer,fLad,fDet,cluster, 0.75) );
1996 if(debug) cout<<"\n"<<": SINGLE SIDE ImpactPoint Created: X = "
1997 <<(x1+x2)/2<<" Z = "<<(z1+z2)/2<<"; Pos = "<<pos;
2006 //_______________________________________________________________________
2008 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)
2047 // get crossing error
2051 dz = TMath::Abs(( dP + dN )*fPitch/(fTanP + fTanN) );
2052 dx = fPitch*(TMath::Abs(dP*(1 - fTanP/(fTanP + fTanN))) +
2053 TMath::Abs(dN *fTanP/(fTanP + fTanN) ));