]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - ITS/AliITSTrackleterSPDEff.cxx
fix typo
[u/mrichter/AliRoot.git] / ITS / AliITSTrackleterSPDEff.cxx
index 38e9f99afb27c91a3d2aee70a4f769056bba42f6..7b54ceb5a6d344917e3ccce99e17bf27098b7d1e 100644 (file)
@@ -32,6 +32,7 @@
 #include <TFile.h>
 #include <TTree.h>
 #include <TParticle.h>
+#include <TParticlePDG.h>
 #include <TSystem.h>
 #include <Riostream.h>
 #include <TClonesArray.h>
 #include "AliRunLoader.h"
 #include "AliITSReconstructor.h"
 #include "AliITSRecPoint.h"
+#include "AliESDEvent.h"
+#include "AliESDVertex.h"
 //____________________________________________________________________
+
+using std::ofstream;
+using std::ios;
+using std::ifstream;
 ClassImp(AliITSTrackleterSPDEff)
 
 
@@ -62,8 +69,8 @@ fNClustersLay1(0),
 fNClustersLay2(0),
 fNTracklets(0),
 fOnlyOneTrackletPerC2(0),
-fPhiWindow(0),
-fZetaWindow(0),
+fPhiWindowL2(0),
+fZetaWindowL2(0),
 fPhiOverlapCut(0),
 fZetaOverlapCut(0),
 fHistOn(0),
@@ -90,16 +97,19 @@ fPhiWindowL1(0),
 fZetaWindowL1(0),
 fOnlyOneTrackletPerC1(0),
 fUpdateOncePerEventPlaneEff(0),
+fMinContVtx(0),
 fChipUpdatedInEvent(0),
 fPlaneEffSPD(0),
+fPlaneEffBkg(0),
 fReflectClusterAroundZAxisForLayer0(kFALSE),
 fReflectClusterAroundZAxisForLayer1(kFALSE),
+fLightBkgStudyInParallel(kFALSE),
 fMC(0),
-fUseOnlyPrimaryForPred(1),
+fUseOnlyPrimaryForPred(0),
 fUseOnlySecondaryForPred(0), 
 fUseOnlySameParticle(0),
 fUseOnlyDifferentParticle(0),
-fUseOnlyStableParticle(0),
+fUseOnlyStableParticle(1),
 fPredictionPrimary(0),
 fPredictionSecondary(0),
 fClusterPrimary(0),
@@ -123,12 +133,19 @@ fhDPhiVsDThetaInterpAcc(0),
 fhDPhiVsDZetaInterpAll(0),
 fhDPhiVsDZetaInterpAcc(0),
 fhetaClustersLay2(0),
-fhphiClustersLay2(0)
+fhphiClustersLay2(0),
+fhClustersInChip(0),
+fhClustersInModuleLay1(0),
+fhClustersInModuleLay2(0)
 {
    // default constructor
 // from AliITSMultReconstructor
-  SetPhiWindow();
-  SetZetaWindow();
+  Init();
+}
+//______________________________________________________________________
+void AliITSTrackleterSPDEff::Init() {
+  SetPhiWindowL2();
+  SetZetaWindowL2();
   SetOnlyOneTrackletPerC2();
   fClustersLay1       = new Float_t*[300000];
   fClustersLay2       = new Float_t*[300000];
@@ -158,6 +175,7 @@ fhphiClustersLay2(0)
   if (GetHistOn()) BookHistos();
 
   fPlaneEffSPD = new AliITSPlaneEffSPD();
+  SetLightBkgStudyInParallel();
 }
 //______________________________________________________________________
 AliITSTrackleterSPDEff::AliITSTrackleterSPDEff(const AliITSTrackleterSPDEff &mr) :  
@@ -171,8 +189,8 @@ fNClustersLay1(mr.fNClustersLay1),
 fNClustersLay2(mr.fNClustersLay2),
 fNTracklets(mr.fNTracklets),
 fOnlyOneTrackletPerC2(mr.fOnlyOneTrackletPerC2),
-fPhiWindow(mr.fPhiWindow),
-fZetaWindow(mr.fZetaWindow),
+fPhiWindowL2(mr.fPhiWindowL2),
+fZetaWindowL2(mr.fZetaWindowL2),
 fPhiOverlapCut(mr.fPhiOverlapCut),
 fZetaOverlapCut(mr.fZetaOverlapCut),
 fHistOn(mr.fHistOn),
@@ -199,10 +217,13 @@ fPhiWindowL1(mr.fPhiWindowL1),
 fZetaWindowL1(mr.fZetaWindowL1),
 fOnlyOneTrackletPerC1(mr.fOnlyOneTrackletPerC1),
 fUpdateOncePerEventPlaneEff(mr.fUpdateOncePerEventPlaneEff),
+fMinContVtx(mr.fMinContVtx),
 fChipUpdatedInEvent(mr.fChipUpdatedInEvent),
 fPlaneEffSPD(mr.fPlaneEffSPD),
+fPlaneEffBkg(mr.fPlaneEffBkg),
 fReflectClusterAroundZAxisForLayer0(mr.fReflectClusterAroundZAxisForLayer0),
 fReflectClusterAroundZAxisForLayer1(mr.fReflectClusterAroundZAxisForLayer1),
+fLightBkgStudyInParallel(mr.fLightBkgStudyInParallel),
 fMC(mr.fMC),
 fUseOnlyPrimaryForPred(mr.fUseOnlyPrimaryForPred),
 fUseOnlySecondaryForPred(mr.fUseOnlySecondaryForPred),
