* provided "as is" without express or implied warranty. *
**************************************************************************/
-//////////////////////////////////////////////////////////////////////////////////////
-//
-// Utility class to check the muon reconstruction. Reconstructed tracks are compared
-// to reference tracks. The reference tracks are built from AliTrackReference for the
-// hit in chamber (0..9) and from kinematics for the vertex parameters.
-//
-//////////////////////////////////////////////////////////////////////////////////////
+/* $Id$ */
+/// \class AliMUONRecoCheck
+/// \brief Utility class to check reconstruction
+/// Reconstructed tracks are compared to reference tracks.
+/// The reference tracks are built from AliTrackReference for the
+/// hit in chamber (0..9) and from kinematics for the vertex parameters.
-#include <TParticle.h>
+#include "AliMUON.h"
+#include "AliMUONRecoCheck.h"
+#include "AliMUONTrack.h"
+#include "AliMUONData.h"
+#include "AliMUONConstants.h"
#include "AliRun.h" // for gAlice
-#include "AliLog.h"
#include "AliLoader.h"
#include "AliRunLoader.h"
-#include "AliTrackReference.h"
#include "AliHeader.h"
-#include "AliMC.h"
#include "AliStack.h"
-#include "AliMUON.h"
-#include "AliMUONRecoCheck.h"
-#include "AliMUONTrack.h"
-#include "AliMUONData.h"
-#include "AliMUONChamber.h"
-#include "AliMUONConstants.h"
+#include "AliTrackReference.h"
+#include "AliLog.h"
+#include <TParticle.h>
+
+/// \cond CLASSIMP
ClassImp(AliMUONRecoCheck)
+/// \endcond
//_____________________________________________________________________________
-AliMUONRecoCheck::AliMUONRecoCheck(Char_t *chLoader)
+ AliMUONRecoCheck::AliMUONRecoCheck(AliRunLoader *runloader, AliMUONData *muondata)
+ : TObject(),
+ fRunLoader(0x0),
+ fMUONData(0x0),
+ fMuonTrackRef(0x0),
+ fTrackReco(0x0),
+ fReconstructibleTracks(0),
+ fRecoTracks(0)
{
-// Constructor
+/// Constructor
+
fMuonTrackRef = new TClonesArray("AliMUONTrack", 10);
- // open the run loader
- fRunLoader = AliRunLoader::Open(chLoader);
+ // run loader
+ fRunLoader = runloader;
if (!fRunLoader) {
- AliError(Form("no run loader found in file %s","galice.root" ));
+ AliError(Form("no run loader found " ));
return;
}
- // initialize loader's
- AliLoader *loader = fRunLoader->GetLoader("MUONLoader");
-
- // initialize container
- fMUONData = new AliMUONData(loader,"MUON","MUON");
- // Loading AliRun master
- if (fRunLoader->GetAliRun() == 0x0) fRunLoader->LoadgAlice();
-
- fRunLoader->LoadKinematics("READ");
- fRunLoader->LoadTrackRefs("READ");
- loader->LoadTracks("READ");
+ // container
+ fMUONData = muondata;
+ if (!fMUONData) {
+ AliError(Form("no MUONData found " ));
+ return;
+ }
- fReconstructibleTracks = 0;
- fRecoTracks = 0;
}
+
//_____________________________________________________________________________
AliMUONRecoCheck::~AliMUONRecoCheck()
{
- fRunLoader->UnloadKinematics();
- fRunLoader->UnloadTrackRefs();
- fRunLoader->UnloadTracks();
+/// Destructor
+
+ fMuonTrackRef->Delete();
delete fMuonTrackRef;
- delete fMUONData;
}
//_____________________________________________________________________________
void AliMUONRecoCheck::MakeTrackRef()
{
- // Make reconstructible tracks
+/// Make reconstructible tracks
AliTrackReference *trackReference;
AliMUONTrack *muonTrack;
TBranch* branch = treeTR->GetBranch("MUON");
if (branch == NULL) return;
- TClonesArray* trackRefs = new TClonesArray("AliTrackReference", 10);
+ TClonesArray* trackRefs = 0;
branch->SetAddress(&trackRefs);
+ branch->SetAutoDelete(kTRUE);
- Int_t nTrackRef = (Int_t)treeTR->GetEntries();
+ Int_t nTrackRef = (Int_t)branch->GetEntries();
track = trackSave = -999;
Bool_t isNewTrack;
- Int_t iHitMin, iChamber;
+ Int_t iHitMin, iChamber, detElemId;
trackParam = new AliMUONTrackParam();
hitForRec = new AliMUONHitForRec();
muonTrack = new AliMUONTrack();
+ Int_t max = fRunLoader->GetHeader()->Stack()->GetNtrack();
for (Int_t iTrackRef = 0; iTrackRef < nTrackRef; iTrackRef++) {
- treeTR->GetEntry(iTrackRef);
+
+ branch->GetEntry(iTrackRef);
iHitMin = 0;
isNewTrack = kTRUE;
- if (!trackRefs->GetEntries()) continue;
-
- while (isNewTrack) {
+ if (!trackRefs->GetEntries()) continue;
+ while (isNewTrack) {
for (Int_t iHit = iHitMin; iHit < trackRefs->GetEntries(); iHit++) {
trackReference = (AliTrackReference*)trackRefs->At(iHit);
track = trackReference->GetTrack();
+ if(track >= max){
+ AliWarningStream()
+ << "Track ID " << track
+ << " larger than max number of particles " << max << endl;
+ isNewTrack = kFALSE;
+ break;
+ }
if (track != trackSave && iHit != 0) {
iHitMin = iHit;
trackSave = track;
trackParam->SetBendingCoor(y);
trackParam->SetNonBendingCoor(x);
trackParam->SetZ(z);
-
+
if (TMath::Abs(pZ) > 0) {
bendingSlope = pY/pZ;
nonBendingSlope = pX/pZ;
hitForRec->SetNonBendingCoor(x);
hitForRec->SetZ(z);
hitForRec->SetBendingReso2(0.0);
- hitForRec->SetNonBendingReso2(0.0);
- iChamber = ChamberNumber(z);
+ hitForRec->SetNonBendingReso2(0.0);
+ detElemId = hitForRec->GetDetElemId();
+ if (detElemId) iChamber = detElemId / 100 - 1;
+ else iChamber = AliMUONConstants::ChamberNumber(z);
hitForRec->SetChamberNumber(iChamber);
- muonTrack->AddTrackParamAtHit(trackParam);
+ muonTrack->AddTrackParamAtHit(trackParam,hitForRec);
muonTrack->AddHitForRecAtHit(hitForRec);
muonTrack->SetTrackID(track);
-
+
trackSave = track;
if (iHit == trackRefs->GetEntries()-1) isNewTrack = kFALSE;
}
-
+
// track parameters at vertex
particle = fRunLoader->GetHeader()->Stack()->Particle(muonTrack->GetTrackID());
+
if (particle) {
+
x = particle->Vx();
y = particle->Vy();
z = particle->Vz();
muonTrack->SetTrackParamAtVertex(trackParam);
}
-
+
AddMuonTrackReference(muonTrack);
muonTrack->ResetTrackParamAtHit();
muonTrack->ResetHitForRecAtHit();
} // end while isNewTrack
-
}
CleanMuonTrackRef();
delete muonTrack;
delete trackParam;
delete hitForRec;
- delete trackRefs;
}
//____________________________________________________________________________
TClonesArray* AliMUONRecoCheck::GetTrackReco()
{
- // Return TClonesArray of reconstructed tracks
+/// Return TClonesArray of reconstructed tracks
- GetMUONData()->SetTreeAddress("RT");
- fTrackReco = GetMUONData()->RecTracks();
- GetMUONData()->GetRecTracks();
+ fMUONData->ResetRecTracks();
+ fMUONData->SetTreeAddress("RT");
+ fTrackReco = fMUONData->RecTracks();
+ fMUONData->GetRecTracks();
fRecoTracks = fTrackReco->GetEntriesFast();
return fTrackReco;
}
//_____________________________________________________________________________
void AliMUONRecoCheck::PrintEvent() const
{
- // debug facility
+/// Debug facility
AliMUONTrack *track;
AliMUONHitForRec *hitForRec;
//_____________________________________________________________________________
void AliMUONRecoCheck::ResetTracks() const
{
+/// Reset tracks
+
if (fMuonTrackRef) fMuonTrackRef->Clear();
}
//_____________________________________________________________________________
void AliMUONRecoCheck::CleanMuonTrackRef()
{
- // Re-calculate hits parameters because two AliTrackReferences are recorded for
- // each chamber (one when particle is entering + one when particle is leaving
- // the sensitive volume)
+/// Re-calculate hits parameters because two AliTrackReferences are recorded for
+/// each chamber (one when particle is entering + one when particle is leaving
+/// the sensitive volume)
Float_t maxGasGap = 1.; // cm
AliMUONTrack *track, *trackNew;
Float_t bendingSlope2,nonBendingSlope2,bendingMomentum2;
TClonesArray *newMuonTrackRef = new TClonesArray("AliMUONTrack", 10);
Int_t iHit1;
- Int_t iChamber = 0;
+ Int_t iChamber = 0, detElemId = 0;
Int_t nRec = 0;
Int_t nTrackHits = 0;
trackNew = new AliMUONTrack();
Int_t nTrackRef = fMuonTrackRef->GetEntriesFast();
-
for (Int_t index = 0; index < nTrackRef; index++) {
track = (AliMUONTrack*)fMuonTrackRef->At(index);
hitForRecAtHit = track->GetHitForRecAtHit();
zRec = zRec1;
bendingSlope1 = trackParam1->GetBendingSlope();
nonBendingSlope1 = trackParam1->GetNonBendingSlope();
- bendingMomentum1 = 1./trackParam1->GetInverseBendingMomentum();
+ bendingMomentum1 = 0;
+ if (TMath::Abs(trackParam1->GetInverseBendingMomentum()) > 0)
+ bendingMomentum1 = 1./trackParam1->GetInverseBendingMomentum();
bendingSlope = bendingSlope1;
nonBendingSlope = nonBendingSlope1;
bendingMomentum = bendingMomentum1;
zRec2 = hitForRec2->GetZ();
bendingSlope2 = trackParam2->GetBendingSlope();
nonBendingSlope2 = trackParam2->GetNonBendingSlope();
- bendingMomentum2 = 1./trackParam2->GetInverseBendingMomentum();
+ bendingMomentum2 = 0;
+ if (TMath::Abs(trackParam2->GetInverseBendingMomentum()) > 0)
+ bendingMomentum2 = 1./trackParam2->GetInverseBendingMomentum();
if ( TMath::Abs(zRec2-zRec1) < maxGasGap ) {
+
nRec++;
xRec += xRec2;
yRec += yRec2;
hitForRec->SetNonBendingCoor(xRec);
hitForRec->SetBendingCoor(yRec);
hitForRec->SetZ(zRec);
- iChamber = ChamberNumber(zRec);
+ detElemId = hitForRec->GetDetElemId();
+ if (detElemId) iChamber = detElemId / 100 - 1;
+ else iChamber = AliMUONConstants::ChamberNumber(zRec);
hitForRec->SetChamberNumber(iChamber);
hitForRec->SetBendingReso2(0.0);
hitForRec->SetNonBendingReso2(0.0);
trackParam->SetZ(zRec);
trackParam->SetNonBendingSlope(nonBendingSlope);
trackParam->SetBendingSlope(bendingSlope);
- trackParam->SetInverseBendingMomentum(1./bendingMomentum);
+ if (TMath::Abs(bendingMomentum) > 0)
+ trackParam->SetInverseBendingMomentum(1./bendingMomentum);
trackNew->AddHitForRecAtHit(hitForRec);
- trackNew->AddTrackParamAtHit(trackParam);
+ trackNew->AddTrackParamAtHit(trackParam,hitForRec);
iHit1++;
} // end iHit1
delete trackNew;
delete hitForRec;
delete trackParam;
+ newMuonTrackRef->Delete();
delete newMuonTrackRef;
}
//_____________________________________________________________________________
void AliMUONRecoCheck::ReconstructibleTracks()
{
- // calculate the number of reconstructible tracks
+/// Calculate the number of reconstructible tracks
AliMUONTrack* track;
TClonesArray* hitForRecAtHit = NULL;
iChamber = hitForRec->GetChamberNumber();
if (iChamber < 0 || iChamber > 10) continue;
isChamberInTrack[iChamber] = 1;
-
- }
- // track is reconstructible if the particle is crossing every tracking chambers
+ }
+ // track is reconstructible if the particle is depositing a hit
+ // in the following chamber combinations:
+
isTrackOK = kTRUE;
- for (Int_t ch = 0; ch < 10; ch++) {
- if (!isChamberInTrack[ch]) isTrackOK = kFALSE;
- }
+ if (!isChamberInTrack[0] && !isChamberInTrack[1]) isTrackOK = kFALSE;
+ if (!isChamberInTrack[2] && !isChamberInTrack[3]) isTrackOK = kFALSE;
+ if (!isChamberInTrack[4] && !isChamberInTrack[5]) isTrackOK = kFALSE;
+ Int_t nHitsInLastStations=0;
+ for (Int_t ch = 6; ch < AliMUONConstants::NTrackingCh(); ch++)
+ if (isChamberInTrack[ch]) nHitsInLastStations++;
+ if(nHitsInLastStations < 3) isTrackOK = kFALSE;
+
if (isTrackOK) fReconstructibleTracks++;
if (!isTrackOK) fMuonTrackRef->Remove(track); // remove non reconstructible tracks
}
fMuonTrackRef->Compress();
}
-
-//_____________________________________________________________________________
-Int_t AliMUONRecoCheck::ChamberNumber(Float_t z) const
-{
- // return chamber number according z position of hit. Should be taken from geometry ?
-
- Float_t dMaxChamber = AliMUONConstants::DzSlat() + AliMUONConstants::DzCh() + 0.25; // cm st 3 &4 & 5
- if ( z > (AliMUONConstants::DefaultChamberZ(4)+50.)) dMaxChamber = 7.; // cm stations 1 & 2
- Int_t iChamber;
-
- for (iChamber = 0; iChamber < 10; iChamber++) {
-
- if (TMath::Abs(z-AliMUONConstants::DefaultChamberZ(iChamber)) < dMaxChamber) {
- return iChamber;
- }
- }
- return -1;
-}