- Adding hits pattern in trigger chambers in AliMUONTrack (Diego)
authormartinez <martinez@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 25 Apr 2007 15:21:13 +0000 (15:21 +0000)
committermartinez <martinez@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 25 Apr 2007 15:21:13 +0000 (15:21 +0000)
- Changes output of AliMuonTrack::GetMatchTrigger() (Diego)
- Option on MUONReconstructor for eriting on disk the digits from raw data during reconstruction (Diego)
-  Common interface for TriggerDigits from rawData/localTrigger (Christian)

12 files changed:
MUON/AliMUONDigitMaker.cxx
MUON/AliMUONDigitMaker.h
MUON/AliMUONReconstructor.cxx
MUON/AliMUONTrack.cxx
MUON/AliMUONTrack.h
MUON/AliMUONTrackHitPattern.cxx [new file with mode: 0644]
MUON/AliMUONTrackHitPattern.h [new file with mode: 0644]
MUON/AliMUONVTrackReconstructor.cxx
MUON/AliMUONVTrackReconstructor.h
MUON/AlirootRun_MUONtest.sh
MUON/MUONrecLinkDef.h
MUON/libMUONrec.pkg

index 771439f..c4f6235 100644 (file)
@@ -76,6 +76,7 @@
 #include "AliRun.h"
 
 #include <TList.h>
+#include <TArrayS.h>
 
 
 /// \cond CLASSIMP
@@ -375,8 +376,22 @@ Int_t AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
            // Make SDigit
 
            digitList.Clear();