@@ -232,7 +253,10 @@ fhDPhiVsDThetaInterpAcc(mr.fhDPhiVsDThetaInterpAcc),
 fhDPhiVsDZetaInterpAll(mr.fhDPhiVsDZetaInterpAll),
 fhDPhiVsDZetaInterpAcc(mr.fhDPhiVsDZetaInterpAcc),
 fhetaClustersLay2(mr.fhetaClustersLay2),
-fhphiClustersLay2(mr.fhphiClustersLay2)
+fhphiClustersLay2(mr.fhphiClustersLay2),
+fhClustersInChip(mr.fhClustersInChip),
+fhClustersInModuleLay1(mr.fhClustersInModuleLay1),
+fhClustersInModuleLay2(mr.fhClustersInModuleLay2)
 {
   // Copy constructor
 }
@@ -284,11 +308,16 @@ AliITSTrackleterSPDEff::~AliITSTrackleterSPDEff(){
 
   // delete PlaneEff
   delete fPlaneEffSPD;
+  fPlaneEffSPD=0;
+  if(fPlaneEffBkg) {
+    delete fPlaneEffBkg;
+    fPlaneEffBkg=0;
+
+  }
 }
 //____________________________________________________________________
 void
-//AliITSTrackleterSPDEff::Reconstruct(TTree* clusterTree, Float_t* vtx, Float_t*, AliStack *pStack, TTree *tRef) {
-AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
+AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef, Bool_t lbkg) {
   //
   // - you have to take care of the following, before of using Reconstruct
   //   1) call LoadClusters(TTree* cl) that finds the position of the clusters (in global coord)
@@ -300,6 +329,16 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
   // - Check if there is a cluster near that point  
   //
   // reset counters
+  if(lbkg && !GetLightBkgStudyInParallel()) {
+    AliError("You asked for lightBackground in the Reconstruction without proper call to SetLightBkgStudyInParallel(1)"); 
+    return;
+  }
+  AliITSPlaneEffSPD *pe;
+  if(lbkg) {
+    pe=fPlaneEffBkg;
+  } else {
+    pe=fPlaneEffSPD;
+  }
   fNTracklets = 0; 
   // retrieve the vertex position
   Float_t vtx[3];
@@ -307,11 +346,11 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
   vtx[1]=(Float_t)GetY();
   vtx[2]=(Float_t)GetZ();
   // to study residual background (i.e. contribution from TT' to measured efficiency) 
-  if(fReflectClusterAroundZAxisForLayer0) ReflectClusterAroundZAxisForLayer(0);
-  if(fReflectClusterAroundZAxisForLayer1) ReflectClusterAroundZAxisForLayer(1);
+  if(fReflectClusterAroundZAxisForLayer0 && !lbkg) ReflectClusterAroundZAxisForLayer(0);
+  if(fReflectClusterAroundZAxisForLayer1 && !lbkg) ReflectClusterAroundZAxisForLayer(1);
   //
-  if(fMC && !pStack) {AliError("You asked for MC infos but AliStack not properly loaded"); return;}
-  if(fMC && !tRef) {AliError("You asked for MC infos but TrackRef Tree not properly loaded"); return;}
+  if(fMC && !pStack && !lbkg) {AliError("You asked for MC infos but AliStack not properly loaded"); return;}
+  if(fMC && !tRef   && !lbkg) {AliError("You asked for MC infos but TrackRef Tree not properly loaded"); return;}
   Bool_t found;
   Int_t nfTraPred1=0;  Int_t ntTraPred1=0;
   Int_t nfTraPred2=0;  Int_t ntTraPred2=0;
@@ -352,12 +391,13 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
     fChipPredOnLay2[iC1] = key;
     fAssociationFlag1[iC1] = kFALSE;
  
-    if (fHistOn) {
+    if (fHistOn && !lbkg) {
       Float_t eta=fClustersLay1[iC1][0];
       eta= TMath::Tan(eta/2.);
       eta=-TMath::Log(eta);
-      fhetaClustersLay1->Fill(eta);    
+      fhetaClustersLay1->Fill(eta);
       fhphiClustersLay1->Fill(fClustersLay1[iC1][1]);
+      fhClustersInChip->Fill(fhClustersInChip->GetBinCenter(key+1)); // if found=kFALSE -> overflow
     }      
   }
   // Loop on layer 2 : finding theta, phi and r   
@@ -376,7 +416,7 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
 
     found=FindChip(key, 0, vtx, fClustersLay2[iC2][0],fClustersLay2[iC2][1]);
     if (!found) {
-      AliWarning(Form("Reconstruct: cannot find chip prediction on inner layer for cluster %d on the outer layer",iC2)); 
+      AliDebug(1,Form("Reconstruct: cannot find chip prediction on inner layer for cluster %d on the outer layer",iC2)); 
       key=999999;
     }
     nfTraPred1+=(Int_t)found; // this for debugging purpose
@@ -384,12 +424,13 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
     fChipPredOnLay1[iC2] = key;
     fAssociationFlag[iC2] = kFALSE;
  
-    if (fHistOn) {
+    if (fHistOn && !lbkg) {
       Float_t eta=fClustersLay2[iC2][0];
       eta= TMath::Tan(eta/2.);
       eta=-TMath::Log(eta);
       fhetaClustersLay2->Fill(eta);
       fhphiClustersLay2->Fill(fClustersLay2[iC2][1]);
+      fhClustersInChip->Fill(fhClustersInChip->GetBinCenter(key+1)); // if found=kFALSE -> overflow
     }
   }  
   
@@ -413,13 +454,13 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
 
     // in any case, if MC has been required, store statistics of primaries and secondaries
     Bool_t primary=kFALSE; Bool_t secondary=kFALSE; // it is better to have both since chip might not be found
-    if (fMC) {
+    if (fMC && !lbkg) {
        Int_t lab1=(Int_t)fClustersLay1[iC1][3];
        Int_t lab2=(Int_t)fClustersLay1[iC1][4];
        Int_t lab3=(Int_t)fClustersLay1[iC1][5];
        // do it always as a function of the chip number used to built the prediction
        found=FindChip(key,0,vtx,fClustersLay1[iC1][0],fClustersLay1[iC1][1],fClustersLay1[iC1][2]);
-       if (!found) {AliWarning(
+       if (!found) {AliDebug(1,
          Form("Reconstruct MC: cannot find chip on inner layer for cluster %d",iC1)); }
        else {
          if((lab1 != -2  &&  PrimaryTrackChecker(lab1,pStack) ) ||
@@ -466,7 +507,7 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
        Float_t r2    = fClustersLay2[iC2][2]/TMath::Cos(fClustersLay2[iC2][0]);
         Float_t dZeta = TMath::Cos(fClustersLay1[iC1][0])*r2 - fClustersLay2[iC2][2];
 
-       if (fHistOn) {
+       if (fHistOn && !lbkg) {
          fhClustersDPhiAll->Fill(dPhi);    
          fhClustersDThetaAll->Fill(dTheta);    
          fhClustersDZetaAll->Fill(dZeta);    
@@ -475,8 +516,8 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
        }
 
        // make "elliptical" cut in Phi and Zeta! 
-       Float_t d = TMath::Sqrt(dPhi*dPhi/fPhiWindow/fPhiWindow + 
-                                dZeta*dZeta/fZetaWindow/fZetaWindow);
+       Float_t d = TMath::Sqrt(dPhi*dPhi/fPhiWindowL2/fPhiWindowL2 + 
+                                dZeta*dZeta/fZetaWindowL2/fZetaWindowL2);
 
        if (d>1) continue;      
        
@@ -493,7 +534,7 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
     
     if (distmin<100) { // This means that a cluster in layer 2 was found that matches with iC1
 
-      if (fHistOn) {
+      if (fHistOn && !lbkg) {
        fhClustersDPhiAcc->Fill(dPhimin);
        fhClustersDThetaAcc->Fill(dThetamin);    
        fhClustersDZetaAcc->Fill(dZetamin);    
@@ -537,7 +578,7 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
         fTracklets[fNTracklets][3] = -2;
       }
 
-      if (fHistOn) {
+      if (fHistOn && !lbkg) {
        Float_t eta=fTracklets[fNTracklets][0];
        eta= TMath::Tan(eta/2.);
        eta=-TMath::Log(eta);
@@ -548,14 +589,14 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
 // Check that this cluster is still in the same chip (here you pass also Zvtx for better computation)
       found=FindChip(key,1,vtx,fClustersLay2[iC2WithBestDist][0],fClustersLay2[iC2WithBestDist][1],fClustersLay2[iC2WithBestDist][2]);
       if(!found){
-        AliWarning(
+        AliDebug(1,
          Form("Reconstruct: cannot find chip on outer layer for cluster %d",iC2WithBestDist));
         key=999999;
       }
       nfClu2+=(Int_t)found; // this for debugging purpose
       ntClu2++;             // to check efficiency of the method FindChip
       if(key<1200) { // the Chip has been found
-        if(fMC) { // this part only for MC
+        if(fMC && !lbkg) { // this part only for MC
           // Int_t labc1=(Int_t)fClustersLay2[iC2WithBestDist][3];
           // Int_t labc2=(Int_t)fClustersLay2[iC2WithBestDist][4];
           // Int_t labc3=(Int_t)fClustersLay2[iC2WithBestDist][5];
@@ -569,17 +610,17 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
 
         if (key==fChipPredOnLay2[iC1]) { // this control seems too loose: has to be checked !
                                         // OK, success
-                fPlaneEffSPD->UpDatePlaneEff(kTRUE,key); // success
+                pe->UpDatePlaneEff(kTRUE,key); // success
                 fChipUpdatedInEvent[key]=kTRUE; 
-                if(fMC) {
+                if(fMC && !lbkg) {
                   if(primary)   fSuccessP[key]++;
                   if(secondary) fSuccessS[key]++;
                 }
         }
         else {
-                fPlaneEffSPD->UpDatePlaneEff(kTRUE,key); // this should not be a failure
+                pe->UpDatePlaneEff(kTRUE,key); // this should not be a failure
                 fChipUpdatedInEvent[key]=kTRUE;          // (might be in the tracking tollerance)
-                if(fMC) {
+                if(fMC && !lbkg) {
                   if(primary)   fSuccessP[key]++;
                   if(secondary) fSuccessS[key]++;
                 }
@@ -590,9 +631,9 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
 
     } // if any cluster found --> increment statistics by 1 failure (provided you have chip prediction)
     else if (fChipPredOnLay2[iC1]<1200) {
-      fPlaneEffSPD->UpDatePlaneEff(kFALSE,fChipPredOnLay2[iC1]);
+      pe->UpDatePlaneEff(kFALSE,fChipPredOnLay2[iC1]);
       fChipUpdatedInEvent[fChipPredOnLay2[iC1]]=kTRUE;
-      if(fMC) {
+      if(fMC && !lbkg) {
         if(primary)   fFailureP[fChipPredOnLay2[iC1]]++;
         if(secondary) fFailureS[fChipPredOnLay2[iC1]]++;
       }
@@ -621,13 +662,13 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
 
     // in any case, if MC has been required, store statistics of primaries and secondaries
     Bool_t primary=kFALSE; Bool_t secondary=kFALSE;
-    if (fMC) {
+    if (fMC && !lbkg) {
        Int_t lab1=(Int_t)fClustersLay2[iC2][3];
        Int_t lab2=(Int_t)fClustersLay2[iC2][4];
        Int_t lab3=(Int_t)fClustersLay2[iC2][5];
        // do it always as a function of the chip number used to built the prediction
        found=FindChip(key,1,vtx,fClustersLay2[iC2][0],fClustersLay2[iC2][1],fClustersLay2[iC2][2]);
-       if (!found) {AliWarning(
+       if (!found) {AliDebug(1,
          Form("Reconstruct MC: cannot find chip on outer layer for cluster %d",iC2)); }
        else {
          if((lab1 != -2  &&  PrimaryTrackChecker(lab1,pStack) ) ||
@@ -676,7 +717,7 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
         Float_t dZeta = TMath::Cos(fClustersLay2[iC2][0])*r1 - fClustersLay1[iC1][2];
 
 
-       if (fHistOn) {
+       if (fHistOn && !lbkg) {
          fhClustersDPhiInterpAll->Fill(dPhi);    
          fhClustersDThetaInterpAll->Fill(dTheta);    
          fhClustersDZetaInterpAll->Fill(dZeta);    
@@ -702,7 +743,7 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
     
     if (distmin<100) { // This means that a cluster in layer 1 was found that matches with iC2
 
-      if (fHistOn) {
+      if (fHistOn && !lbkg) {
        fhClustersDPhiInterpAcc->Fill(dPhimin);
        fhClustersDThetaInterpAcc->Fill(dThetamin);    
        fhClustersDZetaInterpAcc->Fill(dZetamin);    
@@ -749,14 +790,14 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
 // Check that this cluster is still in the same chip (here you pass also Zvtx for better computation)
       found=FindChip(key,0,vtx,fClustersLay1[iC1WithBestDist][0],fClustersLay1[iC1WithBestDist][1],fClustersLay1[iC1WithBestDist][2]);
       if(!found){
-        AliWarning(
+        AliDebug(1,
          Form("Reconstruct: cannot find chip on inner layer for cluster %d",iC1WithBestDist));
         key=999999;
       }
       nfClu1+=(Int_t)found; // this for debugging purpose
       ntClu1++;             // to check efficiency of the method FindChip
       if(key<1200) {
-        if(fMC) { // this part only for MC
+        if(fMC && !lbkg) { // this part only for MC
           // Int_t labc1=(Int_t)fClustersLay1[iC1WithBestDist][3];
           // Int_t labc2=(Int_t)fClustersLay1[iC1WithBestDist][4];
           // Int_t labc3=(Int_t)fClustersLay1[iC1WithBestDist][5];
@@ -770,16 +811,16 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
 
         if (key==fChipPredOnLay1[iC2]) { // this control seems too loose: has to be checked !
                                         // OK, success
-                fPlaneEffSPD->UpDatePlaneEff(kTRUE,key); // success
+                pe->UpDatePlaneEff(kTRUE,key); // success
                 fChipUpdatedInEvent[key]=kTRUE;
-                if(fMC) {
+                if(fMC && !lbkg) {
                   if(primary)   fSuccessP[key]++;
                   if(secondary) fSuccessS[key]++;
                 }
         } else {
-                fPlaneEffSPD->UpDatePlaneEff(kTRUE,key); // this should not be a failure
+                pe->UpDatePlaneEff(kTRUE,key); // this should not be a failure
                 fChipUpdatedInEvent[key]=kTRUE;          // (might be in the tracking tollerance)
-                if(fMC) {
+                if(fMC && !lbkg) {
                   if(primary)   fSuccessP[key]++;
                   if(secondary) fSuccessS[key]++;
                 }
@@ -790,9 +831,9 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
 
     } // if no cluster found --> increment statistics by 1 failure (provided you have chip prediction)
     else if (fChipPredOnLay1[iC2]<1200) {
-      fPlaneEffSPD->UpDatePlaneEff(kFALSE,fChipPredOnLay1[iC2]);
+      pe->UpDatePlaneEff(kFALSE,fChipPredOnLay1[iC2]);
       fChipUpdatedInEvent[fChipPredOnLay1[iC2]]=kTRUE;
-      if(fMC) {
+      if(fMC && !lbkg) {
         if(primary)   fFailureP[fChipPredOnLay1[iC2]]++;
         if(secondary) fFailureS[fChipPredOnLay1[iC2]]++;
       }
@@ -806,7 +847,7 @@ AliITSTrackleterSPDEff::Reconstruct(AliStack *pStack, TTree *tRef) {
   AliDebug(1,Form(("Eff. of method FindChip for Cluster on lay 2 = %d / %d"),nfClu2,ntClu2));
 }
 //____________________________________________________________________
-Bool_t AliITSTrackleterSPDEff::FindChip(UInt_t &key, Int_t layer,  Float_t* vtx, 
+Bool_t AliITSTrackleterSPDEff::FindChip(UInt_t &key, Int_t layer,const  Float_t* vtx, 
                                   Float_t thetaVtx, Float_t phiVtx, Float_t zVtx) {
 //
 // Input: a) layer number in the range [0,1]
@@ -827,7 +868,10 @@ Bool_t AliITSTrackleterSPDEff::FindChip(UInt_t &key, Int_t layer,  Float_t* vtx,
   Double_t zAbs,phiAbs; // those are the polar coordinate, in the Absolute ALICE Reference 
                         // of the intersection of the tracklet with the pixel layer.  
   if (TMath::Abs(zVtx)<100) zAbs=zVtx + vtx[2]; // this is fine only for the cluster, not for the track prediction
-  else zAbs=r/TMath::Tan(thetaVtx) + vtx[2]; // this is the only way to do for the tracklet prediction
+  else {
+    if(TMath::Abs(thetaVtx)<1E-6) return kFALSE;
+    zAbs=r/TMath::Tan(thetaVtx) + vtx[2]; // this is the only way to do for the tracklet prediction
+  }
   AliDebug(1,Form("FindChip: vtx[0] = %f, vtx[1] = %f, vtx[2] = %f",vtx[0],vtx[1],vtx[2]));
   Double_t vtxy[2]={vtx[0],vtx[1]};
   if (vtxy[0]*vtxy[1]+vtxy[1]*vtxy[1]>0) { // this method holds only for displaced vertices 
@@ -976,7 +1020,7 @@ phi=TMath::ATan2(pP[1],pP[0]);
 return kTRUE;
 }
 //___________________________________________________________
-Bool_t AliITSTrackleterSPDEff::SetAngleRange02Pi(Double_t &angle) {
+Bool_t AliITSTrackleterSPDEff::SetAngleRange02Pi(Double_t &angle) const {
 //
 //  simple method to reduce all angles (in rad)
 //  in range [0,2pi[
@@ -1051,13 +1095,13 @@ TParticle* part = stack->Particle(ipart);
 
   Int_t nret=0;
   TParticle* dau = 0;
-  Int_t nDau = 0;
+  //  Int_t nDau = 0;
   Int_t pdgDau;
   Int_t firstDau = part->GetFirstDaughter(); // if no daugther stored then no way to understand i
                                              // its real fate ! But you have to take it !
   if (firstDau > 0) { // if it has daugther(s) try to infer if it is "detectable" as a tracklet
     Int_t lastDau = part->GetLastDaughter();
-    nDau = lastDau - firstDau + 1;
+    //    nDau = lastDau - firstDau + 1;
     Double_t distMax=0.;
     Int_t jmax=0;
     for(Int_t j=firstDau; j<=lastDau; j++)  {
@@ -1335,9 +1379,10 @@ void AliITSTrackleterSPDEff::PrintAscii(ostream *os)const{
     //   none.
     // Return:
     //   none.
-    *os << fPhiWindowL1 <<" "<< fZetaWindowL1 << " " << fPhiWindow <<" "<< fZetaWindow 
+    *os << fPhiWindowL1 <<" "<< fZetaWindowL1 << " " << fPhiWindowL2 <<" "<< fZetaWindowL2 
         << " " << fOnlyOneTrackletPerC1 << " " << fOnlyOneTrackletPerC2 
-        << " " << fUpdateOncePerEventPlaneEff << " " << fReflectClusterAroundZAxisForLayer0
+        << " " << fUpdateOncePerEventPlaneEff << " " << fMinContVtx 
+        << " " << fReflectClusterAroundZAxisForLayer0
         << " " << fReflectClusterAroundZAxisForLayer1;
     *os << " " << fMC;
     if(!fMC) {AliInfo("Writing only cuts, no MC info"); return;}
@@ -1369,9 +1414,10 @@ void AliITSTrackleterSPDEff::ReadAscii(istream *is){
     //   none.
 
     Bool_t tmp= fMC;
-    *is >> fPhiWindowL1 >> fZetaWindowL1 >> fPhiWindow >> fZetaWindow 
+    *is >> fPhiWindowL1 >> fZetaWindowL1 >> fPhiWindowL2 >> fZetaWindowL2 
         >> fOnlyOneTrackletPerC1 >> fOnlyOneTrackletPerC2  
-        >> fUpdateOncePerEventPlaneEff >> fReflectClusterAroundZAxisForLayer0
+        >> fUpdateOncePerEventPlaneEff >> fMinContVtx 
+        >> fReflectClusterAroundZAxisForLayer0
         >> fReflectClusterAroundZAxisForLayer1;
     //if(!fMC) {AliInfo("Reading only cuts, no MC info available");return;}
     *is >> fMC;
@@ -1445,17 +1491,18 @@ void AliITSTrackleterSPDEff::SavePredictionMC(TString filename) const {
  }
  else {
     TFile* mcfile = TFile::Open(filename, "RECREATE");
-    TH1F* cuts = new TH1F("cuts", "list of cuts", 10, 0, 10); // TH1I containing cuts 
+    TH1F* cuts = new TH1F("cuts", "list of cuts", 11, 0, 11); // TH1I containing cuts 
     cuts->SetBinContent(1,fPhiWindowL1);
     cuts->SetBinContent(2,fZetaWindowL1);
-    cuts->SetBinContent(3,fPhiWindow);
-    cuts->SetBinContent(4,fZetaWindow);
+    cuts->SetBinContent(3,fPhiWindowL2);
+    cuts->SetBinContent(4,fZetaWindowL2);
     cuts->SetBinContent(5,fOnlyOneTrackletPerC1);
     cuts->SetBinContent(6,fOnlyOneTrackletPerC2);
     cuts->SetBinContent(7,fUpdateOncePerEventPlaneEff);
-    cuts->SetBinContent(8,fReflectClusterAroundZAxisForLayer0);
-    cuts->SetBinContent(9,fReflectClusterAroundZAxisForLayer1);
-    cuts->SetBinContent(10,fMC);
+    cuts->SetBinContent(8,fMinContVtx);
+    cuts->SetBinContent(9,fReflectClusterAroundZAxisForLayer0);
+    cuts->SetBinContent(10,fReflectClusterAroundZAxisForLayer1);
+    cuts->SetBinContent(11,fMC);
     cuts->Write();
     delete cuts;
     if(!fMC) {AliInfo("Writing only cuts, no MC info");}
@@ -1539,14 +1586,15 @@ void AliITSTrackleterSPDEff::ReadPredictionMC(TString filename) {
     TH1F *cuts = (TH1F*)mcfile->Get("cuts"); 
     fPhiWindowL1=(Float_t)cuts->GetBinContent(1);
     fZetaWindowL1=(Float_t)cuts->GetBinContent(2);
-    fPhiWindow=(Float_t)cuts->GetBinContent(3);
-    fZetaWindow=(Float_t)cuts->GetBinContent(4);
+    fPhiWindowL2=(Float_t)cuts->GetBinContent(3);
+    fZetaWindowL2=(Float_t)cuts->GetBinContent(4);
     fOnlyOneTrackletPerC1=(Bool_t)cuts->GetBinContent(5);
     fOnlyOneTrackletPerC2=(Bool_t)cuts->GetBinContent(6);
     fUpdateOncePerEventPlaneEff=(Bool_t)cuts->GetBinContent(7);
-    fReflectClusterAroundZAxisForLayer0=(Bool_t)cuts->GetBinContent(8);
-    fReflectClusterAroundZAxisForLayer1=(Bool_t)cuts->GetBinContent(9);
-    fMC=(Bool_t)cuts->GetBinContent(10);
+    fMinContVtx=(Int_t)cuts->GetBinContent(8);
+    fReflectClusterAroundZAxisForLayer0=(Bool_t)cuts->GetBinContent(9);
+    fReflectClusterAroundZAxisForLayer1=(Bool_t)cuts->GetBinContent(10);
+    fMC=(Bool_t)cuts->GetBinContent(11);
     if(!fMC) {AliInfo("Reading only cuts, no MC info"); if(tmp) SetMC(kFALSE); }
     else { // only if file with MC predictions 
       if(!tmp) {AliInfo("Calling SetMC() to read this file wtih MC info"); SetMC();}
@@ -1627,6 +1675,13 @@ Bool_t AliITSTrackleterSPDEff::SaveHists() {
 
   fhetaClustersLay2->Write();
   fhphiClustersLay2->Write();
+  fhClustersInChip->Write();
+  for (Int_t nhist=0;nhist<80;nhist++){
+    fhClustersInModuleLay1[nhist]->Write(); 
+  }
+  for (Int_t nhist=0;nhist<160;nhist++){
+    fhClustersInModuleLay2[nhist]->Write(); 
+  }
   return kTRUE;
 }
 //__________________________________________________________
@@ -1636,7 +1691,7 @@ Bool_t AliITSTrackleterSPDEff::WriteHistosToFile(TString filename, Option_t* opt
   // Also the histograms from the base class are saved 
   //
   if (!GetHistOn()) return kFALSE;
-  if (filename.Data()=="") {
+  if (!strcmp(filename.Data(),"")) {
      AliWarning("WriteHistosToFile: null output filename!");
      return kFALSE;
   }
@@ -1718,6 +1773,45 @@ void AliITSTrackleterSPDEff::BookHistos() {
   fhetaClustersLay2->SetDirectory(0);
   fhphiClustersLay2  = new TH1F("phiClustersLay2", "phiCl2", 100, 0., 2*TMath::Pi());
   fhphiClustersLay2->SetDirectory(0);
+  fhClustersInChip = new TH1F("fhClustersInChip", "ClustersPerChip", 1200, -0.5, 1199.5);
+  fhClustersInChip->SetDirectory(0);
+// each chip is divided 8(z) x 4(y), i.e. in 32 squares, each containing 4 columns and 64 rows.
+  Float_t bz[160]; const Float_t kconv = 1.0E-04; // converts microns to cm.
+  for(Int_t i=0;i<160;i++) bz[i] = 425.0; // most are 425 microns except below
+  bz[ 31] = bz[ 32] = 625.0; // first chip boundry
+  bz[ 63] = bz[ 64] = 625.0; // first chip boundry
+  bz[ 95] = bz[ 96] = 625.0; // first chip boundry
+  bz[127] = bz[128] = 625.0; // first chip boundry
+  Double_t xbins[41]; // each bin in x (Z loc coordinate) includes 4 columns
+  //xbins[0]=0;
+  Float_t xmn,xmx,zmn,zmx;
+  if(!fPlaneEffSPD->GetBlockBoundaries(0,xmn,xmx,zmn,zmx)) AliWarning("Could not book histo properly");
+  xbins[0]=(Double_t)zmn;
+  for(Int_t i=0;i<40;i++) {
+   xbins[i+1]=xbins[i] + (bz[4*i]+bz[4*i+1]+bz[4*i+2]+bz[4*i+3])*kconv; 
+  }
+  TString histname="ClustersLay1_mod_",aux;
+  fhClustersInModuleLay1 =new TH2F*[80];
+  for (Int_t nhist=0;nhist<80;nhist++){
+    aux=histname;
+    aux+=nhist;
+    //  
+    fhClustersInModuleLay1[nhist]=new TH2F("histname","histname",40,xbins,4,(Double_t)xmn,(Double_t)xmx); 
+    fhClustersInModuleLay1[nhist]->SetName(aux.Data());
+    fhClustersInModuleLay1[nhist]->SetTitle(aux.Data());
+    fhClustersInModuleLay1[nhist]->SetDirectory(0);
+  }
+  histname="ClustersLay2_mod_";
+  fhClustersInModuleLay2 =new TH2F*[160];
+  for (Int_t nhist=0;nhist<160;nhist++){
+    aux=histname;
+    aux+=nhist;
+    fhClustersInModuleLay2[nhist]=new TH2F("histname","histname",40,xbins,4,(Double_t)xmn,(Double_t)xmx);
+    fhClustersInModuleLay2[nhist]->SetName(aux.Data());
+    fhClustersInModuleLay2[nhist]->SetTitle(aux.Data());
+    fhClustersInModuleLay2[nhist]->SetDirectory(0);
+  }
+//
   return;
 }
 //____________________________________________________________
@@ -1754,15 +1848,24 @@ void AliITSTrackleterSPDEff::DeleteHistos() {
     if(fhDPhiVsDZetaInterpAcc) {delete fhDPhiVsDZetaInterpAcc; fhDPhiVsDZetaInterpAcc=0;}
     if(fhetaClustersLay2) {delete fhetaClustersLay2; fhetaClustersLay2=0;}
     if(fhphiClustersLay2) {delete fhphiClustersLay2; fhphiClustersLay2=0;}
+    if(fhClustersInChip) {delete fhClustersInChip; fhClustersInChip=0;}
+    if(fhClustersInModuleLay1) {
+      for (Int_t i=0; i<80; i++ ) delete fhClustersInModuleLay1[i];
+      delete [] fhClustersInModuleLay1; fhClustersInModuleLay1=0;
+    }
+    if(fhClustersInModuleLay2) {
+      for (Int_t i=0; i<160; i++ ) delete fhClustersInModuleLay2[i];
+      delete [] fhClustersInModuleLay2; fhClustersInModuleLay2=0;
+    }
 }
 //_______________________________________________________________
 Bool_t AliITSTrackleterSPDEff::IsReconstructableAt(Int_t layer,Int_t iC,Int_t ipart,
-                                                   Float_t* vtx, AliStack *stack, TTree *ref) {
+                                                   const Float_t* vtx, const AliStack *stack, TTree *ref) {
 // This (private) method can be used only for MC events, where both AliStack and the TrackReference
 // are available. 
 // It is used to asses whether a tracklet prediction is reconstructable or not at the other layer
 // Input: 
-//      - Int_t layer (either 0 or 1): layer which you want to chech if the tracklete can be 
+//      - Int_t layer (either 0 or 1): layer which you want to check if the tracklete can be 
 //                                     reconstructed at
 //      - Int_t iC : cluster index used to build the tracklet prediction 
 //                   if layer=0 ==> iC=iC2 ; elseif layer=1 ==> iC=iC1
@@ -1823,8 +1926,8 @@ for(Int_t iref=0;iref<nref;iref++) { // loop over all the refs of the matching t
     Float_t dZeta = TMath::Cos(fClustersLay1[iC][0])*r2 - trefLayExtr[2];
 
     // make "elliptical" cut in Phi and Zeta!
-    Float_t d = TMath::Sqrt(dPhi*dPhi/fPhiWindow/fPhiWindow +
-                              dZeta*dZeta/fZetaWindow/fZetaWindow);
+    Float_t d = TMath::Sqrt(dPhi*dPhi/fPhiWindowL2/fPhiWindowL2 +
+                              dZeta*dZeta/fZetaWindowL2/fZetaWindowL2);
     if (d<1) {ret=kTRUE; break;}
   }
   if(layer==0) { // try to see if it is reconstructable at the inner layer
@@ -1875,7 +1978,7 @@ if(ilayer==1) {
 return;
 }
 //____________________________________________________________________________
-Int_t AliITSTrackleterSPDEff::Clusters2Tracks(AliESDEvent *){
+Int_t AliITSTrackleterSPDEff::Clusters2Tracks(AliESDEvent *esd){
 // This method is used to find the tracklets. 
 // It is called from AliReconstruction
 // The vertex is supposed to be associated to the Tracker (i.e. to this) already
@@ -1883,6 +1986,10 @@ Int_t AliITSTrackleterSPDEff::Clusters2Tracks(AliESDEvent *){
 // In case Monte Carlo is required, the appropriate linking to Stack and TrackRef is attempted 
 //
   Int_t rc=1;
+  // apply cuts on the vertex quality
+  const AliESDVertex *vertex = esd->GetVertex();
+  if(vertex->GetNContributors()<fMinContVtx) return 0;
+  //
   AliRunLoader* runLoader = AliRunLoader::Instance();
   if (!runLoader) {
     Error("Clusters2Tracks", "no run loader found");
@@ -1896,6 +2003,12 @@ Int_t AliITSTrackleterSPDEff::Clusters2Tracks(AliESDEvent *){
     tRefTree= runLoader->TreeTR();
   }
   Reconstruct(pStack,tRefTree);
+
+  if (GetLightBkgStudyInParallel()) {
+    AliStack *dummy1=0x0; TTree *dummy2=0x0;
+    ReflectClusterAroundZAxisForLayer(1);
+    Reconstruct(dummy1,dummy2,kTRUE);
+  }
   return 0;
 }
 //____________________________________________________________________________
@@ -1909,6 +2022,12 @@ Int_t AliITSTrackleterSPDEff::PostProcess(AliESDEvent *){
   Int_t rc=0;
   if(GetMC()) SavePredictionMC("TrackletsMCpred.root");
   if(GetHistOn()) rc=(Int_t)WriteHistosToFile();
+  if(GetLightBkgStudyInParallel()) {
+    TString name="AliITSPlaneEffSPDtrackletBkg.root";
+    TFile* pefile = TFile::Open(name, "RECREATE");
+    rc*=fPlaneEffBkg->Write();
+    pefile->Close();
+  }
   return rc;
 }
 //____________________________________________________________________
@@ -1964,6 +2083,11 @@ AliITSTrackleterSPDEff::LoadClusterArrays(TTree* itsClusterTree) {
         for (Int_t i=0; i<3; i++)
                 fClustersLay1[fNClustersLay1][3+i] = cluster->GetLabel(i);
         fNClustersLay1++;
+        if(fHistOn) { 
+          Int_t det=cluster->GetDetectorIndex();
+          if(det<0 || det>79) {AliError("Cluster with det. index out of boundaries"); return;}
+          fhClustersInModuleLay1[det]->Fill((Double_t)cluster->GetDetLocalZ(),(Double_t)cluster->GetDetLocalX());
+        }
       }
       if (layer==1) {
         fClustersLay2[fNClustersLay2][0] = x;
@@ -1973,6 +2097,11 @@ AliITSTrackleterSPDEff::LoadClusterArrays(TTree* itsClusterTree) {
         for (Int_t i=0; i<3; i++)
                 fClustersLay2[fNClustersLay2][3+i] = cluster->GetLabel(i);
         fNClustersLay2++;
+        if(fHistOn) {
+          Int_t det=cluster->GetDetectorIndex();
+          if(det<0 || det>159) {AliError("Cluster with det. index out of boundaries"); return;}
+          fhClustersInModuleLay2[det]->Fill((Double_t)cluster->GetDetLocalZ(),(Double_t)cluster->GetDetLocalX());
+        }
       }
 
     }// end of cluster loop
@@ -1985,4 +2114,41 @@ AliITSTrackleterSPDEff::LoadClusterArrays(TTree* itsClusterTree) {
   }
   AliDebug(1,Form("(clusters in layer 1 : %d,  layer 2: %d)",fNClustersLay1,fNClustersLay2));
 }
-
+//_________________________________________________________________________
+void
+AliITSTrackleterSPDEff::SetLightBkgStudyInParallel(Bool_t b) {
+//     This method:
+//  - set Bool_t fLightBackgroundStudyInParallel = b 
+//    a) if you set this kTRUE, then the estimation of the 
+//      SPD efficiency is done as usual for data, but in 
+//      parallel a light (i.e. without control histograms, etc.) 
+//      evaluation of combinatorial background is performed
+//      with the usual ReflectClusterAroundZAxisForLayer method.
+//    b) if you set this kFALSE, then you would not have a second 
+//      container for PlaneEfficiency statistics to be used for background 
+//      (fPlaneEffBkg=0). If you want to have a full evaluation of the 
+//      background (with all control histograms and additional data 
+//      members referring to the background) then you have to call the 
+//      method SetReflectClusterAroundZAxisForLayer(kTRUE) esplicitily
+  fLightBkgStudyInParallel=b; 
+  if(fLightBkgStudyInParallel) {
+    if(!fPlaneEffBkg) fPlaneEffBkg = new AliITSPlaneEffSPD();   
+  }
+  else {
+    delete fPlaneEffBkg;
+    fPlaneEffBkg=0;
+  }
+}
+//______________________________________________________________
+void AliITSTrackleterSPDEff::SetReflectClusterAroundZAxisForLayer(Int_t ilayer,Bool_t b){  
+//
+// method to study residual background:
+// Input b= KTRUE --> reflect the clusters 
+//      ilayer (either 0 or 1) --> which SPD layers should be reflected
+//
+    if(b) {AliInfo(Form("All clusters on layer %d will be rotated by 180 deg around z",ilayer));
+           SetLightBkgStudyInParallel(kFALSE);}
+    if(ilayer==0) fReflectClusterAroundZAxisForLayer0=b;                   // a rotation by 180degree around the Z axis  
+    else if(ilayer==1) fReflectClusterAroundZAxisForLayer1=b;              // (x->-x; y->-y) to all RecPoints on a 
+    else AliInfo("Nothing done: input argument (ilayer) either 0 or 1");   // given layer is applied. In such a way 
+  }