LCOV - code coverage report
Current view: top level - MUON/MUONevaluation - AliMUONRecoCheck.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 455 0.2 %
Date: 2016-06-14 17:26:59 Functions: 1 30 3.3 %

          Line data    Source code
       1             : /**************************************************************************
       2             : * Copyright(c) 1998-1999, 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$ */
      17             : 
      18             : //-----------------------------------------------------------------------------
      19             : /// \class AliMUONRecoCheck
      20             : /// Utility class to check reconstruction
      21             : /// Reconstructed tracks are compared to reference tracks. 
      22             : /// The reference tracks are built from AliTrackReference for the
      23             : /// hit in chamber (0..9) and from kinematics for the vertex parameters.     
      24             : //-----------------------------------------------------------------------------
      25             : 
      26             : // 13 Nov 2007:
      27             : // Added a method to create a list of reconstructed AliMUONTrack objects from
      28             : // ESD data. This is necessary since the track objects that are actually created
      29             : // during offline reconstruction are no longer stored to disk.
      30             : //  - Artur Szostak <artursz@iafrica.com>
      31             : // 25 Jan 2008:
      32             : // Use the new ESDInterface to create MUON objects from ESD data
      33             : // - Philippe Pillot
      34             : // 
      35             : 
      36             : #include "AliMUONRecoCheck.h"
      37             : #include "AliMUONTrack.h"
      38             : #include "AliMUONVTrackStore.h"
      39             : #include "AliMUONVCluster.h"
      40             : #include "AliMUONVClusterStore.h"
      41             : #include "AliMUONConstants.h"
      42             : #include "AliMUONESDInterface.h"
      43             : #include "AliMUONTrackParam.h"
      44             : #include "AliMUONTriggerTrack.h"
      45             : #include "AliMUONVTriggerTrackStore.h"
      46             : #include "AliMUONTriggerStoreV1.h"
      47             : #include "AliMUONLocalTrigger.h"
      48             : #include "AliMCEventHandler.h"
      49             : #include "AliMCEvent.h"
      50             : #include "AliStack.h"
      51             : #include "AliTrackReference.h"
      52             : #include "AliLog.h"
      53             : #include "AliESDEvent.h"
      54             : #include "AliESDMuonTrack.h"
      55             : #include "AliMUONDigitStoreV2S.h"
      56             : #include "AliMUONVDigit.h"
      57             : #include "AliMpVSegmentation.h"
      58             : #include "AliMpSegmentation.h"
      59             : #include "AliMpPad.h"
      60             : 
      61             : #include "AliGeomManager.h"
      62             : #include "AliCDBManager.h"
      63             : #include "AliMpCDB.h"
      64             : #include "AliMpDDLStore.h"
      65             : #include "AliMUONCDB.h"
      66             : #include "AliMUONGeometryTransformer.h"
      67             : #include "AliMUONTriggerCircuit.h"
      68             : #include "AliMUONVTrackReconstructor.h"
      69             : #include "AliMUONVTriggerStore.h"
      70             : #include "AliMUONCalibrationData.h"
      71             : #include "AliMUONTriggerElectronics.h"
      72             : 
      73             : 
      74             : #include "TGeoManager.h"
      75             : 
      76             : #include <TFile.h>
      77             : #include <TTree.h>
      78             : #include <TParticle.h>
      79             : #include <TParticlePDG.h>
      80             : #include <Riostream.h>
      81             : 
      82             : #include "AliMUONRecoCheck.h"
      83             : 
      84             : /// \cond CLASSIMP
      85          16 : ClassImp(AliMUONRecoCheck)
      86             : /// \endcond
      87             : 
      88             : //_____________________________________________________________________________
      89             : AliMUONRecoCheck::AliMUONRecoCheck(const Char_t *esdFileName, const Char_t *pathSim)
      90           0 : : TObject(),
      91           0 : fMCEventHandler(new AliMCEventHandler()),
      92           0 : fESDEvent(new AliESDEvent()),
      93           0 : fESDTree (0x0),
      94           0 : fESDFile (0x0),
      95           0 : fCurrentEvent(0),
      96           0 : fTrackRefStore(0x0),
      97           0 : fRecoTrackRefStore(0x0),
      98           0 : fRecoTriggerRefStore(0x0),
      99           0 : fRecoTrackStore(0x0),
     100           0 : fRecoTriggerTrackStore(0x0),
     101           0 : fGeometryTransformer(0x0),
     102           0 : fTriggerCircuit(0x0),
     103           0 : fCalibrationData(0x0),
     104           0 : fTriggerElectronics(0x0),
     105           0 : fESDEventOwner(kTRUE)
     106           0 : {
     107             :   /// Normal ctor
     108             :   
     109             :   // TrackRefs and Particules
     110           0 :   fMCEventHandler->SetInputPath(pathSim);
     111           0 :   fMCEventHandler->InitIO("");
     112             :   
     113             :   // ESD MUON Tracks
     114           0 :   fESDFile = TFile::Open(esdFileName); // open the file
     115           0 :   if (!fESDFile || !fESDFile->IsOpen()) {
     116           0 :     AliError(Form("opening ESD file %s failed", esdFileName));
     117           0 :     fESDFile = 0x0;
     118           0 :     return;
     119             :   }
     120           0 :   fESDTree = (TTree*) fESDFile->Get("esdTree"); // get the tree
     121           0 :   if (!fESDTree) {
     122           0 :     AliError("no ESD tree found");
     123           0 :     fESDFile->Close();
     124           0 :     fESDFile = 0x0;
     125           0 :     return;
     126             :   }
     127           0 :   fESDEvent->ReadFromTree(fESDTree); // link fESDEvent to the tree
     128           0 : }
     129             : 
     130             : //_____________________________________________________________________________
     131             : AliMUONRecoCheck::AliMUONRecoCheck(AliESDEvent *esdEvent, AliMCEventHandler *mcEventHandler)
     132           0 : : TObject(),
     133           0 : fMCEventHandler(0),
     134           0 : fESDEvent(0),
     135           0 : fESDTree (0x0),
     136           0 : fESDFile (0x0),
     137           0 : fCurrentEvent(0),
     138           0 : fTrackRefStore(0x0),
     139           0 : fRecoTrackRefStore(0x0),
     140           0 : fRecoTriggerRefStore(0x0),
     141           0 : fRecoTrackStore(0x0),
     142           0 : fRecoTriggerTrackStore(0x0),
     143           0 : fGeometryTransformer(0x0),
     144           0 : fTriggerCircuit(0x0),
     145           0 : fCalibrationData(0x0),
     146           0 : fTriggerElectronics(0x0),
     147           0 : fESDEventOwner(kFALSE)
     148           0 : {
     149             :   /// Normal ctor
     150             :   
     151             :   // TrackRefs and Particules
     152           0 :   fMCEventHandler = mcEventHandler;
     153             :   
     154             :   // ESD MUON Tracks
     155           0 :   fESDEvent = esdEvent;
     156           0 : }
     157             : 
     158             : //_____________________________________________________________________________
     159             : AliMUONRecoCheck::~AliMUONRecoCheck()
     160           0 : {
     161             :   /// Destructor
     162           0 :   if (fESDEventOwner) {
     163           0 :     delete fMCEventHandler;
     164           0 :     delete fESDEvent;
     165           0 :     if (fESDFile) fESDFile->Close();
     166             :   }
     167           0 :   ResetStores();
     168           0 :   delete fGeometryTransformer;
     169           0 :   delete fTriggerCircuit;
     170           0 :   delete fTriggerElectronics;
     171           0 :   delete fCalibrationData;
     172           0 : }
     173             : 
     174             : //_____________________________________________________________________________
     175             : void AliMUONRecoCheck::ResetStores()
     176             : {
     177             :   /// Deletes all the store objects that have been created and resets the pointers to 0x0
     178           0 :   delete fTrackRefStore;      fTrackRefStore = 0x0;
     179           0 :   delete fRecoTrackRefStore;  fRecoTrackRefStore = 0x0;
     180           0 :   delete fRecoTriggerRefStore;  fRecoTriggerRefStore = 0x0;
     181           0 :   delete fRecoTrackStore;     fRecoTrackStore = 0x0;
     182           0 :   delete fRecoTriggerTrackStore; fRecoTriggerTrackStore = 0x0;
     183           0 : }
     184             : 
     185             : //_____________________________________________________________________________
     186             : Bool_t AliMUONRecoCheck::InitCircuit()
     187             : {
     188             :   
     189           0 :   if ( fTriggerCircuit ) return kTRUE;
     190             :   
     191           0 :   if ( ! InitGeometryTransformer() ) return kFALSE;
     192             :   
     193             :   // reset tracker for local trigger to trigger track conversion
     194           0 :   if ( ! AliMUONESDInterface::GetTracker() ) AliMUONESDInterface::ResetTracker();
     195             :   
     196           0 :   fTriggerCircuit = new AliMUONTriggerCircuit(fGeometryTransformer);
     197             :   
     198           0 :   return kTRUE;
     199           0 : }
     200             : 
     201             : 
     202             : //_____________________________________________________________________________
     203             : Int_t AliMUONRecoCheck::GetRunNumber()
     204             : {
     205             :   /// Return the run number of the current ESD event
     206             :   
     207           0 :   if (fESDEventOwner && fRecoTrackStore == 0x0 && fRecoTriggerTrackStore == 0x0) {
     208           0 :     if (!fESDTree || fESDTree->GetEvent(fCurrentEvent) <= 0) {
     209           0 :       AliError(Form("fails to read ESD object for event %d: cannot get the run number",fCurrentEvent));
     210           0 :       return -1;
     211             :     }
     212             :   }
     213             :   
     214           0 :   return fESDEvent->GetRunNumber();
     215           0 : }
     216             : 
     217             : //_____________________________________________________________________________
     218             : Int_t AliMUONRecoCheck::NumberOfEvents() const
     219             : {
     220             :   /// Return the number of events
     221           0 :   if (fESDEventOwner && fESDTree) return fESDTree->GetEntries();
     222           0 :   return 0;
     223           0 : }
     224             : 
     225             : //_____________________________________________________________________________
     226             : AliMUONVTrackStore* AliMUONRecoCheck::ReconstructedTracks(Int_t event, Bool_t refit)
     227             : {
     228             :   /// Return a track store containing the reconstructed tracks (converted into 
     229             :   /// MUONTrack objects) for a given event.
     230             :   /// Track parameters at each clusters are computed or not depending on the flag "refit".
     231             :   /// If not, only the track parameters at first cluster are valid.
     232             :   
     233           0 :   if (!fESDEventOwner) {
     234           0 :     if (fRecoTrackStore == 0x0) MakeReconstructedTracks(refit);
     235           0 :     return fRecoTrackStore;
     236             :   }
     237             : 
     238           0 :   if (event != fCurrentEvent) {
     239           0 :     ResetStores();
     240           0 :     fCurrentEvent = event;
     241           0 :   }
     242             :   
     243           0 :   if (fRecoTrackStore != 0x0) return fRecoTrackStore;
     244             :   else {
     245           0 :     if (!fESDTree) return 0x0;
     246           0 :     if (fESDTree->GetEvent(event) <= 0) {
     247           0 :       AliError(Form("fails to read ESD object for event %d", event));
     248           0 :       return 0x0;
     249             :     }
     250           0 :     MakeReconstructedTracks(refit);
     251           0 :     return fRecoTrackStore;
     252             :   }
     253           0 : }
     254             : 
     255             : 
     256             : //_____________________________________________________________________________
     257             : AliMUONVTriggerTrackStore* AliMUONRecoCheck::TriggeredTracks(Int_t event)
     258             : {
     259             :   /// Return a track store containing the reconstructed trigger tracks (converted into 
     260             :   /// MUONTriggerTrack objects) for a given event.
     261             :         
     262           0 :   if (!fESDEventOwner) {
     263           0 :     if (fRecoTriggerTrackStore == 0x0) MakeTriggeredTracks();
     264           0 :     return fRecoTriggerTrackStore;
     265             :   }
     266             :         
     267           0 :   if (event != fCurrentEvent) {
     268           0 :     ResetStores();
     269           0 :     fCurrentEvent = event;
     270           0 :   }
     271             :         
     272           0 :   if (fRecoTriggerTrackStore != 0x0) return fRecoTriggerTrackStore;
     273             :   else {
     274           0 :     if (!fESDTree) return 0x0;
     275           0 :     if (fESDTree->GetEvent(event) <= 0) {
     276           0 :       AliError(Form("fails to read ESD object for event %d", event));
     277           0 :       return 0x0;
     278             :     }
     279           0 :     MakeTriggeredTracks();
     280           0 :     return fRecoTriggerTrackStore;
     281             :   }
     282           0 : }
     283             : 
     284             : 
     285             : //_____________________________________________________________________________
     286             : AliMUONVTrackStore* AliMUONRecoCheck::TrackRefs(Int_t event)
     287             : {
     288             :   /// Return a track store containing the track references (converted into 
     289             :   /// MUONTrack objects) for a given event
     290             :   
     291           0 :   if (!fESDEventOwner) {
     292           0 :     if (fTrackRefStore == 0x0) MakeTrackRefs();
     293           0 :     return fTrackRefStore;
     294             :   }
     295             : 
     296           0 :   if (event != fCurrentEvent) {
     297           0 :     ResetStores();
     298           0 :     fCurrentEvent = event;
     299           0 :   }
     300             :   
     301           0 :   if (fTrackRefStore != 0x0) return fTrackRefStore;
     302             :   else {
     303           0 :     if (!fMCEventHandler->BeginEvent(event)) {
     304           0 :       AliError(Form("fails to read MC objects for event %d", event));
     305           0 :       return 0x0;
     306             :     }
     307           0 :     MakeTrackRefs();
     308           0 :     fMCEventHandler->FinishEvent();
     309           0 :     return fTrackRefStore;
     310             :   }
     311           0 : }
     312             : 
     313             : //_____________________________________________________________________________
     314             : AliMUONVTriggerTrackStore* AliMUONRecoCheck::TriggerableTracks(Int_t event)
     315             : {
     316             :   /// Return a trigger track store containing the triggerable track references (converted into 
     317             :   /// AliMUONTriggerTrack objects) for a given event
     318             :         
     319           0 :   if (!fESDEventOwner) {
     320           0 :     if (fRecoTriggerRefStore == 0x0) MakeTriggerableTracks();
     321           0 :     return fRecoTriggerRefStore;
     322             :   }
     323             :         
     324           0 :   if (event != fCurrentEvent) {
     325           0 :     ResetStores();
     326           0 :     fCurrentEvent = event;
     327           0 :   }
     328             :         
     329           0 :   if (fRecoTriggerRefStore != 0x0) return fRecoTriggerRefStore;
     330             :   else {
     331           0 :     if (!fMCEventHandler->BeginEvent(event)) {
     332           0 :       AliError(Form("fails to read MC objects for event %d", event));
     333           0 :       return 0x0;
     334             :     }
     335           0 :     MakeTriggerableTracks();
     336           0 :     fMCEventHandler->FinishEvent();
     337           0 :     return fRecoTriggerRefStore;
     338             :   }
     339           0 : }
     340             : 
     341             : 
     342             : //_____________________________________________________________________________
     343             : AliMUONVTrackStore* AliMUONRecoCheck::ReconstructibleTracks(Int_t event, UInt_t requestedStationMask,
     344             :                                                             Bool_t request2ChInSameSt45, Bool_t hitInFrontOfPad)
     345             : {
     346             :   /// Return a track store containing the reconstructible tracks for a given event,
     347             :   /// according to the mask of requested stations and the minimum number of chambers hit in stations 4 & 5.
     348             : 
     349           0 :   if (!fESDEventOwner) {
     350           0 :     if (fRecoTrackRefStore == 0x0) {
     351           0 :       if (TrackRefs(event) == 0x0) return 0x0;
     352           0 :       MakeReconstructibleTracks(requestedStationMask, request2ChInSameSt45, hitInFrontOfPad);
     353           0 :     }
     354           0 :     return fRecoTrackRefStore;
     355             :   }
     356             : 
     357           0 :   if (event != fCurrentEvent) {
     358           0 :     ResetStores();
     359           0 :     fCurrentEvent = event;
     360           0 :   }
     361             :   
     362           0 :   if (fRecoTrackRefStore != 0x0) return fRecoTrackRefStore;
     363             :   else {
     364           0 :     if (TrackRefs(event) == 0x0) return 0x0;
     365           0 :     MakeReconstructibleTracks(requestedStationMask, request2ChInSameSt45, hitInFrontOfPad);
     366           0 :     return fRecoTrackRefStore;
     367             :   }
     368           0 : }
     369             : 
     370             : 
     371             : //_____________________________________________________________________________
     372             : void AliMUONRecoCheck::MakeReconstructedTracks(Bool_t refit)
     373             : {
     374             :   /// Make reconstructed tracks
     375           0 :   if (!(fRecoTrackStore = AliMUONESDInterface::NewTrackStore())) return;
     376             :   
     377             :   // loop over all reconstructed tracks and add them to the store (skip ghosts)
     378           0 :   Int_t nTracks = (Int_t) fESDEvent->GetNumberOfMuonTracks();
     379           0 :   for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
     380           0 :     AliESDMuonTrack* esdTrack = fESDEvent->GetMuonTrack(iTrack);
     381           0 :     if (esdTrack->ContainTrackerData()) AliMUONESDInterface::Add(*esdTrack, *fRecoTrackStore, refit);
     382             :   }
     383             :   
     384           0 : }
     385             : 
     386             : 
     387             : //_____________________________________________________________________________
     388             : void AliMUONRecoCheck::MakeTriggeredTracks()
     389             : {
     390             :   /// Make reconstructed trigger tracks
     391           0 :   if (!(fRecoTriggerTrackStore = AliMUONESDInterface::NewTriggerTrackStore())) return;
     392             :         
     393           0 :   AliMUONVTriggerStore* tmpTriggerStore = AliMUONESDInterface::NewTriggerStore();
     394           0 :   if ( ! tmpTriggerStore ) return;
     395             :   
     396             :   // loop over all reconstructed tracks and add them to the store (include ghosts)
     397           0 :   Int_t nTracks = (Int_t) fESDEvent->GetNumberOfMuonTracks();
     398           0 :   for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
     399           0 :     AliESDMuonTrack* esdTrack = fESDEvent->GetMuonTrack(iTrack);
     400           0 :     if (esdTrack->ContainTriggerData()) AliMUONESDInterface::Add(*esdTrack, *tmpTriggerStore);
     401             :   }
     402             :         
     403           0 :   if ( InitCircuit() ) {
     404             :   
     405           0 :     AliMUONVTrackReconstructor* tracker = AliMUONESDInterface::GetTracker();
     406           0 :     tracker->EventReconstructTrigger(*fTriggerCircuit, *tmpTriggerStore, *fRecoTriggerTrackStore);
     407           0 :   }
     408             :   
     409           0 :   delete tmpTriggerStore;
     410           0 : }
     411             : 
     412             : //_____________________________________________________________________________
     413             : Bool_t AliMUONRecoCheck::TriggerToTrack(const AliMUONLocalTrigger& locTrg, AliMUONTriggerTrack& triggerTrack)
     414             : {
     415             :   /// Make trigger track from local trigger info
     416           0 :   if ( ! InitCircuit() ) return kFALSE;
     417           0 :   AliMUONVTrackReconstructor* tracker = AliMUONESDInterface::GetTracker();
     418           0 :   return tracker->TriggerToTrack(*fTriggerCircuit, locTrg, triggerTrack);
     419           0 : }
     420             : 
     421             : 
     422             : //_____________________________________________________________________________
     423             : void AliMUONRecoCheck::MakeTrackRefs()
     424             : {
     425             :   /// Make reconstructible tracks
     426           0 :   AliMUONVTrackStore *tmpTrackRefStore = AliMUONESDInterface::NewTrackStore();
     427           0 :   if (!tmpTrackRefStore) return;
     428             :   
     429             :   Double_t x, y, z, pX, pY, pZ, bendingSlope, nonBendingSlope, inverseBendingMomentum;
     430           0 :   TParticle* particle;
     431           0 :   TClonesArray* trackRefs;
     432           0 :   Int_t nTrackRef = fMCEventHandler->MCEvent()->GetNumberOfTracks();
     433           0 :   AliMUONVCluster* hit = AliMUONESDInterface::NewCluster();
     434             :   
     435             :   // loop over simulated tracks
     436           0 :   for (Int_t iTrackRef  = 0; iTrackRef < nTrackRef; ++iTrackRef) {
     437           0 :     Int_t nHits = fMCEventHandler->GetParticleAndTR(iTrackRef, particle, trackRefs);
     438             :     
     439             :     // skip empty trackRefs
     440           0 :     if (nHits < 1) continue;
     441             :     
     442             :     // get the particle charge for further calculation
     443           0 :     TParticlePDG* ppdg = particle->GetPDG();
     444           0 :     Int_t charge = ppdg != NULL ? (Int_t)(ppdg->Charge()/3.0) : 0;
     445             :     
     446           0 :     AliMUONTrack track;
     447             :     
     448             :     // loop over simulated track hits
     449           0 :     for (Int_t iHit = 0; iHit < nHits; ++iHit) {        
     450           0 :       AliTrackReference* trackReference = static_cast<AliTrackReference*>(trackRefs->UncheckedAt(iHit));
     451             :       
     452             :       // skip trackRefs not in MUON
     453           0 :       if (trackReference->DetectorId() != AliTrackReference::kMUON) continue;
     454             :     
     455             :       // Get track parameters of current hit
     456           0 :       x = trackReference->X();
     457           0 :       y = trackReference->Y();
     458           0 :       z = trackReference->Z();
     459           0 :       pX = trackReference->Px();
     460           0 :       pY = trackReference->Py();
     461           0 :       pZ = trackReference->Pz();
     462             :       
     463             :       // check chamberId of current trackReference
     464           0 :       Int_t detElemId = trackReference->UserId();
     465           0 :       Int_t chamberId = detElemId / 100 - 1;
     466           0 :       if (chamberId < 0 || chamberId >= AliMUONConstants::NTrackingCh()) continue;
     467             :       
     468             :       // set hit parameters
     469           0 :       hit->SetUniqueID(AliMUONVCluster::BuildUniqueID(chamberId, detElemId, iHit));
     470           0 :       hit->SetXYZ(x,y,z);
     471           0 :       hit->SetErrXY(0.,0.);
     472             :       
     473             :       // compute track parameters at hit
     474             :       bendingSlope = 0;
     475             :       nonBendingSlope = 0;
     476             :       inverseBendingMomentum = 0;
     477           0 :       if (TMath::Abs(pZ) > 0) {
     478           0 :         bendingSlope = pY/pZ;
     479           0 :         nonBendingSlope = pX/pZ;
     480           0 :       }
     481           0 :       Double_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ);
     482           0 :       if (pYZ >0) inverseBendingMomentum = 1/pYZ; 
     483           0 :       inverseBendingMomentum *= charge;
     484             :       
     485             :       // set track parameters at hit
     486           0 :       AliMUONTrackParam trackParam;
     487           0 :       trackParam.SetNonBendingCoor(x);
     488           0 :       trackParam.SetBendingCoor(y);
     489           0 :       trackParam.SetZ(z);
     490           0 :       trackParam.SetBendingSlope(bendingSlope);
     491           0 :       trackParam.SetNonBendingSlope(nonBendingSlope);
     492           0 :       trackParam.SetInverseBendingMomentum(inverseBendingMomentum);
     493             :       
     494             :       // add track parameters at current hit to the track
     495           0 :       track.AddTrackParamAtCluster(trackParam, *hit, kTRUE);
     496           0 :     }
     497             :     
     498             :     // if none of the track hits was in MUON, goto the next track
     499           0 :     if (track.GetNClusters() < 1) continue;
     500             :     
     501             :     // get track parameters at particle's vertex
     502           0 :     x = particle->Vx();
     503           0 :     y = particle->Vy();
     504           0 :     z = particle->Vz();
     505           0 :     pX = particle->Px();
     506           0 :     pY = particle->Py();
     507           0 :     pZ = particle->Pz();
     508             :     
     509             :     // compute rest of track parameters at particle's vertex
     510             :     bendingSlope = 0;
     511             :     nonBendingSlope = 0;
     512             :     inverseBendingMomentum = 0;
     513           0 :     if (TMath::Abs(pZ) > 0) {
     514           0 :       bendingSlope = pY/pZ;
     515           0 :       nonBendingSlope = pX/pZ;
     516           0 :     }
     517           0 :     Double_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ);
     518           0 :     if (pYZ >0) inverseBendingMomentum = 1/pYZ;
     519           0 :     inverseBendingMomentum *= charge;
     520             :     
     521             :     // set track parameters at particle's vertex
     522           0 :     AliMUONTrackParam trackParamAtVertex;
     523           0 :     trackParamAtVertex.SetNonBendingCoor(x);
     524           0 :     trackParamAtVertex.SetBendingCoor(y);
     525           0 :     trackParamAtVertex.SetZ(z);
     526           0 :     trackParamAtVertex.SetBendingSlope(bendingSlope);
     527           0 :     trackParamAtVertex.SetNonBendingSlope(nonBendingSlope);
     528           0 :     trackParamAtVertex.SetInverseBendingMomentum(inverseBendingMomentum);
     529             :     
     530             :     // add track parameters at vertex
     531           0 :     track.SetTrackParamAtVertex(&trackParamAtVertex);
     532             :     
     533             :     // store the track
     534           0 :     track.SetUniqueID(iTrackRef);
     535           0 :     tmpTrackRefStore->Add(track);
     536           0 :   }
     537             :   
     538           0 :   CleanMuonTrackRef(tmpTrackRefStore);
     539             :   
     540           0 :   delete hit;
     541           0 :   delete tmpTrackRefStore;
     542           0 : }
     543             : 
     544             : //_____________________________________________________________________________
     545             : void AliMUONRecoCheck::MakeTriggerableTracks()
     546             : {
     547             :   /// Make triggerable tracks
     548           0 :  if (!(fRecoTriggerRefStore = AliMUONESDInterface::NewTriggerTrackStore()))
     549             :    return;
     550             : 
     551           0 :   Double_t x, y, z, slopeX, slopeY, pZ, xLoc, yLoc, zLoc;
     552           0 :   TParticle* particle;
     553           0 :   TClonesArray* trackRefs;
     554           0 :   Int_t nTrackRef = fMCEventHandler->MCEvent()->GetNumberOfTracks();
     555             :         
     556             :   // loop over simulated tracks
     557           0 :   for (Int_t iTrackRef  = 0; iTrackRef < nTrackRef; ++iTrackRef) {
     558           0 :     Int_t nHits = fMCEventHandler->GetParticleAndTR(iTrackRef, particle, trackRefs);
     559             :                 
     560             :     // skip empty trackRefs
     561           0 :     if (nHits < 1) continue;
     562             :                                 
     563           0 :     AliMUONTriggerTrack track;
     564           0 :     AliMUONDigitStoreV2S digitStore;
     565             :     Int_t hitsOnTrigger = 0;
     566             :     Int_t currCh = -1;
     567             :                 
     568             :     // loop over simulated track hits
     569           0 :     for (Int_t iHit = 0; iHit < nHits; ++iHit) {        
     570           0 :       AliTrackReference* trackReference = static_cast<AliTrackReference*>(trackRefs->UncheckedAt(iHit));
     571             :                         
     572             :       // skip trackRefs not in MUON
     573           0 :       if (trackReference->DetectorId() != AliTrackReference::kMUON) continue;
     574             : 
     575             :       // check chamberId of current trackReference
     576           0 :       Int_t detElemId = trackReference->UserId();
     577           0 :       Int_t chamberId = detElemId / 100 - 1;
     578           0 :       if (chamberId < AliMUONConstants::NTrackingCh() || chamberId >= AliMUONConstants::NCh() ) continue;
     579             : 
     580             :       // Get track parameters of current hit
     581           0 :       x = trackReference->X();
     582           0 :       y = trackReference->Y();
     583           0 :       z = trackReference->Z();
     584             :       
     585           0 :       if ( InitTriggerResponse() ) {
     586           0 :         fGeometryTransformer->Global2Local(detElemId, x, y, z, xLoc, yLoc, zLoc);
     587             :       
     588             :         Int_t nboard = 0;
     589           0 :         for ( Int_t cath = AliMp::kCath0; cath <= AliMp::kCath1; ++cath )
     590             :         {
     591             :           const AliMpVSegmentation* seg 
     592           0 :           = AliMpSegmentation::Instance()
     593           0 :           ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cath));
     594             :         
     595           0 :           AliMpPad pad = seg->PadByPosition(xLoc,yLoc,kFALSE);
     596           0 :           Int_t ix = pad.GetIx();
     597           0 :           Int_t iy = pad.GetIy();
     598             :         
     599           0 :           if ( !pad.IsValid() ) continue;
     600             :         
     601           0 :           if ( cath == AliMp::kCath0 ) nboard = pad.GetLocalBoardId(0);
     602             :         
     603           0 :           AliMUONVDigit* digit = digitStore.Add(detElemId, nboard, pad.GetLocalBoardChannel(0),
     604             :                                                 cath, AliMUONVDigitStore::kDeny);
     605           0 :           if (digit) {
     606           0 :             digit->SetPadXY(ix,iy);
     607           0 :             digit->SetCharge(1.);
     608             :           }
     609           0 :         }
     610           0 :       }
     611             :     
     612           0 :       if ( hitsOnTrigger == 0 ) {
     613           0 :         pZ = trackReference->Pz();
     614           0 :         slopeX = ( pZ == 0. ) ? 99999. : trackReference->Px() / pZ;
     615           0 :         slopeY = ( pZ == 0. ) ? 99999. : trackReference->Py() / pZ;
     616             : 
     617           0 :         track.SetX11(x);
     618           0 :         track.SetY11(y);
     619           0 :         track.SetZ11(z);
     620           0 :         track.SetSlopeX(slopeX);
     621           0 :         track.SetSlopeY(slopeY);
     622           0 :       }
     623             : 
     624           0 :       if ( currCh != chamberId ) {
     625           0 :         hitsOnTrigger++;
     626             :         currCh = chamberId;
     627           0 :       }
     628             : 
     629           0 :     } // loop on hits
     630             :     
     631           0 :     if ( hitsOnTrigger < 3 ) continue;
     632             : 
     633             :     // Check if the track passes the trigger algorithm
     634           0 :     if ( InitTriggerResponse() ) {
     635           0 :       AliMUONTriggerStoreV1 triggerStore;
     636           0 :       fTriggerElectronics->Digits2Trigger(digitStore,triggerStore);
     637             :     
     638           0 :       TIter next(triggerStore.CreateIterator());
     639             :       AliMUONLocalTrigger* locTrg(0x0);
     640             :     
     641             :       Int_t ptCutLevel = 0;
     642             :     
     643           0 :       while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(next()) ) )
     644             :       {
     645           0 :         if ( locTrg->IsTrigX() && locTrg->IsTrigY() ) 
     646             :         {
     647           0 :           ptCutLevel = TMath::Max(ptCutLevel, 1);
     648           0 :           if ( locTrg->LoHpt() ) ptCutLevel = TMath::Max(ptCutLevel, 3);
     649           0 :           else if ( locTrg->LoLpt() ) ptCutLevel = TMath::Max(ptCutLevel, 2);
     650             :         } // board is fired 
     651             :       } // end of loop on Local Trigger
     652           0 :       track.SetPtCutLevel(ptCutLevel);
     653           0 :     }
     654           0 :     track.SetUniqueID(iTrackRef);
     655           0 :     fRecoTriggerRefStore->Add(track);
     656           0 :   }
     657           0 : }
     658             : 
     659             : 
     660             : //_____________________________________________________________________________
     661             : void AliMUONRecoCheck::CleanMuonTrackRef(const AliMUONVTrackStore *tmpTrackRefStore)
     662             : {
     663             :   /// Re-calculate hits parameters because two AliTrackReferences are recorded for
     664             :   /// each chamber (one when particle is entering + one when particle is leaving 
     665             :   /// the sensitive volume) 
     666           0 :   if (!(fTrackRefStore = AliMUONESDInterface::NewTrackStore())) return;
     667             :   
     668             :   Double_t maxGasGap = 1.; // cm 
     669             :   Double_t x, y, z, pX, pY, pZ, x1, y1, z1, pX1, pY1, pZ1, z2;
     670             :   Double_t bendingSlope,nonBendingSlope,inverseBendingMomentum;
     671           0 :   AliMUONVCluster* hit = AliMUONESDInterface::NewCluster();
     672             :   
     673             :   // create iterator
     674           0 :   TIter next(tmpTrackRefStore->CreateIterator());
     675             :   
     676             :   // loop over tmpTrackRef
     677             :   AliMUONTrack* track;
     678           0 :   while ( ( track = static_cast<AliMUONTrack*>(next()) ) ) {
     679             :     
     680           0 :     AliMUONTrack newTrack;
     681             :     
     682             :     // loop over tmpTrackRef's hits
     683             :     Int_t iHit1 = 0;
     684           0 :     Int_t nTrackHits = track->GetNClusters();
     685           0 :     while (iHit1 < nTrackHits) {
     686           0 :       AliMUONTrackParam *trackParam1 = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->UncheckedAt(iHit1);
     687             :       
     688             :       // get track parameters at hit1
     689           0 :       x1  = trackParam1->GetNonBendingCoor();
     690           0 :       y1  = trackParam1->GetBendingCoor();
     691           0 :       z1  = trackParam1->GetZ();
     692           0 :       pX1 = trackParam1->Px();
     693           0 :       pY1 = trackParam1->Py();
     694           0 :       pZ1 = trackParam1->Pz();
     695             :       
     696             :       // prepare new track parameters
     697             :       x  = x1;
     698             :       y  = y1;
     699             :       z  = z1;
     700             :       pX = pX1;
     701             :       pY = pY1;
     702             :       pZ = pZ1;
     703             :       
     704             :       // loop over next tmpTrackRef's hits
     705             :       Int_t nCombinedHits = 1;
     706           0 :       for (Int_t iHit2 = iHit1+1; iHit2 < nTrackHits; iHit2++) {
     707           0 :         AliMUONTrackParam *trackParam2 = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->UncheckedAt(iHit2);
     708             :         
     709             :         // get z position of hit2
     710           0 :         z2 = trackParam2->GetZ();
     711             :         
     712             :         // complete new track parameters if hit2 is on the same detection element
     713           0 :         if ( TMath::Abs(z2-z1) < maxGasGap ) {
     714           0 :           x  += trackParam2->GetNonBendingCoor();
     715           0 :           y  += trackParam2->GetBendingCoor();
     716           0 :           z  += z2;
     717           0 :           pX += trackParam2->Px();
     718           0 :           pY += trackParam2->Py();
     719           0 :           pZ += trackParam2->Pz();
     720           0 :           nCombinedHits++;
     721             :           iHit1 = iHit2;
     722           0 :         }
     723             :         
     724             :       }
     725             :       
     726             :       // finalize new track parameters
     727           0 :       x  /= (Double_t)nCombinedHits;
     728           0 :       y  /= (Double_t)nCombinedHits;
     729           0 :       z  /= (Double_t)nCombinedHits;
     730           0 :       pX /= (Double_t)nCombinedHits;
     731           0 :       pY /= (Double_t)nCombinedHits;
     732           0 :       pZ /= (Double_t)nCombinedHits;
     733             :       bendingSlope = 0;
     734             :       nonBendingSlope = 0;
     735             :       inverseBendingMomentum = 0;
     736           0 :       if (TMath::Abs(pZ) > 0) {
     737           0 :         bendingSlope = pY/pZ;
     738           0 :         nonBendingSlope = pX/pZ;
     739           0 :       }
     740           0 :       Double_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ);
     741           0 :       if (pYZ >0) inverseBendingMomentum = 1/pYZ; 
     742           0 :       inverseBendingMomentum *= trackParam1->GetCharge();
     743             :       
     744             :       // set hit parameters
     745           0 :       hit->SetUniqueID(trackParam1->GetClusterPtr()->GetUniqueID());
     746           0 :       hit->SetXYZ(x,y,z);
     747           0 :       hit->SetErrXY(0.,0.);
     748             :       
     749             :       // set new track parameters at new hit
     750           0 :       AliMUONTrackParam trackParam;
     751           0 :       trackParam.SetNonBendingCoor(x);
     752           0 :       trackParam.SetBendingCoor(y);
     753           0 :       trackParam.SetZ(z);
     754           0 :       trackParam.SetBendingSlope(bendingSlope);
     755           0 :       trackParam.SetNonBendingSlope(nonBendingSlope);
     756           0 :       trackParam.SetInverseBendingMomentum(inverseBendingMomentum);
     757             :       
     758             :       // add track parameters at current hit to the track
     759           0 :       newTrack.AddTrackParamAtCluster(trackParam, *hit, kTRUE);
     760             :       
     761           0 :       iHit1++;
     762           0 :     }
     763             :     
     764           0 :     newTrack.SetUniqueID(track->GetUniqueID());
     765           0 :     newTrack.SetTrackParamAtVertex(track->GetTrackParamAtVertex());
     766           0 :     fTrackRefStore->Add(newTrack);
     767             :     
     768           0 :   }
     769             :   
     770           0 :   delete hit;
     771           0 : }
     772             : 
     773             : //_____________________________________________________________________________
     774             : void AliMUONRecoCheck::MakeReconstructibleTracks(UInt_t requestedStationMask, Bool_t request2ChInSameSt45,
     775             :                                                  Bool_t hitInFrontOfPad)
     776             : {
     777             :   /// Isolate the reconstructible tracks
     778           0 :   if (!(fRecoTrackRefStore = AliMUONESDInterface::NewTrackStore())) return;
     779             :   
     780             :   // need geometry transformer and segmentation to check if trackrefs are located in front of pad(s)
     781           0 :   if (hitInFrontOfPad) {
     782           0 :     if (!InitGeometryTransformer()) return;
     783           0 :     if (!AliMpSegmentation::Instance(kFALSE) && !AliMUONCDB::LoadMapping(kTRUE)) return;
     784             :   }
     785             :   
     786             :   // create iterator on trackRef
     787           0 :   TIter next(fTrackRefStore->CreateIterator());
     788             :   
     789             :   // loop over trackRef and add reconstructible tracks to fRecoTrackRefStore
     790             :   AliMUONTrack* track;
     791           0 :   while ( ( track = static_cast<AliMUONTrack*>(next()) ) ) {
     792             :     
     793             :     // check if the track is valid as it is
     794           0 :     if (track->IsValid(requestedStationMask, request2ChInSameSt45)) {
     795             :       
     796           0 :       if (hitInFrontOfPad) {
     797             :         
     798           0 :         AliMUONTrack trackTmp(*track);
     799             :         
     800             :         // loop over clusters and remove those which are not in front of pad(s)
     801           0 :         AliMUONTrackParam *param = static_cast<AliMUONTrackParam*>(trackTmp.GetTrackParamAtCluster()->First());
     802           0 :         while (param) {
     803           0 :           AliMUONTrackParam *nextParam = static_cast<AliMUONTrackParam*>(trackTmp.GetTrackParamAtCluster()->After(param));
     804           0 :           if (!IsHitInFrontOfPad(param)) trackTmp.RemoveTrackParamAtCluster(param);
     805             :           param = nextParam;
     806             :         }
     807             :         
     808             :         // add the track if it is still valid
     809           0 :         if (trackTmp.IsValid(requestedStationMask, request2ChInSameSt45)) fRecoTrackRefStore->Add(trackTmp);
     810             :         
     811           0 :       } else {
     812             :         
     813             :         // add the track
     814           0 :         fRecoTrackRefStore->Add(*track);
     815             :         
     816             :       }
     817             :       
     818             :     }
     819             :       
     820             :   }
     821             : 
     822           0 : }
     823             : 
     824             : //_____________________________________________________________________________
     825             : AliMUONTrack* AliMUONRecoCheck::FindCompatibleTrack(AliMUONTrack &track, AliMUONVTrackStore &trackStore,
     826             :                                                     Int_t &nMatchClusters, Bool_t useLabel, Double_t sigmaCut)
     827             : {
     828             :   /// Return the track from the store matched with the given track (or 0x0) and the number of matched clusters.
     829             :   /// Matching is done by using the MC label of by comparing cluster/TrackRef positions according to the flag "useLabel".
     830             :   /// WARNING: Who match who matters since the matching algorithm uses the *fraction* of matched clusters of the given track
     831             :   
     832             :   AliMUONTrack *matchedTrack = 0x0;
     833           0 :   nMatchClusters = 0;
     834             :   
     835           0 :   if (useLabel) { // by using the MC label
     836             :     
     837             :     // get the corresponding simulated track if any
     838           0 :     Int_t label = track.GetMCLabel();
     839           0 :     matchedTrack = (AliMUONTrack*) trackStore.FindObject(label);
     840             :     
     841             :     // get the fraction of matched clusters
     842           0 :     if (matchedTrack) {
     843           0 :       Int_t nClusters = track.GetNClusters();
     844           0 :       for (Int_t iCl = 0; iCl < nClusters; iCl++)
     845           0 :         if (((AliMUONTrackParam*) track.GetTrackParamAtCluster()->UncheckedAt(iCl))->GetClusterPtr()->GetMCLabel() == label)
     846           0 :           nMatchClusters++;
     847           0 :     }
     848             :     
     849           0 :   } else { // by comparing cluster/TrackRef positions
     850             :     
     851             :     // look for the corresponding simulated track if any
     852           0 :     TIter next(trackStore.CreateIterator());
     853             :     AliMUONTrack* track2;
     854           0 :     while ( ( track2 = static_cast<AliMUONTrack*>(next()) ) ) {
     855             :       
     856             :       // check compatibility
     857           0 :       Int_t n = 0;
     858           0 :       if (track.Match(*track2, sigmaCut, n)) {
     859             :         matchedTrack = track2;
     860           0 :         nMatchClusters = n;
     861           0 :         break;
     862             :       }
     863             :       
     864           0 :     }
     865             :     
     866           0 :   }
     867             :   
     868           0 :   return matchedTrack;
     869             :   
     870           0 : }
     871             : 
     872             : 
     873             : //_____________________________________________________________________________
     874             : AliMUONTriggerTrack* AliMUONRecoCheck::FindCompatibleTrack(AliMUONTriggerTrack &track, const AliMUONVTriggerTrackStore &triggerTrackStore,
     875             :                                                            Double_t sigmaCut)
     876             : {
     877             :   /// Return the trigger track from the store matched with the given track (or 0x0).
     878             :   /// Matching is done by comparing cluster/TrackRef positions.
     879             :   
     880             :   AliMUONTriggerTrack *matchedTrack = 0x0;
     881             :   
     882             :   // look for the corresponding simulated track if any
     883           0 :   TIter next(triggerTrackStore.CreateIterator());
     884             :   AliMUONTriggerTrack* track2;
     885           0 :   while ( ( track2 = static_cast<AliMUONTriggerTrack*>(next()) ) ) {
     886             :     // check compatibility
     887           0 :     if (track.Match(*track2, sigmaCut)) {
     888             :       matchedTrack = track2;
     889           0 :       break;
     890             :     }
     891             :   }
     892             :   
     893             :   return matchedTrack;
     894             :   
     895           0 : }
     896             : 
     897             : 
     898             : //____________________________________________________________________________ 
     899             : Bool_t AliMUONRecoCheck::InitTriggerResponse()
     900             : {
     901             :   /// Initialize trigger electronics
     902             :   /// for building of triggerable tracks from MC
     903             :   
     904           0 :   if ( fTriggerElectronics ) return kTRUE;
     905             :   
     906           0 :   if ( ! InitGeometryTransformer() ) return kFALSE;
     907             :   
     908           0 :   if ( ! AliMpDDLStore::Instance(false) && ! AliMpCDB::LoadDDLStore()) return kFALSE;
     909             :   
     910           0 :   if ( ! InitCalibrationData() ) return kFALSE;
     911             :   
     912           0 :   fTriggerElectronics = new AliMUONTriggerElectronics(fCalibrationData);
     913             :   
     914           0 :   return kTRUE;
     915           0 : }
     916             : 
     917             : 
     918             : //____________________________________________________________________________ 
     919             : Bool_t AliMUONRecoCheck::InitCalibrationData()
     920             : {
     921             :   /// Initialize calibration data
     922           0 :   if ( ! fCalibrationData ) {
     923           0 :     if ( !AliMUONCDB::CheckOCDB() ) return kFALSE;
     924           0 :     fCalibrationData = new AliMUONCalibrationData(AliCDBManager::Instance()->GetRun());
     925           0 :   }
     926           0 :   return kTRUE;
     927           0 : }
     928             : 
     929             : 
     930             : //____________________________________________________________________________ 
     931             : Bool_t AliMUONRecoCheck::InitGeometryTransformer()
     932             : {
     933             :   /// Return geometry transformer
     934             :   /// (create it if necessary)
     935           0 :   if ( ! fGeometryTransformer ) {
     936             :     
     937           0 :     if ( !AliMUONCDB::CheckOCDB() ) return kFALSE;
     938             :     
     939           0 :     if (!AliGeomManager::GetGeometry()) {
     940           0 :       AliGeomManager::LoadGeometry();
     941           0 :       if (!AliGeomManager::GetGeometry()) return kFALSE;  
     942           0 :       if (!AliGeomManager::ApplyAlignObjsFromCDB("MUON")) return kFALSE;
     943             :     }
     944             :     
     945           0 :     fGeometryTransformer = new AliMUONGeometryTransformer();
     946           0 :     fGeometryTransformer->LoadGeometryData();
     947           0 :   }
     948             :   
     949           0 :   return kTRUE;
     950           0 : }
     951             : 
     952             : //________________________________________________________________________
     953             : Bool_t AliMUONRecoCheck::IsHitInFrontOfPad(AliMUONTrackParam *param) const
     954             : {
     955             :   /// Return kTRUE if the hit is located in front of at least 1 pad
     956             :   
     957           0 :   Int_t deId = param->GetClusterPtr()->GetDetElemId();
     958             :   
     959           0 :   Double_t xL, yL, zL;
     960           0 :   fGeometryTransformer->Global2Local(deId, param->GetNonBendingCoor(), param->GetBendingCoor(), param->GetZ(), xL, yL, zL);
     961             :   
     962           0 :   const AliMpVSegmentation* seg1 = AliMpSegmentation::Instance()->GetMpSegmentation(deId, AliMp::kCath0);
     963           0 :   const AliMpVSegmentation* seg2 = AliMpSegmentation::Instance()->GetMpSegmentation(deId, AliMp::kCath1);
     964           0 :   if (!seg1 || !seg2) return kFALSE;
     965             :   
     966           0 :   AliMpPad pad1 = seg1->PadByPosition(xL, yL, kFALSE);
     967           0 :   AliMpPad pad2 = seg2->PadByPosition(xL, yL, kFALSE);
     968             :   
     969           0 :   return (pad1.IsValid() || pad2.IsValid());
     970           0 : }
     971             : 

Generated by: LCOV version 1.11