LCOV - code coverage report
Current view: top level - HLT/ITS/clusterfinders - AliHLTITSClusterFinderSSD.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 773 0.1 %
Date: 2016-06-14 17:26:59 Functions: 1 11 9.1 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       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             :  **************************************************************************/
      15             : 
      16             : /* $Id: AliHLTITSClusterFinderSSD.cxx 34920 2009-09-22 07:48:53Z masera $ */
      17             : 
      18             : ////////////////////////////////////////////////////////////////////////////
      19             : //            Implementation of the ITS clusterer V2 class                //
      20             : //                                                                        //
      21             : //          Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch            //
      22             : //          Last revision: 13-05-09 Enrico Fragiacomo                     //
      23             : //                                  enrico.fragiacomo@ts.infn.it          //
      24             : //                                                                        //
      25             : ///////////////////////////////////////////////////////////////////////////
      26             : 
      27             : #include <Riostream.h>
      28             : #include "AliLog.h"
      29             : 
      30             : #include "AliHLTITSClusterFinderSSD.h"
      31             : #include "AliITSRecPoint.h"
      32             : #include "AliITSgeomTGeo.h"
      33             : #include "AliITSDetTypeRec.h"
      34             : #include "AliRawReader.h"
      35             : #include "AliITSRawStreamSSD.h"
      36             : #include <TClonesArray.h>
      37             : #include "AliITSdigitSSD.h"
      38             : #include "AliITSReconstructor.h"
      39             : #include "AliITSCalibrationSSD.h"
      40             : #include "AliITSsegmentationSSD.h"
      41             : 
      42             : Short_t *AliHLTITSClusterFinderSSD::fgPairs = 0x0;
      43             : Int_t    AliHLTITSClusterFinderSSD::fgPairsSize = 0;
      44             : const Float_t  AliHLTITSClusterFinderSSD::fgkThreshold = 5.;
      45             : 
      46             : const Float_t AliHLTITSClusterFinderSSD::fgkCosmic2008StripShifts[16][9] = 
      47             :   {{-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35},  // DDL 512
      48             :    {-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35},  // DDL 513
      49             :    {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15},  // DDL 514
      50             :    {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15},  // DDL 515
      51             :    { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},  // DDL 516
      52             :    { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},  // DDL 517
      53             :    {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15},  // DDL 518
      54             :    {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15},  // DDL 519
      55             :    {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.25,-0.15},  // DDL 520
      56             :    {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15},  // DDL 521
      57             :    {-0.10,-0.10,-0.10,-0.40,-0.40,-0.40,-0.10,-0.10,-0.45},  // DDL 522
      58             :    {-0.10,-0.10,-0.10,-0.35,-0.35,-0.35,-0.10,-0.35,-0.50},  // DDL 523
      59             :    { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},  // DDL 524
      60             :    { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},  // DDL 525
      61             :    { 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35},  // DDL 526
      62             :    { 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45}}; // DDL 527
      63             : 
      64           6 : ClassImp(AliHLTITSClusterFinderSSD)
      65             : 
      66             : 
      67             :   AliHLTITSClusterFinderSSD::AliHLTITSClusterFinderSSD(AliITSDetTypeRec* dettyp, AliRawReader *reader)
      68             :     :
      69           0 :     AliITSClusterFinder(dettyp),
      70           0 :     fRecoParam(0),
      71           0 :     fRawReader( reader ),
      72           0 :     fRawStream( 0 ),
      73           0 :     fLastSSD1(AliITSgeomTGeo::GetModuleIndex(6,1,1)-1)
      74           0 : {
      75             : //Default constructor
      76             :  //
      77             :  // Initialisation of ITS geometry
      78             :  //
      79           0 :   Int_t mmax=AliITSgeomTGeo::GetNModules();
      80           0 :   for (Int_t m=0; m<mmax; m++) {
      81           0 :     Int_t lay,lad,det; AliITSgeomTGeo::GetModuleId(m,lay,lad,det);
      82           0 :     fNdet[m] = (lad-1)*AliITSgeomTGeo::GetNDetectors(lay) + (det-1);
      83           0 :     fNlayer[m] = lay-1;
      84           0 :   }
      85             : 
      86           0 :   fRecoParam = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
      87           0 :   if( !fRecoParam ){
      88           0 :     fRecoParam = AliITSRecoParam::GetHighFluxParam();
      89             :     // AliWarning("Using default AliITSRecoParam class");  
      90           0 :   }
      91           0 :   fRawStream = new AliITSRawStreamSSD( fRawReader);
      92           0 : }
      93             :  
      94             : //______________________________________________________________________
      95           0 : AliHLTITSClusterFinderSSD::AliHLTITSClusterFinderSSD(const AliHLTITSClusterFinderSSD &cf) : AliITSClusterFinder(cf),                                                fRecoParam(cf.fRecoParam), fRawReader(cf.fRawReader), fRawStream(0), fLastSSD1(cf.fLastSSD1)
      96           0 : {
      97             :   // Dummy
      98           0 : }
      99             : 
     100             : //______________________________________________________________________
     101             : AliHLTITSClusterFinderSSD& AliHLTITSClusterFinderSSD::operator=(const AliHLTITSClusterFinderSSD&  ){
     102             :   // Dummy
     103           0 :   return *this;
     104             : }
     105             : 
     106             : AliHLTITSClusterFinderSSD::~AliHLTITSClusterFinderSSD()
     107           0 : {
     108             :   // destructor 
     109           0 :   delete fRawStream;
     110           0 : }
     111             : 
     112             : void AliHLTITSClusterFinderSSD::RawdataToClusters( std::vector<AliITSRecPoint> &clusters )
     113             : {
     114             :   //------------------------------------------------------------
     115             :   // Actual SSD cluster finder for raw data
     116             :   //------------------------------------------------------------
     117             :   
     118           0 :   fRawReader->Reset();  
     119             : 
     120             :   const Int_t kNADC = 12;
     121             :   const Int_t kMaxADCClusters = 1000;
     122             : 
     123           0 :   Int_t strips[kNADC][2][kMaxADCClusters][2]; // [ADC],[side],[istrip], [0]=istrip [1]=signal
     124           0 :   Int_t nStrips[kNADC][2];
     125             : 
     126           0 :   for( int i=0; i<kNADC; i++ ){
     127           0 :     nStrips[i][0] = 0;
     128           0 :     nStrips[i][1] = 0;
     129             :   }
     130             : 
     131             :   Int_t ddl = -1;
     132             :   Int_t ad = -1;
     133             :   
     134             :   //*
     135             :   //* Loop over modules DDL+AD
     136             :   //*
     137             :   
     138           0 :   while (kTRUE) {
     139             : 
     140           0 :     bool next = fRawStream->Next();
     141             :     
     142             :     //* 
     143             :     //* Continue if corrupted input
     144             :     //*
     145             : 
     146           0 :     if( (!next)&&(fRawStream->flag) ){
     147           0 :      AliWarning(Form("HLT ClustersFinderSSD: Corrupted data: warning from RawReader"));
     148           0 :       continue; 
     149             :     }
     150             : 
     151           0 :     Int_t newDDL = fRawStream->GetDDL(); 
     152           0 :     Int_t newAD = fRawStream->GetAD();
     153             : 
     154           0 :     if( next ){
     155           0 :       if( newDDL<0 || newDDL>15 ){
     156             :         // AliWarning(Form("HLT ClustersFinderSSD: Corrupted data: wrong DDL number (%d)",newDDL));
     157           0 :         continue;
     158             :       }
     159             :       
     160           0 :       if( newAD<1 || newAD>9 ){
     161             :         // AliWarning(Form("HLT ClustersFinderSSD: Corrupted data: wrong AD number (%d)",newAD));
     162           0 :         continue;
     163             :       }
     164             :     }
     165             : 
     166           0 :     bool newModule = ( !next || ddl!= newDDL || ad!=newAD );
     167             : 
     168           0 :     if( newModule && ddl>=0 && ad>=0 ){ 
     169             : 
     170             :       //*
     171             :       //* Reconstruct the previous module --- actual clusterfinder
     172             :       //* 
     173             :       //cout<<endl;
     174           0 :       for( int adc = 0; adc<kNADC; adc++ ){
     175             :         
     176             :         //* 1D clusterfinder
     177             : 
     178           0 :         Ali1Dcluster clusters1D[2][kMaxADCClusters]; // per ADC, per side
     179           0 :         Int_t nClusters1D[2] = {0,0};
     180             :         //int nstat[2] = {0,0};
     181           0 :         fModule = AliITSRawStreamSSD::GetModuleNumber(ddl, (ad - 1)  * 12 + adc );
     182             :         
     183           0 :         if( fModule<0 ){
     184             :           // AliWarning(Form("HLT ClustersFinderSSD: Corrupted data: module (ddl %d ad %d adc %d) not found in the map",ddl,ad,adc));
     185           0 :           continue;
     186             :         }
     187             : 
     188           0 :         AliITSCalibrationSSD* cal = (AliITSCalibrationSSD*)fDetTypeRec->GetCalibrationModel(fModule);
     189           0 :         if( !cal ){
     190           0 :            AliWarning(Form("HLT ClustersFinderSSD: No calibration found for module (ddl %d ad %d adc %d)",ddl,ad,adc));           
     191           0 :           continue;
     192             :         }
     193             : 
     194             :         Float_t dStrip = 0;
     195             : 
     196           0 :         if( fRecoParam->GetUseCosmicRunShiftsSSD()) {  // Special condition for 2007/2008 cosmic data
     197           0 :           dStrip = fgkCosmic2008StripShifts[ddl][ad-1];
     198           0 :           if (TMath::Abs(dStrip) > 1.5){
     199           0 :             AliWarning(Form("Indexing error in Cosmic calibration: ddl = %d, dStrip %f\n",ddl,dStrip));
     200             :             dStrip = 0;
     201           0 :           }     
     202             :         }
     203             :         
     204           0 :         for( int side=0; side<=1; side++ ){
     205             : 
     206           0 :           Int_t lab[3]={-2,-2,-2};
     207             :           Float_t q = 0.;
     208             :           Float_t y = 0.;
     209             :           Int_t nDigits = 0;
     210             :           Int_t ostrip = -2;
     211             :           Bool_t snFlag = 0;
     212             :           
     213           0 :           Int_t n = nStrips[adc][side];
     214           0 :           for( int istr = 0; istr<n+1; istr++ ){
     215             :             
     216             :             bool stripOK = 1;
     217             :             Int_t strip=0, signal=0;
     218             :             Float_t noise=1, gain=0;
     219             :             
     220           0 :             if( istr<n ){
     221           0 :               strip = strips[adc][side][istr][0];
     222           0 :               signal = strips[adc][side][istr][1];
     223             :               
     224             :               //cout<<"strip "<<adc<<" / "<<side<<": "<<strip<<endl;
     225             : 
     226           0 :               if( cal ){
     227           0 :                 noise = side ?cal->GetNoiseN(strip) :cal->GetNoiseP(strip); 
     228           0 :                 gain = side ?cal->GetGainN(strip) :cal->GetGainP(strip);   
     229           0 :                 stripOK = ( noise>=1. && signal>=3*noise 
     230             :                             //&& !cal->IsPChannelBad(strip) 
     231             :                             );
     232           0 :               }
     233             :             } else stripOK = 0; // end of data
     234             : 
     235           0 :             bool newCluster = ( TMath::Abs(strip-ostrip)>1 || !stripOK );      
     236             :                 
     237           0 :             if( newCluster ){
     238             : 
     239             :               //* Store the previous cluster
     240             : 
     241           0 :               if( nDigits>0 && q>0 && snFlag ){
     242             : 
     243           0 :                 if (nClusters1D[side] >= kMaxADCClusters-1 ) {
     244           0 :                   AliWarning("HLT ClustersFinderSSD: Too many 1D clusters !");
     245           0 :                 }else {
     246             :                   
     247           0 :                   Ali1Dcluster &cluster = clusters1D[side][nClusters1D[side]++];
     248           0 :                   cluster.SetY( y / q + dStrip);
     249           0 :                   cluster.SetQ(q);
     250           0 :                   cluster.SetNd(nDigits);
     251           0 :                   cluster.SetLabels(lab);
     252             :                   //cout<<"cluster 1D side "<<side<<": y= "<<y<<" q= "<<q<<" d="<<dStrip<<" Y="<<cluster.GetY()<<endl;
     253             :                   //Split suspiciously big cluster
     254             : 
     255           0 :                   if( fRecoParam->GetUseUnfoldingInClusterFinderSSD()
     256           0 :                       && nDigits > 4 && nDigits < 25 
     257             :                       ){
     258           0 :                     cluster.SetY(y/q + dStrip - 0.25*nDigits);      
     259           0 :                     cluster.SetQ(0.5*q);          
     260           0 :                     Ali1Dcluster& cluster2 = clusters1D[side][nClusters1D[side]++];
     261           0 :                     cluster2.SetY(y/q + dStrip + 0.25*nDigits);     
     262           0 :                     cluster2.SetQ(0.5*q);
     263           0 :                     cluster2.SetNd(nDigits);
     264           0 :                     cluster2.SetLabels(lab);      
     265           0 :                   } // unfolding is on          
     266             :                 }
     267             :               }
     268             :               y = q = 0.;
     269             :               nDigits = 0;
     270             :               snFlag = 0;
     271             : 
     272           0 :             } //* End store the previous cluster
     273             : 
     274           0 :             if( stripOK ){ // add new signal to the cluster
     275           0 :               signal = (Int_t) ( signal * gain ); // signal is corrected for gain
     276           0 :               if( signal>fgkThreshold*noise) snFlag = 1;
     277           0 :               if( cal ) signal = (Int_t) cal->ADCToKeV( signal ); // signal is  converted in KeV       
     278           0 :               q += signal;        // add digit to current cluster
     279           0 :               y += strip * signal;        
     280           0 :               nDigits++;
     281             :               //nstat[side]++;
     282             :               ostrip = strip;
     283             :               //cout<<"strip "<<adc<<" / "<<side<<": "<<strip<<" / "<<signal<<" stored"<<endl;
     284             : 
     285           0 :             }
     286             :           } //* end loop over strips
     287             : 
     288           0 :         } //* end loop over ADC sides
     289             :         
     290             : 
     291             :         //* 2D clusterfinder
     292             : 
     293           0 :         if( nClusters1D[0] && nClusters1D[1] && fModule>=0 ){
     294           0 :           FindClustersSSD( clusters1D[0], nClusters1D[0], clusters1D[1], nClusters1D[1], clusters); 
     295           0 :         }
     296             :         //cout<<"SG: "<<ddl<<" "<<ad<<" "<<adc<<": strips "<<nstat[0]<<"+"<<nstat[1]<<", clusters 1D= "<<nClusters1D[0]<<" + "<<nClusters1D[1]<<", 2D= "<<clusters.size()<<endl;
     297             : 
     298           0 :       }//* end loop over adc
     299             :       
     300           0 :     }//* end of reconstruction of previous module
     301             :     
     302           0 :     if( newModule ){
     303             :       
     304             :       //*
     305             :       //* Clean up arrays and set new module
     306             :       //* 
     307             :       
     308           0 :       for( int i=0; i<kNADC; i++ ){
     309           0 :         nStrips[i][0] = 0;
     310           0 :         nStrips[i][1] = 0;
     311             :       }     
     312             :       ddl = newDDL;
     313             :       ad = newAD;
     314           0 :     } 
     315             :     
     316             : 
     317             :     //*
     318             :     //* Exit main loop when there is no more input
     319             :     //* 
     320             : 
     321           0 :     if( !next ) break;
     322             :     
     323             :     //* 
     324             :     //* Fill the current strip information
     325             :     //* 
     326             : 
     327           0 :     Int_t adc = fRawStream->GetADC(); 
     328           0 :     if( adc<0 || adc>=kNADC+2 || (adc>5&&adc<8) ){
     329           0 :       AliWarning(Form("HLT ClustersFinderSSD: Corrupted data: wrong adc number (%d)", adc));
     330           0 :       continue;
     331             :     }
     332             : 
     333           0 :     if( adc>7 ) adc-= 2; // shift ADC numbers 8-13 to 6-11
     334             :     
     335           0 :     Bool_t side = fRawStream->GetSideFlag();
     336           0 :     Int_t strip = fRawStream->GetStrip();
     337           0 :     Int_t signal = fRawStream->GetSignal();
     338             : 
     339             :     //cout<<"SSD: "<<ddl<<" "<<ad<<" "<<adc<<" "<<side<<" "<<strip<<" : "<<signal<<endl;
     340             : 
     341           0 :     if( strip<0 || strip>767 ){    
     342           0 :       continue;
     343             :     }
     344             :     
     345           0 :     int &n = nStrips[adc][side];
     346           0 :     if( n >0 ){
     347           0 :       Int_t oldStrip = strips[adc][side][n-1][0];
     348           0 :       if( strip==oldStrip ){
     349           0 :         AliWarning(Form("HLT ClustersFinderSSD: Corrupted data: duplicated signal: ddl %d ad %d adc %d, side %d, strip %d", 
     350             :                         ddl, ad, adc, side, strip ));
     351           0 :         continue;
     352             :       }
     353           0 :     }
     354           0 :     strips[adc][side][n][0] = strip;
     355           0 :     strips[adc][side][n][1] = signal;    
     356           0 :     n++;
     357             : 
     358             :     //cout<<"SSD: "<<fRawStream->GetDDL()<<" "<<fRawStream->GetAD()<<" "
     359             :     //<<fRawStream->GetADC()<<" "<<fRawStream->GetSideFlag()<<" "<<((int)fRawStream->GetStrip())<<" "<<strip<<" : "<<fRawStream->GetSignal()<<endl;
     360             : 
     361           0 :   } //* End main loop over the input
     362             : 
     363           0 : }
     364             : 
     365             : 
     366             : void AliHLTITSClusterFinderSSD::
     367             : FindClustersSSD(Ali1Dcluster* neg, Int_t nn, 
     368             :                 Ali1Dcluster* pos, Int_t np,
     369             :                 std::vector<AliITSRecPoint> &clusters) {
     370             :   //------------------------------------------------------------
     371             :   // Actual SSD cluster finder
     372             :   //------------------------------------------------------------
     373             : 
     374           0 :   const TGeoHMatrix *mT2L=AliITSgeomTGeo::GetTracking2LocalMatrix(fModule);
     375             : 
     376           0 :   AliITSsegmentationSSD *seg = dynamic_cast<AliITSsegmentationSSD*>(fDetTypeRec->GetSegmentationModel(2));
     377           0 :   if(!mT2L || !seg){
     378           0 :      AliError(Form("HLT ClustersFinderSSD: null pointer from TGeo"));
     379           0 :     return;
     380             :   }
     381           0 :   if (fModule>fLastSSD1) 
     382           0 :     seg->SetLayer(6);
     383             :   else 
     384           0 :     seg->SetLayer(5);
     385             : 
     386           0 :   Float_t hwSSD = seg->Dx()*1e-4/2;
     387           0 :   Float_t hlSSD = seg->Dz()*1e-4/2;
     388             : 
     389           0 :   Int_t idet=fNdet[fModule];
     390             :   Int_t ncl=0;
     391             : 
     392             :   //
     393           0 :   Int_t *cnegative = new Int_t[np];  
     394           0 :   Int_t *cused1 = new Int_t[np];
     395           0 :   Int_t *negativepair = new Int_t[10*np];
     396           0 :   Int_t *cpositive = new Int_t[nn];  
     397           0 :   Int_t *cused2 = new Int_t[nn];  
     398           0 :   Int_t *positivepair = new Int_t[10*nn];  
     399           0 :   for (Int_t i=0;i<np;i++) {cnegative[i]=0; cused1[i]=0;}
     400           0 :   for (Int_t i=0;i<nn;i++) {cpositive[i]=0; cused2[i]=0;}
     401           0 :   for (Int_t i=0;i<10*np;i++) {negativepair[i]=0;}
     402           0 :   for (Int_t i=0;i<10*nn;i++) {positivepair[i]=0;}
     403             : 
     404           0 :   if ((np*nn) > fgPairsSize) {
     405             : 
     406           0 :     if (fgPairs) delete [] fgPairs;
     407           0 :     fgPairsSize = 4*np*nn;
     408           0 :     fgPairs = new Short_t[fgPairsSize];
     409           0 :   }
     410           0 :   memset(fgPairs,0,sizeof(Short_t)*np*nn);
     411             : 
     412             :   //
     413             :   // find available pairs
     414             :   //
     415           0 :   for (Int_t i=0; i<np; i++) {
     416           0 :     Float_t yp=pos[i].GetY(); 
     417           0 :     if ( (pos[i].GetQ()>0) && (pos[i].GetQ()<3) ) continue;
     418           0 :     for (Int_t j=0; j<nn; j++) {
     419           0 :       if ( (neg[j].GetQ()>0) && (neg[j].GetQ()<3) ) continue;
     420           0 :       Float_t yn=neg[j].GetY();
     421             : 
     422           0 :       Float_t xt, zt;
     423           0 :       seg->GetPadCxz(yn, yp, xt, zt);
     424             :       //cout<<yn<<" "<<yp<<" "<<xt<<" "<<zt<<endl;
     425             :       
     426           0 :       if (TMath::Abs(xt)<hwSSD)
     427           0 :       if (TMath::Abs(zt)<hlSSD) {
     428           0 :         Int_t in = i*10+cnegative[i];
     429           0 :         Int_t ip = j*10+cpositive[j];
     430           0 :         if ((in < 10*np) && (ip < 10*nn)) {
     431           0 :           negativepair[in] =j;  //index
     432           0 :           positivepair[ip] =i;
     433           0 :           cnegative[i]++;  //counters
     434           0 :           cpositive[j]++;       
     435           0 :           fgPairs[i*nn+j]=100;
     436           0 :         }
     437             :         else
     438           0 :           AliError(Form("Index out of range: ip=%d, in=%d",ip,in));
     439           0 :       }
     440           0 :     }
     441           0 :   }
     442             : 
     443             : 
     444             :   //
     445           0 :   Float_t lp[6];
     446           0 :   Int_t milab[10];
     447             :   Double_t ratio;
     448             :   
     449             : 
     450           0 :   if(fRecoParam->GetUseChargeMatchingInClusterFinderSSD()==kTRUE) {
     451             : 
     452             : 
     453             :     //
     454             :     // sign gold tracks
     455             :     //
     456           0 :     for (Int_t ip=0;ip<np;ip++){
     457             : 
     458             :       Float_t xbest=1000,zbest=1000,qbest=0;
     459             :       //
     460             :       // select gold clusters
     461           0 :       if ( (cnegative[ip]==1) && cpositive[negativepair[10*ip]]==1){ 
     462             : 
     463           0 :         Float_t yp=pos[ip].GetY(); 
     464           0 :         Int_t j = negativepair[10*ip];      
     465             : 
     466           0 :         if( (pos[ip].GetQ()==0) && (neg[j].GetQ() ==0) ) { 
     467             :           // both bad, hence continue;    
     468             :           // mark both as used (to avoid recover at the end)
     469           0 :           cused1[ip]++; 
     470           0 :           cused2[j]++;
     471           0 :           continue;
     472             :         }
     473             : 
     474           0 :         ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
     475             :         //cout<<"ratio="<<ratio<<endl;
     476             : 
     477             :         // charge matching (note that if posQ or negQ is 0 -> ratio=1 and the following condition is met
     478           0 :         if (TMath::Abs(ratio)>0.2) continue; // note: 0.2=3xsigma_ratio calculated in cosmics tests
     479             : 
     480             :         //
     481           0 :         Float_t yn=neg[j].GetY();
     482             :         
     483           0 :         Float_t xt, zt;
     484           0 :         seg->GetPadCxz(yn, yp, xt, zt);
     485             :         
     486           0 :         xbest=xt; zbest=zt; 
     487             : 
     488             :         
     489           0 :         qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
     490           0 :         if( (pos[ip].GetQ()==0)||(neg[j].GetQ()==0)) qbest*=2; // in case of bad strips on one side keep all charge from the other one
     491             :         
     492             :         {
     493           0 :           Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
     494           0 :           mT2L->MasterToLocal(loc,trk);
     495           0 :           lp[0]=trk[1];
     496           0 :           lp[1]=trk[2];
     497           0 :         }
     498           0 :         lp[4]=qbest;        //Q
     499           0 :         for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
     500           0 :         for (Int_t ilab=0;ilab<3;ilab++){
     501           0 :           milab[ilab] = pos[ip].GetLabel(ilab);
     502           0 :           milab[ilab+3] = neg[j].GetLabel(ilab);
     503             :         }
     504             :         //
     505           0 :         CheckLabels2(milab);
     506           0 :         milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det        
     507           0 :         Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
     508             : 
     509           0 :         lp[2]=0.0022*0.0022;  //SigmaY2
     510           0 :         lp[3]=0.110*0.110;  //SigmaZ2
     511             :         // out-of-diagonal element of covariance matrix
     512           0 :         if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
     513           0 :         else if ( (info[0]>1) && (info[1]>1) ) { 
     514           0 :           lp[2]=0.0016*0.0016;  //SigmaY2
     515           0 :           lp[3]=0.08*0.08;  //SigmaZ2
     516           0 :           lp[5]=-0.00006;
     517           0 :         }
     518             :         else {
     519           0 :           lp[3]=0.093*0.093;
     520           0 :           if (info[0]==1) { lp[5]=-0.00014;}
     521           0 :           else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
     522             :         }
     523           0 :         AliITSRecPoint cl2(milab,lp,info);      
     524           0 :         cl2.SetChargeRatio(ratio);      
     525           0 :         cl2.SetType(1);
     526             :               
     527           0 :         fgPairs[ip*nn+j]=1;
     528           0 :         if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
     529           0 :           cl2.SetType(2);
     530           0 :           fgPairs[ip*nn+j]=2;
     531           0 :         }
     532             : 
     533           0 :         if(pos[ip].GetQ()==0) cl2.SetType(3);
     534           0 :         if(neg[j].GetQ()==0) cl2.SetType(4);
     535             : 
     536           0 :         cused1[ip]++;
     537           0 :         cused2[j]++;
     538             : 
     539           0 :         clusters.push_back(cl2);
     540             :         
     541           0 :         ncl++;
     542           0 :       }
     543           0 :     }
     544             : 
     545           0 :     for (Int_t ip=0;ip<np;ip++){
     546             :       Float_t xbest=1000,zbest=1000,qbest=0;
     547             :       //
     548             :       //
     549             :       // select "silber" cluster
     550           0 :       if ( cnegative[ip]==1 && cpositive[negativepair[10*ip]]==2){
     551             :         Int_t in  = negativepair[10*ip];
     552           0 :         Int_t ip2 = positivepair[10*in];
     553           0 :         if (ip2==ip) ip2 =  positivepair[10*in+1];
     554           0 :         Float_t pcharge = pos[ip].GetQ()+pos[ip2].GetQ();
     555             :         
     556             : 
     557             : 
     558           0 :         ratio = (pcharge-neg[in].GetQ())/(pcharge+neg[in].GetQ());
     559           0 :         if ( (TMath::Abs(ratio)<0.2) && (pcharge!=0) ) {
     560             :           //if ( (TMath::Abs(pcharge-neg[in].GetQ())<30) && (pcharge!=0) ) { // 
     561             :           
     562             :           //
     563             :           // add first pair
     564           0 :           if ( (fgPairs[ip*nn+in]==100)&&(pos[ip].GetQ() ) ) {  //
     565             :             
     566           0 :             Float_t yp=pos[ip].GetY(); 
     567           0 :             Float_t yn=neg[in].GetY();
     568             :             
     569           0 :             Float_t xt, zt;
     570           0 :             seg->GetPadCxz(yn, yp, xt, zt);
     571             :             
     572           0 :             xbest=xt; zbest=zt; 
     573             : 
     574           0 :             qbest =pos[ip].GetQ();
     575           0 :             Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
     576           0 :             mT2L->MasterToLocal(loc,trk);
     577           0 :             lp[0]=trk[1];
     578           0 :             lp[1]=trk[2];
     579             :             
     580           0 :             lp[4]=qbest;        //Q
     581           0 :             for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
     582           0 :             for (Int_t ilab=0;ilab<3;ilab++){
     583           0 :               milab[ilab] = pos[ip].GetLabel(ilab);
     584           0 :               milab[ilab+3] = neg[in].GetLabel(ilab);
     585             :             }
     586             :             //
     587           0 :             CheckLabels2(milab);
     588           0 :             ratio = (pos[ip].GetQ()-neg[in].GetQ())/(pos[ip].GetQ()+neg[in].GetQ());
     589           0 :             milab[3]=(((ip<<10) + in)<<10) + idet; // pos|neg|det
     590           0 :             Int_t info[3] = {pos[ip].GetNd(),neg[in].GetNd(),fNlayer[fModule]};
     591             :             
     592           0 :             lp[2]=0.0022*0.0022;  //SigmaY2
     593           0 :             lp[3]=0.110*0.110;  //SigmaZ2
     594             :             // out-of-diagonal element of covariance matrix
     595           0 :             if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
     596           0 :             else if ( (info[0]>1) && (info[1]>1) ) { 
     597           0 :               lp[2]=0.0016*0.0016;  //SigmaY2
     598           0 :               lp[3]=0.08*0.08;  //SigmaZ2
     599           0 :               lp[5]=-0.00006;
     600           0 :             }
     601             :             else {
     602           0 :               lp[3]=0.093*0.093;
     603           0 :               if (info[0]==1) { lp[5]=-0.00014;}
     604           0 :               else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
     605             :             }
     606             : 
     607           0 :             AliITSRecPoint cl2(milab,lp,info);      
     608           0 :             cl2.SetChargeRatio(ratio);          
     609           0 :             cl2.SetType(5);
     610           0 :             fgPairs[ip*nn+in] = 5;
     611           0 :             if ((pos[ip].GetNd()+neg[in].GetNd())>6){ //multi cluster
     612           0 :               cl2.SetType(6);
     613           0 :               fgPairs[ip*nn+in] = 6;
     614           0 :             }       
     615           0 :             clusters.push_back(cl2);
     616           0 :             ncl++;
     617           0 :           }
     618             :           
     619             :           
     620             :           //
     621             :           // add second pair
     622             :           
     623             :           //    if (!(cused1[ip2] || cused2[in])){  //
     624           0 :           if ( (fgPairs[ip2*nn+in]==100) && (pos[ip2].GetQ()) ) {
     625             :             
     626           0 :             Float_t yp=pos[ip2].GetY();
     627           0 :             Float_t yn=neg[in].GetY();
     628             :             
     629           0 :             Float_t xt, zt;
     630           0 :             seg->GetPadCxz(yn, yp, xt, zt);
     631             :             
     632           0 :             xbest=xt; zbest=zt; 
     633             : 
     634           0 :             qbest =pos[ip2].GetQ();
     635             :             
     636           0 :             Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
     637           0 :             mT2L->MasterToLocal(loc,trk);
     638           0 :             lp[0]=trk[1];
     639           0 :             lp[1]=trk[2];
     640             :             
     641           0 :             lp[4]=qbest;        //Q
     642           0 :             for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
     643           0 :             for (Int_t ilab=0;ilab<3;ilab++){
     644           0 :               milab[ilab] = pos[ip2].GetLabel(ilab);
     645           0 :               milab[ilab+3] = neg[in].GetLabel(ilab);
     646             :             }
     647             :             //
     648           0 :             CheckLabels2(milab);
     649           0 :             ratio = (pos[ip2].GetQ()-neg[in].GetQ())/(pos[ip2].GetQ()+neg[in].GetQ());
     650           0 :             milab[3]=(((ip2<<10) + in)<<10) + idet; // pos|neg|det
     651           0 :             Int_t info[3] = {pos[ip2].GetNd(),neg[in].GetNd(),fNlayer[fModule]};
     652             :             
     653           0 :             lp[2]=0.0022*0.0022;  //SigmaY2
     654           0 :             lp[3]=0.110*0.110;  //SigmaZ2
     655             :             // out-of-diagonal element of covariance matrix
     656           0 :             if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
     657           0 :             else if ( (info[0]>1) && (info[1]>1) ) { 
     658           0 :               lp[2]=0.0016*0.0016;  //SigmaY2
     659           0 :               lp[3]=0.08*0.08;  //SigmaZ2
     660           0 :               lp[5]=-0.00006;
     661           0 :             }
     662             :             else {
     663           0 :               lp[3]=0.093*0.093;
     664           0 :               if (info[0]==1) { lp[5]=-0.00014;}
     665           0 :               else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
     666             :             }
     667             :             
     668           0 :             AliITSRecPoint cl2(milab,lp,info);
     669           0 :             cl2.SetChargeRatio(ratio);          
     670           0 :             cl2.SetType(5);
     671           0 :             fgPairs[ip2*nn+in] =5;
     672           0 :             if ((pos[ip2].GetNd()+neg[in].GetNd())>6){ //multi cluster
     673           0 :               cl2.SetType(6);
     674           0 :               fgPairs[ip2*nn+in] =6;
     675           0 :             }
     676           0 :             clusters.push_back(cl2);
     677           0 :             ncl++;
     678           0 :           }
     679             :           
     680           0 :           cused1[ip]++;
     681           0 :           cused1[ip2]++;
     682           0 :           cused2[in]++;
     683             :           
     684           0 :         } // charge matching condition
     685             :         
     686           0 :       } // 2 Pside cross 1 Nside
     687             :     } // loop over Pside clusters
     688             :     
     689             :       
     690             :       //  
     691           0 :     for (Int_t jn=0;jn<nn;jn++){
     692           0 :       if (cused2[jn]) continue;
     693             :       Float_t xbest=1000,zbest=1000,qbest=0;
     694             :       // select "silber" cluster
     695           0 :       if ( cpositive[jn]==1 && cnegative[positivepair[10*jn]]==2){
     696             :         Int_t ip  = positivepair[10*jn];
     697           0 :         Int_t jn2 = negativepair[10*ip];
     698           0 :         if (jn2==jn) jn2 =  negativepair[10*ip+1];
     699           0 :         Float_t pcharge = neg[jn].GetQ()+neg[jn2].GetQ();
     700             :         //
     701             :         
     702             : 
     703           0 :         ratio = (pcharge-pos[ip].GetQ())/(pcharge+pos[ip].GetQ());
     704           0 :         if ( (TMath::Abs(ratio)<0.2) && (pcharge!=0) ) {
     705             : 
     706             :           /*
     707             :         if ( (TMath::Abs(pcharge-pos[ip].GetQ())<30) &&  // charge matching 
     708             :              (pcharge!=0) ) { // reject combinations of bad strips
     709             :           */
     710             : 
     711             : 
     712             :           //
     713             :           // add first pair
     714             :           //    if (!(cused1[ip]||cused2[jn])){
     715           0 :           if ( (fgPairs[ip*nn+jn]==100) && (neg[jn].GetQ()) ) {  //
     716             :             
     717           0 :             Float_t yn=neg[jn].GetY(); 
     718           0 :             Float_t yp=pos[ip].GetY();
     719             : 
     720           0 :             Float_t xt, zt;
     721           0 :             seg->GetPadCxz(yn, yp, xt, zt);
     722             :             
     723           0 :             xbest=xt; zbest=zt; 
     724             : 
     725           0 :             qbest =neg[jn].GetQ();
     726             : 
     727             :             {
     728           0 :               Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
     729           0 :               mT2L->MasterToLocal(loc,trk);
     730           0 :               lp[0]=trk[1];
     731           0 :               lp[1]=trk[2];
     732           0 :           }
     733             :           
     734           0 :           lp[4]=qbest;        //Q
     735           0 :           for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
     736           0 :           for (Int_t ilab=0;ilab<3;ilab++){
     737           0 :             milab[ilab] = pos[ip].GetLabel(ilab);
     738           0 :             milab[ilab+3] = neg[jn].GetLabel(ilab);
     739             :           }
     740             :           //
     741           0 :           CheckLabels2(milab);
     742           0 :           ratio = (pos[ip].GetQ()-neg[jn].GetQ())/(pos[ip].GetQ()+neg[jn].GetQ());
     743           0 :           milab[3]=(((ip<<10) + jn)<<10) + idet; // pos|neg|det
     744           0 :           Int_t info[3] = {pos[ip].GetNd(),neg[jn].GetNd(),fNlayer[fModule]};
     745             : 
     746           0 :           lp[2]=0.0022*0.0022;  //SigmaY2
     747           0 :           lp[3]=0.110*0.110;  //SigmaZ2
     748             :           // out-of-diagonal element of covariance matrix
     749           0 :           if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
     750           0 :           else if ( (info[0]>1) && (info[1]>1) ) { 
     751           0 :             lp[2]=0.0016*0.0016;  //SigmaY2
     752           0 :             lp[3]=0.08*0.08;  //SigmaZ2
     753           0 :             lp[5]=-0.00006;
     754           0 :           }
     755             :           else {
     756           0 :             lp[3]=0.093*0.093;
     757           0 :             if (info[0]==1) { lp[5]=-0.00014;}
     758           0 :             else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
     759             :           }
     760             :           
     761           0 :           AliITSRecPoint cl2(milab,lp,info);
     762           0 :           cl2.SetChargeRatio(ratio);            
     763           0 :           cl2.SetType(7);
     764           0 :           fgPairs[ip*nn+jn] =7;
     765           0 :           if ((pos[ip].GetNd()+neg[jn].GetNd())>6){ //multi cluster
     766           0 :             cl2.SetType(8);
     767           0 :             fgPairs[ip*nn+jn]=8;
     768           0 :           }
     769           0 :           clusters.push_back(cl2);
     770             :           
     771           0 :           ncl++;
     772           0 :           }
     773             :         //
     774             :         // add second pair
     775             :         //      if (!(cused1[ip]||cused2[jn2])){
     776           0 :         if ( (fgPairs[ip*nn+jn2]==100)&&(neg[jn2].GetQ() ) ) {  //
     777             : 
     778           0 :           Float_t yn=neg[jn2].GetY(); 
     779           0 :           Double_t yp=pos[ip].GetY(); 
     780             : 
     781           0 :           Float_t xt, zt;
     782           0 :           seg->GetPadCxz(yn, yp, xt, zt);
     783             :           
     784           0 :           xbest=xt; zbest=zt; 
     785             : 
     786           0 :           qbest =neg[jn2].GetQ();
     787             : 
     788             :           {
     789           0 :           Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
     790           0 :           mT2L->MasterToLocal(loc,trk);
     791           0 :           lp[0]=trk[1];
     792           0 :           lp[1]=trk[2];
     793           0 :           }
     794             : 
     795           0 :           lp[4]=qbest;        //Q
     796           0 :           for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
     797           0 :           for (Int_t ilab=0;ilab<3;ilab++){
     798           0 :             milab[ilab] = pos[ip].GetLabel(ilab);
     799           0 :             milab[ilab+3] = neg[jn2].GetLabel(ilab);
     800             :           }
     801             :           //
     802           0 :           CheckLabels2(milab);
     803           0 :           ratio = (pos[ip].GetQ()-neg[jn2].GetQ())/(pos[ip].GetQ()+neg[jn2].GetQ());
     804           0 :           milab[3]=(((ip<<10) + jn2)<<10) + idet; // pos|neg|det
     805           0 :           Int_t info[3] = {pos[ip].GetNd(),neg[jn2].GetNd(),fNlayer[fModule]};
     806             : 
     807           0 :           lp[2]=0.0022*0.0022;  //SigmaY2
     808           0 :           lp[3]=0.110*0.110;  //SigmaZ2
     809             :           // out-of-diagonal element of covariance matrix
     810           0 :           if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
     811           0 :           else if ( (info[0]>1) && (info[1]>1) ) { 
     812           0 :             lp[2]=0.0016*0.0016;  //SigmaY2
     813           0 :             lp[3]=0.08*0.08;  //SigmaZ2
     814           0 :             lp[5]=-0.00006;
     815           0 :           }
     816             :           else {
     817           0 :             lp[3]=0.093*0.093;
     818           0 :             if (info[0]==1) { lp[5]=-0.00014;}
     819           0 :           else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
     820             :           }
     821             :           
     822           0 :           AliITSRecPoint cl2(milab,lp,info);
     823           0 :           cl2.SetChargeRatio(ratio);            
     824           0 :           fgPairs[ip*nn+jn2]=7;
     825           0 :           cl2.SetType(7);
     826           0 :           if ((pos[ip].GetNd()+neg[jn2].GetNd())>6){ //multi cluster
     827           0 :             cl2.SetType(8);
     828           0 :             fgPairs[ip*nn+jn2]=8;
     829           0 :           }
     830           0 :           clusters.push_back( cl2 );
     831           0 :           ncl++;
     832           0 :         }
     833           0 :         cused1[ip]++;
     834           0 :         cused2[jn]++;
     835           0 :         cused2[jn2]++;
     836             :         
     837           0 :         } // charge matching condition
     838             :         
     839           0 :       } // 2 Nside cross 1 Pside
     840           0 :     } // loop over Pside clusters
     841             : 
     842             :   
     843             : 
     844           0 :     for (Int_t ip=0;ip<np;ip++){
     845             : 
     846           0 :       if(cused1[ip]) continue;
     847             : 
     848             : 
     849             :       Float_t xbest=1000,zbest=1000,qbest=0;
     850             :       //
     851             :       // 2x2 clusters
     852             :       //
     853           0 :       if ( (cnegative[ip]==2) && cpositive[negativepair[10*ip]]==2){ 
     854             :         Float_t minchargediff =4.;
     855             :         //Float_t minchargeratio =0.2;
     856             : 
     857             :         Int_t j=-1;
     858           0 :         for (Int_t di=0;di<cnegative[ip];di++){
     859           0 :           Int_t   jc = negativepair[ip*10+di];
     860           0 :           Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
     861           0 :           ratio = (pos[ip].GetQ()-neg[jc].GetQ())/(pos[ip].GetQ()+neg[jc].GetQ()); 
     862             :           //if (TMath::Abs(chargedif)<minchargediff){
     863           0 :           if (TMath::Abs(ratio)<0.2){
     864             :             j =jc;
     865           0 :             minchargediff = TMath::Abs(chargedif);
     866             :             //minchargeratio = TMath::Abs(ratio);
     867           0 :           }
     868             :         }
     869           0 :         if (j<0) continue;  // not proper cluster      
     870             :         
     871             : 
     872             :         Int_t count =0;
     873           0 :         for (Int_t di=0;di<cnegative[ip];di++){
     874           0 :           Int_t   jc = negativepair[ip*10+di];
     875           0 :           Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
     876           0 :           if (TMath::Abs(chargedif)<minchargediff+3.) count++;
     877             :         }
     878           0 :         if (count>1) continue;  // more than one "proper" cluster for positive
     879             :         //
     880             :         
     881             :         count =0;
     882           0 :         for (Int_t dj=0;dj<cpositive[j];dj++){
     883           0 :           Int_t   ic  = positivepair[j*10+dj];
     884           0 :           Float_t chargedif = pos[ic].GetQ()-neg[j].GetQ();
     885           0 :           if (TMath::Abs(chargedif)<minchargediff+3.) count++;
     886             :         }
     887           0 :         if (count>1) continue;  // more than one "proper" cluster for negative
     888             :         
     889             :         Int_t jp = 0;
     890             :         
     891             :         count =0;
     892           0 :         for (Int_t dj=0;dj<cnegative[jp];dj++){
     893           0 :           Int_t   ic = positivepair[jp*10+dj];
     894           0 :           Float_t chargedif = pos[ic].GetQ()-neg[jp].GetQ();
     895           0 :           if (TMath::Abs(chargedif)<minchargediff+4.) count++;
     896             :         }
     897           0 :         if (count>1) continue;   
     898           0 :         if (fgPairs[ip*nn+j]<100) continue;
     899             :         //
     900             :         
     901             : 
     902             : 
     903             :         //almost gold clusters
     904           0 :         Float_t yp=pos[ip].GetY(); 
     905           0 :         Float_t yn=neg[j].GetY();      
     906           0 :         Float_t xt, zt;
     907           0 :         seg->GetPadCxz(yn, yp, xt, zt);      
     908           0 :         xbest=xt; zbest=zt; 
     909           0 :         qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
     910             :         {
     911           0 :           Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
     912           0 :           mT2L->MasterToLocal(loc,trk);
     913           0 :           lp[0]=trk[1];
     914           0 :           lp[1]=trk[2];
     915           0 :         }
     916           0 :         lp[4]=qbest;        //Q
     917           0 :         for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
     918           0 :         for (Int_t ilab=0;ilab<3;ilab++){
     919           0 :           milab[ilab] = pos[ip].GetLabel(ilab);
     920           0 :           milab[ilab+3] = neg[j].GetLabel(ilab);
     921             :         }
     922             :         //
     923           0 :         CheckLabels2(milab);
     924           0 :         if ((neg[j].GetQ()==0)&&(pos[ip].GetQ()==0)) continue; // reject crosses of bad strips!!
     925           0 :         ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
     926           0 :         milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
     927           0 :         Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
     928             : 
     929           0 :         lp[2]=0.0022*0.0022;  //SigmaY2
     930           0 :         lp[3]=0.110*0.110;  //SigmaZ2
     931             :         // out-of-diagonal element of covariance matrix
     932           0 :         if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
     933           0 :         else if ( (info[0]>1) && (info[1]>1) ) { 
     934           0 :           lp[2]=0.0016*0.0016;  //SigmaY2
     935           0 :           lp[3]=0.08*0.08;  //SigmaZ2
     936           0 :           lp[5]=-0.00006;
     937           0 :         }
     938             :         else {
     939           0 :           lp[3]=0.093*0.093;
     940           0 :           if (info[0]==1) { lp[5]=-0.00014;}
     941           0 :           else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
     942             :         }
     943             : 
     944           0 :         AliITSRecPoint cl2(milab,lp,info);
     945           0 :         cl2.SetChargeRatio(ratio);      
     946           0 :         cl2.SetType(10);
     947           0 :         fgPairs[ip*nn+j]=10;
     948           0 :         if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
     949           0 :           cl2.SetType(11);
     950           0 :           fgPairs[ip*nn+j]=11;
     951           0 :         }
     952           0 :         cused1[ip]++;
     953           0 :         cused2[j]++;      
     954             :         
     955           0 :         clusters.push_back(cl2);
     956           0 :         ncl++;
     957             :         
     958           0 :       } // 2X2
     959           0 :     } // loop over Pside 1Dclusters
     960             : 
     961             : 
     962           0 :     for (Int_t ip=0;ip<np;ip++){
     963             : 
     964           0 :       if(cused1[ip]) continue;
     965             : 
     966             : 
     967             :       Float_t xbest=1000,zbest=1000,qbest=0;
     968             :       //
     969             :       // manyxmany clusters
     970             :       //
     971           0 :       if ( (cnegative[ip]<5) && cpositive[negativepair[10*ip]]<5){ 
     972             :         Float_t minchargediff =4.;
     973             :         Int_t j=-1;
     974           0 :         for (Int_t di=0;di<cnegative[ip];di++){
     975           0 :           Int_t   jc = negativepair[ip*10+di];
     976           0 :           Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
     977           0 :           if (TMath::Abs(chargedif)<minchargediff){
     978             :             j =jc;
     979           0 :             minchargediff = TMath::Abs(chargedif);
     980           0 :           }
     981             :         }
     982           0 :         if (j<0) continue;  // not proper cluster      
     983             :         
     984             :         Int_t count =0;
     985           0 :         for (Int_t di=0;di<cnegative[ip];di++){
     986           0 :           Int_t   jc = negativepair[ip*10+di];
     987           0 :           Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
     988           0 :           if (TMath::Abs(chargedif)<minchargediff+3.) count++;
     989             :         }
     990           0 :         if (count>1) continue;  // more than one "proper" cluster for positive
     991             :         //
     992             :         
     993             :         count =0;
     994           0 :         for (Int_t dj=0;dj<cpositive[j];dj++){
     995           0 :           Int_t   ic  = positivepair[j*10+dj];
     996           0 :           Float_t chargedif = pos[ic].GetQ()-neg[j].GetQ();
     997           0 :           if (TMath::Abs(chargedif)<minchargediff+3.) count++;
     998             :         }
     999           0 :         if (count>1) continue;  // more than one "proper" cluster for negative
    1000             :         
    1001             :         Int_t jp = 0;
    1002             :         
    1003             :         count =0;
    1004           0 :         for (Int_t dj=0;dj<cnegative[jp];dj++){
    1005           0 :           Int_t   ic = positivepair[jp*10+dj];
    1006           0 :           Float_t chargedif = pos[ic].GetQ()-neg[jp].GetQ();
    1007           0 :           if (TMath::Abs(chargedif)<minchargediff+4.) count++;
    1008             :         }
    1009           0 :         if (count>1) continue;   
    1010           0 :         if (fgPairs[ip*nn+j]<100) continue;
    1011             :         //
    1012             :         
    1013             :         //almost gold clusters
    1014           0 :         Float_t yp=pos[ip].GetY(); 
    1015           0 :         Float_t yn=neg[j].GetY();
    1016             :       
    1017             : 
    1018           0 :         Float_t xt, zt;
    1019           0 :         seg->GetPadCxz(yn, yp, xt, zt);
    1020             :         
    1021           0 :         xbest=xt; zbest=zt; 
    1022             : 
    1023           0 :         qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
    1024             : 
    1025             :         {
    1026           0 :           Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
    1027           0 :           mT2L->MasterToLocal(loc,trk);
    1028           0 :           lp[0]=trk[1];
    1029           0 :           lp[1]=trk[2];
    1030           0 :         }
    1031           0 :         lp[4]=qbest;        //Q
    1032           0 :         for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
    1033           0 :         for (Int_t ilab=0;ilab<3;ilab++){
    1034           0 :           milab[ilab] = pos[ip].GetLabel(ilab);
    1035           0 :           milab[ilab+3] = neg[j].GetLabel(ilab);
    1036             :         }
    1037             :         //
    1038           0 :         CheckLabels2(milab);
    1039           0 :         if ((neg[j].GetQ()==0)&&(pos[ip].GetQ()==0)) continue; // reject crosses of bad strips!!
    1040           0 :         ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
    1041           0 :         milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
    1042           0 :         Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
    1043             : 
    1044           0 :         lp[2]=0.0022*0.0022;  //SigmaY2
    1045           0 :         lp[3]=0.110*0.110;  //SigmaZ2
    1046             :         // out-of-diagonal element of covariance matrix
    1047           0 :         if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
    1048           0 :         else if ( (info[0]>1) && (info[1]>1) ) { 
    1049           0 :           lp[2]=0.0016*0.0016;  //SigmaY2
    1050           0 :           lp[3]=0.08*0.08;  //SigmaZ2
    1051           0 :           lp[5]=-0.00006;
    1052           0 :         }
    1053             :         else {
    1054           0 :           lp[3]=0.093*0.093;
    1055           0 :           if (info[0]==1) { lp[5]=-0.00014;}
    1056           0 :           else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
    1057             :         }
    1058             : 
    1059           0 :         AliITSRecPoint cl2(milab,lp,info);
    1060           0 :         cl2.SetChargeRatio(ratio);      
    1061           0 :         cl2.SetType(12);
    1062           0 :         fgPairs[ip*nn+j]=12;
    1063           0 :         if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
    1064           0 :           cl2.SetType(13);
    1065           0 :           fgPairs[ip*nn+j]=13;
    1066           0 :         }
    1067           0 :         cused1[ip]++;
    1068           0 :         cused2[j]++;      
    1069           0 :         clusters.push_back( cl2 );
    1070           0 :         ncl++;
    1071             :         
    1072           0 :       } // manyXmany
    1073           0 :     } // loop over Pside 1Dclusters
    1074             :     
    1075           0 :   } // use charge matching
    1076             :   
    1077             :   // recover all the other crosses
    1078             :   //  
    1079           0 :   for (Int_t i=0; i<np; i++) {
    1080             :     Float_t xbest=1000,zbest=1000,qbest=0;
    1081           0 :     Float_t yp=pos[i].GetY(); 
    1082           0 :     if ((pos[i].GetQ()>0)&&(pos[i].GetQ()<3)) continue;
    1083           0 :     for (Int_t j=0; j<nn; j++) {
    1084             :     //    for (Int_t di = 0;di<cpositive[i];di++){
    1085             :     //  Int_t j = negativepair[10*i+di];
    1086           0 :       if ((neg[j].GetQ()>0)&&(neg[j].GetQ()<3)) continue;
    1087             : 
    1088           0 :       if ((neg[j].GetQ()==0)&&(pos[i].GetQ()==0)) continue; // reject crosses of bad strips!!
    1089             : 
    1090           0 :       if (cused2[j]||cused1[i]) continue;      
    1091           0 :       if (fgPairs[i*nn+j]>0 &&fgPairs[i*nn+j]<100) continue;
    1092           0 :       ratio = (pos[i].GetQ()-neg[j].GetQ())/(pos[i].GetQ()+neg[j].GetQ());      
    1093           0 :       Float_t yn=neg[j].GetY();
    1094             :       
    1095           0 :       Float_t xt, zt;
    1096           0 :       seg->GetPadCxz(yn, yp, xt, zt);
    1097             :       
    1098           0 :       if (TMath::Abs(xt)<hwSSD)
    1099           0 :       if (TMath::Abs(zt)<hlSSD) {
    1100           0 :         xbest=xt; zbest=zt; 
    1101             : 
    1102           0 :         qbest=0.5*(pos[i].GetQ()+neg[j].GetQ());
    1103             : 
    1104             :         {
    1105           0 :         Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
    1106           0 :         mT2L->MasterToLocal(loc,trk);
    1107           0 :         lp[0]=trk[1];
    1108           0 :         lp[1]=trk[2];
    1109           0 :         }
    1110           0 :         lp[4]=qbest;        //Q
    1111           0 :         for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
    1112           0 :         for (Int_t ilab=0;ilab<3;ilab++){
    1113           0 :           milab[ilab] = pos[i].GetLabel(ilab);
    1114           0 :           milab[ilab+3] = neg[j].GetLabel(ilab);
    1115             :         }
    1116             :         //
    1117           0 :         CheckLabels2(milab);
    1118           0 :         milab[3]=(((i<<10) + j)<<10) + idet; // pos|neg|det
    1119           0 :         Int_t info[3] = {pos[i].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
    1120             : 
    1121           0 :         lp[2]=0.0022*0.0022;  //SigmaY2
    1122           0 :         lp[3]=0.110*0.110;  //SigmaZ2
    1123             :         // out-of-diagonal element of covariance matrix
    1124           0 :         if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
    1125           0 :         else if ( (info[0]>1) && (info[1]>1) ) { 
    1126           0 :           lp[2]=0.0016*0.0016;  //SigmaY2
    1127           0 :           lp[3]=0.08*0.08;  //SigmaZ2
    1128           0 :           lp[5]=-0.00006;
    1129           0 :         }
    1130             :         else {
    1131           0 :           lp[3]=0.093*0.093;
    1132           0 :           if (info[0]==1) { lp[5]=-0.00014;}
    1133           0 :           else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
    1134             :         }
    1135             : 
    1136           0 :         AliITSRecPoint cl2(milab,lp,info);
    1137           0 :         cl2.SetChargeRatio(ratio);
    1138           0 :         cl2.SetType(100+cpositive[j]+cnegative[i]);       
    1139             : 
    1140           0 :         if(pos[i].GetQ()==0) cl2.SetType(200+cpositive[j]+cnegative[i]);
    1141           0 :         if(neg[j].GetQ()==0) cl2.SetType(300+cpositive[j]+cnegative[i]);
    1142           0 :         clusters.push_back( cl2 );
    1143           0 :         ncl++;
    1144           0 :       }
    1145           0 :     }
    1146           0 :   }
    1147             : 
    1148             : 
    1149           0 :   if(fRecoParam->GetUseBadChannelsInClusterFinderSSD()==kTRUE) {
    1150             :     
    1151             :     //---------------------------------------------------------
    1152             :     // recover crosses of good 1D clusters with bad strips on the other side
    1153             :     // Note1: at first iteration skip modules with a bad side (or almost), (would produce too many fake!) 
    1154             :     // Note2: for modules with a bad side see below 
    1155             :     
    1156           0 :     AliITSCalibrationSSD* cal = (AliITSCalibrationSSD*) fDetTypeRec->GetCalibrationModel(fModule);
    1157             :     Int_t countPbad=0, countNbad=0;
    1158           0 :     for(Int_t ib=0; ib<768; ib++) {
    1159           0 :       if(cal->IsPChannelBad(ib)) countPbad++;
    1160           0 :       if(cal->IsNChannelBad(ib)) countNbad++;
    1161             :     }
    1162             :     //  AliInfo(Form("module %d has %d P- and %d N-bad strips",fModule,countPbad,countNbad));
    1163             :     
    1164           0 :     if( (countPbad<100) && (countNbad<100) ) { // no bad side!!
    1165             :       
    1166           0 :       for (Int_t i=0; i<np; i++) { // loop over Nside 1Dclusters with no crosses
    1167           0 :         if(cnegative[i]) continue; // if intersecting Pside clusters continue;
    1168             :         
    1169             :         //      for(Int_t ib=0; ib<768; ib++) { // loop over all Pstrips
    1170           0 :         for(Int_t ib=15; ib<753; ib++) { // loop over all Pstrips
    1171             :           
    1172           0 :           if(cal->IsPChannelBad(ib)) { // check if strips is bad
    1173           0 :             Float_t yN=pos[i].GetY();   
    1174           0 :             Float_t xt, zt;
    1175           0 :             seg->GetPadCxz(1.*ib, yN, xt, zt);       
    1176             :             
    1177             :             //----------
    1178             :             // bad Pstrip is crossing the Nside 1Dcluster -> create recpoint
    1179             :             // 
    1180           0 :             if ( (TMath::Abs(xt)<hwSSD) && (TMath::Abs(zt)<hlSSD) ) {
    1181           0 :               Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
    1182           0 :               mT2L->MasterToLocal(loc,trk);
    1183           0 :               lp[0]=trk[1];
    1184           0 :               lp[1]=trk[2];        
    1185           0 :               lp[4]=pos[i].GetQ(); //Q
    1186           0 :               for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
    1187           0 :               for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = pos[i].GetLabel(ilab);    
    1188           0 :               CheckLabels2(milab);
    1189           0 :               milab[3]=( (i<<10) << 10 ) + idet; // pos|neg|det
    1190           0 :               Int_t info[3] = {pos[i].GetNd(),0,fNlayer[fModule]};
    1191             :               
    1192             :               // out-of-diagonal element of covariance matrix
    1193           0 :               if (info[0]==1) lp[5]=0.0065;
    1194           0 :               else lp[5]=0.0093;
    1195             :               
    1196           0 :               lp[2]=0.0022*0.0022;  //SigmaY2
    1197           0 :               lp[3]=0.110*0.110;  //SigmaZ2
    1198           0 :               lp[5]=-0.00012; // out-of-diagonal element of covariance matrix
    1199             :               
    1200           0 :               AliITSRecPoint cl2(milab,lp,info);
    1201           0 :               cl2.SetChargeRatio(1.);
    1202           0 :               cl2.SetType(50);    
    1203           0 :               clusters.push_back( cl2 );
    1204           0 :               ncl++;
    1205           0 :             } // cross is within the detector
    1206             :             //
    1207             :             //--------------
    1208             :             
    1209           0 :           } // bad Pstrip
    1210             :           
    1211             :         } // end loop over Pstrips
    1212             :         
    1213           0 :       } // end loop over Nside 1D clusters
    1214             :       
    1215           0 :       for (Int_t j=0; j<nn; j++) { // loop over Pside 1D clusters with no crosses
    1216           0 :         if(cpositive[j]) continue;
    1217             :         
    1218             :         //      for(Int_t ib=0; ib<768; ib++) { // loop over all Nside strips
    1219           0 :         for(Int_t ib=15; ib<753; ib++) { // loop over all Nside strips
    1220             :           
    1221           0 :           if(cal->IsNChannelBad(ib)) { // check if strip is bad
    1222           0 :             Float_t yP=neg[j].GetY();   
    1223           0 :             Float_t xt, zt;
    1224           0 :             seg->GetPadCxz(yP, 1.*ib, xt, zt);       
    1225             :             
    1226             :             //----------
    1227             :             // bad Nstrip is crossing the Pside 1Dcluster -> create recpoint
    1228             :             // 
    1229           0 :             if ( (TMath::Abs(xt)<hwSSD) && (TMath::Abs(zt)<hlSSD) ) {
    1230           0 :               Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
    1231           0 :               mT2L->MasterToLocal(loc,trk);
    1232           0 :               lp[0]=trk[1];
    1233           0 :               lp[1]=trk[2];        
    1234           0 :               lp[4]=neg[j].GetQ(); //Q
    1235           0 :               for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
    1236           0 :               for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = neg[j].GetLabel(ilab);    
    1237           0 :               CheckLabels2(milab);
    1238           0 :               milab[3]=( j << 10 ) + idet; // pos|neg|det
    1239           0 :               Int_t info[3]={0,(Int_t)neg[j].GetNd(),fNlayer[fModule]};
    1240             :               
    1241           0 :               lp[2]=0.0022*0.0022;  //SigmaY2
    1242           0 :               lp[3]=0.110*0.110;  //SigmaZ2
    1243           0 :               lp[5]=-0.00012; // out-of-diagonal element of covariance matrix
    1244             :               
    1245           0 :               AliITSRecPoint cl2(milab,lp,info);
    1246           0 :               cl2.SetChargeRatio(1.);
    1247           0 :               cl2.SetType(60);    
    1248           0 :               clusters.push_back( cl2 );
    1249           0 :               ncl++;
    1250           0 :             } // cross is within the detector
    1251             :             //
    1252             :             //--------------
    1253             :             
    1254           0 :           } // bad Nstrip
    1255             :         } // end loop over Nstrips
    1256           0 :       } // end loop over Pside 1D clusters
    1257             :       
    1258           0 :     } // no bad sides 
    1259             :     
    1260             :     //---------------------------------------------------------
    1261             :     
    1262           0 :     else if( (countPbad>700) && (countNbad<100) ) { // bad Pside!!
    1263             :       
    1264           0 :       for (Int_t i=0; i<np; i++) { // loop over Nside 1Dclusters with no crosses
    1265           0 :         if(cnegative[i]) continue; // if intersecting Pside clusters continue;
    1266             :         
    1267           0 :         Float_t xt, zt;
    1268           0 :         Float_t yN=pos[i].GetY();       
    1269             :         Float_t yP=0.;
    1270           0 :         if (seg->GetLayer()==5) yP = yN + (7.6/1.9);
    1271           0 :         else yP = yN - (7.6/1.9);
    1272           0 :         seg->GetPadCxz(yP, yN, xt, zt);      
    1273             :         
    1274           0 :         if ( (TMath::Abs(xt)<hwSSD) && (TMath::Abs(zt)<hlSSD) ) {
    1275           0 :           Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
    1276           0 :           mT2L->MasterToLocal(loc,trk);
    1277           0 :           lp[0]=trk[1];
    1278           0 :           lp[1]=trk[2];        
    1279           0 :           lp[4]=pos[i].GetQ(); //Q
    1280           0 :           for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
    1281           0 :           for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = pos[i].GetLabel(ilab);        
    1282           0 :           CheckLabels2(milab);
    1283           0 :           milab[3]=( (i<<10) << 10 ) + idet; // pos|neg|det
    1284           0 :           Int_t info[3] = {(Int_t)pos[i].GetNd(),0,fNlayer[fModule]};
    1285             :           
    1286           0 :           lp[2]=0.031*0.031;  //SigmaY2
    1287           0 :           lp[3]=1.15*1.15;  //SigmaZ2
    1288           0 :           lp[5]=-0.036;
    1289             :           
    1290           0 :           AliITSRecPoint cl2(milab,lp,info);
    1291           0 :           cl2.SetChargeRatio(1.);
    1292           0 :           cl2.SetType(70);        
    1293           0 :           clusters.push_back( cl2 );
    1294           0 :           ncl++;
    1295           0 :         } // cross is within the detector
    1296             :         //
    1297             :         //--------------
    1298             :         
    1299           0 :       } // end loop over Nside 1D clusters
    1300             :       
    1301           0 :     } // bad Pside module
    1302             :     
    1303           0 :     else if( (countNbad>700) && (countPbad<100) ) { // bad Nside!!
    1304             :       
    1305           0 :       for (Int_t j=0; j<nn; j++) { // loop over Pside 1D clusters with no crosses
    1306           0 :         if(cpositive[j]) continue;
    1307             :         
    1308           0 :         Float_t xt, zt;
    1309           0 :         Float_t yP=neg[j].GetY();       
    1310             :         Float_t yN=0.;
    1311           0 :         if (seg->GetLayer()==5) yN = yP - (7.6/1.9);
    1312           0 :         else yN = yP + (7.6/1.9);
    1313           0 :         seg->GetPadCxz(yP, yN, xt, zt);      
    1314             :         
    1315           0 :         if ( (TMath::Abs(xt)<hwSSD) && (TMath::Abs(zt)<hlSSD) ) {
    1316           0 :           Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
    1317           0 :           mT2L->MasterToLocal(loc,trk);
    1318           0 :           lp[0]=trk[1];
    1319           0 :           lp[1]=trk[2];        
    1320           0 :           lp[4]=neg[j].GetQ(); //Q
    1321           0 :           for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
    1322           0 :           for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = neg[j].GetLabel(ilab);        
    1323           0 :           CheckLabels2(milab);
    1324           0 :           milab[3]=( j << 10 ) + idet; // pos|neg|det
    1325           0 :           Int_t info[3] = {0,(Int_t)neg[j].GetNd(),fNlayer[fModule]};
    1326             :           
    1327           0 :           lp[2]=0.0085*0.0085;  //SigmaY2
    1328           0 :           lp[3]=1.15*1.15;  //SigmaZ2
    1329           0 :           lp[5]=0.0093;
    1330             :           
    1331           0 :           AliITSRecPoint cl2(milab,lp,info);        
    1332           0 :           cl2.SetChargeRatio(1.);
    1333           0 :           cl2.SetType(80);        
    1334           0 :           clusters.push_back( cl2 );
    1335           0 :           ncl++;
    1336           0 :         } // cross is within the detector
    1337             :         //
    1338             :         //--------------
    1339             :         
    1340           0 :       } // end loop over Pside 1D clusters
    1341             :       
    1342           0 :     } // bad Nside module
    1343             :     
    1344             :     //---------------------------------------------------------
    1345             :     
    1346           0 :   } // use bad channels
    1347             : 
    1348             :   //cout<<ncl<<" clusters for this module"<<endl;
    1349             : 
    1350           0 :   delete [] cnegative;
    1351           0 :   delete [] cused1;
    1352           0 :   delete [] negativepair;
    1353           0 :   delete [] cpositive;
    1354           0 :   delete [] cused2;
    1355           0 :   delete [] positivepair;
    1356             : 
    1357           0 : }

Generated by: LCOV version 1.11