]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/AliMUONVTrackReconstructor.cxx
Updated list of MUON libraries
[u/mrichter/AliRoot.git] / MUON / AliMUONVTrackReconstructor.cxx
index 33136e98831995e459e716b1023acd681b3d60f9..f615a2ca53f37f28494ddc0664c9b210dd8ada97 100644 (file)
@@ -15,9 +15,9 @@
 
 /* $Id$ */
 
-/// \class AliMUONVTrackReconstructor
 ////////////////////////////////////
 ///
+/// \class AliMUONVTrackReconstructor
 /// Virtual MUON track reconstructor in ALICE (class renamed from AliMUONEventReconstructor)
 ///
 /// This class contains as data:
 /// * EventReconstruct to build the muon tracks
 /// * EventReconstructTrigger to build the trigger tracks
 ///
+///  \author Philippe Pillot
+///
 ////////////////////////////////////
 
-#include <stdlib.h>
-#include <Riostream.h>
-#include <TClonesArray.h>
-#include <TMath.h>
-#include <TTree.h>
-
 #include "AliMUONVTrackReconstructor.h"
-#include "AliMUONData.h"
+#include "AliMUONRecData.h"
 #include "AliMUONConstants.h"
 #include "AliMUONHitForRec.h"
 #include "AliMUONObjectPair.h"
 #include "AliMUONTrack.h"
 #include "AliMUONTrackParam.h"
 #include "AliMUONTrackExtrap.h"
-#include "AliMagF.h"
+#include "AliMUONTrackHitPattern.h"
+
 #include "AliLog.h"
 #include "AliTracker.h"
 
+#include <Riostream.h>
+#include <TClonesArray.h>
+#include <TMath.h>
+
+/// \cond CLASSIMP
 ClassImp(AliMUONVTrackReconstructor) // Class implementation in ROOT context
+/// \endcond
 
 //************* Defaults parameters for reconstruction
 const Double_t AliMUONVTrackReconstructor::fgkDefaultMinBendingMomentum = 3.0;
@@ -65,7 +68,7 @@ const Double_t AliMUONVTrackReconstructor::fgkDefaultNonBendingVertexDispersion
 const Double_t AliMUONVTrackReconstructor::fgkDefaultMaxNormChi2MatchTrigger = 16.0;
 
 //__________________________________________________________________________
-AliMUONVTrackReconstructor::AliMUONVTrackReconstructor(AliMUONData* data)
+AliMUONVTrackReconstructor::AliMUONVTrackReconstructor(AliMUONRecData* data)
   : TObject(),
     fMinBendingMomentum(fgkDefaultMinBendingMomentum),
     fMaxBendingMomentum(fgkDefaultMaxBendingMomentum),
@@ -74,8 +77,6 @@ AliMUONVTrackReconstructor::AliMUONVTrackReconstructor(AliMUONData* data)
     fBendingVertexDispersion(fgkDefaultBendingVertexDispersion),
     fNonBendingVertexDispersion(fgkDefaultNonBendingVertexDispersion),
     fMaxNormChi2MatchTrigger(fgkDefaultMaxNormChi2MatchTrigger),
-    fSegmentMaxDistBending(0x0),
-    fSegmentMaxDistNonBending(0x0),
     fHitsForRecPtr(0x0),
     fNHitsForRec(0),
     fNHitsForRecPerChamber(0x0),