-           
-           if( TriggerDigits(localBoard, localStruct, digitList) ) {
+           //FIXEME should find something better than a TArray
+           TArrayS xyPattern[2];
+           xyPattern[0].Set(4);
+           xyPattern[1].Set(4);
+
+           xyPattern[0].AddAt(localStruct->GetX1(),0);
+           xyPattern[0].AddAt(localStruct->GetX2(),1);
+           xyPattern[0].AddAt(localStruct->GetX3(),2);
+           xyPattern[0].AddAt(localStruct->GetX4(),3);
+
+           xyPattern[1].AddAt(localStruct->GetY1(),0);
+           xyPattern[1].AddAt(localStruct->GetY2(),1);
+           xyPattern[1].AddAt(localStruct->GetY3(),2);
+           xyPattern[1].AddAt(localStruct->GetY4(),3);
+
+           if( TriggerDigits(loCircuit, xyPattern, digitList) ) {
 
              for (Int_t iEntry = 0; iEntry < digitList.GetEntries(); iEntry++) {
 
@@ -405,118 +420,82 @@ Int_t AliMUONDigitMaker::ReadTriggerDDL(AliRawReader* rawReader)
   return kTRUE;
 
 }
+
 //____________________________________________________________________
-void AliMUONDigitMaker::GetTriggerChamber(AliMUONLocalStruct* localStruct, Int_t& xyPattern, 
-                                         Int_t& iChamber, Int_t& iCath, Int_t icase)
-{
-  /// get chamber & cathode number, (chamber starts at 0 !)
-
-    switch(icase) {
-    case 0: 
-      xyPattern =  localStruct->GetX1();
-      iCath = 0;
-      iChamber = 10;
-      break;
-    case 1: 
-      xyPattern =  localStruct->GetX2();
-      iCath = 0;
-      iChamber = 11;
-      break;
-    case 2: 
-      xyPattern =  localStruct->GetX3();
-      iCath = 0;
-      iChamber = 12;
-      break;
-    case 3: 
-      xyPattern =  localStruct->GetX4();
-      iCath = 0;
-      iChamber = 13;
-      break;
-    case 4: 
-      xyPattern =  localStruct->GetY1();
-      iCath = 1;
-      iChamber = 10;
-      break;
-    case 5: 
-      xyPattern =  localStruct->GetY2();
-      iCath = 1;
-      iChamber = 11;
-      break;
-    case 6: 
-      xyPattern =  localStruct->GetY3();
-      iCath = 1;
-      iChamber = 12;
-      break;
-    case 7: 
-      xyPattern =  localStruct->GetY4();
-      iCath = 1;
-      iChamber = 13;
-      break;
-    }
-}
-//____________________________________________________________________
-Int_t AliMUONDigitMaker::TriggerDigits(AliMUONLocalTriggerBoard* localBoard, 
-                                      AliMUONLocalStruct* localStruct,
+Int_t AliMUONDigitMaker::TriggerDigits(Int_t nBoard, 
+                                      TArrayS* xyPattern,
                                       TList& digitList)
 {
   /// make (S)Digit for trigger
 
   Int_t detElemId;
-  Int_t nBoard;
-  Int_t iCath = -1;
-  Int_t iChamber = 0;
-  Int_t xyPattern = 0;
+  Int_t previousDetElemId[4] = {0};
+  Int_t previousBoard[4] = {0};
 
   // loop over x1-4 and y1-4
-  for (Int_t icase = 0; icase < 8; icase++) {
-
-    // get chamber, cathode and associated trigger response pattern
-    GetTriggerChamber(localStruct, xyPattern, iChamber, iCath, icase);
+  for(Int_t iChamber = 0; iChamber < 4; ++iChamber){
+    for(Int_t iCath = 0; iCath < 2; ++iCath){
   
-    if (!xyPattern) continue;
+      Int_t pattern = (Int_t)xyPattern[iCath].At(iChamber); 
+      if (!pattern) continue;
+
+      // get detElemId
+      AliMUONTriggerCircuit triggerCircuit;
+      AliMUONLocalTriggerBoard* localBoard = fCrateManager->LocalBoard(nBoard);
+      detElemId = triggerCircuit.DetElemId(iChamber+10, localBoard->GetName());//FIXME +/-10 (should be ok with new mapping)
+
 
-    // get detElemId
-    AliMUONTriggerCircuit triggerCircuit;
-    detElemId = triggerCircuit.DetElemId(iChamber, localBoard->GetName());
-    nBoard    = localBoard->GetNumber();
+      if(iCath == 1){ // FIXME should find a more elegant way
+       // Don't save twice the same digit
+       // (since strips in non bending plane can cross several boards)
+       Int_t prevDetElemId = previousDetElemId[iChamber];
+       Int_t prevBoard = previousBoard[iChamber];
+       previousDetElemId[iChamber] = detElemId;
+       previousBoard[iChamber] = nBoard;
+
+       if(detElemId == prevDetElemId){
+         if(nBoard-prevBoard==1) continue;
+       }
+      }
 
-    const AliMpVSegmentation* seg 
-      = AliMpSegmentation::Instance()
-        ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));  
+      const AliMpVSegmentation* seg 
+         = AliMpSegmentation::Instance()
+         ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));  
 
-    // loop over the 16 bits of pattern
-    for (Int_t ibitxy = 0; ibitxy < 16; ibitxy++) {
+      // loop over the 16 bits of pattern
+      for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) {
     
-      if ((xyPattern >> ibitxy) & 0x1) {
-
-       // not quite sure about this
-       Int_t offset = 0;
-       if (iCath && localBoard->GetSwitch(6)) offset = -8;
-
-       AliMpPad pad = seg->PadByLocation(AliMpIntPair(nBoard,ibitxy+offset),kTRUE);
-
-       AliMUONDigit* digit = new  AliMUONDigit();
-       if (!pad.IsValid()) {
-         AliWarning(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
-                         detElemId, nBoard, ibitxy));
-         continue;
-       } // 
-
-       Int_t padX = pad.GetIndices().GetFirst();
-       Int_t padY = pad.GetIndices().GetSecond();
-
-       // file digit
-       digit->SetPadX(padX);
-       digit->SetPadY(padY);
-       digit->SetSignal(1.);
-       digit->SetCathode(iCath);
-       digit->SetDetElemId(detElemId);
-       digit->SetElectronics(nBoard, ibitxy);
-       digitList.Add(digit);
+       if ((pattern >> ibitxy) & 0x1) {
+
+         // not quite sure about this
+         Int_t offset = 0;
+         if (iCath && localBoard->GetSwitch(6)) offset = -8;
+
+         AliMpPad pad = seg->PadByLocation(AliMpIntPair(nBoard,ibitxy+offset),kTRUE);
+
+         AliMUONDigit* digit = new  AliMUONDigit();
+         if (!pad.IsValid()) {
+           AliWarning(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
+                           detElemId, nBoard, ibitxy));
+           continue;
+         } // 
+
+         Int_t padX = pad.GetIndices().GetFirst();
+         Int_t padY = pad.GetIndices().GetSecond();
+
+         // file digit
+         digit->SetPadX(padX);
+         digit->SetPadY(padY);
+         digit->SetSignal(1.);
+         digit->SetCathode(iCath);
+         digit->SetDetElemId(detElemId);
+         digit->SetElectronics(nBoard, ibitxy);
+         digitList.Add(digit);
        
-      }// xyPattern
-    }// ibitxy
-  }// case
+       }// xyPattern
+      }// ibitxy
+    }// cath
+  } // ichamber
 
   return kTRUE;
 } 
index c3d3daa..d46ef4d 100644 (file)
@@ -15,6 +15,7 @@
 #include "TStopwatch.h"
 
 class TList;
+class TArrayS;
 
 class AliRawReader;
 class AliMUONData;
@@ -22,7 +23,6 @@ class AliMUONDigit;
 class AliMUONGlobalTrigger;
 class AliMUONLocalTrigger;
 class AliMUONTriggerCrateStore;
