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
27 Eroor counting routines
28 Automatic combination routines improved (traps)
34 #include "AliITSMapA1.h"
35 #include "AliITSClusterFinderSSD.h"
36 #include "AliITSclusterSSD.h"
37 #include "AliITSpackageSSD.h"
40 const Bool_t AliITSClusterFinderSSD::fgkSIDEP=kTRUE;
41 const Bool_t AliITSClusterFinderSSD::fgkSIDEN=kFALSE;
43 static const Int_t debug=0;
45 ClassImp(AliITSClusterFinderSSD)
47 //____________________________________________________________________
50 //____________________________________________________________________
54 AliITSClusterFinderSSD::AliITSClusterFinderSSD(AliITSsegmentation *seg, TClonesArray *digits, TClonesArray *recp)
61 fMap = new AliITSMapA1(fSegmentation,fDigits);
63 fITS=(AliITS*)gAlice->GetModule("ITS");
65 fClusterP = new TClonesArray ("AliITSclusterSSD",200);
68 fClusterN= new TClonesArray ("AliITSclusterSSD",200);
71 fPackages = new TClonesArray ("AliITSpackageSSD",200); //packages
75 fDigitsIndexP = new TArrayI(300);
78 fDigitsIndexN = new TArrayI(300);
86 fPitch = fSegmentation->Dpx(0);
87 Float_t StereoP,StereoN;
88 fSegmentation->Angles(StereoP,StereoN);
89 fTanP=TMath::Tan(StereoP);
90 fTanN=TMath::Tan(StereoN);
92 fPNsignalRatio=7./8.; // warning: hard-wired number
96 //-------------------------------------------------------
97 AliITSClusterFinderSSD::~AliITSClusterFinderSSD() {
102 delete fDigitsIndexP;
103 delete fDigitsIndexN;
109 //-------------------------------------------------------
110 void AliITSClusterFinderSSD::InitReconstruction()
113 register Int_t i; //iterator
115 for (i=0;i<fNClusterP;i++)
117 fClusterP->RemoveAt(i);
120 for (i=0;i<fNClusterN;i++)
122 fClusterN->RemoveAt(i);
126 for (i=0;i<fNPackages;i++)
128 fPackages->RemoveAt(i);
135 Float_t StereoP,StereoN;
136 fSegmentation->Angles(StereoP,StereoN);
138 CalcStepFactor (StereoP,StereoN);
140 if (debug) cout<<"fSFF = "<<fSFF<<" fSFB = "<<fSFB<<"\n";
144 //---------------------------------------------
145 void AliITSClusterFinderSSD::FindRawClusters()
147 //Piotr Krzysztof Skowronski
148 //Warsaw University of Technology
149 //skowron@if.pw.edu.pl
151 // This function findes out all clusters belonging to one module
152 // 1. Zeroes all space after previous module reconstruction
153 // 2. Finds all neighbouring digits
154 // 3. If necesery, resolves for each group of neighbouring digits
155 // how many clusters creates it.
156 // 4. Creates packages
157 // 5. Creates clusters
159 InitReconstruction(); //ad. 1
163 FindNeighbouringDigits(); //ad. 2
164 SeparateOverlappedClusters(); //ad. 3
165 ClustersToPackages(); //ad. 4
167 PackagesToPoints(); //ad. 5
168 ReconstructNotConsumedClusters();
174 //-------------------------------------------------
175 void AliITSClusterFinderSSD::FindNeighbouringDigits()
179 //Piotr Krzysztof Skowronski
180 //Warsaw University of Technology
181 //skowron@if.pw.edu.pl
185 //If there are any digits on this side, create 1st Cluster,
186 // add to it this digit, and increment number of clusters
188 if ((fNDigitsP>0 ) && (fNDigitsN > 0 )) {
190 Int_t currentstripNo;
191 Int_t *dbuffer = new Int_t [300]; //buffer for strip numbers
192 Int_t dnumber; //curent number of digits in buffer
193 TArrayI &lDigitsIndexP = *fDigitsIndexP;
194 TArrayI &lDigitsIndexN = *fDigitsIndexN;
195 TObjArray &lDigits=*fDigits;
196 TClonesArray &lClusterP = *fClusterP;
197 TClonesArray &lClusterN = *fClusterN;
201 dbuffer[0]=lDigitsIndexP[0];
202 //If next digit is a neighbour of previous, adds to last cluster this digit
203 for (i=1; i<fNDigitsP; i++) {
205 currentstripNo = ((AliITSdigitSSD*)lDigits[lDigitsIndexP[i]])->
207 //check if it is a neighbour of a previous one
208 if ( (((AliITSdigitSSD*)lDigits[lDigitsIndexP[i-1]])->GetStripNumber())
209 == (currentstripNo-1) ) dbuffer[dnumber++]=lDigitsIndexP[i];
211 //create a new one side cluster
212 new(lClusterP[fNClusterP++]) AliITSclusterSSD(dnumber,dbuffer,fDigits,fgkSIDEP);
213 dbuffer[0]=lDigitsIndexP[i];
216 } // end loop over fNDigitsP
217 new(lClusterP[fNClusterP++]) AliITSclusterSSD(dnumber,dbuffer,fDigits,fgkSIDEP);
221 //for comments, see above
223 dbuffer[0]=lDigitsIndexN[0];
224 //If next digit is a neighbour of previous, adds to last cluster this digit
225 for (i=1; i<fNDigitsN; i++) {
226 currentstripNo = ((AliITSdigitSSD*)(lDigits[lDigitsIndexN[i]]))->
228 if ( (((AliITSdigitSSD*)lDigits[lDigitsIndexN[i-1]])->GetStripNumber())
229 == (currentstripNo-1) ) dbuffer[dnumber++]=lDigitsIndexN[i];
231 new(lClusterN[fNClusterN++]) AliITSclusterSSD(dnumber,dbuffer,fDigits,fgkSIDEN);
232 dbuffer[0]=lDigitsIndexN[i];
235 } // end loop over fNDigitsN
236 new(lClusterN[fNClusterN++]) AliITSclusterSSD(dnumber,dbuffer,fDigits,fgkSIDEN);
239 } // end condition on NDigits
241 if (debug) cout<<"\n Found clusters: fNClusterP = "<<fNClusterP<<" fNClusterN ="<<fNClusterN<<"\n";
244 /**********************************************************************/
247 void AliITSClusterFinderSSD::SeparateOverlappedClusters()
249 //************************************************
250 //Piotr Krzysztof Skowronski
251 //Warsaw University of Technology
252 //skowron@if.pw.edu.pl
254 register Int_t i; //iterator
256 Float_t factor=0.75; // How many percent must be lower signal
257 // on the middle one digit
258 // from its neighbours
259 Int_t signal0; //signal on the strip before the current one
260 Int_t signal1; //signal on the current one signal
261 Int_t signal2; //signal on the strip after the current one
262 TArrayI *splitlist; // List of splits
263 Int_t numerofsplits=0; // number of splits
264 Int_t initPsize = fNClusterP; //initial size of the arrays
265 Int_t initNsize = fNClusterN; //we have to keep it because it will grow
266 // in this function and it doasn't make
267 // sense to pass through it again
269 splitlist = new TArrayI(300);
271 for (i=0;i<initPsize;i++)
273 if (( ((AliITSclusterSSD*)(*fClusterP)[i])->GetNumOfDigits())==1) continue;
274 if (( ((AliITSclusterSSD*)(*fClusterP)[i])->GetNumOfDigits())==2) continue;
275 Int_t nj=(((AliITSclusterSSD*)(*fClusterP)[i])->GetNumOfDigits()-1);
276 for (Int_t j=1; j<nj; j++)
278 signal1=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j);
279 signal0=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j-1);
280 signal2=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j+1);
281 //if signal is less then factor*signal of its neighbours
282 if ( (signal1<(factor*signal0)) && (signal1<(factor*signal2)) )
284 (*splitlist)[numerofsplits++]=j;
286 } // end loop over number of digits
287 //split this cluster if necessary
288 if(numerofsplits>0) SplitCluster(splitlist,numerofsplits,i,fgkSIDEP);
291 //in signed places (splitlist)
292 } // end loop over clusters on Pside
294 for (i=0;i<initNsize;i++) {
295 if (( ((AliITSclusterSSD*)(*fClusterN)[i])->GetNumOfDigits())==1) continue;
296 if (( ((AliITSclusterSSD*)(*fClusterN)[i])->GetNumOfDigits())==2) continue;
297 Int_t nj=(((AliITSclusterSSD*)(*fClusterN)[i])->GetNumOfDigits()-1);
298 for (Int_t j=1; j<nj; j++)
300 signal1=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j);
301 signal0=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j-1);
302 signal2=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j+1);
303 //if signal is less then factor*signal of its neighbours
304 if ( (signal1<(factor*signal0)) && (signal1<(factor*signal2)) )
305 (*splitlist)[numerofsplits++]=j;
306 } // end loop over number of digits
307 //split this cluster into more clusters
308 if(numerofsplits>0) SplitCluster(splitlist,numerofsplits,i,fgkSIDEN);
309 numerofsplits=0; //in signed places (splitlist)
310 } // end loop over clusters on Nside
315 //-------------------------------------------------------
316 void AliITSClusterFinderSSD::SplitCluster(TArrayI *list, Int_t nsplits, Int_t index, Bool_t side)
320 //Piotr Krzysztof Skowronski
321 //Warsaw University of Technology
322 //skowron@if.pw.edu.pl
324 //This function splits one side cluster into more clusters
325 //number of splits is defined by "nsplits"
326 //Place of splits are defined in the TArray "list"
328 // For further optimisation: Replace this function by two
329 // specialised ones (each for one side)
332 //For comlete comments see AliITSclusterSSD::SplitCluster
335 register Int_t i; //iterator
337 AliITSclusterSSD* curentcluster;
338 Int_t *tmpdigits = new Int_t[100];
340 // side true means P side
342 curentcluster =((AliITSclusterSSD*)((*fClusterP)[index])) ;
343 for (i = nsplits; i>0 ;i--) {
344 NN=curentcluster->SplitCluster((*list)[(i-1)],tmpdigits);
345 new ((*fClusterP)[fNClusterP]) AliITSclusterSSD(NN,tmpdigits,fDigits,side);
346 ( (AliITSclusterSSD*)((*fClusterP)[fNClusterP]) )->
347 SetLeftNeighbour(kTRUE);
348 //if left cluster had neighbour on the right before split
349 //new should have it too
350 if ( curentcluster->GetRightNeighbour() )
351 ( (AliITSclusterSSD*)((*fClusterP)[fNClusterP]) )->
352 SetRightNeighbour(kTRUE);
353 else curentcluster->SetRightNeighbour(kTRUE);
355 } // end loop over nplits
357 curentcluster =((AliITSclusterSSD*)((*fClusterN)[index]));
358 for (i = nsplits; i>0 ;i--) {
359 NN=curentcluster->SplitCluster((*list)[(i-1)],tmpdigits);
360 new ((*fClusterN)[fNClusterN]) AliITSclusterSSD(NN,tmpdigits,fDigits,side);
361 ((AliITSclusterSSD*)((*fClusterN)[fNClusterN]))->
362 SetRightNeighbour(kTRUE);
363 if (curentcluster->GetRightNeighbour())
364 ( (AliITSclusterSSD*)( (*fClusterN)[fNClusterN]) )->
365 SetRightNeighbour(kTRUE);
366 else curentcluster->SetRightNeighbour(kTRUE);
368 } // end loop over nplits
375 //-------------------------------------------------
376 Int_t AliITSClusterFinderSSD::SortDigitsP(Int_t start, Int_t end)
380 //Piotr Krzysztof Skowronski
381 //Warsaw University of Technology
382 //skowron@if.pw.edu.pl
386 if (start != (end - 1) )
388 left=this->SortDigitsP(start,(start+end)/2);
389 right=this->SortDigitsP((start+end)/2,end);
390 return (left || right);
394 left = ((AliITSdigitSSD*)((*fDigits)[(*fDigitsIndexP)[start]]))->GetStripNumber();
395 right= ((AliITSdigitSSD*)((*fDigits)[(*fDigitsIndexP)[end]]))->GetStripNumber();
398 Int_t tmp = (*fDigitsIndexP)[start];
399 (*fDigitsIndexP)[start]=(*fDigitsIndexP)[end];
400 (*fDigitsIndexP)[end]=tmp;
408 //--------------------------------------------------
410 Int_t AliITSClusterFinderSSD::SortDigitsN(Int_t start, Int_t end)
414 //Piotr Krzysztof Skowronski
415 //Warsaw University of Technology
416 //skowron@if.pw.edu.pl
420 if (start != (end - 1))
422 left=this->SortDigitsN(start,(start+end)/2);
423 right=this->SortDigitsN((start+end)/2,end);
424 return (left || right);
428 left =((AliITSdigitSSD*)((*fDigits)[(*fDigitsIndexN)[start]]))->GetStripNumber();
429 right=((AliITSdigitSSD*)((*fDigits)[(*fDigitsIndexN)[end]]))->GetStripNumber();
432 Int_t tmp = (*fDigitsIndexN)[start];
433 (*fDigitsIndexN)[start]=(*fDigitsIndexN)[end];
434 (*fDigitsIndexN)[end]=tmp;
441 //------------------------------------------------
442 void AliITSClusterFinderSSD::FillDigitsIndex()
446 //Piotr Krzysztof Skowronski
447 //Warsaw University of Technology
448 //skowron@if.pw.edu.pl
450 //Fill the indexes of the clusters belonging to a given ITS module
451 //Created by Piotr K. Skowronski, August 7 1999
458 N = fDigits->GetEntriesFast();
460 Int_t* PSidx = new Int_t [N*sizeof(Int_t)];
461 Int_t* NSidx = new Int_t [N*sizeof(Int_t)];
462 if (fDigitsIndexP==NULL) fDigitsIndexP = new TArrayI(N);
463 if (fDigitsIndexN==NULL) fDigitsIndexN = new TArrayI(N);
467 for ( i = 0 ; i< N; i++ ) {
468 dig=(AliITSdigitSSD*)fDigits->UncheckedAt(i);
471 tmp=dig->GetStripNumber();
472 // I find this totally unnecessary - it's just a
473 // CPU consuming double check
478 if (debug) cout<<"Such a digit exists \n";
484 fDigitsIndexP->AddAt(i,fNDigitsP++);
489 tmp=dig->GetStripNumber();
495 if (debug) cout<<"Such a digit exists \n";
501 fDigitsIndexN->AddAt(i,fNDigitsN++);
508 if (debug) cout<<"Digits : P = "<<fNDigitsP<<" N = "<<fNDigitsN<<endl;
513 //-------------------------------------------
515 void AliITSClusterFinderSSD::SortDigits()
519 //Piotr Krzysztof Skowronski
520 //Warsaw University of Technology
521 //skowron@if.pw.edu.pl
527 for (i=0;i<fNDigitsP-1;i++)
528 if (SortDigitsP(0,(fNDigitsP-1-i))==0) break;
531 for (i=0;i<fNDigitsN-1;i++)
532 if(SortDigitsN(0,(fNDigitsN-1-i))==0) break;
537 //----------------------------------------------
538 void AliITSClusterFinderSSD::FillClIndexArrays(Int_t* arrayP, Int_t *arrayN)
542 //Piotr Krzysztof Skowronski
543 //Warsaw University of Technology
544 //skowron@if.pw.edu.pl
548 for (i=0; i<fNClusterP;i++)
552 for (i=0; i<fNClusterN;i++)
559 //------------------------------------------------------
560 void AliITSClusterFinderSSD::SortClusters(Int_t* arrayP, Int_t *arrayN)
564 //Piotr Krzysztof Skowronski
565 //Warsaw University of Technology
566 //skowron@if.pw.edu.pl
571 for (i=0;i<fNClusterP-1;i++)
572 if (SortClustersP(0,(fNClusterP-1),arrayP)==0) break;
576 for (i=0;i<fNClusterN-1;i++)
577 if (SortClustersN(0,(fNClusterN-1),arrayN)==0) break;
583 //---------------------------------------------------
584 Int_t AliITSClusterFinderSSD::SortClustersP(Int_t start, Int_t end, Int_t *array)
588 //Piotr Krzysztof Skowronski
589 //Warsaw University of Technology
590 //skowron@if.pw.edu.pl
596 if (start != (end - 1) ) {
597 left=this->SortClustersP(start,(start+end)/2,array);
598 right=this->SortClustersP((start+end)/2,end,array);
599 return (left || right);
601 left =((AliITSclusterSSD*)((*fClusterP)[array[start]]))->
603 right=((AliITSclusterSSD*)((*fClusterP)[array[ end ]]))->
606 Int_t tmp = array[start];
607 array[start]=array[end];
618 //-------------------------------------------------------
619 Int_t AliITSClusterFinderSSD::SortClustersN(Int_t start, Int_t end, Int_t *array)
623 //Piotr Krzysztof Skowronski
624 //Warsaw University of Technology
625 //skowron@if.pw.edu.pl
630 if (start != (end - 1) ) {
631 left=this->SortClustersN(start,(start+end)/2,array);
632 right=this->SortClustersN((start+end)/2,end,array);
633 return (left || right);
635 left =((AliITSclusterSSD*)((*fClusterN)[array[start]]))->
637 right=((AliITSclusterSSD*)((*fClusterN)[array[ end ]]))->
640 Int_t tmp = array[start];
641 array[start]=array[end];
651 //-------------------------------------------------------
652 void AliITSClusterFinderSSD::ClustersToPackages()
657 //Piotr Krzysztof Skowronski
658 //Warsaw University of Technology
659 //skowron@if.pw.edu.pl
662 Int_t *oneSclP = new Int_t[fNClusterP]; //I want to have sorted 1 S clusters
663 Int_t *oneSclN = new Int_t[fNClusterN]; //I can not sort it in TClonesArray
664 //so, I create table of indexes and
666 //I do not use TArrayI on purpose
667 // MB: well, that's not true that one
668 //cannot sort objects in TClonesArray
670 register Int_t i; //iterator
671 AliITSpackageSSD *currentpkg;
672 AliITSclusterSSD *currentP;
673 AliITSclusterSSD *currentN;
674 AliITSclusterSSD *fcurrN;
676 Int_t lastNclIndex=0; //index of last N sidecluster
677 Int_t Nclpack=0; //number of P clusters in current package
678 Int_t Pclpack=0; //number of N clusters in current package
683 Int_t tmplastNclIndex;
685 //Fills in One Side Clusters Index Array
686 FillClIndexArrays(oneSclP,oneSclN);
687 //Sorts filled Arrays
688 SortClusters(oneSclP,oneSclN);
692 new ((*fPackages)[0]) AliITSpackageSSD(fClusterP,fClusterN);
693 currentpkg = (AliITSpackageSSD*)((*fPackages)[0]);
695 //main loop on sorted P side clusters
697 for (i=0;i<fNClusterP;i++) {
698 //Take new P side cluster
699 currentP = GetPSideCluster(oneSclP[i]);
700 currentN = GetNSideCluster(oneSclN[lastNclIndex]);
701 // take a new P cluster or not ?
702 if(IsCrossing(currentP,currentN)) {
703 // don't take a new P cluster
705 currentP->AddCross(oneSclN[lastNclIndex]);
706 currentN->AddCross(oneSclP[i]);
707 currentpkg->AddPSideCluster(oneSclP[i]);
709 currentpkg->AddNSideCluster(oneSclN[lastNclIndex]);
712 //check if previous N side clusters crosses with it too
713 for(k=1;k<fSFB+1;k++) {
714 //check if we are not out of array
715 if ((lastNclIndex-k)>-1) {
716 fcurrN = GetNSideCluster( oneSclN[lastNclIndex-k] );
717 if( IsCrossing(currentP,fcurrN) ) {
718 currentP->AddCross(oneSclN[lastNclIndex-k]);
719 fcurrN->AddCross(oneSclP[i]);
720 } else break; //There is no sense to check rest of clusters
723 tmplastNclIndex=lastNclIndex;
724 //Check if next N side clusters crosses with it too
725 for (Int_t k=1;k<fSFF+1;k++) {
726 //check if we are not out of array
727 if ((tmplastNclIndex+k)<fNClusterN) {
728 fcurrN = GetNSideCluster( oneSclN[tmplastNclIndex+k] );
729 if(IsCrossing(currentP,fcurrN) ) {
731 fcurrN->AddCross(oneSclP[i]);
732 currentP->AddCross(oneSclN[tmplastNclIndex+k]);
733 currentpkg->AddNSideCluster(oneSclN[lastNclIndex]);
742 lastStripP = currentP->GetLastDigitStripNo();
743 lastStripN = currentN->GetLastDigitStripNo();
745 if((lastStripN-fSFF) < lastStripP ) {
747 if((Nclpack>0)&& (Pclpack>0)) {
748 new ((*fPackages)[fNPackages]) AliITSpackageSSD(fClusterP,fClusterN);
749 currentpkg = (AliITSpackageSSD*)((*fPackages)[fNPackages++]);
752 //so we have to take another cluster on side N and check it
753 //we have to check until taken cluster's last strip will
754 //be > last of this cluster(P)
755 //so it means that there is no corresponding cluster on side N
756 //to this cluster (P)
757 //so we have to continue main loop with new "lastNclIndex"
761 //We are not sure that next N cluter will cross with this P cluster
762 //There might one, or more, clusters that do not have any
763 //corresponding cluster on the other side
766 //Check if we are not out of array
767 if (lastNclIndex<fNClusterN) {
768 currentN = GetNSideCluster(oneSclN[lastNclIndex]);
769 if ( IsCrossing(currentP, currentN) ){
772 currentP->AddCross(oneSclN[lastNclIndex]);
773 currentN->AddCross(oneSclP[i]);
774 currentpkg->AddNSideCluster(oneSclN[lastNclIndex]);
775 currentpkg->AddPSideCluster(oneSclP[i]);
776 //Check, if next N side clusters crosses with it too
777 tmplastNclIndex=lastNclIndex;
778 for (Int_t k=1;k<fSFF+1;k++) {
779 //Check if we are not out of array
780 if ((tmplastNclIndex+k)<fNClusterN) {
781 fcurrN = GetNSideCluster(oneSclN[tmplastNclIndex+k]);
782 if( IsCrossing(currentP, fcurrN) ) {
785 currentP->AddCross(oneSclN[tmplastNclIndex+k]);
786 fcurrN->AddCross(oneSclP[i]);
787 currentpkg->AddNSideCluster(oneSclN[tmplastNclIndex+k]);
789 } else break; //we are out of array
793 firstStripP = currentP->GetFirstDigitStripNo();
794 firstStripN = currentN->GetFirstDigitStripNo();
795 if((firstStripN+fSFB)>=firstStripP) break;
798 } else goto EndOfFunction;
800 } else //EndOfPackage
803 } //else EndOfPackage
810 if ((Nclpack<1) || (Pclpack<1)) fNPackages--;
819 //-----------------------------------------------
820 void AliITSClusterFinderSSD::PackagesToPoints()
824 AliITSpackageSSD *currentpkg;
830 for (i=0;i<fNPackages;i++) {
831 //get pointer to next package
832 currentpkg = (AliITSpackageSSD*)((*fPackages)[i]);
833 NumNcl = currentpkg->GetNumOfClustersN();
834 NumPcl = currentpkg->GetNumOfClustersP();
835 if(debug) cout<<"New Package\nNumPcl ="<<NumPcl<<" NumNcl ="<<NumNcl<<"\n";
837 while(((NumPcl>=2)&&(NumNcl>2))||((NumPcl>2)&&(NumNcl>=2))) {
838 //This is case of "big" pacakage
839 //conditions see 3 lines above
840 //if in the big package exists cluster with one cross
841 //we can reconstruct this point without any geometrical ambiguities
842 if(currentpkg->GetClusterWithOneCross(clusterIndex, clusterSide) )
844 ResolveClusterWithOneCross(currentpkg, clusterIndex, clusterSide);
845 } else if (clusterIndex == -2) {
850 if ( (NumNcl==NumPcl) && (NumPcl<10)) {
851 //if there is no cluster with one cross
852 //we can resolve whole package at once
853 //by finding best combination
854 //we can make combinations when NumNcl==NumPcl
855 if (ResolvePackageBestCombin(currentpkg)) {
856 //sometimes creating combinations fail,
857 //but it happens very rarely
861 } else ResolveOneBestMatchingPoint(currentpkg);
863 ResolveOneBestMatchingPoint(currentpkg);
866 NumNcl = currentpkg->GetNumOfClustersN();
867 NumPcl = currentpkg->GetNumOfClustersP();
869 if ((NumPcl==1)&&(NumNcl==1)) {
870 ResolveSimplePackage(currentpkg);
874 ResolvePackageWithOnePSideCluster(currentpkg);
878 ResolvePackageWithOneNSideCluster(currentpkg);
881 if ((NumPcl==2)&&(NumNcl==2)) {
882 ResolveTwoForTwoPackage(currentpkg);
885 if ((NumPcl==0)&&(NumNcl>0)) { }
886 if ((NumNcl==0)&&(NumPcl>0)) { }
888 } // end loop over fNPackages
894 //----------------------------------------------------------
896 void AliITSClusterFinderSSD::
897 ResolveClusterWithOneCross(AliITSpackageSSD *currentpkg, Int_t clusterIndex, Bool_t clSide)
900 if (clSide == fgkSIDEP) ResolvePClusterWithOneCross(currentpkg,clusterIndex);
901 else ResolveNClusterWithOneCross(currentpkg,clusterIndex);
906 //---------------------------------------------------------
907 void AliITSClusterFinderSSD::
908 ResolvePClusterWithOneCross(AliITSpackageSSD *pkg, Int_t clusterIndex)
912 There is cluster (side P) which crosses with only one cluster on the other
928 AliITSclusterSSD * clusterP;
929 AliITSclusterSSD * clusterN;
931 Float_t posClusterP; //Cluster P position in strip coordinates
932 Float_t posClusterN; //Cluster N position in strip coordinates
934 Float_t posErrorClusterP;
935 Float_t posErrorClusterN;
940 Float_t sigErrorClusterP;
941 Float_t sigErrorClusterN;
949 if (debug) cout<<"ResolvePClusterWithOneCross\n";
951 clusterP=pkg->GetPSideCluster(clusterIndex);
952 posClusterP = GetClusterZ(clusterP);
953 posErrorClusterP = clusterP->GetPositionError();
954 sigClusterP = ps = clusterP->GetTotalSignal();
955 sigErrorClusterP = clusterP->GetTotalSignalError();
956 //carefully, it returns index in TClonesArray
958 clusterIdx = clusterP->GetCross(0);
959 clusterN=this->GetNSideCluster(clusterIdx);
960 ns = clusterN->GetTotalSignal();
961 posClusterN = GetClusterZ(clusterN);
962 posErrorClusterN = clusterN->GetPositionError();
963 pkg->DelCluster(clusterIndex,fgkSIDEP);
964 sigClusterN = ps/fPNsignalRatio;
965 // there is no sonse to check how signal ratio is far from perfect
966 // matching line if the if below it is true
967 if (ns < sigClusterN) {
969 if (debug) cout<<"n1 < p1/fPNsignalRatio";
970 if (debug) cout<<"Attempting to del cluster N "<<clusterIdx<<" ... \n";
971 pkg->DelClusterOI(clusterIdx,fgkSIDEN);
973 //Let's see how signal ratio is far from perfect matching line
974 Chicomb = DistToPML(ps,ns);
975 if (debug) cout<<"Chic "<<Chicomb<<"\n";
976 if (Chicomb > falpha2) {
977 //it is near, so we can risk throwing this cluster away too
978 if (debug) cout<<"Attempting to del cluster N "<<clusterIdx<<"...\n";
979 pkg->DelClusterOI(clusterIdx,fgkSIDEN);
981 clusterN->CutTotalSignal(sigClusterN);
982 if (debug) cout <<"Signal cut |||||||||||||\n";
985 sigErrorClusterN= clusterN->GetTotalSignalError();
986 CreateNewRecPoint(posClusterP,posErrorClusterP,posClusterN,posErrorClusterN,
987 sigClusterP+sigClusterN, sigErrorClusterN+sigErrorClusterP,
988 clusterP, clusterN, 0.75);
993 //------------------------------------------------------
994 void AliITSClusterFinderSSD::
995 ResolveNClusterWithOneCross(AliITSpackageSSD *pkg, Int_t clusterIndex)
998 AliITSclusterSSD * clusterP;
999 AliITSclusterSSD * clusterN;
1001 Float_t posClusterP; //Cluster P position in strip coordinates
1002 Float_t posClusterN; //Cluster N position in strip coordinates
1004 Float_t posErrorClusterP;
1005 Float_t posErrorClusterN;
1007 Float_t sigClusterP;
1008 Float_t sigClusterN;
1010 Float_t sigErrorClusterP;
1011 Float_t sigErrorClusterN;
1019 if (debug) cout<<"ResolveNClusterWithOneCross\n";
1021 clusterN=pkg->GetNSideCluster(clusterIndex);
1022 posClusterN = GetClusterZ(clusterN);
1023 posErrorClusterN = clusterN->GetPositionError();
1024 sigClusterN = ns = clusterN->GetTotalSignal();
1025 sigErrorClusterN = clusterN->GetTotalSignalError();
1026 //carefully, it returns index in TClonesArray
1027 clusterIdx = clusterN->GetCross(0);
1028 clusterP=this->GetPSideCluster(clusterIdx);
1029 ps = clusterP->GetTotalSignal();
1030 posClusterP = GetClusterZ(clusterP);
1031 posErrorClusterP = clusterP->GetPositionError();
1032 pkg->DelCluster(clusterIndex,fgkSIDEN);
1033 sigClusterP=ns*fPNsignalRatio;
1034 // there is no sonse to check how signal ratio is far from perfect
1035 // matching line if the if below it is true
1036 if (ps < sigClusterP) {
1038 if (debug) cout<<"ps < ns*fPNsignalRatio";
1039 if (debug) cout<<"Attempting to del cluster P "<<clusterIdx<<" ... \n";
1040 pkg->DelClusterOI(clusterIdx,fgkSIDEP);
1042 //Let's see how signal ratio is far from perfect matching line
1043 Chicomb = DistToPML(ps,ns);
1044 if (debug) cout<<"Chic "<<Chicomb<<"\n";
1045 if (Chicomb > falpha2) {
1046 //it is near, so we can risk frowing this cluster away too
1047 if (debug) cout<<"Attempting to del cluster P "<<clusterIdx<<"...\n";
1048 pkg->DelClusterOI(clusterIdx,fgkSIDEP);
1050 clusterN->CutTotalSignal(sigClusterP);
1051 if (debug) cout <<"Signal cut ------------\n";
1054 sigErrorClusterP= clusterP->GetTotalSignalError();
1055 CreateNewRecPoint( posClusterP,posErrorClusterP,posClusterN,posErrorClusterN,
1056 sigClusterP+sigClusterN,sigErrorClusterN+sigErrorClusterP,
1057 clusterP, clusterN, 0.75);
1064 //-------------------------------------------------------
1066 Bool_t AliITSClusterFinderSSD::
1067 ResolvePackageBestCombin(AliITSpackageSSD *pkg)
1069 if (debug) cout<<"NumNcl==NumPcl ("<<pkg->GetNumOfClustersN()
1070 <<"=="<<pkg->GetNumOfClustersP()<<"); Generating combinations ... \n";
1073 AliITSclusterSSD * clusterP;
1074 AliITSclusterSSD * clusterN;
1076 Int_t Ncombin; //Number of combinations
1077 Int_t itera; //iterator
1078 Int_t sizet=1; //size of array to allocate
1080 Int_t NP = pkg->GetNumOfClustersP();
1081 for (itera =2; itera <= NP ;itera ++) {
1083 if (sizet > 10000) {
1089 Int_t** combin = new Int_t*[sizet]; //2D array to keep combinations in
1091 for (itera =0; itera <sizet;itera++) {
1092 combin[itera] = new Int_t[NP+1];
1095 pkg->GetAllCombinations(combin,Ncombin,sizet);
1098 if (debug) cout<<"No combin Error";
1101 //calculate which combination fits the best to perfect matching line
1102 Int_t bc = GetBestComb(combin,Ncombin,NP,pkg);
1103 if (debug) cout<<" bc "<<bc <<"\n";
1105 for (itera =0; itera < NP; itera ++) {
1106 clusterP = pkg->GetPSideCluster(itera);
1108 //becase AliITSclusterSSD::GetCross returns index in
1109 //AliITSmoduleSSD.fClusterP, which is put to "combin"
1110 clusterN = GetNSideCluster(combin[bc][itera]);
1111 CreateNewRecPoint(clusterP, clusterN, 0.75);
1114 for (itera =0; itera <sizet;itera++) {
1115 delete [](combin[itera]);
1123 //----------------------------------------------------
1124 void AliITSClusterFinderSSD::
1125 ResolveOneBestMatchingPoint(AliITSpackageSSD *pkg)
1131 Int_t nextP, nextN=0;
1134 AliITSclusterSSD * clusterP;
1135 AliITSclusterSSD * clusterN;
1137 Bool_t split = kFALSE;
1139 if (debug) cout<<"ResolveOneBestMatchingPoint \n";
1141 GetBestMatchingPoint(pi, ni, pkg);
1143 clusterP = GetPSideCluster(pi);
1144 clusterN = GetNSideCluster(ni);
1146 CreateNewRecPoint(clusterP, clusterN, 0.75);
1148 if ((nextP=pkg->GetNextPIdx(pi))!=-1)
1149 if ((nextN=pkg->GetNextNIdx(ni))!=-1)
1150 if ((prvP=pkg->GetPrvPIdx(pi))!=-1)
1151 if ((prvN=pkg->GetPrvNIdx(ni))!=-1)
1152 if( !(GetPSideCluster(prvP)->IsCrossingWith(nextN)))
1153 if( !(GetPSideCluster(nextP)->IsCrossingWith(prvN)))
1159 pkg->DelClusterOI(pi, fgkSIDEP);
1160 pkg->DelClusterOI(ni, fgkSIDEN);
1163 if (debug) cout<<"spltting package ...\n";
1164 new ((*fPackages)[fNPackages]) AliITSpackageSSD(fClusterP,fClusterN);
1166 SplitPackage(nextP,nextN,(AliITSpackageSSD*)((*fPackages)[fNPackages++]));
1172 //--------------------------------------------------
1173 void AliITSClusterFinderSSD::ResolveSimplePackage(AliITSpackageSSD *pkg)
1176 AliITSclusterSSD * clusterP;
1177 AliITSclusterSSD * clusterN;
1179 clusterP = pkg->GetPSideCluster(0);
1181 clusterN = pkg->GetNSideCluster(0);
1183 CreateNewRecPoint(clusterP, clusterN, 1.0);
1189 //--------------------------------------------------
1190 void AliITSClusterFinderSSD:: ResolvePackageWithOnePSideCluster(AliITSpackageSSD *pkg) {
1206 /************************/
1207 /**************************/
1208 /*XP SP itg jest tylko jeden nie musi byc tablica i w peetli nie trzeba po niej iterowcac*/
1209 /***************************/
1213 AliITSclusterSSD * clusterP;
1214 AliITSclusterSSD * clusterN;
1216 Int_t NN=pkg->GetNumOfClustersN();
1222 Float_t * XN = new Float_t[NN];
1223 Float_t * XNerr = new Float_t[NN];
1225 Float_t * SP = new Float_t[NN];
1226 Float_t * SN = new Float_t[NN];
1228 Float_t * SPerr = new Float_t[NN];
1229 Float_t * SNerr = new Float_t[NN];
1234 clusterP = pkg->GetPSideCluster(0);
1235 p1 = clusterP->GetTotalSignal();
1237 XP = GetClusterZ(clusterP);
1238 XPerr = clusterP->GetPositionError();
1239 p1err = clusterP->GetTotalSignalError();
1241 for (k=0;k<NN;k++) {
1242 SN[k] = pkg->GetNSideCluster(k)->GetTotalSignal();
1243 SNerr[k] = pkg->GetNSideCluster(k)->GetTotalSignalError();
1246 for (k=0;k<NN;k++) {
1247 clusterN = pkg->GetNSideCluster(k);
1248 SP[k]= p1*SN[k]/sumsig;
1249 SPerr[k] = p1err*SN[k]/sumsig;
1250 XN[k]=GetClusterZ(clusterN);
1251 XNerr[k]= clusterN->GetPositionError();
1252 CreateNewRecPoint(XP,XPerr, XN[k],XNerr[k], SP[k]+SN[k], SPerr[k]+SNerr[k], clusterP, clusterN, 1.0);
1259 //---------------------------------------------------------
1260 void AliITSClusterFinderSSD::ResolvePackageWithOneNSideCluster(AliITSpackageSSD *pkg) {
1277 AliITSclusterSSD * clusterP;
1278 AliITSclusterSSD * clusterN;
1280 Int_t NP=pkg->GetNumOfClustersP();
1283 Float_t * XP = new Float_t[NP];
1284 Float_t * XPerr = new Float_t[NP];
1289 Float_t * SP = new Float_t[NP];
1290 Float_t * SN = new Float_t[NP];
1292 Float_t * SPerr = new Float_t[NP];
1293 Float_t * SNerr = new Float_t[NP];
1298 clusterN = pkg->GetNSideCluster(0);
1299 n1 = clusterN->GetTotalSignal();
1301 XN = GetClusterZ(clusterN);
1302 XNerr = clusterN->GetPositionError();
1304 n1err=clusterN->GetTotalSignalError();
1306 for (k=0;k<NP;k++) {
1307 SP[k] = pkg->GetPSideCluster(k)->GetTotalSignal();
1309 SPerr[k] = pkg->GetPSideCluster(k)->GetTotalSignalError();
1312 for (k=0;k<NP;k++) {
1313 clusterP = pkg->GetPSideCluster(k);
1314 SN[k]= n1*SP[k]/sumsig;
1315 XP[k]=GetClusterZ(clusterP);
1316 XPerr[k]= clusterP->GetPositionError();
1317 SNerr[k] = n1err*SP[k]/sumsig;
1318 CreateNewRecPoint(XP[k],XPerr[k], XN,XNerr, SP[k]+SN[k], SPerr[k]+SNerr[k],clusterP, clusterN, 1.0);
1324 /**********************************************************************/
1325 /********* 2 X 2 *********************************************/
1326 /**********************************************************************/
1328 void AliITSClusterFinderSSD::
1329 ResolveTwoForTwoPackage(AliITSpackageSSD *pkg)
1332 AliITSclusterSSD *clusterP1 = pkg->GetPSideCluster(0);
1333 AliITSclusterSSD *clusterP2 = pkg->GetPSideCluster(1);
1334 AliITSclusterSSD *clusterN1 = pkg->GetNSideCluster(0);
1335 AliITSclusterSSD *clusterN2 = pkg->GetNSideCluster(1);
1337 AliITSclusterSSD *tmp;
1364 if(clusterP1->GetDigitStripNo(0) > clusterP2->GetDigitStripNo(0)) {
1365 if (debug) cout<<"P strips flip\n";
1367 clusterP1 = clusterP2;
1370 if(clusterN1->GetDigitStripNo(0) > clusterN2->GetDigitStripNo(0)) {
1371 if (debug) cout<<"N strips flip\n";
1373 clusterN1 = clusterN2;
1376 p1sig = clusterP1->GetTotalSignal();
1377 p2sig = clusterP2->GetTotalSignal();
1378 n1sig = clusterN1->GetTotalSignal();
1379 n2sig = clusterN2->GetTotalSignal();
1382 p1sigErr = clusterP1->GetTotalSignalError();
1383 n1sigErr = clusterN1->GetTotalSignalError();
1384 p2sigErr = clusterP2->GetTotalSignalError();
1385 n2sigErr = clusterN2->GetTotalSignalError();
1387 ZposP1 = clusterP1->GetPosition();
1388 ZposN1 = clusterN1->GetPosition();
1389 ZposP2 = clusterP2->GetPosition();
1390 ZposN2 = clusterN2->GetPosition();
1392 ZposErrP1 = clusterP1->GetPositionError();
1393 ZposErrN1 = clusterN1->GetPositionError();
1394 ZposErrP2 = clusterP2->GetPositionError();
1395 ZposErrN2 = clusterN2->GetPositionError();
1397 //in this may be two types:
1398 // 1.When each cluster crosses with 2 clusters on the other side
1399 // gives 2 ghosts and 2 real points
1401 // 2.When two clusters (one an each side) crosses with only one on
1402 // the other side and two crosses (one on the each side) with
1403 // two on the other gives 2 or 3 points,
1405 if (debug) cout<<"2 for 2 ambiguity ...";
1406 /***************************/
1407 /*First sort of combination*/
1408 /***************************/
1410 if((clusterP1->GetCrossNo()==2) && (clusterN1->GetCrossNo()==2)) {
1411 if (debug) cout<<"All clusters has 2 crosses\n";
1412 D12 = TMath::Sqrt((Float_t)((p1sig -p2sig)*(p1sig -p2sig) + (n1sig -n2sig)*(n1sig -n2sig)));
1414 if(debug) cout<<"Distance between points in P(N) plane D12 = "<<D12<<"\n";
1416 /*********************************************/
1417 /*resolving ambiguities: */
1418 /*we count Chicomb's and we take combination */
1419 /*giving lower Chicomb as a real points */
1420 /*Keep only better combinantion */
1421 /*********************************************/
1423 if (D12 > (falpha3*17.8768)) {
1424 if (debug) cout<<"decided to take only one pair \n";
1425 Chicomb1 = DistToPML(p1sig,n1sig) + DistToPML(p2sig,n2sig);
1426 Chicomb2 = DistToPML(p2sig,n1sig) + DistToPML(p1sig,n2sig);
1428 cout<<" 00 11 combination : "<<Chicomb1<<" 01 10 combination : "<<Chicomb2<<" \n";
1429 cout<<"p1 = "<<p1sig<<" n1 = "<<n1sig<<" p2 = "<<p2sig<<" n2 = "<<n2sig<<"\n";
1431 if (Chicomb1 < Chicomb2) {
1432 if (debug) cout<<"00 11";
1433 CreateNewRecPoint(ZposP1,ZposErrP1, ZposN1,ZposErrN1, p1sig+n1sig, p1sigErr+n1sigErr, clusterP1, clusterN1, 0.75);
1434 CreateNewRecPoint(ZposP2,ZposErrP2, ZposN2,ZposErrN2, p2sig+n2sig, p2sigErr+n2sigErr, clusterP2, clusterN2, 0.75);
1437 //second cominantion
1439 if (debug) cout<<"01 10";
1440 CreateNewRecPoint(ZposP1,0, ZposN2,0, p1sig+n2sig, p1sigErr+n2sigErr, clusterP1, clusterN2, 0.75);
1441 CreateNewRecPoint(ZposP2,0, ZposN1,0, p2sig+n1sig, p2sigErr+n1sigErr, clusterP2, clusterN1, 0.75);
1442 } //end second combinantion
1443 //if (D12 > falpha3*17.8768)
1444 //keep all combinations
1446 if (debug) cout<<"We decide to take all points\n";
1447 CreateNewRecPoint(ZposP1,ZposErrP1, ZposN1,ZposErrN1, p1sig+n1sig, p1sigErr+n1sigErr, clusterP1, clusterN1, 0.5);
1448 CreateNewRecPoint(ZposP2,ZposErrP2, ZposN2,ZposErrN2, p2sig+n2sig, p2sigErr+n2sigErr, clusterP2, clusterN2, 0.5);
1449 CreateNewRecPoint(ZposP1,ZposErrP1, ZposN2,ZposErrN2, p1sig+n2sig, p1sigErr+n2sigErr, clusterP1, clusterN2, 0.5);
1450 CreateNewRecPoint(ZposP2,ZposErrP2, ZposN1,ZposErrN1, p2sig+n1sig, p2sigErr+n1sigErr, clusterP2, clusterN1, 0.5);
1453 // ad.2 Second type of combination
1455 Chicomb1 = DistToPML(p1sig,n1sig) + DistToPML(p2sig,n2sig);
1456 if (debug) cout<<"\nhere can be reconstructed 3 points: chicomb = "<<Chicomb1<<"\n";
1458 if (Chicomb1<falpha1) {
1459 if (debug) cout<<"\nWe decided to take 3rd point";
1460 if (clusterP1->GetCrossNo()==1) {
1461 if (debug) cout<<"... P1 has one cross\n";
1462 n1sig = p1sig/fPNsignalRatio;
1463 p2sig = n2sig*fPNsignalRatio;
1465 clusterN1->CutTotalSignal(n1sig);
1466 clusterP2->CutTotalSignal(p2sig);
1468 CreateNewRecPoint(ZposP2,ZposErrP2, ZposN1,ZposErrN1, p2sig+n1sig, p2sigErr+n1sigErr, clusterP2, clusterN1, 0.5);
1470 n1sig = clusterN1->GetTotalSignal();
1471 p2sig = clusterP2->GetTotalSignal();
1474 if (debug) cout<<"... N1 has one cross\n";
1476 n2sig=p2sig/fPNsignalRatio;
1477 p1sig=n1sig*fPNsignalRatio;
1479 clusterN2->CutTotalSignal(n2sig);
1480 clusterP1->CutTotalSignal(p1sig);
1482 CreateNewRecPoint(ZposP1,ZposErrP1, ZposN2,ZposErrN2, p1sig+n2sig, p1sigErr+n2sigErr, clusterP1, clusterN2, 0.5);
1484 n2sig=clusterN2->GetTotalSignal();
1485 p1sig=clusterP1->GetTotalSignal();
1488 if (debug) cout<<"\nWe decided NOT to take 3rd point\n";
1491 CreateNewRecPoint(ZposP1,ZposErrP1, ZposN1,ZposErrN1, p1sig+n1sig, p1sigErr+n1sigErr, clusterP1, clusterN1, 1.0);
1492 CreateNewRecPoint(ZposP2,ZposErrP2, ZposN2,ZposErrN2, p2sig+n2sig, p2sigErr+n2sigErr, clusterP2, clusterN2, 1.0);
1500 //------------------------------------------------------
1501 Bool_t AliITSClusterFinderSSD::
1502 CreateNewRecPoint(Float_t P, Float_t dP, Float_t N, Float_t dN,
1503 Float_t Sig,Float_t dSig,
1504 AliITSclusterSSD *clusterP, AliITSclusterSSD *clusterN,
1508 const Float_t kdEdXtoQ = 2.778e+8;
1509 const Float_t kconv = 1.0e-4;
1510 const Float_t kRMSx = 20.0*kconv; // microns->cm ITS TDR Table 1.3
1511 const Float_t kRMSz = 830.0*kconv; // microns->cm ITS TDR Table 1.3
1516 Int_t stripP, stripN;
1518 AliITSdigitSSD *digP, *digN;
1519 if (GetCrossing(P,N)) {
1520 GetCrossingError(dP,dN);
1521 AliITSRawClusterSSD cnew;
1522 Int_t nstripsP=clusterP->GetNumOfDigits();
1523 Int_t nstripsN=clusterN->GetNumOfDigits();
1524 cnew.fMultiplicity=nstripsP;
1525 cnew.fMultiplicityN=nstripsN;
1527 if (nstripsP > 100) {
1528 printf("multiplicity > 100 - increase the dimension of the arrays %d\n",nstripsP);
1531 for(int i=0;i<nstripsP;i++) {
1532 // check if 'clusterP->GetDigitStripNo(i)' returns the digit index
1533 cnew.fIndexMap[i] = clusterP->GetDigitStripNo(i);
1535 if (nstripsN > 100) {
1536 printf("multiplicity > 100 - increase the dimension of the arrays %d\n",nstripsN);
1539 for(int i=0;i<nstripsN;i++) {
1540 // check if 'clusterN->GetDigitStripNo(i)' returns the digit index
1541 cnew.fIndexMapN[i] = clusterN->GetDigitStripNo(i);
1545 //cnew.fProbability=(float)prob;
1546 fITS->AddCluster(2,&cnew);
1547 fSegmentation->GetPadIxz(P,N,stripP,stripN);
1548 digP = (AliITSdigitSSD*)fMap->GetHit(1,stripP);
1549 digN = (AliITSdigitSSD*)fMap->GetHit(0,stripN);
1550 sigP = digP->fSignal;
1551 sigN = digN->fSignal;
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];
1566 rnew.fTracks[0]=digN->fTracks[0];
1567 rnew.fTracks[1]=digN->fTracks[1];
1568 rnew.fTracks[2]=digN->fTracks[2];
1570 fITS->AddRecPoint(rnew);
1573 fPointsM->AddLast( (TObject*)
1574 new AliITSRecPointSSD(P,dP,0,0,N,dN,Sig,dSig,fLayer,fLad,fDet,clusterP,clusterN,prob) );
1577 if(debug) cout<<"\n"<<": ImpactPoint Created: X = "<<P<<" Z = "<<N<<"; P = "<<p<<" N = "<<n<<"\n";
1581 cout<<"\n"<<": ATENTION : stupid ImpactPoit Point X = "<<P<<" Z = "<<N<<"; P = "<<p<<" N = "<<n<<"\n";
1589 /**********************************************************************/
1590 Bool_t AliITSClusterFinderSSD::
1591 CreateNewRecPoint(AliITSclusterSSD *clusterP, AliITSclusterSSD *clusterN, Stat_t prob)
1593 Float_t posClusterP; //Cluster P position in strip coordinates
1594 Float_t posClusterN; //Cluster N position in strip coordinates
1596 Float_t posErrorClusterP;
1597 Float_t posErrorClusterN;
1599 Float_t sigClusterP;
1600 Float_t sigClusterN;
1602 Float_t sigErrorClusterP;
1603 Float_t sigErrorClusterN;
1605 posClusterP = clusterP->GetPosition();
1606 posErrorClusterP = clusterP->GetPositionError();
1607 sigClusterP = clusterP->GetTotalSignal();
1608 sigErrorClusterP = clusterP->GetTotalSignalError();
1610 posClusterN = clusterN->GetPosition();
1611 posErrorClusterN = clusterN->GetPositionError();
1612 sigClusterN = clusterN->GetTotalSignal();
1613 sigErrorClusterN = clusterN->GetTotalSignalError();
1615 return CreateNewRecPoint( posClusterP,posErrorClusterP, posClusterN,posErrorClusterN,
1616 sigClusterP+sigClusterN, sigErrorClusterN+sigErrorClusterP,
1617 clusterP, clusterN, prob);
1621 //--------------------------------------------------
1622 Bool_t AliITSClusterFinderSSD::IsCrossing(AliITSclusterSSD* p, AliITSclusterSSD* n)
1624 Float_t x = p->GetPosition();
1625 Float_t y = n->GetPosition();
1626 return GetCrossing(x,y);
1630 //----------------------------------------------
1631 Bool_t AliITSClusterFinderSSD::Strip2Local( Float_t stripP, Float_t stripN, Float_t &Z,Float_t &X)
1635 //Piotr Krzysztof Skowronski
1636 //Warsaw University of Technology
1637 //skowron@if.pw.edu.pl
1640 Z = (stripN-stripP)*fFactorOne;
1641 X = (stripN + stripP - fStripZeroOffset)*fFactorTwo;
1650 if (debug) cout<<"P="<<stripP<<" N="<<stripN<<" X = "<<X<<" Z = "<<Z<<"\n";
1651 if ((Z<2.1)&&(Z>-2.1)&&(X<3.65)&&(X>-3.65)) return kTRUE;
1657 //-----------------------------------------------------------
1658 Float_t AliITSClusterFinderSSD::GetClusterZ(AliITSclusterSSD* clust)
1661 return clust->GetPosition();
1665 //-------------------------------------------------------------
1666 Int_t AliITSClusterFinderSSD::GetBestComb
1667 (Int_t** comb,Int_t Ncomb, Int_t Ncl, AliITSpackageSSD * pkg)
1671 //Piotr Krzysztof Skowronski
1672 //Warsaw University of Technology
1673 //skowron@if.pw.edu.pl
1675 //returns index of best combination in "comb"
1676 //comb : sets of combinations
1677 // in given combination on place "n" is index of
1678 // Nside cluster coresponding to "n" P side cluster
1680 //Ncomb : number of combinations == number of rows in "comb"
1682 //Ncl : number of clusters in each row == number of columns in "comb"
1687 Float_t currbval=-1; //current best value,
1688 //starting value is set to number negative,
1689 //to be changed in first loop turn automatically
1691 Int_t curridx=0; //index of combination giving currently the best chi^2
1693 Float_t ps, ns; //signal of P cluster and N cluster
1695 for (Int_t i=0;i<Ncomb;i++)
1699 for (Int_t j=0;j<Ncl;j++)
1701 ps = pkg->GetPSideCluster(j)->GetTotalSignal(); //carrefully here, different functions
1702 ns = GetNSideCluster(comb[i][j])->GetTotalSignal();
1703 chi+=DistToPML(ps,ns);
1706 if (currbval==-1) currbval = chi;
1719 //--------------------------------------------------
1720 void AliITSClusterFinderSSD::GetBestMatchingPoint
1721 (Int_t & ip, Int_t & in, AliITSpackageSSD* pkg )
1725 //Piotr Krzysztof Skowronski
1726 //Warsaw University of Technology
1727 //skowron@if.pw.edu.pl
1729 if (debug) pkg->PrintClusters();
1731 Float_t ps, ns; //signals on side p & n
1733 Int_t nc; // number of crosses in given p side cluster
1735 AliITSclusterSSD *curPcl, *curNcl; //current p side cluster
1736 Float_t bestchi, chi;
1737 ip=p=pkg->GetPSideClusterIdx(0);
1738 in=n=pkg->GetNSideClusterIdx(0);
1740 bestchi=DistToPML( pkg->GetPSideCluster(0)->GetTotalSignal(),
1741 pkg->GetNSideCluster(0)->GetTotalSignal() );
1742 for (Int_t i = 0; i< pkg->GetNumOfClustersP(); i++)
1745 p = pkg->GetPSideClusterIdx(i);
1746 curPcl= GetPSideCluster(p);
1747 nc=curPcl->GetCrossNo();
1748 ps=curPcl->GetTotalSignal();
1750 for (Int_t j = 0; j< nc; j++)
1752 n=curPcl->GetCross(j);
1753 curNcl= GetNSideCluster(n);
1754 ns=curNcl->GetTotalSignal();
1755 chi = DistToPML(ps, ns);
1769 //------------------------------------------------------
1770 void AliITSClusterFinderSSD::CalcStepFactor(Float_t Psteo, Float_t Nsteo )
1774 //Piotr Krzysztof Skowronski
1775 //Warsaw University of Technology
1776 //skowron@if.pw.edu.pl
1779 // 95 is the pitch, 4000 - dimension along z ?
1781 fSFF = ( (Int_t) (Psteo*40000/95 ) );// +1;
1782 fSFB = ( (Int_t) (Nsteo*40000/95 ) );// +1;
1786 Float_t dz=fSegmentation->Dz();
1788 fSFF = ( (Int_t) (Psteo*dz/fPitch ) );// +1;
1789 fSFB = ( (Int_t) (Nsteo*dz/fPitch ) );// +1;
1794 //-----------------------------------------------------------
1795 AliITSclusterSSD* AliITSClusterFinderSSD::GetPSideCluster(Int_t idx)
1799 //Piotr Krzysztof Skowronski
1800 //Warsaw University of Technology
1801 //skowron@if.pw.edu.pl
1805 if((idx<0)||(idx>=fNClusterP))
1807 printf("AliITSClusterFinderSSD::GetPSideCluster : index out of range\n");
1812 return (AliITSclusterSSD*)((*fClusterP)[idx]);
1816 //-------------------------------------------------------
1817 AliITSclusterSSD* AliITSClusterFinderSSD::GetNSideCluster(Int_t idx)
1821 //Piotr Krzysztof Skowronski
1822 //Warsaw University of Technology
1823 //skowron@if.pw.edu.pl
1825 if((idx<0)||(idx>=fNClusterN))
1827 printf("AliITSClusterFinderSSD::GetNSideCluster : index out of range\n");
1832 return (AliITSclusterSSD*)((*fClusterN)[idx]);
1836 //--------------------------------------------------------
1837 AliITSclusterSSD* AliITSClusterFinderSSD::GetCluster(Int_t idx, Bool_t side)
1841 //Piotr Krzysztof Skowronski
1842 //Warsaw University of Technology
1843 //skowron@if.pw.edu.pl
1845 return (side) ? GetPSideCluster(idx) : GetNSideCluster(idx);
1849 //--------------------------------------------------------
1850 void AliITSClusterFinderSSD::ConsumeClusters()
1854 for ( Int_t i=0;i<fNPackages;i++)
1856 ((AliITSpackageSSD*)((*fPackages)[i]))->ConsumeClusters();
1862 //--------------------------------------------------------
1863 void AliITSClusterFinderSSD::ReconstructNotConsumedClusters()
1866 AliITSclusterSSD *cluster;
1870 Float_t x1,x2,z1,z2;
1872 Float_t Dx = fSegmentation->Dx();
1873 Float_t Dz = fSegmentation->Dz();
1875 const Float_t kdEdXtoQ = 2.778e+8; // GeV -> number of e-hole pairs
1876 const Float_t kconv = 1.0e-4;
1877 const Float_t kRMSx = 20.0*kconv; // microns->cm ITS TDR Table 1.3
1878 const Float_t kRMSz = 830.0*kconv; // microns->cm ITS TDR Table 1.3
1880 Int_t stripP,stripN;
1881 AliITSdigitSSD *dig;
1882 for (i=0;i<fNClusterP;i++)
1884 cluster = GetPSideCluster(i);
1885 if (!cluster->IsConsumed())
1887 if( (pos = cluster->GetPosition()) < fSFB)
1889 sig = cluster->GetTotalSignal();
1891 sig += sig/fPNsignalRatio;
1893 sigerr = cluster->GetTotalSignalError();
1894 x1 = -Dx/2 + pos *fPitch;
1899 GetCrossing (x2,z2);
1900 AliITSRawClusterSSD cnew;
1901 Int_t nstripsP=cluster->GetNumOfDigits();
1902 cnew.fMultiplicity=nstripsP;
1903 cnew.fMultiplicityN=0;
1905 if (nstripsP > 100) {
1906 printf("multiplicity > 100 - increase the dimension of the arrays %d\n",nstripsP);
1909 for(int k=0;k<nstripsP;k++) {
1910 // check if 'clusterP->GetDigitStripNo(i)' returns
1911 // the digit index and not smth else
1912 cnew.fIndexMap[k] = cluster->GetDigitStripNo(k);
1916 //cnew.fProbability=0.75;
1917 fITS->AddCluster(2,&cnew);
1918 fSegmentation->GetPadIxz((x1+x2)/2,(z1+z2)/2,stripP,stripN);
1919 dig = (AliITSdigitSSD*)fMap->GetHit(1,stripP);
1920 // add the rec point info
1921 AliITSRecPoint rnew;
1922 rnew.SetX(kconv*(x1+x2)/2);
1923 rnew.SetZ(kconv*(z1+z2)/2);
1925 rnew.SetdEdX(sig/kdEdXtoQ);
1926 rnew.SetSigmaX2( kRMSx* kRMSx);
1927 rnew.SetSigmaZ2( kRMSz* kRMSz);
1928 rnew.SetProbability(0.75);
1929 rnew.fTracks[0]=dig->fTracks[0];
1930 rnew.fTracks[1]=dig->fTracks[1];
1931 rnew.fTracks[2]=dig->fTracks[2];
1932 fITS->AddRecPoint(rnew);
1934 fPointsM->AddLast( (TObject*)
1935 new AliITSRecPointSSD((x1+x2)/2 ,0,0,0,(z1+z2)/2,0,sig,sigerr,fLayer,fLad,fDet,cluster, 0.75) );
1938 if(debug) cout<<"\n"<<": SINGLE SIDE ImpactPoint Created: X = "
1939 <<(x1+x2)/2<<" Z = "<<(z1+z2)/2<<"; Pos = "<<pos;
1944 for (i=0;i<fNClusterN;i++)
1946 cluster = GetNSideCluster(i);
1947 if (!cluster->IsConsumed())
1949 if( (pos = cluster->GetPosition()) < fSFF)
1951 sig = cluster->GetTotalSignal();
1953 sig += sig*fPNsignalRatio;
1955 sigerr = cluster->GetTotalSignalError();
1957 x1 = -Dx/2 + pos *fPitch;
1963 GetCrossing (x2,z2);
1964 AliITSRawClusterSSD cnew;
1965 Int_t nstripsN=cluster->GetNumOfDigits();
1966 cnew.fMultiplicity=0;
1967 cnew.fMultiplicityN=nstripsN;
1969 if (nstripsN > 100) {
1970 printf("multiplicity > 100 - increase the dimension of the arrays %d\n",nstripsN);
1973 for(int k=0;k<nstripsN;k++) {
1974 // check if 'clusterP->GetDigitStripNo(i)' returns
1975 // the digit index and not smth else
1976 cnew.fIndexMapN[k] = cluster->GetDigitStripNo(k);
1980 //cnew.fProbability=0.75;
1981 fITS->AddCluster(2,&cnew);
1982 // add the rec point info
1983 fSegmentation->GetPadIxz((x1+x2)/2,(z1+z2)/2,stripP,stripN);
1984 dig = (AliITSdigitSSD*)fMap->GetHit(0,stripN);
1985 AliITSRecPoint rnew;
1986 rnew.SetX(kconv*(x1+x2)/2);
1987 rnew.SetZ(kconv*(z1+z2)/2);
1989 rnew.SetdEdX(sig/kdEdXtoQ);
1990 rnew.SetSigmaX2( kRMSx* kRMSx);
1991 rnew.SetSigmaZ2( kRMSz* kRMSz);
1992 rnew.SetProbability(0.75);
1993 rnew.fTracks[0]=dig->fTracks[0];
1994 rnew.fTracks[1]=dig->fTracks[1];
1995 rnew.fTracks[2]=dig->fTracks[2];
1996 fITS->AddRecPoint(rnew);
1998 fPointsM->AddLast( (TObject*)
1999 new AliITSRecPointSSD((x1+x2)/2 ,0,0,0,(z1+z2)/2,0,sig,sigerr,fLayer,fLad,fDet,cluster, 0.75) );
2002 if(debug) cout<<"\n"<<": SINGLE SIDE ImpactPoint Created: X = "
2003 <<(x1+x2)/2<<" Z = "<<(z1+z2)/2<<"; Pos = "<<pos;
2012 //_______________________________________________________________________
2014 Bool_t AliITSClusterFinderSSD::GetCrossing (Float_t &P, Float_t &N)
2017 Float_t Dx = fSegmentation->Dx();
2018 Float_t Dz = fSegmentation->Dz();
2027 //P = (kZ * fTan + N + P)/2.0; // x coordinate
2028 //N = kZ - (P-N)/fTan; // z coordinate
2030 if(fTanP + fTanN == 0) return kFALSE;
2032 N = (N - P + fTanN * Dz) / (fTanP + fTanN); // X coordinate
2033 P = P + fTanP * N; // Y coordinate
2038 // N = -(N - P + kZ/2*(fTanP + fTanN))/(fTanP + fTanN);
2039 // P = (fTanP*(N-kX/2-kZ*fTanN/2) + fTanN*(P-kX/2-kZ*fTanP/2) )/(fTanP + fTanN);
2041 if ( ( N < -(Dz/2+dx) ) || ( N > (Dz/2+dx) ) ) return kFALSE;
2042 if ( ( P < -(Dx/2+dx) ) || ( P > (Dx/2+dx) ) ) return kFALSE;
2048 //_________________________________________________________________________
2050 void AliITSClusterFinderSSD::GetCrossingError(Float_t& dP, Float_t& dN)
2054 dz = TMath::Abs(( dP + dN )*fPitch/(fTanP + fTanN) );
2055 dx = fPitch*(TMath::Abs(dP*(1 - fTanP/(fTanP + fTanN))) +
2056 TMath::Abs(dN *fTanP/(fTanP + fTanN) ));