@@ -87,13 +88,9 @@ AliMUONVTrackReconstructor::AliMUONVTrackReconstructor(AliMUONData* data)
     fTriggerCircuit(0x0)
 {
   /// Constructor for class AliMUONVTrackReconstructor
-  fSegmentMaxDistBending = new Double_t[AliMUONConstants::NTrackingSt()];
-  fSegmentMaxDistNonBending = new Double_t[AliMUONConstants::NTrackingSt()];
   fNHitsForRecPerChamber = new Int_t[AliMUONConstants::NTrackingCh()];
   fIndexOfFirstHitForRecPerChamber = new Int_t[AliMUONConstants::NTrackingCh()];
 
-  SetReconstructionParametersToDefaults();
-  
   // Memory allocation for the TClonesArray of hits for reconstruction
   // Is 10000 the right size ????
   fHitsForRecPtr = new TClonesArray("AliMUONHitForRec", 10000);
@@ -102,63 +99,36 @@ AliMUONVTrackReconstructor::AliMUONVTrackReconstructor(AliMUONData* data)
   const AliMagF* kField = AliTracker::GetFieldMap();
   if (!kField) AliFatal("No field available");
   AliMUONTrackExtrap::SetField(kField);
+
+  fTrackHitPattern = new AliMUONTrackHitPattern(fMUONData);
 }
 
   //__________________________________________________________________________
 AliMUONVTrackReconstructor::~AliMUONVTrackReconstructor(void)
 {
   /// Destructor for class AliMUONVTrackReconstructor
-  delete [] fSegmentMaxDistBending;
-  delete [] fSegmentMaxDistNonBending;
   delete [] fNHitsForRecPerChamber;
   delete [] fIndexOfFirstHitForRecPerChamber;
   delete fTriggerTrack;
   delete fHitsForRecPtr;
-}
-
-  //__________________________________________________________________________
-void AliMUONVTrackReconstructor::SetReconstructionParametersToDefaults(void)
-{
-  /// Set reconstruction parameters for making segments to default values
-  // Would be much more convenient with a structure (or class) ????
-
-  // ******** Parameters for making segments
-  // should be parametrized ????
-  // according to interval between chambers in a station ????
-  // Maximum distance in non bending plane
-  // 5 * 0.22 just to remember the way it was made in TRACKF_STAT
-  // SIGCUT*DYMAX(IZ)
-  for (Int_t st = 0; st < AliMUONConstants::NTrackingSt(); st++)
-    fSegmentMaxDistNonBending[st] = 5. * 0.22;
-  // Maximum distance in bending plane:
-  // values from TRACKF_STAT, corresponding to (J psi 20cm),
-  // scaled to the real distance between chambers in a station
-  fSegmentMaxDistBending[0] = TMath::Abs( 1.5 *
-                                         (AliMUONConstants::DefaultChamberZ(1) - AliMUONConstants::DefaultChamberZ(0)) / 20.0);
-  fSegmentMaxDistBending[1] = TMath::Abs( 1.5 *
-                                         (AliMUONConstants::DefaultChamberZ(3) - AliMUONConstants::DefaultChamberZ(2)) / 20.0);
-  fSegmentMaxDistBending[2] = TMath::Abs( 3.0 *
-                                         (AliMUONConstants::DefaultChamberZ(5) - AliMUONConstants::DefaultChamberZ(4)) / 20.0);
-  fSegmentMaxDistBending[3] = TMath::Abs( 6.0 *
-                                         (AliMUONConstants::DefaultChamberZ(7) - AliMUONConstants::DefaultChamberZ(6)) / 20.0);
-  fSegmentMaxDistBending[4] = TMath::Abs( 6.0 *
-                                         (AliMUONConstants::DefaultChamberZ(9) - AliMUONConstants::DefaultChamberZ(8)) / 20.0);
-
-  return;
+  delete fTrackHitPattern;
 }
 
   //__________________________________________________________________________
 void AliMUONVTrackReconstructor::EventReconstruct(void)
 {
-  // To reconstruct one event
+  /// To reconstruct one event
   AliDebug(1,"Enter EventReconstruct");
+  
   ResetTracks(); //AZ
   ResetHitsForRec(); //AZ
   AddHitsForRecFromRawClusters();
   MakeTracks();
   if (fMUONData->IsTriggerTrackBranchesInTree()) 
     ValidateTracksWithTrigger(); 
-  
+
+  fTrackHitPattern->GetHitPattern(fRecTracksPtr);
+
   // Add tracks to MUON data container 
   for(Int_t i=0; i<fNRecTracks; i++) {
     AliMUONTrack * track = (AliMUONTrack*) fRecTracksPtr->At(i);
@@ -230,8 +200,7 @@ TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsInStation(Int_t station)
   
   AliMUONHitForRec *hit1Ptr, *hit2Ptr;
   AliMUONObjectPair *segment;
-  Double_t bendingSlope, distBend, distNonBend, extBendCoor, extNonBendCoor, extrapFact;
-  Double_t impactParam = 0., bendingMomentum = 0.; // to avoid compilation warning
+  Double_t bendingSlope = 0, impactParam = 0., bendingMomentum = 0.; // to avoid compilation warning
   // first and second chambers (0...) in the station
   Int_t ch1 = 2 * station;
   Int_t ch2 = ch1 + 1;
@@ -243,24 +212,14 @@ TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsInStation(Int_t station)
        hit1++) {
     // pointer to the HitForRec
     hit1Ptr = (AliMUONHitForRec*) ((*fHitsForRecPtr)[hit1]);
-    // extrapolation, on the straight line joining the HitForRec to the vertex (0,0,0),
-    // to the Z of the HitForRec in the second chamber of the station
     // Loop over HitsForRec's in the second chamber of the station
     for (Int_t hit2 = fIndexOfFirstHitForRecPerChamber[ch2];
         hit2 < fIndexOfFirstHitForRecPerChamber[ch2] + fNHitsForRecPerChamber[ch2];
         hit2++) {
       // pointer to the HitForRec
       hit2Ptr = (AliMUONHitForRec*) ((*fHitsForRecPtr)[hit2]);
-      // absolute values of distances, in bending and non bending planes,
-      // between the HitForRec in the second chamber
-      // and the previous extrapolation
-      extrapFact = hit2Ptr->GetZ()/ hit1Ptr->GetZ();
-      extBendCoor = extrapFact * hit1Ptr->GetBendingCoor();
-      extNonBendCoor = extrapFact * hit1Ptr->GetNonBendingCoor();
-      distBend = TMath::Abs(hit2Ptr->GetBendingCoor() - extBendCoor);
-      distNonBend = TMath::Abs(hit2Ptr->GetNonBendingCoor() - extNonBendCoor);
-      // bending slope
       if ( hit1Ptr->GetZ() - hit2Ptr->GetZ() != 0. ) {
+        // bending slope
         bendingSlope = (hit1Ptr->GetBendingCoor() - hit2Ptr->GetBendingCoor()) / (hit1Ptr->GetZ() - hit2Ptr->GetZ());
         // impact parameter
         impactParam = hit1Ptr->GetBendingCoor() - hit1Ptr->GetZ() * bendingSlope;
@@ -270,18 +229,12 @@ TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsInStation(Int_t station)
         AliWarning("hit1Ptr->GetZ() = hit2Ptr->GetZ(): no segment created");
         continue;
       }   
-      // check for distances not too large,
-      // and impact parameter not too big if stations downstream of the dipole.
-      // Conditions "distBend" and "impactParam" correlated for these stations ????
-      if ((distBend < fSegmentMaxDistBending[station]) && (distNonBend < fSegmentMaxDistNonBending[station]) &&
-         (bendingMomentum < fMaxBendingMomentum) && (bendingMomentum > fMinBendingMomentum)) {
+      // check for bending momentum within tolerances
+      if ((bendingMomentum < fMaxBendingMomentum) && (bendingMomentum > fMinBendingMomentum)) {
        // make new segment
        segment = new ((*segments)[segments->GetLast()+1]) AliMUONObjectPair(hit1Ptr, hit2Ptr, kFALSE, kFALSE);
        if (AliLog::GetGlobalDebugLevel() > 1) {
-         cout << "segmentIndex(0...): " << segments->GetLast()
-              << "  distBend: " << distBend
-              << "  distNonBend: " << distNonBend
-              << endl;
+         cout << "segmentIndex(0...): " << segments->GetLast() << endl;
          segment->Dump();
          cout << "HitForRec in first chamber" << endl;
          hit1Ptr->Dump();
@@ -304,21 +257,28 @@ void AliMUONVTrackReconstructor::ValidateTracksWithTrigger(void)
   AliMUONTrack *track;
   AliMUONTrackParam trackParam; 
   AliMUONTriggerTrack *triggerTrack;
+  AliMUONLocalTrigger *locTrg;
   
   fMUONData->SetTreeAddress("RL");
   fMUONData->GetRecTriggerTracks();
   TClonesArray *recTriggerTracks = fMUONData->RecTriggerTracks();
-  
-  Bool_t matchTrigger;
+
+  fMUONData->SetTreeAddress("TC");
+  fMUONData->GetTrigger();
+  TClonesArray *localTrigger = fMUONData->LocalTrigger();
+
+  Int_t matchTrigger;
   Int_t loTrgNum;
   Double_t distTriggerTrack[3];
   Double_t xTrack, yTrack, ySlopeTrack, chi2MatchTrigger, minChi2MatchTrigger, chi2;
   
   track = (AliMUONTrack*) fRecTracksPtr->First();
   while (track) {
-    matchTrigger = kFALSE;
+    matchTrigger = -1;
     chi2MatchTrigger = 0.;
     loTrgNum = -1;
+    Int_t doubleMatch=-1; // Check if track matches 2 trigger tracks
+    Double_t doubleChi2 = -1.;
 
     trackParam = *((AliMUONTrackParam*) (track->GetTrackParamAtHit()->Last()));
     AliMUONTrackExtrap::ExtrapToZ(&trackParam, AliMUONConstants::DefaultChamberZ(10)); // extrap to 1st trigger chamber
@@ -336,14 +296,38 @@ void AliMUONVTrackReconstructor::ValidateTracksWithTrigger(void)
       chi2 = 0.;
       for (Int_t iVar = 0; iVar < 3; iVar++) chi2 += distTriggerTrack[iVar]*distTriggerTrack[iVar];
       chi2 /= 3.; // Normalized Chi2: 3 degrees of freedom (X,Y,slopeY)
-      if (chi2 < minChi2MatchTrigger && chi2 < fMaxNormChi2MatchTrigger) {
-        minChi2MatchTrigger = chi2;
-        matchTrigger = kTRUE;
-        chi2MatchTrigger = chi2;
-       loTrgNum=triggerTrack->GetLoTrgNum();
+      if (chi2 < fMaxNormChi2MatchTrigger) {
+         Bool_t isDoubleTrack = (TMath::Abs(chi2 - minChi2MatchTrigger)<1.);
+         if (chi2 < minChi2MatchTrigger && chi2 < fMaxNormChi2MatchTrigger) {
+             if(isDoubleTrack){
+                 doubleMatch = loTrgNum;
+                 doubleChi2 = chi2MatchTrigger;
+             }
+             minChi2MatchTrigger = chi2;
+             chi2MatchTrigger = chi2;
+             loTrgNum=triggerTrack->GetLoTrgNum();
+             locTrg = (AliMUONLocalTrigger*)localTrigger->UncheckedAt(loTrgNum);
+             matchTrigger=0;
+             if(locTrg->LoLpt()>0)matchTrigger=1;
+             if(locTrg->LoHpt()>0)matchTrigger=2;
+         }
+         else if(isDoubleTrack) {
+             doubleMatch = triggerTrack->GetLoTrgNum();
+             doubleChi2 = chi2;
+         }
       }
       triggerTrack = (AliMUONTriggerTrack*) recTriggerTracks->After(triggerTrack);
     }
+    if(doubleMatch>=0){ // If two trigger tracks match, select the one passing more trigger cuts
+       AliDebug(1, Form("Two candidates found: %i and %i",loTrgNum,doubleMatch));
+       AliMUONLocalTrigger *locTrg1 = (AliMUONLocalTrigger*)localTrigger->UncheckedAt(doubleMatch);
+       if((locTrg1->LoLpt()>0 && matchTrigger<1) || (locTrg1->LoHpt() && matchTrigger<2)){
+           if(locTrg1->LoHpt()>0)matchTrigger=2;
+           else matchTrigger=1;
+           loTrgNum = doubleMatch;
+           chi2MatchTrigger=doubleChi2;
+       }
+    }
     
     track->SetMatchTrigger(matchTrigger);
     track->SetLoTrgNum(loTrgNum);
@@ -366,7 +350,7 @@ void AliMUONVTrackReconstructor::EventReconstructTrigger(void)
   //__________________________________________________________________________
 Bool_t AliMUONVTrackReconstructor::MakeTriggerTracks(void)
 {
-    // To make the trigger tracks from Local Trigger
+  /// To make the trigger tracks from Local Trigger
   AliDebug(1, "Enter MakeTriggerTracks");
   
   TTree* treeR;
@@ -407,31 +391,53 @@ Bool_t AliMUONVTrackReconstructor::MakeTriggerTracks(void)
   Float_t x11 = 0.;
 
   for (Int_t i=0; i<nlocals; i++) { // loop on Local Trigger
-    locTrg = (AliMUONLocalTrigger*)localTrigger->UncheckedAt(i);      
-
-    AliDebug(1, "AliMUONTrackReconstructor::MakeTriggerTrack using NEW trigger \n");
-    AliMUONTriggerCircuit* circuit = 
-      (AliMUONTriggerCircuit*)fTriggerCircuit->At(locTrg->LoCircuit()-1); // -1 !!!
-
-    y11 = circuit->GetY11Pos(locTrg->LoStripX()); 
-    stripX21 = locTrg->LoStripX()+locTrg->LoDev()+1;
-    y21 = circuit->GetY21Pos(stripX21);       
-    x11 = circuit->GetX11Pos(locTrg->LoStripY());
-    
-    AliDebug(1, Form(" MakeTriggerTrack %d %d %d %d %d %f %f %f \n",i,locTrg->LoCircuit(),
-                    locTrg->LoStripX(),locTrg->LoStripX()+locTrg->LoDev()+1,locTrg->LoStripY(),y11, y21, x11));
-    
-    Float_t thetax = TMath::ATan2( x11 , z11 );
-    Float_t thetay = TMath::ATan2( (y21-y11) , (z21-z11) );
-    
-    fTriggerTrack->SetX11(x11);
-    fTriggerTrack->SetY11(y11);
-    fTriggerTrack->SetThetax(thetax);
-    fTriggerTrack->SetThetay(thetay);
-    fTriggerTrack->SetGTPattern(gloTrigPat);
-    fTriggerTrack->SetLoTrgNum(i);
-         
-    fMUONData->AddRecTriggerTrack(*fTriggerTrack);
+      locTrg = (AliMUONLocalTrigger*)localTrigger->UncheckedAt(i);      
+      
+      Bool_t xTrig=kFALSE;
+      Bool_t yTrig=kFALSE;
+      
+      if ( locTrg->LoSdev()==1 && locTrg->LoDev()==0 && 
+          locTrg->LoStripX()==0) xTrig=kFALSE; // no trigger in X
+      else xTrig=kTRUE;                         // trigger in X
+      if (locTrg->LoTrigY()==1 && 
+         locTrg->LoStripY()==15 ) yTrig = kFALSE; // no trigger in Y
+      else yTrig = kTRUE;                          // trigger in Y
+
+      if (xTrig && yTrig) { // make Trigger Track if trigger in X and Y
+         
+         AliDebug(1, "AliMUONTrackReconstructor::MakeTriggerTrack using NEW trigger \n");
+         AliMUONTriggerCircuit* circuit = 
+             (AliMUONTriggerCircuit*)fTriggerCircuit->At(locTrg->LoCircuit()-1); // -1 !!!
+         
+         y11 = circuit->GetY11Pos(locTrg->LoStripX()); 
+// need first to convert deviation to [0-30] 
+// (see AliMUONLocalTriggerBoard::LocalTrigger)
+         Int_t deviation = locTrg->LoDev(); 
+         Int_t sign = 0;
+         if ( !locTrg->LoSdev() &&  deviation ) sign=-1;
+         if ( !locTrg->LoSdev() && !deviation ) sign= 0;
+         if (  locTrg->LoSdev() == 1 )          sign=+1;
+         deviation *= sign;
+         deviation += 15;
+         stripX21 = locTrg->LoStripX()+deviation+1;
+         y21 = circuit->GetY21Pos(stripX21);       
+         x11 = circuit->GetX11Pos(locTrg->LoStripY());
+         
+         AliDebug(1, Form(" MakeTriggerTrack %d %d %d %d %d %f %f %f \n",i,locTrg->LoCircuit(),
+                          locTrg->LoStripX(),locTrg->LoStripX()+locTrg->LoDev()+1,locTrg->LoStripY(),y11, y21, x11));
+         
+         Float_t thetax = TMath::ATan2( x11 , z11 );
+         Float_t thetay = TMath::ATan2( (y21-y11) , (z21-z11) );
+         
+         fTriggerTrack->SetX11(x11);
+         fTriggerTrack->SetY11(y11);
+         fTriggerTrack->SetThetax(thetax);
+         fTriggerTrack->SetThetay(thetay);
+         fTriggerTrack->SetGTPattern(gloTrigPat);
+         fTriggerTrack->SetLoTrgNum(i);
+             
+         fMUONData->AddRecTriggerTrack(*fTriggerTrack);
+      } // board is fired 
   } // end of loop on Local Trigger
   
   return kTRUE;