-class AliMUONLocalTriggerBoard;
 class AliMUONLocalStruct;
 
 class AliMUONRawStreamTracker;
@@ -48,11 +48,7 @@ class AliMUONDigitMaker : public TObject
   Int_t GetMapping(Int_t buspatchId, UShort_t manuId, 
                          UChar_t channelId, AliMUONDigit* digit );
 
-  Int_t TriggerDigits(AliMUONLocalTriggerBoard* localBoard, 
-                     AliMUONLocalStruct* localStruct, TList& digitList );
-
-  void GetTriggerChamber(AliMUONLocalStruct* localStruct, 
-                        Int_t& xyPattern, Int_t& iChamber, Int_t& iCath, Int_t iCase );
+  Int_t TriggerDigits(Int_t nBoard, TArrayS* xyPattern, TList& digitList );
 
         /// Set flag to generates scaler event
   void  SetScalerEvent() {fScalerEvent = kTRUE;}
index 7bf15be..5ecfd42 100644 (file)
@@ -395,11 +395,16 @@ void AliMUONReconstructor::Reconstruct(AliRunLoader* runLoader,
     //    AliDebug(1,Form("Making Digit Container for event %d",iEvent));
     //    loader->MakeDigitsContainer();
     //  }
-    //  Digits are not stored on disk and created on flight from rawdata.
-    //  In order to write digits on disk the following lines should be uncommented
-    //  fMUONData->MakeBranch("D,GLT");
-    //  fMUONData->SetTreeAddress("D,GLT");
-    fMUONData->SetDataContainer("D, GLT");
+    // Write digits from raw data on disk
+    if (strstr(GetOption(),"SAVEDIGITS")) {
+       if (!loader->TreeD())fMUONData->GetLoader()->MakeDigitsContainer();
+       fMUONData->MakeBranch("D,GLT");
+       fMUONData->SetTreeAddress("D,GLT");
+       AliInfo("Digits from raw data will be stored.");
+    }
+    else {
+       fMUONData->SetDataContainer("D, GLT");
+    }
     rawTimer.Start(kFALSE);
     fDigitMaker->Raw2Digits(rawReader);
     rawTimer.Stop();
@@ -410,10 +415,12 @@ void AliMUONReconstructor::Reconstruct(AliRunLoader* runLoader,
       calibration->ExecuteTask();
       calibTimer.Stop();
     }
-    // Digits are not stored on disk and created on flight from rawdata.
-    // In order to write digits on disk the following lines should be uncommented
-    // fMUONData->Fill("D,GLT");
-    // loader->WriteDigits("OVERWRITE");
+
+    // Write digits from raw data on disk
+    if (strstr(GetOption(),"SAVEDIGITS")) {
+       fMUONData->Fill("D,GLT");
+       loader->WriteDigits("OVERWRITE");
+    }
     //----------------------- digit2cluster & Trigger2Trigger -------------------
     clusterTimer.Start(kFALSE);
 
@@ -478,7 +485,8 @@ void AliMUONReconstructor::FillESD(AliRunLoader* runLoader, AliESD* esd) const
   Double_t fitFmin, chi2MatchTrigger;
   Double_t xRec, yRec, zRec, bendingSlope, nonBendingSlope, inverseBendingMomentum;
   Double_t xVtx, yVtx, zVtx, bendingSlopeAtVtx, nonBendingSlopeAtVtx, inverseBendingMomentumAtVtx;
-  Bool_t matchTrigger;
+  Int_t matchTrigger;
+  UShort_t hitsPatternInTrigCh;
 
   // setting pointer for tracks, triggertracks & trackparam at vertex
   AliMUONTrack* recTrack = 0;
@@ -555,6 +563,7 @@ void AliMUONReconstructor::FillESD(AliRunLoader* runLoader, AliESD* esd) const
     fitFmin          = recTrack->GetFitFMin();
     matchTrigger     = recTrack->GetMatchTrigger();
     chi2MatchTrigger = recTrack->GetChi2MatchTrigger();
+    hitsPatternInTrigCh = recTrack->GetHitsPatternInTrigCh();
 
     // setting data member of ESD MUON
     // at first station
@@ -576,6 +585,7 @@ void AliMUONReconstructor::FillESD(AliRunLoader* runLoader, AliESD* esd) const
     theESDTrack->SetNHit(nTrackHits);
     theESDTrack->SetMatchTrigger(matchTrigger);
     theESDTrack->SetChi2MatchTrigger(chi2MatchTrigger);
+    theESDTrack->SetHitsPatternInTrigCh(hitsPatternInTrigCh);
 
     // storing ESD MUON Track into ESD Event 
     if (nRecTracks != 0)  
index 8c539e9..661271b 100644 (file)
@@ -56,10 +56,11 @@ AliMUONTrack::AliMUONTrack()
     fFitWithVertex(kFALSE),
     fVertex(0x0),
     fFitFMin(-1.),
-    fMatchTrigger(kFALSE),
+    fMatchTrigger(-1),
     floTrgNum(-1),
     fChi2MatchTrigger(0.),
-    fTrackID(0)
+    fTrackID(0),
+    fHitsPatternInTrigCh(0)
 {
   /// Default constructor
 }
@@ -75,10 +76,11 @@ AliMUONTrack::AliMUONTrack(AliMUONHitForRec* hitForRec1, AliMUONHitForRec* hitFo
     fFitWithVertex(kFALSE),
     fVertex(0x0),
     fFitFMin(-1.),
-    fMatchTrigger(kFALSE),
+    fMatchTrigger(-1),
     floTrgNum(-1),    
     fChi2MatchTrigger(0.),
-    fTrackID(0)
+    fTrackID(0),
+    fHitsPatternInTrigCh(0)
 {
   /// Constructor from thw hitForRec's
 
@@ -168,7 +170,8 @@ AliMUONTrack::AliMUONTrack (const AliMUONTrack& theMUONTrack)
     fMatchTrigger(theMUONTrack.fMatchTrigger),
     floTrgNum(theMUONTrack.floTrgNum),    
     fChi2MatchTrigger(theMUONTrack.fChi2MatchTrigger),
-    fTrackID(theMUONTrack.fTrackID)
+    fTrackID(theMUONTrack.fTrackID),
+    fHitsPatternInTrigCh(theMUONTrack.fHitsPatternInTrigCh)
 {
   ///copy constructor
   Int_t maxIndex = 0;
@@ -256,7 +259,8 @@ AliMUONTrack & AliMUONTrack::operator=(const AliMUONTrack& theMUONTrack)
   fMatchTrigger       =  theMUONTrack.fMatchTrigger;
   floTrgNum           =  theMUONTrack.floTrgNum;
   fChi2MatchTrigger   =  theMUONTrack.fChi2MatchTrigger;
-  fTrackID            =  theMUONTrack.fTrackID;
+  fTrackID            =  theMUONTrack.fTrackID; 
+  fHitsPatternInTrigCh = theMUONTrack.fHitsPatternInTrigCh;
 
   return *this;
 }
index e0e50e7..cc43d79 100644 (file)
@@ -69,12 +69,12 @@ class AliMUONTrack : public TObject
   Double_t                   GetFitFMin(void) const {return fFitFMin;}
        /// set the minimum value of the function minimized by the fit
   void                       SetFitFMin(Double_t chi2) { fFitFMin = chi2; }
-       /// return kTrue if track matches with trigger track, kFalse if not
-  Bool_t                     GetMatchTrigger(void) const {return fMatchTrigger;}
+        /// return 0,1,2 if track matches with trigger track, -1 if not
+  Int_t                     GetMatchTrigger(void) const {return fMatchTrigger;}
   /// returns the local trigger number corresponding to the trigger track 
   Int_t                      GetLoTrgNum(void) const {return floTrgNum;}
        /// set the flag telling whether track matches with trigger track or not
-   void                             SetMatchTrigger(Bool_t matchTrigger) {fMatchTrigger = matchTrigger;}
+   void                             SetMatchTrigger(Int_t matchTrigger) {fMatchTrigger = matchTrigger;}
    /// set the local trigger number corresponding to the trigger track
    void                             SetLoTrgNum(Int_t loTrgNum) {floTrgNum = loTrgNum;}
        /// return the chi2 of trigger/track matching 
@@ -90,6 +90,11 @@ class AliMUONTrack : public TObject
        /// set track number in TrackRefs
   void                       SetTrackID(Int_t trackID) {fTrackID = trackID;}
 
+        /// set word telling which trigger chambers where hit by track
+  UShort_t                   GetHitsPatternInTrigCh() const {return fHitsPatternInTrigCh;}
+        /// set word telling which trigger chambers where hit by track
+  void                       SetHitsPatternInTrigCh(UShort_t hitsPatternInTrigCh) {fHitsPatternInTrigCh = hitsPatternInTrigCh;}
+
   Double_t                   TryOneHitForRec(AliMUONHitForRec* hitForRec);
   Double_t                   TryTwoHitForRec(AliMUONHitForRec* hitForRec1, AliMUONHitForRec* hitForRec2); 
   
@@ -113,14 +118,18 @@ class AliMUONTrack : public TObject
   AliMUONHitForRec *fVertex; //!< Vertex used during the tracking procedure if required
   
   Double_t fFitFMin; ///< minimum value of the function minimized by the fit
-  Bool_t fMatchTrigger; ///< 1 if track matches with trigger track, 0 if not
+  Int_t fMatchTrigger;  ///< -1 track does not match trigger
+                        ///<  0 track match but does not pass pt cut
+                        ///<  1 track match Low pt cut
+                        ///<  2 track match High pt cut
   Int_t floTrgNum; ///< the number of the corresponding loTrg, -1 if no matching
   Double_t fChi2MatchTrigger; ///< chi2 of trigger/track matching 
   
   Int_t fTrackID; ///< track ID = track number in TrackRefs
+  UShort_t fHitsPatternInTrigCh; ///< Word containing info on the hits left in trigger chambers
   
   
-  ClassDef(AliMUONTrack, 4) // Reconstructed track in ALICE dimuon spectrometer
+  ClassDef(AliMUONTrack, 5) // Reconstructed track in ALICE dimuon spectrometer
 };
        
 #endif
diff --git a/MUON/AliMUONTrackHitPattern.cxx b/MUON/AliMUONTrackHitPattern.cxx
new file mode 100644 (file)
index 0000000..600904a
--- /dev/null
@@ -0,0 +1,302 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+////////////////////////////////////
+///
+/// \class AliMUONTrackHitPattern
+///
+/// This class propagates tracks to trigger chambers 
+/// searching for fired strips.
+///
+/// To each track, a hit pattern for trigger chambers is set.
+/// The hit pattern is a UShort_t with 8 bits used:
+///
+///            1  1  0  1    1  1  0  1
+///           |           |            |
+///            ----------- ------------
+/// chamber:  11 12 13 14 | 11 12 13 14
+/// cathode:    bending   | non-bending
+///
+/// The main method is:
+/// * GetHitPattern
+///
+///  \author Diego Stocco
+///
+////////////////////////////////////
+
+
+#include "AliMUONTrackHitPattern.h"
+#include "AliMUONData.h"
+#include "AliMUONTrack.h"
+#include "AliMUONTrackParam.h"
+#include "AliMUONTrackExtrap.h"
+#include "AliMUONConstants.h"
+#include "AliMUONGeometryTransformer.h"
+#include "AliMUONDigit.h"
+#include "AliMUONLocalTrigger.h"
+#include "AliMUONTriggerCrateStore.h"
+#include "AliMUONLocalTriggerBoard.h"
+#include "AliMUONTriggerCircuit.h"
+#include "AliMUONDigitMaker.h"
+
+#include "AliMpPad.h"
+#include "AliMpVSegmentation.h"
+#include "AliMpSegmentation.h"
+
+#include "AliLog.h"
+#include "AliTracker.h"
+#include "AliMagF.h"
+
+#include <Riostream.h>
+#include <TClonesArray.h>
+#include <TMath.h>
+#include <TMatrixD.h>
+#include <TArrayS.h>
+
+/// \cond CLASSIMP
+ClassImp(AliMUONTrackHitPattern) // Class implementation in ROOT context
+/// \endcond
+
+
+//______________________________________________________________________________
+AliMUONTrackHitPattern::AliMUONTrackHitPattern(AliMUONData *data)
+    : TObject(),
+      fMUONData(data),
+      fTransformer(new AliMUONGeometryTransformer(kTRUE)),
+      fCrateManager(new AliMUONTriggerCrateStore())
+{
+    /// Default constructor
+
+    // Set magnetic field
+    const AliMagF* kField = AliTracker::GetFieldMap();
+    if (!kField) AliFatal("No field available");
+    AliMUONTrackExtrap::SetField(kField);
+
+    // Geometry transformer
+    fTransformer->ReadGeometryData("volpath.dat", "geometry.root");
+
+    // Crate manager to retrieve local boards
+    fCrateManager->ReadFromFile();
+
+    for(Int_t ch=0; ch<4; ch++){
+       fTriggerDigitsList[ch].Clear();
+    }
+}
+
+
+//______________________________________________________________________________
+AliMUONTrackHitPattern::~AliMUONTrackHitPattern(void)
+{
+/// Destructor
+    for(Int_t ch=0; ch<4; ch++){
+       fTriggerDigitsList[ch].Delete();
+    }
+    delete fCrateManager;
+}
+
+
+//______________________________________________________________________________
+void AliMUONTrackHitPattern::GetHitPattern(TClonesArray *recTracksPtr)
+{
+    //
+    /// Main method:
+    /// Loops on reco tracks, extrapolates them to trigger chambers
+    /// and searches for matching digits
+    //
+    
+    const Int_t mask[2][4]={{0x80, 0x40, 0x20, 0x10},
+                           {0x08, 0x04, 0x02, 0x01}};
+    Bool_t isMatch[2];
+    UShort_t pattern=0;
+    TriggerDigits();
+    Int_t nRecTracks = (Int_t)recTracksPtr->GetEntriesFast();
+    for(Int_t iTrack=0; iTrack<nRecTracks; iTrack++){
+       pattern = 0;
+       AliMUONTrack *muonTrack = (AliMUONTrack*) recTracksPtr->At(iTrack);
+       AliMUONTrackParam *trackParam = (AliMUONTrackParam*) ((muonTrack->GetTrackParamAtHit())->Last());
+       for(Int_t ch=0; ch<4; ch++){
+           AliMUONTrackExtrap::ExtrapToZCov(trackParam, AliMUONConstants::DefaultChamberZ(10+ch));
+           FindPadMatchingTrack(trackParam, isMatch, ch);
+           for(Int_t cath=0; cath<2; cath++){
+               if(isMatch[cath]) pattern |= mask[cath][ch];
+           }
+       }
+       muonTrack->SetHitsPatternInTrigCh(pattern);
+    }
+    return;
+}
+
+
+//______________________________________________________________________________
+void AliMUONTrackHitPattern::FindPadMatchingTrack(AliMUONTrackParam *trackParam,
+                                                 Bool_t isMatch[2], Int_t iChamber)
+{
+    //
+    /// Given track position, searches for matching digits.
+    //
+
+    Float_t minMatchDist[2];
+
+    for(Int_t cath=0; cath<2; cath++){
+       isMatch[cath]=kFALSE;
+       minMatchDist[cath]=9999.;
+    }
+
+    Int_t ndigits = (Int_t)fTriggerDigitsList[iChamber].GetEntries();
+    AliMUONDigit * mDigit = 0x0;
+    for(Int_t idigit=0; idigit<ndigits; idigit++) { // digit loop
+       mDigit = (AliMUONDigit*)fTriggerDigitsList[iChamber].At(idigit);
+       Int_t currDetElemId = mDigit->DetElemId();
+
+       Int_t cathode = mDigit->Cathode();
+       Int_t ix = mDigit->PadX();
+       Int_t iy = mDigit->PadY();
+       Float_t xpad, ypad, zpad;
+       const AliMpVSegmentation* seg = AliMpSegmentation::Instance()
+           ->GetMpSegmentation(currDetElemId,AliMp::GetCathodType(cathode));
+
+       AliMpPad pad = seg->PadByIndices(AliMpIntPair(ix,iy),kTRUE);
+       Float_t xlocal1 = pad.Position().X();
+       Float_t ylocal1 = pad.Position().Y();
+       Float_t dpx = pad.Dimensions().X();
+       Float_t dpy = pad.Dimensions().Y();
+       fTransformer->Local2Global(currDetElemId, xlocal1, ylocal1, 0, xpad, ypad, zpad);
+       Float_t matchDist = MinDistanceFromPad(xpad, ypad, zpad, dpx, dpy, trackParam);
+       if(matchDist>minMatchDist[cathode])continue;
+       isMatch[cathode] = kTRUE;
+       minMatchDist[cathode] = matchDist;
+    }
+
+    return;
+}
+
+
+//______________________________________________________________________________
+Float_t AliMUONTrackHitPattern::MinDistanceFromPad(Float_t xPad, Float_t yPad, Float_t zPad,
+                                                  Float_t dpx, Float_t dpy, AliMUONTrackParam *trackParam)
+{
+    //
+    /// Decides if the digit belongs to the track.
+    //
+    Float_t xTrackAtPad = trackParam->GetNonBendingCoor();
+    Float_t yTrackAtPad = trackParam->GetBendingCoor();
+
+    Float_t sigmaX, sigmaY, sigmaMS;
+    GetPosUncertainty(trackParam, zPad, sigmaX, sigmaY, sigmaMS);
+
+    Float_t maxDistX = 3.*(sigmaX + sigmaMS); // in cm
+    Float_t maxDistY = 3.*(sigmaY + sigmaMS); // in cm
+
+    Float_t deltaX = TMath::Abs(xPad-xTrackAtPad)-dpx;
+    Float_t deltaY = TMath::Abs(yPad-yTrackAtPad)-dpy;
+
+    Float_t matchDist = 99999.;
+    if(deltaX<=maxDistX && deltaY<=maxDistY) matchDist = TMath::Max(deltaX, deltaY);
+    return matchDist;
+}
+
+
+//______________________________________________________________________________
+void AliMUONTrackHitPattern::GetPosUncertainty(AliMUONTrackParam *trackParam, Float_t zChamber, 
+                                              Float_t &sigmaX, Float_t &sigmaY, Float_t &sigmaMS)
+{
+    //
+    /// Returns uncertainties on extrapolated position.
+    /// Takes into account Branson plane corrections in the iron wall.
+    //
+
+    const Float_t alpha = 0.1123; // GeV/c
+    
+    // Find a better way to get such parameters ???
+    const Float_t kZFilterIn = 1471.; // From STRUCT/SHILConst2.h
+    const Float_t kZFilterOut = kZFilterIn + 120.; // From STRUCT/SHILConst2.h
+    
+    const Float_t zBranson = - (kZFilterIn + (kZFilterOut - kZFilterIn)*2./3. ); // - sign because distance are positive
+    Float_t zDistFromWall = TMath::Abs(zChamber - zBranson);
+    Float_t zDistFromLastTrackCh = TMath::Abs(zChamber - AliMUONConstants::DefaultChamberZ(9));
+
+    TMatrixD *covParam = trackParam->GetCovariances();
+    
+    sigmaX = (*covParam)(0,0);
+    sigmaY = (*covParam)(2,2);
+
+    // If covariance matrix is not extrapolated, use "reasonable" errors
+    // (To be removed as soon as covariance matrix is correctly propagated).
+    if (sigmaX==0.)sigmaX = 0.003 * zDistFromLastTrackCh;
+    if (sigmaY==0.)sigmaY = 0.004 * zDistFromLastTrackCh;
+
+    Float_t p = trackParam->P();
+    Float_t thetaMS = alpha/p;
+    sigmaMS = zDistFromWall * TMath::Tan(thetaMS);
+
+    return;
+}
+
+
+//____________________________________________________________________
+Bool_t AliMUONTrackHitPattern::TriggerDigits()
+{
+    //
+    /// make (S)Digit for trigger
+    //
+
+    Int_t nBoard;
+
+    TList digitList;
+
+    AliMUONDigitMaker* digitMaker = new AliMUONDigitMaker(); // should be put as member in class
+
+    AliMUONLocalTrigger *locTrg = 0x0;
+
+    fMUONData->SetTreeAddress("RC,TC");
+    fMUONData->GetTrigger();
+
+    TClonesArray *localTrigger = fMUONData->LocalTrigger();
+    Int_t nLocTrig = (Int_t) localTrigger->GetEntriesFast();
+
+    for(Int_t iLoc=0; iLoc<nLocTrig; iLoc++) {
+      locTrg = (AliMUONLocalTrigger*)localTrigger->UncheckedAt(iLoc);
+
+      TArrayS xyPattern[2];
+      xyPattern[0].Set(4);
+      xyPattern[1].Set(4);
+
+      xyPattern[0].AddAt(locTrg->GetX1Pattern(),0);
+      xyPattern[0].AddAt(locTrg->GetX2Pattern(),1);
+      xyPattern[0].AddAt(locTrg->GetX3Pattern(),2);
+      xyPattern[0].AddAt(locTrg->GetX4Pattern(),3);
+
+      xyPattern[1].AddAt(locTrg->GetY1Pattern(),0);
+      xyPattern[1].AddAt(locTrg->GetY2Pattern(),1);
+      xyPattern[1].AddAt(locTrg->GetY3Pattern(),2);
+      xyPattern[1].AddAt(locTrg->GetY4Pattern(),3);
+
+      digitList.Clear();
+      nBoard    = locTrg->LoCircuit();
+      digitMaker->TriggerDigits(nBoard, xyPattern, digitList);
+
+
+    } // loop on localTriggers
+
+    for (Int_t iEntry = 0; iEntry < digitList.GetEntries(); ++iEntry) {
+      AliMUONDigit* digit = (AliMUONDigit*)digitList.At(iEntry);
+      Int_t detElemId = digit->DetElemId();
+      Int_t iChamber  = detElemId/100 - 1; //FIXEME should be given by mapping
+      fTriggerDigitsList[iChamber].Add(digit);
+
+    }
+
+    return kTRUE;
+}
diff --git a/MUON/AliMUONTrackHitPattern.h b/MUON/AliMUONTrackHitPattern.h
new file mode 100644 (file)
index 0000000..3aa6286
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef ALIMUONTRACKHITPATTERN_H
+#define ALIMUONTRACKHITPATTERN_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/// \ingroup rec
+/// \class AliMUONTrackHitPattern
+/// \brief Class for the MUON track hit pattern
+///
+//  Author: Diego Stocco
+
+#include <TObject.h>
+#include <TList.h>
+
+class AliMUONData;
+class AliMUONLocalStruct;
+class AliMUONLocalTriggerBoard;
+class AliMUONTrackParam;
+class AliMUONTriggerCrateStore;
+
+class AliMUONGeometryTransformer;
+
+class TClonesArray;
+
+class AliMUONTrackHitPattern : public TObject {
+public:
+    AliMUONTrackHitPattern(AliMUONData *MUONData); // Default Constructor
+    virtual ~AliMUONTrackHitPattern(); // Destructor
+    
+    void GetHitPattern(TClonesArray *recTracksArray);
+    
+    void FindPadMatchingTrack(AliMUONTrackParam *trackParam, Bool_t isMatch[2], Int_t iChamber);
+    Float_t MinDistanceFromPad(Float_t xPad, Float_t yPad, Float_t zPad,
+                              Float_t dpx, Float_t dpy, AliMUONTrackParam *trackParam);
+    void GetPosUncertainty(AliMUONTrackParam *trackParm, Float_t zChamber,
+                          Float_t &sigmaX, Float_t &sigmaY, Float_t &sigmaMS);
+
+    Bool_t TriggerDigits();
+
+private:
+    AliMUONData *fMUONData; ///< Data container for MUON subsystem
+    TList fTriggerDigitsList[4]; ///< List of trigger digits, one per chamber
+    AliMUONGeometryTransformer *fTransformer; //!< pointer to transformation
+    AliMUONTriggerCrateStore *fCrateManager; ///< pointer to crate manager
+
+    ClassDef(AliMUONTrackHitPattern, 0) // MUON track hit pattern
+};
+
+#endif
index 77d4c92..50dd89f 100644 (file)
@@ -45,6 +45,7 @@
 #include "AliMUONTrack.h"
 #include "AliMUONTrackParam.h"
 #include "AliMUONTrackExtrap.h"
+#include "AliMUONTrackHitPattern.h"
 
 #include "AliLog.h"
 #include "AliTracker.h"
@@ -98,6 +99,8 @@ AliMUONVTrackReconstructor::AliMUONVTrackReconstructor(AliMUONData* data)
   const AliMagF* kField = AliTracker::GetFieldMap();
   if (!kField) AliFatal("No field available");
   AliMUONTrackExtrap::SetField(kField);
+
+  fTrackHitPattern = new AliMUONTrackHitPattern(fMUONData);
 }
 
   //__________________________________________________________________________
@@ -108,6 +111,7 @@ AliMUONVTrackReconstructor::~AliMUONVTrackReconstructor(void)
   delete [] fIndexOfFirstHitForRecPerChamber;
   delete fTriggerTrack;
   delete fHitsForRecPtr;
+  delete fTrackHitPattern;
 }
 
   //__________________________________________________________________________
@@ -122,7 +126,9 @@ void AliMUONVTrackReconstructor::EventReconstruct(void)
   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);
@@ -251,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
@@ -283,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);
index 171da60..1d258cb 100644 (file)
@@ -16,6 +16,7 @@
 class TClonesArray;
 class AliMUONData;
 class AliMUONTriggerTrack;
+class AliMUONTrackHitPattern;
 
 class AliMUONVTrackReconstructor : public TObject {
 
@@ -107,6 +108,8 @@ class AliMUONVTrackReconstructor : public TObject {
                /// \todo add comment
   virtual void FillMUONTrack(void) = 0;
 
+  AliMUONTrackHitPattern *fTrackHitPattern; ///< Pointer to class for hit pattern recognition
+
  private:
   
   AliMUONTriggerTrack* fTriggerTrack; ///< Trigger track structure
index 760805a..0afbc0d 100755 (executable)
@@ -59,12 +59,16 @@ MuonRec.SetLoadAlignData("MUON");
 // Use the following to disconnect the status map creation (only for debug!)
 // as this speeds up startup a bit...
 //MuonRec.SetOption("MUON","NOSTATUSMAP");
+// Use the following to write to disk the digits (from raw data)
+//MuonRec.SetOption("MUON","SAVEDIGITS");
 MuonRec.Run();
 .q
 EOF
 
-echo "Moving Digits files back ..."
-mv MUON.Digits/MUON.Digits.root . 
+if [ ! -e MUON.Digits.root ]; then
+    echo "Moving Digits files back ..."
+    mv MUON.Digits/MUON.Digits.root .
+fi 
 
 echo "Running Trigger efficiency  ..."
 aliroot -b >& testTriggerResults.out << EOF
index b0dddd5..84ef500 100644 (file)
@@ -35,6 +35,7 @@
 #pragma link C++ class AliMUONClusterFinderCOG+;
 #pragma link C++ class AliMUONClusterFinderMLEM+;
 #pragma link C++ class AliMUONClusterSplitterMLEM+;
+#pragma link C++ class AliMUONTrackHitPattern+;
 
 // calibration
 #pragma link C++ class AliMUONDigitCalibrator+;
index 8498e71..11c4924 100644 (file)
@@ -36,7 +36,8 @@ SRCS:= AliMUONClusterReconstructor.cxx \
        AliMUONCluster.cxx \
        AliMUONPadStatusMaker.cxx \
        AliMUONPadStatusMapMaker.cxx \
-       AliMUONHVNamer.cxx
+       AliMUONHVNamer.cxx \
+       AliMUONTrackHitPattern.cxx
        
 HDRS:= $(SRCS:.cxx=.h)