///
TObject::Copy(obj);
AliMUONCluster& dest = static_cast<AliMUONCluster&>(obj);
+ delete dest.fPads;
dest.fPads = 0x0;
if ( fPads )
{
// pre-cluster and treat it
fPreCluster = fPreClusterFinder->NextCluster();
-
+
+ fClusterList.Delete(); // reset the list of clusters for this pre-cluster
+ fClusterNumber = -1; //AZ
+
if (!fPreCluster)
{
// we are done
return 0x0;
}
- fClusterList.Delete(); // reset the list of clusters for this pre-cluster
- fClusterNumber = -1; //AZ
-
WorkOnPreCluster();
// WorkOnPreCluster may have used only part of the pads, so we check that
/// Remove a cluster
AliMUONVCluster* c = static_cast<AliMUONVCluster*>(fClusters->Remove(&cluster));
- if (c) {
+ if (c)
+ {
fClusters->Compress();
fMapped = kFALSE;
}
+ else
+ {
+ AliError("Could not remove cluster from array");
+ }
return c;
}
// Create (or clear) the TClonesArray of map
Int_t nChamber = AliMpConstants::NofTrackingChambers();
- if (!fMap) fMap = new TClonesArray("AliMpExMap",nChamber);
- else fMap->Clear("C");
- // Create one map per chamber
- AliMpExMap *map;
- for (Int_t chamber=0; chamber<nChamber; chamber++) {
- map = new((*fMap)[chamber]) AliMpExMap(kTRUE);
- map->SetOwner(kFALSE);
+ if (!fMap) {
+ fMap = new TClonesArray("AliMpExMap",nChamber);
+
+ // Create one map per chamber
+ AliMpExMap *map;
+ for (Int_t chamber=0; chamber<nChamber; chamber++) {
+ map = new((*fMap)[chamber]) AliMpExMap(kTRUE);
+ map->SetOwner(kFALSE);
+ }
}
-
+ else {
+ for (Int_t chamber=0; chamber<nChamber; chamber++) {
+ AliMpExMap *map = static_cast<AliMpExMap *>(fMap->At(chamber));
+ map->Clear("C");
+ }
+ }
+
// Fill the maps
TIter next(fClusters);
AliMUONVCluster* cluster;
#include "AliMpConstants.h"
#include "AliMpExMap.h"
#include "AliMpCDB.h"
+#include "AliMpArea.h"
+#include <float.h>
+#include "AliMpVPadIterator.h"
+#include "AliMpPad.h"
+#include "AliMpDEIterator.h"
+#include <TVector2.h>
+#include "AliMpVSegmentation.h"
+#include "AliMpSegmentation.h"
#include "AliLog.h"
#include "AliAlignObjMatrix.h"
: TObject(),
fDetectorName(fgkDefaultDetectorName),
fModuleTransformers(0),
- fMisAlignArray(0)
+ fMisAlignArray(0),
+ fDEAreas(0x0)
{
/// Standard constructor
: TObject(),
fDetectorName(),
fModuleTransformers(0),
- fMisAlignArray(0)
+ fMisAlignArray(0),
+ fDEAreas(0x0)
{
/// Default constructor
}
delete fModuleTransformers;
delete fMisAlignArray;
+ delete fDEAreas;
}
//
// private methods
//
+
+//_____________________________________________________________________________
+AliMpArea*
+AliMUONGeometryTransformer::GetDEArea(Int_t detElemId) const
+{
+ /// Get area (in global coordinates) covered by a given detection element
+ if (!fDEAreas)
+ {
+ CreateDEAreas();
+ }
+ return static_cast<AliMpArea*>(fDEAreas->GetValue(detElemId));
+}
+
+//_____________________________________________________________________________
+void
+AliMUONGeometryTransformer::CreateDEAreas() const
+{
+ /// Create DE areas
+
+ fDEAreas = new AliMpExMap(true);
+
+ AliMpDEIterator it;
+
+ it.First();
+
+ /// Generate the DE areas in global coordinates
+
+ while ( !it.IsDone() )
+ {
+ Int_t detElemId = it.CurrentDEId();
+
+ if ( !HasDE(detElemId) ) continue;
+
+ const AliMpVSegmentation* seg = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath0);
+
+ Double_t xg,yg,zg;
+
+ AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
+
+ Double_t xl(0.0), yl(0.0), zl(0.0);
+ Double_t dx(seg->Dimensions().X());
+ Double_t dy(seg->Dimensions().Y());
+
+ if ( stationType == AliMp::kStation1 || stationType == AliMp::kStation2 )
+ {
+ Double_t xmin(FLT_MAX);
+ Double_t xmax(-FLT_MAX);
+ Double_t ymin(FLT_MAX);
+ Double_t ymax(-FLT_MAX);
+
+ for ( Int_t icathode = 0; icathode < 2; ++icathode )
+ {
+ const AliMpVSegmentation* cathode
+ = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::GetCathodType(icathode));
+
+ AliMpVPadIterator* it = cathode->CreateIterator();
+
+ it->First();
+
+ while ( !it->IsDone() )
+ {
+ AliMpPad pad = it->CurrentItem();
+ AliMpArea a(pad.Position(),pad.Dimensions());
+ xmin = TMath::Min(xmin,a.LeftBorder());
+ xmax = TMath::Max(xmax,a.RightBorder());
+ ymin = TMath::Min(ymin,a.DownBorder());
+ ymax = TMath::Max(ymax,a.UpBorder());
+ it->Next();
+ }
+
+ delete it;
+ }
+
+ xl = (xmin+xmax)/2.0;
+ yl = (ymin+ymax)/2.0;
+ dx = (xmax-xmin)/2.0;
+ dy = (ymax-ymin)/2.0;
+
+ Local2Global(detElemId,xl,yl,zl,xg,yg,zg);
+ }
+ else
+ {
+ Local2Global(detElemId,xl,yl,zl,xg,yg,zg);
+ }
+
+ fDEAreas->Add(detElemId,new AliMpArea(TVector2(xg,yg),TVector2(dx,dy)));
+
+ it.Next();
+ }
+}
+
//_____________________________________________________________________________
Bool_t AliMUONGeometryTransformer::LoadMapping() const
{
class TGeoManager;
class TClonesArray;
+class AliMpExMap;
+class AliMpArea;
class AliMUONGeometryTransformer : public TObject
{
Bool_t HasDE(Int_t detElemId) const;
+ AliMpArea* GetDEArea(Int_t detElemId) const;
+
protected:
/// Not implemented
AliMUONGeometryTransformer(const AliMUONGeometryTransformer& right);
private:
// methods
+
+ void CreateDEAreas() const;
+
Bool_t LoadMapping() const;
AliMUONGeometryModuleTransformer* GetModuleTransformerNonConst(
Int_t index, Bool_t warn = true) const;
TString fDetectorName; ///< Detector name
TObjArray* fModuleTransformers; ///< array of module transformers
TClonesArray* fMisAlignArray; ///< array of misalignment data
-
- ClassDef(AliMUONGeometryTransformer,3) // Geometry parametrisation
+ mutable AliMpExMap* fDEAreas; ///< areas of detection elements in global coordinates
+
+ ClassDef(AliMUONGeometryTransformer,4) // Geometry parametrisation
};
// inline methods
--- /dev/null
+/**************************************************************************
+* 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. *
+**************************************************************************/
+
+// $Id$
+
+/// \class AliMUONLegacyClusterServer
+///
+/// Special implementation of AliMUONVClusterServer, which will only return
+/// clusters from a pre-defined cluster store.
+///
+/// Made to recover the old (i.e. before introduction of VClusterServer) behavior
+/// of the MUON recontruction where rec points were always written to TreeR,
+/// and then the tracking picked them from that tree, in order to have the
+/// possibility to save full rec points (for debugging the spectro, mainly, should
+/// not be an option used during final production).
+///
+/// \author Laurent Aphecetche, Subatech
+///
+
+#include "AliMUONLegacyClusterServer.h"
+
+#include "AliCodeTimer.h"
+#include "AliLog.h"
+#include "AliMUONGeometryTransformer.h"
+#include "AliMUONTriggerTrackToTrackerClusters.h"
+#include "AliMUONVCluster.h"
+#include "AliMUONVClusterStore.h"
+#include "AliMpArea.h"
+#include <TCollection.h>
+
+/// \cond CLASSIMP
+ClassImp(AliMUONLegacyClusterServer)
+/// \endcond
+
+//_____________________________________________________________________________
+AliMUONLegacyClusterServer::AliMUONLegacyClusterServer(const AliMUONGeometryTransformer& transformer, AliMUONVClusterStore* store)
+: AliMUONVClusterServer(), fTransformer(transformer), fClusterStore(store), fTriggerTrackStore(0x0),
+fBypass(0x0)
+{
+ /// ctor. Mode Read : we'll only server clusters from existing store
+}
+
+//_____________________________________________________________________________
+AliMUONLegacyClusterServer::~AliMUONLegacyClusterServer()
+{
+ /// dtor
+ delete fBypass;
+}
+
+//_____________________________________________________________________________
+Int_t
+AliMUONLegacyClusterServer::Clusterize(Int_t chamberId,
+ AliMUONVClusterStore& clusterStore,
+ const AliMpArea& /*area*/)
+{
+ /// Fills clusterStore with clusters in given chamber
+ ///
+ /// Return the number of clusters added to clusterStore
+
+ AliCodeTimerAuto(Form("Chamber %d",chamberId));
+
+ if ( fBypass && chamberId >= 6 )
+ {
+ return fBypass->GenerateClusters(chamberId,clusterStore);
+ }
+
+ AliDebug(1,Form("chamberId=%d fClusterStore(%p).GetSize()=%d clusterStore(%p).GetSize()=%d",
+ chamberId,
+ fClusterStore,fClusterStore->GetSize(),
+ &clusterStore,clusterStore.GetSize()));
+
+ TIter next(fClusterStore->CreateChamberIterator(chamberId,chamberId));
+ AliMUONVCluster* cluster;
+ Int_t n(0);
+ TObjArray a;
+
+ while ( ( cluster = static_cast<AliMUONVCluster*>(next()) ) )
+ {
+ clusterStore.Add(*cluster);
+ a.Add(cluster);
+ ++n;
+ }
+
+ TIter remove(&a);
+ while ( ( cluster = static_cast<AliMUONVCluster*>(remove()) ) )
+ {
+ fClusterStore->Remove(*cluster);
+ }
+
+ AliDebug(1,Form("n=%d remaining clusters=%d",n,fClusterStore->GetSize()));
+
+ return n;
+}
+
+//_____________________________________________________________________________
+Bool_t
+AliMUONLegacyClusterServer::UseTriggerTrackStore(AliMUONVTriggerTrackStore* trackStore)
+{
+ /// Tells us to use trigger track store, and thus to bypass St45 clusters
+ fTriggerTrackStore = trackStore; // not owner
+ delete fBypass;
+ fBypass = new AliMUONTriggerTrackToTrackerClusters(fTransformer,fTriggerTrackStore);
+ return kTRUE;
+}
+
+//_____________________________________________________________________________
+void
+AliMUONLegacyClusterServer::UseDigits(TIter&)
+{
+ /// Give the iterator to our delegate if we have one, of issue and error
+
+ AliError("Not implemented for this class, as we're not writing clusters, but reading them instead !");
+}
+
--- /dev/null
+#ifndef ALIMUONLEGACYCLUSTERSERVER_H
+#define ALIMUONLEGACYCLUSTERSERVER_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice */
+
+// $Id$
+
+/// \ingroup rec
+/// \class AliMUONLegacyClusterServer
+/// \brief Cluster server that always clusterize everything.
+///
+// Author Laurent Aphecetche, Subatech
+
+#ifndef ALIMUONVCLUSTERSERVER_H
+# include "AliMUONVClusterServer.h"
+#endif
+
+class AliMUONTriggerTrackToTrackerClusters;
+class AliMUONVClusterStore;
+class AliMUONGeometryTransformer;
+
+class AliMUONLegacyClusterServer : public AliMUONVClusterServer
+{
+public:
+ AliMUONLegacyClusterServer(const AliMUONGeometryTransformer& transformer, AliMUONVClusterStore* store=0x0);
+
+ virtual ~AliMUONLegacyClusterServer();
+
+ virtual Int_t Clusterize(Int_t chamberId,
+ AliMUONVClusterStore& clusterStore,
+ const AliMpArea& area);
+
+ virtual void UseDigits(TIter& next);
+
+ /// Use trigger tracks. Return kFALSE if not used.
+ virtual Bool_t UseTriggerTrackStore(AliMUONVTriggerTrackStore* trackStore);
+
+private:
+ /// not defined
+ AliMUONLegacyClusterServer(const AliMUONLegacyClusterServer& rhs);
+ /// not defined
+ AliMUONLegacyClusterServer& operator=(const AliMUONLegacyClusterServer& rhs);
+
+ const AliMUONGeometryTransformer& fTransformer; //<! geometry convertor
+ AliMUONVClusterStore* fClusterStore; //<! cluster store
+ AliMUONVTriggerTrackStore* fTriggerTrackStore; //<! trigger track store
+ AliMUONTriggerTrackToTrackerClusters* fBypass; //<! bypass
+
+ ClassDef(AliMUONLegacyClusterServer,1) // Implementation of AliMUONVClusterServer
+};
+
+#endif
UInt_t *digitsIdNew = new UInt_t[fNDigits+1];
memcpy(digitsIdNew,fDigitsId, fNDigits*sizeof(UInt_t));
digitsIdNew[fNDigits++] = id;
- delete fDigitsId;
+ delete[] fDigitsId;
fDigitsId = digitsIdNew;
}
fTrackingMode("KALMAN"),
fMinBendingMomentum(0.),
fMaxBendingMomentum(0.),
+ fMaxNonBendingSlope(0.),
fNonBendingVertexDispersion(0.),
fBendingVertexDispersion(0.),
fMaxNonBendingDistanceToTrack(0.),
fTrackAllTracks(kFALSE),
fRecoverTracks(kFALSE),
fMakeTrackCandidatesFast(kFALSE),
+ fMakeMoreTrackCandidates(kFALSE),
fComplementTracks(kFALSE),
fImproveTracks(kFALSE),
fUseSmoother(kFALSE),
fSaveFullClusterInESD(kTRUE),
- fCalibrationMode("NOGAIN")
+ fCalibrationMode("NOGAIN"),
+ fBypassSt45(kFALSE)
{
/// Constructor
SetNameTitle("MUON","MUON");
/// Destructor
}
+//_____________________________________________________________________________
+Option_t*
+AliMUONRecoParam::GetCalibrationMode() const
+{
+ /// Return the calibration mode. Can be :
+ /// NOGAIN : only do pedestal subtraction
+ /// GAIN : do pedestal subtraction, and apply gain correction, but with a
+ /// single capacitance value for all channels
+ /// GAINCONSTANTCAPA : as GAIN, but with a channel-dependent capacitance value
+
+ return fCalibrationMode.Data();
+}
+
//_____________________________________________________________________________
AliMUONRecoParam *AliMUONRecoParam::GetLowFluxParam()
{
{
/// Set reconstruction parameters for low flux environment
- fMinBendingMomentum = 0.5;
+ fMinBendingMomentum = 1.;
fMaxBendingMomentum = 3000.;
+ fMaxNonBendingSlope = 0.3;
fNonBendingVertexDispersion = 10.;
fBendingVertexDispersion = 10.;
- fMaxNonBendingDistanceToTrack = 2.;
- fMaxBendingDistanceToTrack = 2.;
+ fMaxNonBendingDistanceToTrack = 1.;
+ fMaxBendingDistanceToTrack = 1.;
fSigmaCutForTracking = 6.;
fSigmaCutForImprovement = 5.;
fSigmaCutForTrigger = 8.;
fTrackAllTracks = kTRUE;
fRecoverTracks = kTRUE;
fMakeTrackCandidatesFast = kFALSE;
+ fMakeMoreTrackCandidates = kFALSE;
fComplementTracks = kTRUE;
fImproveTracks = kTRUE;
fUseSmoother = kTRUE;
+ for (Int_t iCh = 0; iCh < 10; iCh++) fUseChamber[iCh] = kTRUE;
+ for (Int_t iSt = 0; iSt < 5; iSt++) fRequestStation[iSt] = kTRUE;
}
{
/// Set reconstruction parameters for high flux environment
- fMinBendingMomentum = 0.5;
+ fMinBendingMomentum = 1.;
fMaxBendingMomentum = 3000.;
+ fMaxNonBendingSlope = 0.3;
fNonBendingVertexDispersion = 10.;
fBendingVertexDispersion = 10.;
- fMaxNonBendingDistanceToTrack = 2.;
- fMaxBendingDistanceToTrack = 2.;
+ fMaxNonBendingDistanceToTrack = 1.;
+ fMaxBendingDistanceToTrack = 1.;
fSigmaCutForTracking = 6.;
fSigmaCutForImprovement = 5.;
fSigmaCutForTrigger = 8.;
fTrackAllTracks = kTRUE;
fRecoverTracks = kTRUE;
fMakeTrackCandidatesFast = kFALSE;
+ fMakeMoreTrackCandidates = kFALSE;
fComplementTracks = kTRUE;
fImproveTracks = kTRUE;
fUseSmoother = kTRUE;
+ for (Int_t iCh = 0; iCh < 10; iCh++) fUseChamber[iCh] = kTRUE;
+ for (Int_t iSt = 0; iSt < 5; iSt++) fRequestStation[iSt] = kTRUE;
}
cout<<Form("Calibration mode = %s",fCalibrationMode.Data())<<endl;
cout<<Form("Clustering mode = %s",fClusteringMode.Data())<<endl;
-
cout<<Form("Tracking mode = %s",fTrackingMode.Data())<<endl;
+
+ if (BypassSt45()) cout << "Will bypass St45 (replacing their clusters by generated ones from trigger tracks)" << endl;
if (fCombinedClusterTrackReco) cout<<"Combined cluster/track reconstruction: ON"<<endl;
else cout<<"Combined cluster/track reconstruction: OFF"<<endl;
cout<<Form("Bending momentum range = [%5.2f,%5.2f]",fMinBendingMomentum,fMaxBendingMomentum)<<endl;
+ cout<<Form("Maximum non bending slope = %5.2f",fMaxNonBendingSlope)<<endl;
+
if (strstr(fTrackingMode,"ORIGINAL"))
cout<<Form("Vertex dispertion = (%5.2f,%5.2f)",fNonBendingVertexDispersion,fBendingVertexDispersion)<<endl;
else if (strstr(option,"FULL"))
} else if (fMakeTrackCandidatesFast)
cout<<"Make track candidates assuming linear propagation between stations 4 and 5"<<endl;
+ if (strstr(option,"FULL")) {
+ cout<<"Make track candidates starting from 1 cluster in each of the stations 4 and 5: ";
+ if (fMakeMoreTrackCandidates) cout<<"ON"<<endl;
+ else cout<<"OFF"<<endl;
+ } else if (fMakeMoreTrackCandidates)
+ cout<<"Make track candidates starting from 1 cluster in each of the stations 4 and 5"<<endl;
+
if (strstr(option,"FULL")) {
cout<<"Try to recover tracks getting lost during tracking: ";
if (fRecoverTracks) cout<<"ON"<<endl;
cout<<Form("Maximum normalized chi2 of tracking/trigger track matching = %5.2f",fMaxNormChi2MatchTrigger)<<endl;
+ Bool_t discardedCh = kFALSE;
+ Int_t ch = 0;
+ do {
+ if (!UseChamber(ch)) {
+ if (!discardedCh) {
+ cout<<"Discarded chambers(1..): "<<ch+1;
+ discardedCh = kTRUE;
+ }
+ else cout<<" "<<ch+1;
+ }
+ } while (++ch < 10);
+ if (discardedCh) cout<<endl;
+
+ Bool_t discardedSt = kFALSE;
+ Int_t st = 0;
+ do {
+ if (!RequestStation(st)) {
+ if (!discardedSt) {
+ cout<<"Not requested stations(1..): "<<st+1;
+ discardedSt = kTRUE;
+ }
+ else cout<<" "<<st+1;
+ }
+ } while (++st < 5);
+ if (discardedSt) cout<<endl;
+
+
cout<<"\t-------------------------------------"<<endl<<endl;
}
static AliMUONRecoParam *GetLowFluxParam();
static AliMUONRecoParam *GetHighFluxParam();
- /// set the calibration mode
+ /// set the calibration mode (see GetCalibrationMode() for possible modes)
void SetCalibrationMode(Option_t* mode) { fCalibrationMode = mode; fCalibrationMode.ToUpper();}
- /// get the calibration mode
- Option_t* GetCalibrationMode() const { return fCalibrationMode.Data(); }
-
+
+ Option_t* GetCalibrationMode() const;
+
/// set the clustering (pre-clustering) mode
void SetClusteringMode(Option_t* mode) {fClusteringMode = mode; fClusteringMode.ToUpper();}
/// get the clustering (pre-clustering) mode
void SetMaxBendingMomentum(Double_t val) {fMaxBendingMomentum = val;}
/// return the maximum value (GeV/c) of momentum in bending plane
Double_t GetMaxBendingMomentum() const {return fMaxBendingMomentum;}
+ /// set the maximum value of the non bending slope
+ void SetMaxNonBendingSlope(Double_t val) {fMaxNonBendingSlope = val;}
+ /// return the maximum value of the non bending slope
+ Double_t GetMaxNonBendingSlope() const {return fMaxNonBendingSlope;}
/// set the vertex dispersion (cm) in non bending plane (used for original tracking only)
void SetNonBendingVertexDispersion(Double_t val) {fNonBendingVertexDispersion = val;}
/// return kTRUE/kFALSE if the fast building of track candidates is switched on/off
Bool_t MakeTrackCandidatesFast() const {return fMakeTrackCandidatesFast;}
+ /// switch on/off the building of track candidates starting from 1 cluster in each of the stations 4 and 5
+ void MakeMoreTrackCandidates(Bool_t flag) {fMakeMoreTrackCandidates = flag;}
+ /// return kTRUE/kFALSE if the building of extra track candidates is switched on/off
+ Bool_t MakeMoreTrackCandidates() const {return fMakeMoreTrackCandidates;}
+
/// switch on/off the completion of reconstructed track
void ComplementTracks(Bool_t flag) {fComplementTracks = flag;}
/// return kTRUE/kFALSE if completion of the reconstructed track is switched on/off
/// return kTRUE/kFALSE if the use of the smoother is switched on/off
Bool_t UseSmoother() const {return fUseSmoother;}
- virtual void Print(Option_t *option = "") const;
+ /// switch on/off a chamber in the reconstruction
+ void UseChamber(Int_t iCh, Bool_t flag) {if (iCh >= 0 && iCh < 10) fUseChamber[iCh] = flag;}
+ /// return kTRUE/kFALSE whether the chamber must be used or not
+ Bool_t UseChamber(Int_t iCh) const {return (iCh >= 0 && iCh < 10) ? fUseChamber[iCh] : kFALSE;}
+
+ /// request or not at least one cluster in the station to validate the track
+ void RequestStation(Int_t iSt, Bool_t flag) {if (iSt >= 0 && iSt < 5) fRequestStation[iSt] = flag;}
+ /// return kTRUE/kFALSE whether at least one cluster is requested in the station to validate the track
+ Bool_t RequestStation(Int_t iSt) const {return (iSt >= 0 && iSt < 5) ? fRequestStation[iSt] : kFALSE;}
+
+ /// return kTRUE if we should replace clusters in St 4 and 5 by generated clusters from trigger tracks
+ Bool_t BypassSt45() const { return fBypassSt45; }
+ /// set the bypassSt45 value
+ void BypassSt45(Bool_t value) { fBypassSt45 = value; }
+
+ virtual void Print(Option_t *option = "") const;
private:
Double32_t fMinBendingMomentum; ///< minimum value (GeV/c) of momentum in bending plane
Double32_t fMaxBendingMomentum; ///< maximum value (GeV/c) of momentum in bending plane
+ Double32_t fMaxNonBendingSlope; ///< maximum value of the non bending slope
Double32_t fNonBendingVertexDispersion; ///< vertex dispersion (cm) in non bending plane (used for original tracking only)
Double32_t fBendingVertexDispersion; ///< vertex dispersion (cm) in bending plane (used for original tracking only)
Bool_t fMakeTrackCandidatesFast; ///< kTRUE to make candidate tracks assuming linear propagation between stations 4 and 5
+ Bool_t fMakeMoreTrackCandidates; ///< kTRUE to make candidate tracks starting from 1 cluster in each of the stations 4 and 5
+
Bool_t fComplementTracks; ///< kTRUE to try to complete the reconstructed tracks by adding missing clusters
Bool_t fImproveTracks; ///< kTRUE to try to improve the reconstructed tracks by removing bad clusters
Bool_t fSaveFullClusterInESD; ///< kTRUE to save all cluster info (including pads) in ESD
- /// calibration mode: GAIN, NOGAIN
+ /// calibration mode: GAIN, NOGAIN, GAINCONSTANTCAPA
TString fCalibrationMode; ///<\brief calibration mode
+ Bool_t fBypassSt45; ///< kTRUE to use trigger tracks to generate "fake" clusters in St 4 and 5
+
+ Bool_t fUseChamber[10]; ///< kTRUE to use the chamber i in the tracking algorithm
+
+ Bool_t fRequestStation[5]; ///< kTRUE to request at least one cluster in station i to validate the track
+
// functions
void SetLowFluxParam();
void SetHighFluxParam();
- ClassDef(AliMUONRecoParam,2) // MUON reco parameters
+ ClassDef(AliMUONRecoParam,3) // MUON reco parameters
};
#endif
#include "AliMUONClusterFinderSimpleFit.h"
#include "AliMUONClusterFinderPeakCOG.h"
#include "AliMUONClusterFinderPeakFit.h"
+#include "AliMUONClusterStoreV1.h"
+#include "AliMUONClusterStoreV2.h"
#include "AliMUONConstants.h"
#include "AliMUONDigitCalibrator.h"
#include "AliMUONDigitMaker.h"
CreateTriggerCircuit();
CreateDigitMaker();
CreateClusterServer();
+
+ AliMUONTracker* tracker(0x0);
- if (!fClusterServer)
+ if ( ! AliMUONReconstructor::GetRecoParam()->CombineClusterTrackReco() )
{
- AliError("ClusterServer is NULL ! Cannot create tracker");
- return 0x0;
+ tracker = new AliMUONTracker(0x0,
+ *DigitStore(),
+ fDigitMaker,
+ fTransformer,
+ fTriggerCircuit);
+ }
+ else
+ {
+ tracker = new AliMUONTracker(fClusterServer,
+ *DigitStore(),
+ fDigitMaker,
+ fTransformer,
+ fTriggerCircuit);
}
- AliMUONTracker* tracker = new AliMUONTracker(*fClusterServer,
- *DigitStore(),
- fDigitMaker,
- fTransformer,
- fTriggerCircuit);
return tracker;
}
//_____________________________________________________________________________
AliMUONVClusterFinder*
-AliMUONReconstructor::CreateClusterFinder(const char* clusterFinderType) const
+AliMUONReconstructor::CreateClusterFinder(const char* clusterFinderType)
{
/// Create a given cluster finder instance
- AliCodeTimerAuto("")
+ AliCodeTimerAutoGeneral("")
AliMUONVClusterFinder* clusterFinder(0x0);
}
else
{
- AliError(Form("clustering mode \"%s\" does not exist",opt.Data()));
+ AliErrorClass(Form("clustering mode \"%s\" does not exist",opt.Data()));
return 0x0;
}
if ( fClusterServer ) return;
- AliCodeTimerAuto("")
-
- AliDebug(1,"");
-
+ AliCodeTimerAuto("");
+
AliMUONVClusterFinder* clusterFinder = CreateClusterFinder(GetRecoParam()->GetClusteringMode());
if ( !clusterFinder ) return;
AliInfo(Form("Will use %s for clusterizing",clusterFinder->ClassName()));
- fClusterServer = new AliMUONSimpleClusterServer(*clusterFinder,*fTransformer);
+ fClusterServer = new AliMUONSimpleClusterServer(clusterFinder,*fTransformer);
}
//_____________________________________________________________________________
AliDebug(1,"");
Bool_t ok(kFALSE);
+ Bool_t alone(kTRUE); // is trigger the only info in TreeR ?
+
+ if ( ! AliMUONReconstructor::GetRecoParam()->CombineClusterTrackReco() )
+ {
+ alone = kFALSE; // we'll get both tracker and trigger information in TreeR
+ }
+
if ( triggerStore )
{
- ok = triggerStore->Connect(clustersTree,kTRUE);
+ ok = triggerStore->Connect(clustersTree,alone);
if (!ok)
{
AliError("Could not create triggerStore branches in TreeR");
}
}
+
+ AliMUONVClusterStore* clusterStore(0x0);
+ if ( !alone )
+ {
+ clusterStore = new AliMUONClusterStoreV2;
+
+ CreateClusterServer();
+
+ TIter next(DigitStore()->CreateIterator());
+ fClusterServer->UseDigits(next);
+
+ AliMpArea area;
+
+ AliDebug(1,Form("Doing full clusterization in local reconstruction using %s ",fClusterServer->ClassName()));
+
+ for ( Int_t i = 0; i < AliMpConstants::NofTrackingChambers(); ++i )
+ {
+ if (AliMUONReconstructor::GetRecoParam()->UseChamber(i))
+ {
+ if ( i >= 6 && AliMUONReconstructor::GetRecoParam()->BypassSt45() ) continue;
+
+ fClusterServer->Clusterize(i,*clusterStore,area);
+ }
+ }
+
+ Bool_t cok = clusterStore->Connect(clustersTree,alone);
+
+ if (!cok) AliError("Could not connect clusterStore to clusterTree");
+
+ AliDebug(1,Form("Number of clusters found = %d",clusterStore->GetSize()));
+
+ StdoutToAliDebug(1,clusterStore->Print());
+ }
+
if (ok) // at least one type of branches created successfully
{
clustersTree.Fill();
}
+
+ delete clusterStore;
}
//_____________________________________________________________________________
static const AliMUONRecoParam* GetRecoParam();
+ static AliMUONVClusterFinder* CreateClusterFinder(const char* clusterFinderType);
+
private:
/// Not implemented
AliMUONReconstructor(const AliMUONReconstructor&);
void Calibrate(AliMUONVDigitStore& digitStore) const;
AliMUONTriggerCrateStore* CrateManager() const;
void CreateCalibrator() const;
- AliMUONVClusterFinder* CreateClusterFinder(const char* clusterFinderType) const;
void CreateDigitMaker() const;
void CreateTriggerCircuit() const;
void CreateClusterServer() const;
AliMUONVDigitStore* DigitStore() const;
AliMUONVTriggerStore* TriggerStore() const;
-
+
private:
mutable AliMUONTriggerCrateStore* fCrateManager; //!< Trigger Crate manager
mutable AliMUONDigitMaker* fDigitMaker; //!< Raw to Digits converter
static AliMUONRecoParam* fgRecoParam; //!< parameters used to tune the MUON reconstruction
- ClassDef(AliMUONReconstructor,5) // Implementation of AliReconstructor
+ ClassDef(AliMUONReconstructor,6) // Implementation of AliReconstructor
};
#endif
#include "AliMUONVClusterStore.h"
#include "AliMUONVTrackStore.h"
#include "AliMUONTrack.h"
-
+#include "AliMUONTracker.h"
#include "AliLog.h"
//-----------------------------------------------------------------------------
/// Default constructor
CreateGeometryTransformer();
CreateClusterServer(*fGeometryTransformer);
- if (fClusterServer) CreateTrackReconstructor(*fClusterServer);
+ if (fClusterServer) AliMUONTracker::CreateTrackReconstructor(AliMUONReconstructor::GetRecoParam()->GetTrackingMode(),fClusterServer);
if (!fClusterServer || !fTracker) {
AliFatal("refitter initialization failed");
exit(-1);
void AliMUONRefitter::CreateClusterServer(AliMUONGeometryTransformer& transformer)
{
/// Create cluster server
- AliMUONVClusterFinder* clusterFinder = CreateClusterFinder();
- fClusterServer = clusterFinder ? new AliMUONSimpleClusterServer(*clusterFinder,transformer) : 0x0;
-}
-
-//_____________________________________________________________________________
-AliMUONVClusterFinder* AliMUONRefitter::CreateClusterFinder()
-{
- /// Create a given cluster finder instance
- AliMUONVClusterFinder* clusterFinder;
- Option_t *opt = AliMUONReconstructor::GetRecoParam()->GetClusteringMode();
-
- if (strstr(opt,"PRECLUSTERV2")) clusterFinder = new AliMUONPreClusterFinderV2;
- else if (strstr(opt,"PRECLUSTERV3")) clusterFinder = new AliMUONPreClusterFinderV3;
- else if (strstr(opt,"PRECLUSTER")) clusterFinder = new AliMUONPreClusterFinder;
- else if (strstr(opt,"COG")) clusterFinder = new AliMUONClusterFinderCOG(new AliMUONPreClusterFinder);
- else if (strstr(opt,"SIMPLEFITV3")) clusterFinder = new AliMUONClusterFinderSimpleFit(new AliMUONClusterFinderCOG(new AliMUONPreClusterFinderV3));
- else if (strstr(opt,"SIMPLEFIT")) clusterFinder = new AliMUONClusterFinderSimpleFit(new AliMUONClusterFinderCOG(new AliMUONPreClusterFinder));
- else if (strstr(opt,"MLEM:DRAW")) clusterFinder = new AliMUONClusterFinderMLEM(kTRUE,new AliMUONPreClusterFinder);
- else if (strstr(opt,"MLEMV3")) clusterFinder = new AliMUONClusterFinderMLEM(kFALSE,new AliMUONPreClusterFinderV3);
- else if (strstr(opt,"MLEMV2")) clusterFinder = new AliMUONClusterFinderMLEM(kFALSE,new AliMUONPreClusterFinderV2);
- else if (strstr(opt,"MLEM")) clusterFinder = new AliMUONClusterFinderMLEM(kFALSE,new AliMUONPreClusterFinder);
- else clusterFinder = 0x0;
-
- if (clusterFinder) {
- AliInfo(Form("Will use %s for clusterizing",clusterFinder->ClassName()));
- } else {
- AliError(Form("clustering mode \"%s\" does not exist",opt));
- }
-
- return clusterFinder;
-}
-
-//_____________________________________________________________________________
-void AliMUONRefitter::CreateTrackReconstructor(AliMUONVClusterServer& clusterServer)
-{
- /// Create track reconstructor, depending on tracking mode set in RecoParam
- Option_t *opt = AliMUONReconstructor::GetRecoParam()->GetTrackingMode();
-
- if (strstr(opt,"ORIGINAL")) fTracker = new AliMUONTrackReconstructor(clusterServer);
- else if (strstr(opt,"KALMAN")) fTracker = new AliMUONTrackReconstructorK(clusterServer);
- else fTracker = 0x0;
-
- if (fTracker) {
- AliInfo(Form("Will use %s for tracking",fTracker->ClassName()));
- } else {
- AliError(Form("tracking mode \"%s\" does not exist",opt));
- }
+ AliMUONVClusterFinder* clusterFinder = AliMUONReconstructor::CreateClusterFinder(AliMUONReconstructor::GetRecoParam()->GetClusteringMode());
+ fClusterServer = clusterFinder ? new AliMUONSimpleClusterServer(clusterFinder,transformer) : 0x0;
}
//_____________________________________________________________________________
#include "AliMUONSimpleClusterServer.h"
-#include "AliMUONConstants.h"
+#include "AliCodeTimer.h"
+#include "AliLog.h"
#include "AliMUONCluster.h"
+#include "AliMUONConstants.h"
#include "AliMUONGeometryTransformer.h"
#include "AliMUONPad.h"
+#include "AliMUONTriggerTrackToTrackerClusters.h"
#include "AliMUONVCluster.h"
#include "AliMUONVClusterFinder.h"
#include "AliMUONVClusterStore.h"
#include "AliMpDEIterator.h"
#include "AliMpDEManager.h"
#include "AliMpExMap.h"
+#include "AliMpPad.h"
#include "AliMpSegmentation.h"
-#include "AliMpVPadIterator.h"
#include "AliMpVSegmentation.h"
-#include "AliESDMuonPad.h"
-#include "AliLog.h"
-#include <float.h>
#include <Riostream.h>
#include <TClonesArray.h>
#include <TString.h>
-
+#include <float.h>
/// \class AliMUONSimpleClusterServer
///
}
//_____________________________________________________________________________
-AliMUONSimpleClusterServer::AliMUONSimpleClusterServer(AliMUONVClusterFinder& clusterFinder,
+AliMUONSimpleClusterServer::AliMUONSimpleClusterServer(AliMUONVClusterFinder* clusterFinder,
const AliMUONGeometryTransformer& transformer)
: AliMUONVClusterServer(),
fClusterFinder(clusterFinder),
fTransformer(transformer),
fPads(),
- fDEAreas(new AliMpExMap(true))
+ fTriggerTrackStore(0x0),
+ fBypass(0x0)
{
/// Ctor
+ /// Note that we take ownership of the clusterFinder
fPads[0] = new AliMpExMap(true);
fPads[1] = new AliMpExMap(true);
- AliMpDEIterator it;
-
- it.First();
-
- /// Generate the DE areas in global coordinates
-
- while ( !it.IsDone() )
- {
- Int_t detElemId = it.CurrentDEId();
-
- const AliMpVSegmentation* seg = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath0);
-
- Double_t xg,yg,zg;
-
- AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
-
- Double_t xl(0.0), yl(0.0), zl(0.0);
- Double_t dx(seg->Dimensions().X());
- Double_t dy(seg->Dimensions().Y());
-
- if ( stationType == AliMp::kStation1 || stationType == AliMp::kStation2 )
- {
- Double_t xmin(FLT_MAX);
- Double_t xmax(-FLT_MAX);
- Double_t ymin(FLT_MAX);
- Double_t ymax(-FLT_MAX);
-
- for ( Int_t icathode = 0; icathode < 2; ++icathode )
- {
- const AliMpVSegmentation* cathode
- = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::GetCathodType(icathode));
-
- AliMpVPadIterator* it = cathode->CreateIterator();
-
- it->First();
-
- while ( !it->IsDone() )
- {
- AliMpPad pad = it->CurrentItem();
- AliMpArea a(pad.Position(),pad.Dimensions());
- xmin = TMath::Min(xmin,a.LeftBorder());
- xmax = TMath::Max(xmax,a.RightBorder());
- ymin = TMath::Min(ymin,a.DownBorder());
- ymax = TMath::Max(ymax,a.UpBorder());
- it->Next();
- }
-
- delete it;
- }
-
- xl = (xmin+xmax)/2.0;
- yl = (ymin+ymax)/2.0;
- dx = (xmax-xmin)/2.0;
- dy = (ymax-ymin)/2.0;
-
- fTransformer.Local2Global(detElemId,xl,yl,zl,xg,yg,zg);
- }
- else
- {
- fTransformer.Local2Global(detElemId,xl,yl,zl,xg,yg,zg);
- }
-
- fDEAreas->Add(detElemId,new AliMpArea(TVector2(xg,yg),TVector2(dx,dy)));
-
- it.Next();
- }
}
//_____________________________________________________________________________
AliMUONSimpleClusterServer::~AliMUONSimpleClusterServer()
{
/// Dtor
- delete &fClusterFinder;
+ delete fClusterFinder;
delete fPads[0];
delete fPads[1];
- delete fDEAreas;
+ delete fBypass;
}
//_____________________________________________________________________________
/// We first find out the list of DE that have a non-zero overlap with area,
/// and then use the clusterfinder to find clusters in those areas (and DE).
+ AliCodeTimerAuto(Form("Chamber %d",chamberId));
+
+ if ( fTriggerTrackStore && chamberId >= 6 )
+ {
+ return fBypass->GenerateClusters(chamberId,clusterStore);
+ }
+
AliMpDEIterator it;
it.First(chamberId);
if ( ok )
{
- if ( fClusterFinder.NeedSegmentation() )
+ if ( fClusterFinder->NeedSegmentation() )
{
const AliMpVSegmentation* seg[2] =
{ AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath0),
AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath1)
};
- fClusterFinder.Prepare(detElemId,pads,deArea,seg);
+ fClusterFinder->Prepare(detElemId,pads,deArea,seg);
}
else
{
- fClusterFinder.Prepare(detElemId,pads,deArea);
+ fClusterFinder->Prepare(detElemId,pads,deArea);
}
AliDebug(1,Form("Clusterizing DE %04d with %3d pads (cath0) and %3d pads (cath1)",
AliMUONCluster* cluster;
- while ( ( cluster = fClusterFinder.NextCluster() ) )
+ while ( ( cluster = fClusterFinder->NextCluster() ) )
{
// add new cluster to the store with information to build its ID
// increment the number of clusters into the store
return nofAddedClusters;
}
+
//_____________________________________________________________________________
void
AliMUONSimpleClusterServer::Global2Local(Int_t detElemId, const AliMpArea& globalArea,
Bool_t overlap(kFALSE);
- AliMpArea* globalDEArea = static_cast<AliMpArea*>(fDEAreas->GetValue(detElemId));
+ AliMpArea* globalDEArea = fTransformer.GetDEArea(detElemId);
+
+ if (!globalDEArea) return kFALSE;
AliMpArea overlapArea;
return static_cast<TClonesArray*>(fPads[cathode]->GetValue(detElemId));
}
+//_____________________________________________________________________________
+Bool_t
+AliMUONSimpleClusterServer::UseTriggerTrackStore(AliMUONVTriggerTrackStore* trackStore)
+{
+ /// Tells us to use trigger track store, and thus to bypass St45 clusters
+ fTriggerTrackStore = trackStore; // not owner
+ delete fBypass;
+ fBypass = new AliMUONTriggerTrackToTrackerClusters(fTransformer,fTriggerTrackStore);
+ return kTRUE;
+}
+
//_____________________________________________________________________________
void
AliMUONSimpleClusterServer::UseDigits(TIter& next)
# include "AliMUONVClusterServer.h"
#endif
-class AliMUONVClusterFinder;
+class AliESDMuonPad;
class AliMUONGeometryTransformer;
+class AliMUONTriggerTrackToTrackerClusters;
+class AliMUONVClusterFinder;
class AliMpExMap;
-class AliESDMuonPad;
class TClonesArray;
class AliMUONSimpleClusterServer : public AliMUONVClusterServer
{
public:
- AliMUONSimpleClusterServer(AliMUONVClusterFinder& clusterFinder,
+ AliMUONSimpleClusterServer(AliMUONVClusterFinder* clusterFinder,
const AliMUONGeometryTransformer& transformer);
virtual ~AliMUONSimpleClusterServer();
void UseDigits(TIter& next);
void Print(Option_t* opt="") const;
-
+
+ /// Use trigger tracks. Return kFALSE if not used.
+ virtual Bool_t UseTriggerTrackStore(AliMUONVTriggerTrackStore* trackStore);
+
private:
/// Not implemented
AliMUONSimpleClusterServer(const AliMUONSimpleClusterServer& rhs);
TClonesArray* PadArray(Int_t detElemId, Int_t cathode) const;
private:
- AliMUONVClusterFinder& fClusterFinder; //!< the cluster finder (owner)
+ AliMUONVClusterFinder* fClusterFinder; //!< the cluster finder (owner)
const AliMUONGeometryTransformer& fTransformer; //!< the geometry transformer (not owner)
AliMpExMap* fPads[2]; ///< map of TClonesArray of AliMUONPads
- AliMpExMap* fDEAreas; ///< map of detection element areas in global coordinates
+ AliMUONVTriggerTrackStore* fTriggerTrackStore; ///< trigger track store (if bypassing of St45 was requested) (not owner)
+ AliMUONTriggerTrackToTrackerClusters* fBypass; ///< to convert trigger track into tracker clusters (owner)
ClassDef(AliMUONSimpleClusterServer,0) // Cluster server
};
#include "AliMUONTrack.h"
+#include "AliMUONReconstructor.h"
+#include "AliMUONRecoParam.h"
#include "AliMUONVCluster.h"
#include "AliMUONVClusterStore.h"
#include "AliMUONObjectPair.h"
fVertexErrXY2[1] = 0.;
// Pointers to clusters from the segment
- AliMUONVCluster* cluster1 = (AliMUONVCluster*) segment->First();
- AliMUONVCluster* cluster2 = (AliMUONVCluster*) segment->Second();
-
- // check sorting in -Z (spectro z<0)
- if (cluster1->GetZ() < cluster2->GetZ()) {
- cluster1 = cluster2;
- cluster2 = (AliMUONVCluster*) segment->First();
- }
-
- // order the clusters into the track according to the station the segment belong to
- // to anticipate the direction of propagation in the first tracking step
- // (go backward if the segment is on the last station / go forward otherwise)
- AliMUONVCluster *firstCluster, *lastCluster;
- if (cluster1->GetChamberId() == 8) { // last station
- firstCluster = cluster1;
- lastCluster = cluster2;
- } else {
- firstCluster = cluster2;
- lastCluster = cluster1;
- }
+ AliMUONVCluster* firstCluster = (AliMUONVCluster*) segment->First();
+ AliMUONVCluster* lastCluster = (AliMUONVCluster*) segment->Second();
// Compute track parameters
Double_t z1 = firstCluster->GetZ();
Double_t bendingImpact = bendingCoor1 - z1 * bendingSlope;
Double_t inverseBendingMomentum = 1. / AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(bendingImpact);
-
- // Set track parameters at first cluster (needed by any tracking algorithm)
+ // Set track parameters at first cluster
AliMUONTrackParam trackParamAtFirstCluster;
trackParamAtFirstCluster.SetZ(z1);
trackParamAtFirstCluster.SetNonBendingCoor(nonBendingCoor1);
trackParamAtFirstCluster.SetBendingSlope(bendingSlope);
trackParamAtFirstCluster.SetInverseBendingMomentum(inverseBendingMomentum);
-
- // Set track parameters at last cluster (used by Kalman only)
+ // Set track parameters at last cluster
AliMUONTrackParam trackParamAtLastCluster;
trackParamAtLastCluster.SetZ(z2);
trackParamAtLastCluster.SetNonBendingCoor(nonBendingCoor2);
trackParamAtLastCluster.SetBendingSlope(bendingSlope);
trackParamAtLastCluster.SetInverseBendingMomentum(inverseBendingMomentum);
-
- // Compute and set track parameters covariances at first cluster (needed by any tracking algorithm)
- TMatrixD paramCov1(5,5);
- paramCov1.Zero();
+ // Compute and set track parameters covariances at first cluster
+ TMatrixD paramCov(5,5);
+ paramCov.Zero();
// Non bending plane
- paramCov1(0,0) = firstCluster->GetErrX2();
- paramCov1(0,1) = firstCluster->GetErrX2() / dZ;
- paramCov1(1,0) = paramCov1(0,1);
- paramCov1(1,1) = ( firstCluster->GetErrX2() + lastCluster->GetErrX2() ) / dZ / dZ;
+ paramCov(0,0) = firstCluster->GetErrX2();
+ paramCov(0,1) = firstCluster->GetErrX2() / dZ;
+ paramCov(1,0) = paramCov(0,1);
+ paramCov(1,1) = ( firstCluster->GetErrX2() + lastCluster->GetErrX2() ) / dZ / dZ;
// Bending plane
- paramCov1(2,2) = firstCluster->GetErrY2();
- paramCov1(2,3) = firstCluster->GetErrY2() / dZ;
- paramCov1(3,2) = paramCov1(2,3);
- paramCov1(3,3) = ( firstCluster->GetErrY2() + lastCluster->GetErrY2() ) / dZ / dZ;
- // Inverse bending momentum (50% error)
- paramCov1(4,4) = 0.5*inverseBendingMomentum * 0.5*inverseBendingMomentum;
- // Set covariances
- trackParamAtFirstCluster.SetCovariances(paramCov1);
+ paramCov(2,2) = firstCluster->GetErrY2();
+ paramCov(2,3) = firstCluster->GetErrY2() / dZ;
+ paramCov(3,2) = paramCov(2,3);
+ paramCov(3,3) = ( firstCluster->GetErrY2() + lastCluster->GetErrY2() ) / dZ / dZ;
+ // Inverse bending momentum (vertex resolution + bending slope resolution + 10% error on dipole parameters+field)
+ paramCov(4,4) = ((AliMUONReconstructor::GetRecoParam()->GetBendingVertexDispersion() *
+ AliMUONReconstructor::GetRecoParam()->GetBendingVertexDispersion() +
+ (z1 * z1 * lastCluster->GetErrY2() + z2 * z2 * firstCluster->GetErrY2()) / dZ / dZ) /
+ bendingImpact / bendingImpact + 0.1 * 0.1) * inverseBendingMomentum * inverseBendingMomentum;
+ paramCov(2,4) = - z2 * firstCluster->GetErrY2() * inverseBendingMomentum / bendingImpact / dZ;
+ paramCov(4,2) = paramCov(2,4);
+ paramCov(3,4) = - (z1 * lastCluster->GetErrY2() + z2 * firstCluster->GetErrY2()) * inverseBendingMomentum / bendingImpact / dZ / dZ;
+ paramCov(4,3) = paramCov(3,4);
-
- // Compute and set track parameters covariances at last cluster as if the first cluster did not exist (used by Kalman only)
- TMatrixD paramCov2(5,5);
- paramCov2.Zero();
- // Non bending plane
- paramCov2(0,0) = paramCov1(0,0);
- paramCov2(1,1) = 100.*paramCov1(1,1);
- // Bending plane
- paramCov2(2,2) = paramCov1(2,2);
- paramCov2(3,3) = 100.*paramCov1(3,3);
- // Inverse bending momentum
- paramCov2(4,4) = paramCov1(4,4);
// Set covariances
- trackParamAtLastCluster.SetCovariances(paramCov2);
+ trackParamAtFirstCluster.SetCovariances(paramCov);
- // Flag clusters as being removable
- trackParamAtFirstCluster.SetRemovable(kTRUE);
- trackParamAtLastCluster.SetRemovable(kTRUE);
+ // Compute and set track parameters covariances at last cluster
+ paramCov(1,0) = - paramCov(1,0);
+ paramCov(0,1) = - paramCov(0,1);
+ paramCov(3,2) = - paramCov(3,2);
+ paramCov(2,3) = - paramCov(2,3);
+ paramCov(2,4) = z1 * lastCluster->GetErrY2() * inverseBendingMomentum / bendingImpact / dZ;
+ paramCov(4,2) = paramCov(2,4);
+ trackParamAtLastCluster.SetCovariances(paramCov);
// Add track parameters at clusters
AddTrackParamAtCluster(trackParamAtFirstCluster,*firstCluster);
//__________________________________________________________________________
Bool_t AliMUONTrack::IsValid()
{
- /// check the validity of the current track (at least one cluster per station)
+ /// check the validity of the current track (at least one cluster per requested station)
Int_t nClusters = GetNClusters();
AliMUONTrackParam *trackParam;
for (Int_t i = 0; i < nClusters; i++) {
trackParam = (AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(i);
+ // skip unrequested stations
+ while (expectedStation < AliMUONConstants::NTrackingSt() &&
+ !AliMUONReconstructor::GetRecoParam()->RequestStation(expectedStation)) expectedStation++;
+
currentStation = trackParam->GetClusterPtr()->GetChamberId()/2;
// missing station
}
- return currentStation == AliMUONConstants::NTrackingSt() - 1;
+ return expectedStation == AliMUONConstants::NTrackingSt();
}
//__________________________________________________________________________
void AliMUONTrack::TagRemovableClusters() {
/// Identify clusters that can be removed from the track,
- /// with the only requirement to have at least 1 cluster per station
+ /// with the only requirement to have at least 1 cluster per requested station
Int_t nClusters = GetNClusters();
AliMUONTrackParam *trackParam, *nextTrackParam;
Int_t currentCh, nextCh;
- // reset flags to default
+ // reset flags to kFALSE for all clusters in required station
for (Int_t i = 0; i < nClusters; i++) {
trackParam = (AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(i);
- trackParam->SetRemovable(kFALSE);
+ if (AliMUONReconstructor::GetRecoParam()->RequestStation(trackParam->GetClusterPtr()->GetChamberId()/2))
+ trackParam->SetRemovable(kFALSE);
+ else trackParam->SetRemovable(kTRUE);
}
// loop over track parameters
Double_t numberOfDegFree = (2. * GetNClusters() - 5.);
if (numberOfDegFree > 0.) return fGlobalChi2 / numberOfDegFree;
- else return 1.e10;
+ else return fGlobalChi2; // system is under-constraint
}
//__________________________________________________________________________
if (bendingMomentum == 0.) return 1.e10;
+ const Double_t kCorrectionFactor = 0.9; // impact parameter is 10% overestimated
Double_t simpleBPosition = 0.5 * (AliMUONConstants::CoilZ() + AliMUONConstants::YokeZ());
Double_t simpleBLength = 0.5 * (AliMUONConstants::CoilL() + AliMUONConstants::YokeL());
- Float_t b[3], x[3] = {0.,0.,(Float_t) simpleBPosition};
+ Float_t b[3], x[3] = {50.,50.,(Float_t) simpleBPosition};
if (fgkField) fgkField->Field(x,b);
else {
cout<<"F-AliMUONTrackExtrap::GetField: fgkField = 0x0"<<endl;
}
Double_t simpleBValue = (Double_t) b[0];
- return (-0.0003 * simpleBValue * simpleBLength * simpleBPosition / bendingMomentum);
+ return kCorrectionFactor * (-0.0003 * simpleBValue * simpleBLength * simpleBPosition / bendingMomentum);
}
//__________________________________________________________________________
if (impactParam == 0.) return 1.e10;
+ const Double_t kCorrectionFactor = 1.1; // bending momentum is 10% underestimated
Double_t simpleBPosition = 0.5 * (AliMUONConstants::CoilZ() + AliMUONConstants::YokeZ());
Double_t simpleBLength = 0.5 * (AliMUONConstants::CoilL() + AliMUONConstants::YokeL());
- Float_t b[3], x[3] = {0.,0.,(Float_t) simpleBPosition};
+ Float_t b[3], x[3] = {50.,50.,(Float_t) simpleBPosition};
if (fgkField) fgkField->Field(x,b);
else {
cout<<"F-AliMUONTrackExtrap::GetField: fgkField = 0x0"<<endl;
}
Double_t simpleBValue = (Double_t) b[0];
- return (-0.0003 * simpleBValue * simpleBLength * simpleBPosition / impactParam);
+ return kCorrectionFactor * (-0.0003 * simpleBValue * simpleBLength * simpleBPosition / impactParam);
}
//__________________________________________________________________________
// Get reference to the parameter covariance matrix
const TMatrixD& kParamCov = trackParam->GetCovariances();
-
+
// Extrapolate track parameters to "zEnd"
ExtrapToZ(trackParam,zEnd);
for (Int_t i = firstChamber; i <= lastChamber; ++i )
{
- fClusterServer.Clusterize(i, clusterStore, AliMpArea());
+ if (AliMUONReconstructor::GetRecoParam()->UseChamber(i)) fClusterServer.Clusterize(i, clusterStore, AliMpArea());
}
// Loop over stations(1..) 5 and 4 and make track candidates
for (Int_t istat=4; istat>=3; istat--) {
// Make segments in the station
- segments = MakeSegmentsInStation(clusterStore,istat);
+ segments = MakeSegmentsBetweenChambers(clusterStore, 2*istat, 2*istat+1);
// Loop over segments
for (Int_t iseg=0; iseg<segments->GetEntriesFast(); iseg++)
track = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack((AliMUONObjectPair*)((*segments)[iseg]));
fNRecTracks++;
- // Printout for debuging
- if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
- cout<<endl<<"Track parameter covariances at first cluster:"<<endl;
- ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->First())->GetCovariances().Print();
- }
-
// Look for compatible cluster(s) in the other station
if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast())
clusterFound = FollowLinearTrackInStation(*track, clusterStore, 7-istat);
else clusterFound = FollowTrackInStation(*track, clusterStore, 7-istat);
// Remove track if no cluster found
- if (!clusterFound) {
+ if (!clusterFound && AliMUONReconstructor::GetRecoParam()->RequestStation(7-istat)) {
fRecTracksPtr->Remove(track);
fNRecTracks--;
}
AliDebug(1,Form("Number of good candidates = %d",fNRecTracks));
+}
+
+ //__________________________________________________________________________
+void AliMUONTrackReconstructor::MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore)
+{
+ /// To make extra track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE):
+ /// clustering is supposed to be already done
+ /// Start with segments made of 1 cluster in each of the stations 4 and 5 then follow track in remaining chambers.
+ /// Good candidates are made of at least three clusters if both station are requested (two otherwise).
+ /// Keep only best candidates or all of them according to the flag fgkTrackAllTracks.
+
+ TClonesArray *segments;
+ AliMUONTrack *track;
+ Int_t iCandidate = 0, iCurrentTrack, nCurrentTracks;
+ Bool_t clusterFound;
+
+ AliDebug(1,"Enter MakeMoreTrackCandidates");
+
+ // Double loop over chambers in stations(1..) 4 and 5 to make track candidates
+ for (Int_t ich1 = 6; ich1 <= 7; ich1++) {
+ for (Int_t ich2 = 8; ich2 <= 9; ich2++) {
+
+ // Make segments in the station
+ segments = MakeSegmentsBetweenChambers(clusterStore, ich1, ich2);
+
+ // Loop over segments
+ for (Int_t iseg=0; iseg<segments->GetEntriesFast(); iseg++)
+ {
+ AliDebug(1,Form("Making primary candidate(1..) %d",++iCandidate));
+
+ // Transform segments to tracks and put them at the end of fRecTracksPtr
+ iCurrentTrack = fRecTracksPtr->GetLast()+1;
+ track = new ((*fRecTracksPtr)[iCurrentTrack]) AliMUONTrack((AliMUONObjectPair*)((*segments)[iseg]));
+ fNRecTracks++;
+
+ // Look for compatible cluster(s) in the second chamber of station 5
+ if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast())
+ clusterFound = FollowLinearTrackInChamber(*track, clusterStore, 17-ich2);
+ else clusterFound = FollowTrackInChamber(*track, clusterStore, 17-ich2);
+
+ // skip the original track in case it has been removed
+ if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() && clusterFound) iCurrentTrack++;
+
+ // loop over every new tracks
+ nCurrentTracks = fRecTracksPtr->GetLast()+1;
+ while (iCurrentTrack < nCurrentTracks) {
+ track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iCurrentTrack);
+
+ // Look for compatible cluster(s) in the second chamber of station 4
+ if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast())
+ FollowLinearTrackInChamber(*track, clusterStore, 13-ich1);
+ else FollowTrackInChamber(*track, clusterStore, 13-ich1);
+
+ iCurrentTrack++;
+ }
+
+ }
+
+ // delete the array of segments
+ delete segments;
+ }
+ }
+
+ fRecTracksPtr->Compress(); // this is essential before checking tracks
+
+ // Keep all different tracks or only the best ones as required
+ if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) RemoveIdenticalTracks();
+ else RemoveDoubleTracks();
+
+ AliDebug(1,Form("Number of good candidates = %d",fNRecTracks));
+
}
//__________________________________________________________________________
AliMUONTrack *track, *nextTrack;
AliMUONTrackParam *trackParam, *nextTrackParam;
Int_t currentNRecTracks;
- Bool_t clusterFound;
Double_t sigmaCut2 = AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking();
// Fit the track:
// Do not take into account the multiple scattering to speed up the fit
// Calculate the track parameter covariance matrix
- // If "station" is station(1..) 3 then use the vertex to better constrain the fit
- if (station==2) Fit(*track, kFALSE, kTRUE, kTRUE);
+ // If there is no cluster out of station 4 or 5 then use the vertex to better constrain the fit
+ if (((AliMUONTrackParam*) track->GetTrackParamAtCluster()->First())->GetClusterPtr()->GetChamberId() > 5)
+ Fit(*track, kFALSE, kTRUE, kTRUE);
else Fit(*track, kFALSE, kFALSE, kTRUE);
- // Remove the track if the normalized chi2 is too high
- if (track->GetNormalizedChi2() > sigmaCut2) {
- fRecTracksPtr->Remove(track);
+ // remove track with absolute bending momentum out of limits
+ // or if the normalized chi2 is too high
+ Double_t bendingMomentum = TMath::Abs(1. / ((AliMUONTrackParam*)track->GetTrackParamAtCluster()->First())->GetInverseBendingMomentum());
+ if (bendingMomentum < AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum() ||
+ bendingMomentum > AliMUONReconstructor::GetRecoParam()->GetMaxBendingMomentum() ||
+ track->GetNormalizedChi2() > sigmaCut2) {
+ fRecTracksPtr->Remove(track);
fNRecTracks--;
continue;
}
} else { // or save track parameters on last station only
- // save parameters from fit
trackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First();
- trackParam->SetSmoothParameters(trackParam->GetParameters());
- trackParam->SetSmoothCovariances(trackParam->GetCovariances());
-
- // save parameters extrapolated to the second chamber of the same station if it has been hit
- nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(trackParam);
- if (nextTrackParam->GetClusterPtr()->GetChamberId() < 2*(station+2)) {
-
- // reset parameters and covariances
- nextTrackParam->SetParameters(trackParam->GetParameters());
- nextTrackParam->SetZ(trackParam->GetZ());
- nextTrackParam->SetCovariances(trackParam->GetCovariances());
+ if (trackParam->GetClusterPtr()->GetChamberId() < 2*(station+2)) {
- // extrapolate them to the z of the corresponding cluster
- AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetClusterPtr()->GetZ());
+ // save parameters from fit
+ trackParam->SetSmoothParameters(trackParam->GetParameters());
+ trackParam->SetSmoothCovariances(trackParam->GetCovariances());
- // save them
- nextTrackParam->SetSmoothParameters(nextTrackParam->GetParameters());
- nextTrackParam->SetSmoothCovariances(nextTrackParam->GetCovariances());
+ // save parameters extrapolated to the second chamber of the same station if it has been hit
+ nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(trackParam);
+ if (nextTrackParam->GetClusterPtr()->GetChamberId() < 2*(station+2)) {
+
+ // reset parameters and covariances
+ nextTrackParam->SetParameters(trackParam->GetParameters());
+ nextTrackParam->SetZ(trackParam->GetZ());
+ nextTrackParam->SetCovariances(trackParam->GetCovariances());
+
+ // extrapolate them to the z of the corresponding cluster
+ AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetClusterPtr()->GetZ());
+
+ // save them
+ nextTrackParam->SetSmoothParameters(nextTrackParam->GetParameters());
+ nextTrackParam->SetSmoothCovariances(nextTrackParam->GetCovariances());
+
+ }
}
}
- // Printout for debuging
- if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
- cout<<endl<<"Track parameter covariances at first cluster:"<<endl;
- ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->First())->GetCovariances().Print();
- }
-
// Look for compatible cluster(s) in station(0..) "station"
- clusterFound = FollowTrackInStation(*track, clusterStore, station);
-
- // Try to recover track if required
- if (!clusterFound && AliMUONReconstructor::GetRecoParam()->RecoverTracks())
- clusterFound = RecoverTrack(*track, clusterStore, station);
-
- // remove track if no cluster found
- if (!clusterFound) {
- fRecTracksPtr->Remove(track);
- fNRecTracks--;
+ if (!FollowTrackInStation(*track, clusterStore, station)) {
+
+ // Try to recover track if required
+ if (AliMUONReconstructor::GetRecoParam()->RecoverTracks()) {
+
+ // work on a copy of the track if this station is not required
+ // to keep the case where no cluster is reconstructed as a possible candidate
+ if (!AliMUONReconstructor::GetRecoParam()->RequestStation(station)) {
+ track = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(*track);
+ fNRecTracks++;
+ }
+
+ // try to recover
+ if (!RecoverTrack(*track, clusterStore, station)) {
+ // remove track if no cluster found
+ fRecTracksPtr->Remove(track);
+ fNRecTracks--;
+ }
+
+ } else if (AliMUONReconstructor::GetRecoParam()->RequestStation(station)) {
+ // remove track if no cluster found
+ fRecTracksPtr->Remove(track);
+ fNRecTracks--;
+ }
+
}
}
// save parameters from fit into smoothed parameters to complete track afterward
if (AliMUONReconstructor::GetRecoParam()->ComplementTracks()) {
- // save parameters from fit
trackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First();
- trackParam->SetSmoothParameters(trackParam->GetParameters());
- trackParam->SetSmoothCovariances(trackParam->GetCovariances());
-
- // save parameters extrapolated to the second chamber of the same station if it has been hit
- nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(trackParam);
- if (nextTrackParam->GetClusterPtr()->GetChamberId() < 2) {
-
- // reset parameters and covariances
- nextTrackParam->SetParameters(trackParam->GetParameters());
- nextTrackParam->SetZ(trackParam->GetZ());
- nextTrackParam->SetCovariances(trackParam->GetCovariances());
+ if (trackParam->GetClusterPtr()->GetChamberId() < 2) {
- // extrapolate them to the z of the corresponding cluster
- AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetClusterPtr()->GetZ());
+ // save parameters from fit
+ trackParam->SetSmoothParameters(trackParam->GetParameters());
+ trackParam->SetSmoothCovariances(trackParam->GetCovariances());
- // save them
- nextTrackParam->SetSmoothParameters(nextTrackParam->GetParameters());
- nextTrackParam->SetSmoothCovariances(nextTrackParam->GetCovariances());
+ // save parameters extrapolated to the second chamber of the same station if it has been hit
+ nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(trackParam);
+ if (nextTrackParam->GetClusterPtr()->GetChamberId() < 2) {
+
+ // reset parameters and covariances
+ nextTrackParam->SetParameters(trackParam->GetParameters());
+ nextTrackParam->SetZ(trackParam->GetZ());
+ nextTrackParam->SetCovariances(trackParam->GetCovariances());
+
+ // extrapolate them to the z of the corresponding cluster
+ AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetClusterPtr()->GetZ());
+
+ // save them
+ nextTrackParam->SetSmoothParameters(nextTrackParam->GetParameters());
+ nextTrackParam->SetSmoothCovariances(nextTrackParam->GetCovariances());
+
+ }
}
fRecTracksPtr->Compress();
+}
+
+ //__________________________________________________________________________
+Bool_t AliMUONTrackReconstructor::FollowTrackInChamber(AliMUONTrack &trackCandidate, AliMUONVClusterStore& clusterStore, Int_t nextChamber)
+{
+ /// Follow trackCandidate in chamber(0..) nextChamber and search for compatible cluster(s)
+ /// Keep all possibilities or only the best one(s) according to the flag fgkTrackAllTracks:
+ /// kTRUE: duplicate "trackCandidate" if there are several possibilities and add the new tracks at the end of
+ /// fRecTracksPtr to avoid conficts with other track candidates at this current stage of the tracking procedure.
+ /// Remove the obsolete "trackCandidate" at the end.
+ /// kFALSE: add only the best cluster(s) to the "trackCandidate". Try to add a couple of clusters in priority.
+ AliDebug(1,Form("Enter FollowTrackInChamber(1..) %d", nextChamber+1));
+
+ Double_t chi2WithOneCluster = 1.e10;
+ Double_t maxChi2WithOneCluster = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
+ AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
+ Double_t bestChi2WithOneCluster = maxChi2WithOneCluster;
+ Bool_t foundOneCluster = kFALSE;
+ AliMUONTrack *newTrack = 0x0;
+ AliMUONVCluster *cluster;
+ AliMUONTrackParam extrapTrackParam;
+ AliMUONTrackParam extrapTrackParamAtCh;
+ AliMUONTrackParam extrapTrackParamAtCluster;
+ AliMUONTrackParam bestTrackParamAtCluster;
+
+ // Get track parameters according to the propagation direction
+ if (nextChamber > 7) extrapTrackParamAtCh = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->Last();
+ else extrapTrackParamAtCh = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First();
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
+ cout<<endl<<"Track parameters and covariances at first cluster:"<<endl;
+ extrapTrackParamAtCh.GetParameters().Print();
+ extrapTrackParamAtCh.GetCovariances().Print();
+ }
+
+ // Add MCS effect
+ AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
+
+ // Add MCS in the missing chamber(s) if any
+ Int_t currentChamber = extrapTrackParamAtCh.GetClusterPtr()->GetChamberId();
+ while (currentChamber > nextChamber + 1) {
+ // extrapolation to the missing chamber
+ currentChamber--;
+ AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber));
+ // add MCS effect
+ AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
+ }
+
+ //Extrapolate trackCandidate to chamber
+ AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(nextChamber));
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
+ cout<<endl<<"Track parameters and covariances at first cluster extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(nextChamber)<<":"<<endl;
+ extrapTrackParamAtCh.GetParameters().Print();
+ extrapTrackParamAtCh.GetCovariances().Print();
+ }
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+ cout << "FollowTrackInStation: look for clusters in chamber(1..): " << nextChamber+1 << endl;
+ }
+
+ // Ask the clustering to reconstruct new clusters around the track position in the current chamber
+ // except for station 4 and 5 that are already entirely clusterized
+ if (AliMUONReconstructor::GetRecoParam()->CombineClusterTrackReco()) {
+ if (nextChamber < 6) AskForNewClustersInChamber(extrapTrackParamAtCh, clusterStore, nextChamber);
+ }
+
+ // Create iterators to loop over clusters in both chambers
+ TIter next(clusterStore.CreateChamberIterator(nextChamber,nextChamber));
+
+ // look for cluster in chamber
+ while ( ( cluster = static_cast<AliMUONVCluster*>(next()) ) ) {
+
+ // try to add the current cluster fast
+ if (!TryOneClusterFast(extrapTrackParamAtCh, cluster)) continue;
+
+ // try to add the current cluster accuratly
+ chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCh, cluster, extrapTrackParamAtCluster);
+
+ // if good chi2 then consider to add cluster
+ if (chi2WithOneCluster < maxChi2WithOneCluster) {
+ foundOneCluster = kTRUE;
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+ cout << "FollowTrackInStation: found one cluster in chamber(1..): " << nextChamber+1
+ << " (Chi2 = " << chi2WithOneCluster << ")" << endl;
+ cluster->Print();
+ }
+
+ if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
+ // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
+ newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
+ UpdateTrack(*newTrack,extrapTrackParamAtCluster);
+ fNRecTracks++;
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+ cout << "FollowTrackInStation: added one cluster in chamber(1..): " << nextChamber+1 << endl;
+ if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
+ }
+
+ } else if (chi2WithOneCluster < bestChi2WithOneCluster) {
+ // keep track of the best single cluster except if a couple of clusters has already been found
+ bestChi2WithOneCluster = chi2WithOneCluster;
+ bestTrackParamAtCluster = extrapTrackParamAtCluster;
+ }
+
+ }
+
+ }
+
+ // fill out the best track if required else clean up the fRecTracksPtr array
+ if (!AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
+ if (foundOneCluster) {
+ UpdateTrack(trackCandidate,bestTrackParamAtCluster);
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+ cout << "FollowTrackInStation: added the best cluster in chamber(1..): " << bestTrackParamAtCluster.GetClusterPtr()->GetChamberId()+1 << endl;
+ if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
+ }
+
+ } else return kFALSE;
+
+ } else if (foundOneCluster) {
+
+ // remove obsolete track
+ fRecTracksPtr->Remove(&trackCandidate);
+ fNRecTracks--;
+
+ } else return kFALSE;
+
+ return kTRUE;
+
}
//__________________________________________________________________________
if (nextStation==4) extrapTrackParamAtCh = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->Last();
else extrapTrackParamAtCh = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First();
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
+ cout<<endl<<"Track parameters and covariances at first cluster:"<<endl;
+ extrapTrackParamAtCh.GetParameters().Print();
+ extrapTrackParamAtCh.GetCovariances().Print();
+ }
+
// Add MCS effect
AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
- // Add MCS in the missing chamber if any (only 1 chamber can be missing according to tracking criteria)
- if (ch1 < ch2 && extrapTrackParamAtCh.GetClusterPtr()->GetChamberId() > ch2 + 1) {
+ // Add MCS in the missing chamber(s) if any
+ Int_t currentChamber = extrapTrackParamAtCh.GetClusterPtr()->GetChamberId();
+ while (ch1 < ch2 && currentChamber > ch2 + 1) {
// extrapolation to the missing chamber
- AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch2 + 1));
+ currentChamber--;
+ AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber));
// add MCS effect
AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
}
// Printout for debuging
if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
- cout<<endl<<"Track parameter covariances at first cluster extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(ch2)<<":"<<endl;
+ cout<<endl<<"Track parameters and covariances at first cluster extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(ch2)<<":"<<endl;
+ extrapTrackParamAtCh.GetParameters().Print();
extrapTrackParamAtCh.GetCovariances().Print();
}
if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch2+1
<< " (Chi2 = " << chi2WithOneCluster << ")" << endl;
+ clusterCh2->Print();
cout << " look for second clusters in chamber(1..): " << ch1+1 << " ..." << endl;
}
// Printout for debuging
if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
cout << "FollowTrackInStation: found second cluster in chamber(1..): " << ch1+1
- << " (Global Chi2 = " << chi2WithTwoClusters << ")" << endl;
+ << " (Global Chi2 = " << chi2WithTwoClusters << ")" << endl;
+ clusterCh1->Print();
}
if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
// if we want to keep all possible tracks or if no good couple of clusters has been found
if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() || !foundTwoClusters) {
- // Printout for debuging
- if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
- cout << "FollowTrackInStation: look for single clusters in chamber(1..): " << ch1+1 << endl;
- }
-
// add MCS effect for next step
AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
//Extrapolate trackCandidate to chamber "ch1"
AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch1));
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
+ cout<<endl<<"Track parameters and covariances at first cluster extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(ch1)<<":"<<endl;
+ extrapTrackParamAtCh.GetParameters().Print();
+ extrapTrackParamAtCh.GetCovariances().Print();
+ }
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+ cout << "FollowTrackInStation: look for single clusters in chamber(1..): " << ch1+1 << endl;
+ }
+
// reset cluster iterator of chamber 1
nextInCh1.Reset();
iCluster1 = -1;
// try to add the current cluster accuratly
chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCh, clusterCh1, extrapTrackParamAtCluster1);
-
+
// if good chi2 then consider to add clusterCh1
// We do not try to attach a cluster in the other chamber too since it has already been done above
if (chi2WithOneCluster < maxChi2WithOneCluster) {
foundOneCluster = kTRUE;
-
+
// Printout for debuging
if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1
<< " (Chi2 = " << chi2WithOneCluster << ")" << endl;
+ clusterCh1->Print();
}
if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
deltaY*deltaY / cluster->GetErrY2();
// Flag cluster as being not removable
- trackParamAtCluster.SetRemovable(kFALSE);
+ if (AliMUONReconstructor::GetRecoParam()->RequestStation(cluster->GetChamberId()/2))
+ trackParamAtCluster.SetRemovable(kFALSE);
+ else trackParamAtCluster.SetRemovable(kTRUE);
trackParamAtCluster.SetLocalChi2(0.); // --> Local chi2 not used
// Update the chi2 of the new track
if (nextStation > 1) return kFALSE;
Int_t worstClusterNumber = -1;
- Double_t localChi2, worstLocalChi2 = 0.;
+ Double_t localChi2, worstLocalChi2 = -1.;
// Look for the cluster to remove
for (Int_t clusterNumber = 0; clusterNumber < 2; clusterNumber++) {
AliMUONTrackParam *trackParamAtCluster = (AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(clusterNumber);
+ // check if current cluster is in the previous station
+ if (trackParamAtCluster->GetClusterPtr()->GetChamberId()/2 != nextStation+1) break;
+
// check if current cluster is removable
if (!trackParamAtCluster->IsRemovable()) return kFALSE;
+ // reset the current cluster as beig not removable if it is on a required station
+ if (AliMUONReconstructor::GetRecoParam()->RequestStation(nextStation+1)) trackParamAtCluster->SetRemovable(kFALSE);
+
// Pick up cluster with the worst chi2
localChi2 = trackParamAtCluster->GetLocalChi2();
if (localChi2 > worstLocalChi2) {
worstLocalChi2 = localChi2;
worstClusterNumber = clusterNumber;
}
+
}
- // Reset best cluster as being NOT removable
- ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt((worstClusterNumber+1)%2))->SetRemovable(kFALSE);
+ // check if worst cluster found
+ if (worstClusterNumber < 0) return kFALSE;
// Remove the worst cluster
trackCandidate.RemoveTrackParamAtCluster((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(worstClusterNumber));
gMinuit->SetFCN(TrackChi2);
// Set fitted parameters (!! The order is very important for the covariance matrix !!)
+ // Mandatory limits to avoid NaN values of parameters
trackParam = (AliMUONTrackParam*) (track.GetTrackParamAtCluster()->First());
- // could be tried with no limits for the search (min=max=0) ????
- // mandatory limits in non Bending to avoid NaN values of parameters
+ Double_t maxIBM = 1. / AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum();
gMinuit->mnparm(0, "X", trackParam->GetNonBendingCoor(), 0.03, -500.0, 500.0, status);
- gMinuit->mnparm(1, "NonBenS", trackParam->GetNonBendingSlope(), 0.001, -0.5, 0.5, status);
- // mandatory limits in Bending to avoid NaN values of parameters
+ gMinuit->mnparm(1, "NonBenS", trackParam->GetNonBendingSlope(), 0.001, -1., 1., status);
gMinuit->mnparm(2, "Y", trackParam->GetBendingCoor(), 0.10, -500.0, 500.0, status);
- gMinuit->mnparm(3, "BenS", trackParam->GetBendingSlope(), 0.001, -0.5, 0.5, status);
- gMinuit->mnparm(4, "InvBenP", trackParam->GetInverseBendingMomentum(), 0.003, -0.5, 0.5, status);
+ gMinuit->mnparm(3, "BenS", trackParam->GetBendingSlope(), 0.001, -1.5, 1.5, status);
+ gMinuit->mnparm(4, "InvBenP", trackParam->GetInverseBendingMomentum(), 0.003, -maxIBM, maxIBM, status);
// minimization
gMinuit->mnexcm("MIGRAD", arg, 0, status);
if (!track.IsImproved()) track.UpdateCovTrackParamAtCluster();
}
-//__________________________________________________________________________
+ //__________________________________________________________________________
Bool_t AliMUONTrackReconstructor::RefitTrack(AliMUONTrack &track)
{
/// re-fit the given track
// Functions
virtual void MakeTrackCandidates(AliMUONVClusterStore& clusterStore);
+ virtual void MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore);
virtual void FollowTracks(AliMUONVClusterStore& clusterStore);
virtual void ComplementTracks(const AliMUONVClusterStore& clusterStore);
virtual void ImproveTrack(AliMUONTrack &track);
/// Not implemented copy assignment operator
AliMUONTrackReconstructor& operator=(const AliMUONTrackReconstructor& rhs);
+ Bool_t FollowTrackInChamber(AliMUONTrack &trackCandidate, AliMUONVClusterStore& clusterStore, Int_t nextChamber);
Bool_t FollowTrackInStation(AliMUONTrack &trackCandidate, AliMUONVClusterStore& clusterStore, Int_t nextStation);
Double_t TryTwoClusters(const AliMUONTrackParam &trackParamAtCluster, AliMUONVCluster* cluster2, AliMUONTrackParam &trackParamAtCluster2);
{
/// To make track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE):
/// Start with segments station(1..) 4 or 5 then follow track in station 5 or 4.
- /// Good candidates are made of at least three clusters.
+ /// Good candidates are made of at least three clusters if both station are requested (two otherwise).
/// Keep only best candidates or all of them according to the flag fgkTrackAllTracks.
TClonesArray *segments;
for (Int_t i = firstChamber; i <= lastChamber; ++i )
{
- fClusterServer.Clusterize(i, clusterStore, AliMpArea());
+ if (AliMUONReconstructor::GetRecoParam()->UseChamber(i)) fClusterServer.Clusterize(i, clusterStore, AliMpArea());
}
// Loop over stations(1..) 5 and 4 and make track candidates
for (Int_t istat=4; istat>=3; istat--) {
// Make segments in the station
- segments = MakeSegmentsInStation(clusterStore, istat);
+ segments = MakeSegmentsBetweenChambers(clusterStore, 2*istat, 2*istat+1);
// Loop over segments
for (Int_t iseg=0; iseg<segments->GetEntriesFast(); iseg++) {
track = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack((AliMUONObjectPair*)((*segments)[iseg]));
fNRecTracks++;
- // Printout for debuging
- if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
- cout<<endl<<"Track parameter covariances at first cluster:"<<endl;
- ((AliMUONTrackParam*) (track->GetTrackParamAtCluster()->First()))->GetCovariances().Print();
- }
-
// Look for compatible cluster(s) in the other station
if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast())
clusterFound = FollowLinearTrackInStation(*track, clusterStore, 7-istat);
else {
// First recompute track parameters and covariances on station(1..) 5 using Kalman filter
// (to make sure all tracks are treated in the same way)
- if (istat == 4) RetraceTrack(*track, kFALSE);
+ if (istat == 4) RetraceTrack(*track, kTRUE);
clusterFound = FollowTrackInStation(*track, clusterStore, 7-istat);
}
- // Remove track if no cluster found
+ // Remove track if no cluster found on a requested station
if (!clusterFound) {
- fRecTracksPtr->Remove(track);
- fNRecTracks--;
+ if (AliMUONReconstructor::GetRecoParam()->RequestStation(7-istat)) {
+ fRecTracksPtr->Remove(track);
+ fNRecTracks--;
+ } else if (istat == 3 && !AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast()) {
+ // update track parameters and covariances using Kalman filter
+ RetraceTrack(*track, kTRUE);
+ }
}
}
AliDebug(1,Form("Number of good candidates = %d",fNRecTracks));
+}
+
+ //__________________________________________________________________________
+void AliMUONTrackReconstructorK::MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore)
+{
+ /// To make extra track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE):
+ /// clustering is supposed to be already done
+ /// Start with segments made of 1 cluster in each of the stations 4 and 5 then follow track in remaining chambers.
+ /// Good candidates are made of at least three clusters if both station are requested (two otherwise).
+ /// Keep only best candidates or all of them according to the flag fgkTrackAllTracks.
+
+ TClonesArray *segments;
+ AliMUONTrack *track;
+ Int_t iCandidate = 0, iCurrentTrack, nCurrentTracks;
+ Int_t initialNRecTracks = fNRecTracks;
+ Bool_t clusterFound;
+
+ AliDebug(1,"Enter MakeMoreTrackCandidates");
+
+ // Double loop over chambers in stations(1..) 4 and 5 to make track candidates
+ for (Int_t ich1 = 6; ich1 <= 7; ich1++) {
+ for (Int_t ich2 = 8; ich2 <= 9; ich2++) {
+
+ // Make segments between ch1 and ch2
+ segments = MakeSegmentsBetweenChambers(clusterStore, ich1, ich2);
+
+ // Loop over segments
+ for (Int_t iseg=0; iseg<segments->GetEntriesFast(); iseg++) {
+ AliDebug(1,Form("Making primary candidate(1..) %d",++iCandidate));
+
+ // Transform segments to tracks and put them at the end of fRecTracksPtr
+ iCurrentTrack = fRecTracksPtr->GetLast()+1;
+ track = new ((*fRecTracksPtr)[iCurrentTrack]) AliMUONTrack((AliMUONObjectPair*)((*segments)[iseg]));
+ fNRecTracks++;
+
+ // Look for compatible cluster(s) in the second chamber of station 5
+ if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast())
+ clusterFound = FollowLinearTrackInChamber(*track, clusterStore, 17-ich2);
+ else clusterFound = FollowTrackInChamber(*track, clusterStore, 17-ich2);
+
+ // skip the original track in case it has been removed
+ if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() && clusterFound) iCurrentTrack++;
+
+ // loop over every new tracks
+ nCurrentTracks = fRecTracksPtr->GetLast()+1;
+ while (iCurrentTrack < nCurrentTracks) {
+ track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iCurrentTrack);
+
+ // Look for compatible cluster(s) in the second chamber of station 4
+ if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast())
+ FollowLinearTrackInChamber(*track, clusterStore, 13-ich1);
+ else FollowTrackInChamber(*track, clusterStore, 13-ich1);
+
+ iCurrentTrack++;
+ }
+
+ }
+
+ // delete the array of segments
+ delete segments;
+ }
+ }
+
+ fRecTracksPtr->Compress(); // this is essential before checking tracks
+
+ // Retrace tracks using Kalman filter
+ for (Int_t iRecTrack = initialNRecTracks; iRecTrack < fNRecTracks; iRecTrack++) {
+ track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iRecTrack);
+
+ // Recompute track parameters and covariances using Kalman filter
+ RetraceTrack(*track,kTRUE);
+
+ // Remove the track if the normalized chi2 is too high
+ // (only if the tracking has been done without magnetic field)
+ if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast() &&
+ track->GetNormalizedChi2() > AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
+ AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking()) {
+ fRecTracksPtr->Remove(track);
+ fNRecTracks--;
+ }
+
+ }
+
+ // this is essential before checking tracks
+ if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast()) fRecTracksPtr->Compress();
+
+ // Keep all different tracks or only the best ones as required
+ if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) RemoveIdenticalTracks();
+ else RemoveDoubleTracks();
+
+ AliDebug(1,Form("Number of good candidates = %d",fNRecTracks));
+
}
//__________________________________________________________________________
lastTrackParam->SetNonBendingSlope((x1 - x2) / dZ);
lastTrackParam->SetBendingSlope((y1 - y2) / dZ);
Double_t bendingImpact = y2 - z2 * lastTrackParam->GetBendingSlope();
- lastTrackParam->SetInverseBendingMomentum(1. / AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(bendingImpact));
+ Double_t inverseBendingMomentum = 1. / AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(bendingImpact);
+ lastTrackParam->SetInverseBendingMomentum(inverseBendingMomentum);
// => Reset track parameter covariances at last cluster (as if the other clusters did not exist)
TMatrixD lastParamCov(5,5);
// Bending plane
lastParamCov(2,2) = cluster2->GetErrY2();
lastParamCov(3,3) = 100. * ( cluster1->GetErrY2() + cluster2->GetErrY2() ) / dZ / dZ;
- // Inverse bending momentum (50% error)
- lastParamCov(4,4) = 0.5*lastTrackParam->GetInverseBendingMomentum() * 0.5*lastTrackParam->GetInverseBendingMomentum();
+ // Inverse bending momentum (vertex resolution + bending slope resolution + 10% error on dipole parameters+field)
+ lastParamCov(4,4) = ((AliMUONReconstructor::GetRecoParam()->GetBendingVertexDispersion() *
+ AliMUONReconstructor::GetRecoParam()->GetBendingVertexDispersion() +
+ (z1 * z1 * cluster2->GetErrY2() + z2 * z2 * cluster1->GetErrY2()) / dZ / dZ) /
+ bendingImpact / bendingImpact + 0.1 * 0.1) * inverseBendingMomentum * inverseBendingMomentum;
lastTrackParam->SetCovariances(lastParamCov);
// Reset the track chi2
// reset propagator for smoother
if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) trackParamAtCluster->ResetPropagator();
- // add MCS in missing chambers if any (at most 2 chambers can be missing according to tracking criteria)
+ // add MCS in missing chambers if any
currentChamber = trackParamAtCluster->GetClusterPtr()->GetChamberId();
while (currentChamber < expectedChamber) {
// extrapolation to the missing chamber (update the propagator)
trackParamAtCluster->SetExtrapCovariances(trackParamAtCluster->GetCovariances());
}
- // Compute new track parameters including "clusterCh2" using kalman filter
+ // Compute new track parameters using kalman filter
addChi2TrackAtCluster = RunKalmanFilter(*trackParamAtCluster);
// Update the track chi2
AliMUONTrack *track;
Int_t currentNRecTracks;
- Bool_t clusterFound;
for (Int_t station = 2; station >= 0; station--) {
track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iRecTrack);
- // Printout for debuging
- if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
- cout<<endl<<"Track parameter covariances at first cluster:"<<endl;
- ((AliMUONTrackParam*) (track->GetTrackParamAtCluster()->First()))->GetCovariances().Print();
- }
-
// Look for compatible cluster(s) in station(0..) "station"
- clusterFound = FollowTrackInStation(*track, clusterStore, station);
-
- // Try to recover track if required
- if (!clusterFound && AliMUONReconstructor::GetRecoParam()->RecoverTracks())
- clusterFound = RecoverTrack(*track, clusterStore, station);
-
- // remove track if no cluster found
- if (!clusterFound) {
- fRecTracksPtr->Remove(track);
- fNRecTracks--;
+ if (!FollowTrackInStation(*track, clusterStore, station)) {
+
+ // Try to recover track if required
+ if (AliMUONReconstructor::GetRecoParam()->RecoverTracks()) {
+
+ // work on a copy of the track if this station is not required
+ // to keep the case where no cluster is reconstructed as a possible candidate
+ if (!AliMUONReconstructor::GetRecoParam()->RequestStation(station)) {
+ track = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(*track);
+ fNRecTracks++;
+ }
+
+ // try to recover
+ if (!RecoverTrack(*track, clusterStore, station)) {
+ // remove track if no cluster found
+ fRecTracksPtr->Remove(track);
+ fNRecTracks--;
+ }
+
+ } else if (AliMUONReconstructor::GetRecoParam()->RequestStation(station)) {
+ // remove track if no cluster found
+ fRecTracksPtr->Remove(track);
+ fNRecTracks--;
+ }
+
}
}
}
+}
+
+ //__________________________________________________________________________
+Bool_t AliMUONTrackReconstructorK::FollowTrackInChamber(AliMUONTrack &trackCandidate, AliMUONVClusterStore& clusterStore, Int_t nextChamber)
+{
+ /// Follow trackCandidate in chamber(0..) nextChamber and search for compatible cluster(s)
+ /// Keep all possibilities or only the best one(s) according to the flag fgkTrackAllTracks:
+ /// kTRUE: duplicate "trackCandidate" if there are several possibilities and add the new tracks at the end of
+ /// fRecTracksPtr to avoid conficts with other track candidates at this current stage of the tracking procedure.
+ /// Remove the obsolete "trackCandidate" at the end.
+ /// kFALSE: add only the best cluster(s) to the "trackCandidate". Try to add a couple of clusters in priority.
+ /// return kTRUE if new cluster(s) have been found (otherwise return kFALSE)
+ AliDebug(1,Form("Enter FollowTrackInChamber(1..) %d", nextChamber+1));
+
+ Double_t bendingMomentum;
+ Double_t chi2OfCluster;
+ Double_t maxChi2OfCluster = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
+ AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
+ Double_t addChi2TrackAtCluster;
+ Double_t bestAddChi2TrackAtCluster = 1.e10;
+ Bool_t foundOneCluster = kFALSE;
+ AliMUONTrack *newTrack = 0x0;
+ AliMUONVCluster *cluster;
+ AliMUONTrackParam extrapTrackParamAtCh;
+ AliMUONTrackParam extrapTrackParamAtCluster;
+ AliMUONTrackParam bestTrackParamAtCluster;
+
+ // Get track parameters according to the propagation direction
+ if (nextChamber > 7) extrapTrackParamAtCh = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->Last();
+ else extrapTrackParamAtCh = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First();
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
+ cout<<endl<<"Track parameters and covariances at first cluster:"<<endl;
+ extrapTrackParamAtCh.GetParameters().Print();
+ extrapTrackParamAtCh.GetCovariances().Print();
+ }
+
+ // Add MCS effect
+ AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
+
+ // reset propagator for smoother
+ if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) extrapTrackParamAtCh.ResetPropagator();
+
+ // Add MCS in the missing chamber(s) if any
+ Int_t currentChamber = extrapTrackParamAtCh.GetClusterPtr()->GetChamberId();
+ while (currentChamber > nextChamber + 1) {
+ // extrapolation to the missing chamber
+ currentChamber--;
+ AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber),
+ AliMUONReconstructor::GetRecoParam()->UseSmoother());
+ // add MCS effect
+ AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
+ }
+
+ //Extrapolate trackCandidate to chamber
+ AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(nextChamber),
+ AliMUONReconstructor::GetRecoParam()->UseSmoother());
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
+ cout<<endl<<"Track parameters and covariances at first cluster extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(nextChamber)<<":"<<endl;
+ extrapTrackParamAtCh.GetParameters().Print();
+ extrapTrackParamAtCh.GetCovariances().Print();
+ }
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+ cout << "FollowTrackInChamber: look for clusters in chamber(1..): " << nextChamber+1 << endl;
+ }
+
+ // Ask the clustering to reconstruct new clusters around the track position in the current chamber
+ // except for station 4 and 5 that are already entirely clusterized
+ if (AliMUONReconstructor::GetRecoParam()->CombineClusterTrackReco()) {
+ if (nextChamber < 6) AskForNewClustersInChamber(extrapTrackParamAtCh, clusterStore, nextChamber);
+ }
+
+ // Create iterators to loop over clusters in both chambers
+ TIter next(clusterStore.CreateChamberIterator(nextChamber,nextChamber));
+
+ // look for candidates in chamber
+ while ( ( cluster = static_cast<AliMUONVCluster*>(next()) ) ) {
+
+ // try to add the current cluster fast
+ if (!TryOneClusterFast(extrapTrackParamAtCh, cluster)) continue;
+
+ // try to add the current cluster accuratly
+ chi2OfCluster = TryOneCluster(extrapTrackParamAtCh, cluster, extrapTrackParamAtCluster,
+ AliMUONReconstructor::GetRecoParam()->UseSmoother());
+
+ // if good chi2 then consider to add cluster
+ if (chi2OfCluster < maxChi2OfCluster) {
+ foundOneCluster = kTRUE;
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+ cout << "FollowTrackInChamber: found one cluster in chamber(1..): " << nextChamber+1
+ << " (Chi2 = " << chi2OfCluster << ")" << endl;
+ cluster->Print();
+ }
+
+ if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) {
+ // save extrapolated parameters for smoother
+ extrapTrackParamAtCluster.SetExtrapParameters(extrapTrackParamAtCluster.GetParameters());
+
+ // save extrapolated covariance matrix for smoother
+ extrapTrackParamAtCluster.SetExtrapCovariances(extrapTrackParamAtCluster.GetCovariances());
+ }
+
+ // Compute new track parameters including new cluster using kalman filter
+ addChi2TrackAtCluster = RunKalmanFilter(extrapTrackParamAtCluster);
+
+ // skip track with absolute bending momentum out of limits
+ bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster.GetInverseBendingMomentum());
+ if (bendingMomentum < AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum() ||
+ bendingMomentum > AliMUONReconstructor::GetRecoParam()->GetMaxBendingMomentum()) continue;
+
+ if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
+ // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
+ newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
+ UpdateTrack(*newTrack,extrapTrackParamAtCluster,addChi2TrackAtCluster);
+ fNRecTracks++;
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+ cout << "FollowTrackInChamber: added one cluster in chamber(1..): " << nextChamber+1 << endl;
+ if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
+ }
+
+ } else if (addChi2TrackAtCluster < bestAddChi2TrackAtCluster) {
+ // keep track of the best cluster
+ bestAddChi2TrackAtCluster = addChi2TrackAtCluster;
+ bestTrackParamAtCluster = extrapTrackParamAtCluster;
+ }
+
+ }
+
+ }
+
+ // fill out the best track if required else clean up the fRecTracksPtr array
+ if (!AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
+ if (foundOneCluster) {
+ UpdateTrack(trackCandidate,bestTrackParamAtCluster,bestAddChi2TrackAtCluster);
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+ cout << "FollowTrackInChamber: added the best cluster in chamber(1..): " << bestTrackParamAtCluster.GetClusterPtr()->GetChamberId()+1 << endl;
+ if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
+ }
+
+ } else return kFALSE;
+
+ } else if (foundOneCluster) {
+
+ // remove obsolete track
+ fRecTracksPtr->Remove(&trackCandidate);
+ fNRecTracks--;
+
+ } else return kFALSE;
+
+ return kTRUE;
+
}
//__________________________________________________________________________
ch2 = 2*nextStation+1;
}
+ Double_t bendingMomentum;
Double_t chi2OfCluster;
Double_t maxChi2OfCluster = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
if (nextStation==4) extrapTrackParamAtCh = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->Last();
else extrapTrackParamAtCh = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First();
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
+ cout<<endl<<"Track parameters and covariances at first cluster:"<<endl;
+ extrapTrackParamAtCh.GetParameters().Print();
+ extrapTrackParamAtCh.GetCovariances().Print();
+ }
+
// Add MCS effect
AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
// reset propagator for smoother
if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) extrapTrackParamAtCh.ResetPropagator();
- // Add MCS in the missing chamber if any (only 1 chamber can be missing according to tracking criteria)
- if (ch1 < ch2 && extrapTrackParamAtCh.GetClusterPtr()->GetChamberId() > ch2 + 1) {
+ // Add MCS in the missing chamber(s) if any
+ Int_t currentChamber = extrapTrackParamAtCh.GetClusterPtr()->GetChamberId();
+ while (ch1 < ch2 && currentChamber > ch2 + 1) {
// extrapolation to the missing chamber
- AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch2 + 1),
+ currentChamber--;
+ AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber),
AliMUONReconstructor::GetRecoParam()->UseSmoother());
// add MCS effect
AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
// Printout for debuging
if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
- cout<<endl<<"Track parameter covariances at first cluster extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(ch2)<<":"<<endl;
+ cout<<endl<<"Track parameters and covariances at first cluster extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(ch2)<<":"<<endl;
+ extrapTrackParamAtCh.GetParameters().Print();
extrapTrackParamAtCh.GetCovariances().Print();
}
if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch2+1
<< " (Chi2 = " << chi2OfCluster << ")" << endl;
+ clusterCh2->Print();
cout << " look for second clusters in chamber(1..): " << ch1+1 << " ..." << endl;
}
// Compute new track parameters including "clusterCh2" using kalman filter
addChi2TrackAtCluster2 = RunKalmanFilter(extrapTrackParamAtCluster2);
+ // skip track with absolute bending momentum out of limits
+ bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster2.GetInverseBendingMomentum());
+ if (bendingMomentum < AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum() ||
+ bendingMomentum > AliMUONReconstructor::GetRecoParam()->GetMaxBendingMomentum()) continue;
+
// copy new track parameters for next step
extrapTrackParam = extrapTrackParamAtCluster2;
// try to add the current cluster accuratly
chi2OfCluster = TryOneCluster(extrapTrackParam, clusterCh1, extrapTrackParamAtCluster1,
- AliMUONReconstructor::GetRecoParam()->UseSmoother());
+ AliMUONReconstructor::GetRecoParam()->UseSmoother());
// if good chi2 then consider to add the 2 clusters to the "trackCandidate"
if (chi2OfCluster < maxChi2OfCluster) {
// Printout for debuging
if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1
- << " (Chi2 = " << chi2OfCluster << ")" << endl;
+ << " (Chi2 = " << chi2OfCluster << ")" << endl;
+ clusterCh1->Print();
}
if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) {
// Compute new track parameters including "clusterCh1" using kalman filter
addChi2TrackAtCluster1 = RunKalmanFilter(extrapTrackParamAtCluster1);
+ // skip track with absolute bending momentum out of limits
+ bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster1.GetInverseBendingMomentum());
+ if (bendingMomentum < AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum() ||
+ bendingMomentum > AliMUONReconstructor::GetRecoParam()->GetMaxBendingMomentum()) continue;
+
if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
// copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new clusters
newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
// if we want to keep all possible tracks or if no good couple of clusters has been found
if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() || !foundTwoClusters) {
- // Printout for debuging
- if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
- cout << "FollowTrackInStation: look for single clusters in chamber(1..): " << ch1+1 << endl;
- }
-
// add MCS effect for next step
AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch1),
AliMUONReconstructor::GetRecoParam()->UseSmoother());
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
+ cout<<endl<<"Track parameters and covariances at first cluster extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(ch1)<<":"<<endl;
+ extrapTrackParamAtCh.GetParameters().Print();
+ extrapTrackParamAtCh.GetCovariances().Print();
+ }
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+ cout << "FollowTrackInStation: look for single clusters in chamber(1..): " << ch1+1 << endl;
+ }
+
// reset cluster iterator of chamber 1
nextInCh1.Reset();
iCluster1 = -1;
if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1
<< " (Chi2 = " << chi2OfCluster << ")" << endl;
+ clusterCh1->Print();
}
if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) {
// Compute new track parameters including "clusterCh1" using kalman filter
addChi2TrackAtCluster1 = RunKalmanFilter(extrapTrackParamAtCluster1);
+ // skip track with absolute bending momentum out of limits
+ bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster1.GetInverseBendingMomentum());
+ if (bendingMomentum < AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum() ||
+ bendingMomentum > AliMUONReconstructor::GetRecoParam()->GetMaxBendingMomentum()) continue;
+
if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
// copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
// if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station
// (going in the right direction)
if (nextStation == 4) RetraceTrack(trackCandidate,kTRUE);
-
+
// Printout for debuging
if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
cout << "FollowTrackInStation: added the two best clusters in station(1..): " << nextStation+1 << endl;
// if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station
// (going in the right direction)
if (nextStation == 4) RetraceTrack(trackCandidate,kTRUE);
-
+
// Printout for debuging
if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
cout << "FollowTrackInStation: added the best cluster in chamber(1..): " << bestTrackParamAtCluster1.GetClusterPtr()->GetChamberId()+1 << endl;
delete [] clusterCh1Used;
return kFALSE;
}
+
} else if (foundOneCluster || foundTwoClusters) {
// remove obsolete track
} else {
delete [] clusterCh1Used;
return kFALSE;
- }
+ }
+
delete [] clusterCh1Used;
return kTRUE;
/// Add 1 cluster to the track candidate
/// Update chi2 of the track
- // Flag cluster as being not removable
- trackParamAtCluster.SetRemovable(kFALSE);
+ // Flag cluster as being (not) removable
+ if (AliMUONReconstructor::GetRecoParam()->RequestStation(trackParamAtCluster.GetClusterPtr()->GetChamberId()/2))
+ trackParamAtCluster.SetRemovable(kFALSE);
+ else trackParamAtCluster.SetRemovable(kTRUE);
trackParamAtCluster.SetLocalChi2(0.); // --> Local chi2 not used
// Update the track chi2 into trackParamAtCluster
if (nextStation > 1) return kFALSE;
Int_t worstClusterNumber = -1;
- Double_t localChi2, worstLocalChi2 = 0.;
+ Double_t localChi2, worstLocalChi2 = -1.;
// Look for the cluster to remove
for (Int_t clusterNumber = 0; clusterNumber < 2; clusterNumber++) {
AliMUONTrackParam *trackParamAtCluster = (AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(clusterNumber);
+ // check if current cluster is in the previous station
+ if (trackParamAtCluster->GetClusterPtr()->GetChamberId()/2 != nextStation+1) break;
+
// check if current cluster is removable
if (!trackParamAtCluster->IsRemovable()) return kFALSE;
+ // reset the current cluster as being not removable if it is on a required station
+ if (AliMUONReconstructor::GetRecoParam()->RequestStation(nextStation+1)) trackParamAtCluster->SetRemovable(kFALSE);
+
// Pick up cluster with the worst chi2
localChi2 = trackParamAtCluster->GetLocalChi2();
if (localChi2 > worstLocalChi2) {
}
}
- // Reset best cluster as being NOT removable
- ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt((worstClusterNumber+1)%2))->SetRemovable(kFALSE);
+ // check if worst cluster found
+ if (worstClusterNumber < 0) return kFALSE;
// Remove the worst cluster
trackCandidate.RemoveTrackParamAtCluster((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(worstClusterNumber));
// Re-calculate track parameters at the (new) first cluster
RetracePartialTrack(trackCandidate,(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(1));
+ // skip track with absolute bending momentum out of limits
+ Double_t bendingMomentum = TMath::Abs(1. / ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First())->GetInverseBendingMomentum());
+ if (bendingMomentum < AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum() ||
+ bendingMomentum > AliMUONReconstructor::GetRecoParam()->GetMaxBendingMomentum()) return kFALSE;
+
// Look for new cluster(s) in next station
return FollowTrackInStation(trackCandidate, clusterStore, nextStation);
// Functions
virtual void MakeTrackCandidates(AliMUONVClusterStore& clusterStore);
+ virtual void MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore);
virtual void FollowTracks(AliMUONVClusterStore& clusterStore);
virtual void ComplementTracks(const AliMUONVClusterStore& clusterStore);
virtual void ImproveTrack(AliMUONTrack &track);
void RetraceTrack(AliMUONTrack &trackCandidate, Bool_t resetSeed);
void RetracePartialTrack(AliMUONTrack &trackCandidate, const AliMUONTrackParam* startingTrackParam);
+ Bool_t FollowTrackInChamber(AliMUONTrack &trackCandidate, AliMUONVClusterStore& clusterStore, Int_t nextChamber);
Bool_t FollowTrackInStation(AliMUONTrack &trackCandidate, AliMUONVClusterStore& clusterStore, Int_t nextStation);
Double_t RunKalmanFilter(AliMUONTrackParam &trackParamAtCluster);
#include "AliMUONTracker.h"
-#include "AliMUONReconstructor.h"
+#include "AliCodeTimer.h"
+#include "AliESDEvent.h"
+#include "AliESDMuonTrack.h"
+#include "AliESDVertex.h"
+#include "AliLog.h"
+#include "AliMUONClusterStoreV2.h"
+#include "AliMUONESDInterface.h"
+#include "AliMUONLegacyClusterServer.h"
#include "AliMUONRecoParam.h"
+#include "AliMUONReconstructor.h"
#include "AliMUONTrack.h"
#include "AliMUONTrackExtrap.h"
#include "AliMUONTrackHitPattern.h"
#include "AliMUONTrackParam.h"
-#include "AliMUONVCluster.h"
-#include "AliMUONVClusterServer.h"
-#include "AliMUONVDigitStore.h"
#include "AliMUONTrackReconstructor.h"
#include "AliMUONTrackReconstructorK.h"
#include "AliMUONTrackStoreV1.h"
#include "AliMUONTriggerTrackStoreV1.h"
-#include "AliMUONClusterStoreV2.h"
+#include "AliMUONVCluster.h"
+#include "AliMUONVClusterServer.h"
+#include "AliMUONVDigitStore.h"
#include "AliMUONVTriggerStore.h"
-#include "AliMUONESDInterface.h"
-
-#include "AliESDEvent.h"
-#include "AliESDVertex.h"
-#include "AliESDMuonTrack.h"
-#include "AliLog.h"
-#include "AliCodeTimer.h"
-
#include <Riostream.h>
-#include <TTree.h>
#include <TRandom.h>
+#include <TTree.h>
/// \cond CLASSIMP
ClassImp(AliMUONTracker)
//_____________________________________________________________________________
-AliMUONTracker::AliMUONTracker(AliMUONVClusterServer& clusterServer,
- const AliMUONVDigitStore& digitStore,
+AliMUONTracker::AliMUONTracker(AliMUONVClusterServer* clusterServer,
+ const AliMUONVDigitStore& digitStore,
const AliMUONDigitMaker* digitMaker,
const AliMUONGeometryTransformer* transformer,
const AliMUONTriggerCircuit* triggerCircuit)
fTrackReco(0x0),
fClusterStore(0x0),
fTriggerStore(0x0),
- fClusterServer(clusterServer), // not owner
- fDigitStore(digitStore) // not owner
+ fClusterServer(clusterServer),
+ fIsOwnerOfClusterServer(kFALSE),
+ fDigitStore(digitStore), // not owner
+ fInputClusterStore(0x0),
+ fTriggerTrackStore(0x0)
{
/// constructor
if (fTransformer && fDigitMaker)
fTrackHitPatternMaker = new AliMUONTrackHitPattern(*fTransformer,*fDigitMaker);
- TIter next(fDigitStore.CreateIterator());
- fClusterServer.UseDigits(next);
+ if (!fClusterServer)
+ {
+ AliInfo("No cluster server given. Will use AliMUONLegacyClusterServer");
+ fIsOwnerOfClusterServer = kTRUE;
+ }
+ else
+ {
+ TIter next(fDigitStore.CreateIterator());
+ fClusterServer->UseDigits(next);
+
+ SetupClusterServer(*fClusterServer);
+ }
}
//_____________________________________________________________________________
delete fTrackHitPatternMaker;
delete fClusterStore;
delete fTriggerStore;
+ if ( fIsOwnerOfClusterServer ) delete fClusterServer;
+ delete fInputClusterStore;
+ delete fTriggerTrackStore;
}
//_____________________________________________________________________________
return fClusterStore;
}
+//_____________________________________________________________________________
+AliMUONVTriggerTrackStore*
+AliMUONTracker::TriggerTrackStore() const
+{
+ /// Return (and create if necessary) the trigger track container
+ if (!fTriggerTrackStore)
+ {
+ fTriggerTrackStore = new AliMUONTriggerTrackStoreV1;
+ }
+ return fTriggerTrackStore;
+}
+
//_____________________________________________________________________________
Int_t AliMUONTracker::LoadClusters(TTree* clustersTree)
{
/// Load triggerStore from clustersTree
- ClusterStore()->Clear();
-
delete fTriggerStore;
+ delete fInputClusterStore;
+ fInputClusterStore=0x0;
if ( ! clustersTree ) {
AliFatal("No clustersTree");
return 2;
}
- ClusterStore()->Connect(*clustersTree,kFALSE);
+ if ( fIsOwnerOfClusterServer )
+ {
+ fInputClusterStore = AliMUONVClusterStore::Create(*clustersTree);
+ if ( fInputClusterStore )
+ {
+ AliInfo(Form("Created %s from cluster tree",fInputClusterStore->ClassName()));
+ fInputClusterStore->Clear();
+ fInputClusterStore->Connect(*clustersTree,kFALSE);
+ }
+ delete fClusterServer;
+ fClusterServer = new AliMUONLegacyClusterServer(*fTransformer,fInputClusterStore);
+ SetupClusterServer(*fClusterServer);
+ }
+
fTriggerStore->Connect(*clustersTree,kFALSE);
clustersTree->GetEvent(0);
AliDebug(1,"");
AliCodeTimerAuto("")
- if (!fTrackReco) CreateTrackReconstructor();
+ if (!fTrackReco)
+ {
+ fTrackReco = CreateTrackReconstructor(AliMUONReconstructor::GetRecoParam()->GetTrackingMode(),fClusterServer);
+ }
// if the required tracking mode does not exist
if (!fTrackReco) return 1;
return 3;
}
+ // Make trigger tracks
+ if ( fTriggerCircuit )
+ {
+ TriggerTrackStore()->Clear();
+ fTrackReco->EventReconstructTrigger(*fTriggerCircuit,*fTriggerStore,*(TriggerTrackStore()));
+ }
+
// Make tracker tracks
AliMUONVTrackStore* trackStore = new AliMUONTrackStoreV1;
fTrackReco->EventReconstruct(*(ClusterStore()),*trackStore);
- // Make trigger tracks
- AliMUONVTriggerTrackStore* triggerTrackStore(0x0);
- if ( fTriggerCircuit ) {
- triggerTrackStore = new AliMUONTriggerTrackStoreV1;
- fTrackReco->EventReconstructTrigger(*fTriggerCircuit,*fTriggerStore,*triggerTrackStore);
- }
-
// Match tracker/trigger tracks
- if ( triggerTrackStore && fTrackHitPatternMaker ) {
- fTrackReco->ValidateTracksWithTrigger(*trackStore,*triggerTrackStore,*fTriggerStore,*fTrackHitPatternMaker);
+ if ( fTrackHitPatternMaker )
+ {
+ fTrackReco->ValidateTracksWithTrigger(*trackStore,*(TriggerTrackStore()),*fTriggerStore,*fTrackHitPatternMaker);
}
// Fill ESD
// cleanup
delete trackStore;
- delete triggerTrackStore;
return 0;
}
}
//_____________________________________________________________________________
-void AliMUONTracker::CreateTrackReconstructor()
+AliMUONVTrackReconstructor* AliMUONTracker::CreateTrackReconstructor(const char* trackingMode, AliMUONVClusterServer* clusterServer)
{
/// Create track reconstructor, depending on tracking mode set in RecoParam
- TString opt(AliMUONReconstructor::GetRecoParam()->GetTrackingMode());
+ AliMUONVTrackReconstructor* trackReco(0x0);
+
+ TString opt(trackingMode);
opt.ToUpper();
if (strstr(opt,"ORIGINAL"))
{
- fTrackReco = new AliMUONTrackReconstructor(fClusterServer);
+ trackReco = new AliMUONTrackReconstructor(*clusterServer);
}
else if (strstr(opt,"KALMAN"))
{
- fTrackReco = new AliMUONTrackReconstructorK(fClusterServer);
+ trackReco = new AliMUONTrackReconstructorK(*clusterServer);
}
else
{
- AliError(Form("tracking mode \"%s\" does not exist",opt.Data()));
- return;
+ AliErrorClass(Form("tracking mode \"%s\" does not exist",opt.Data()));
+ return 0x0;
}
- AliInfo(Form("Will use %s for tracking",fTrackReco->ClassName()));
+ AliInfoClass(Form("Will use %s for tracking",trackReco->ClassName()));
+
+ return trackReco;
}
//_____________________________________________________________________________
{
/// Clear internal clusterStore
- ClusterStore()->Clear();
+ delete fInputClusterStore;
+ fInputClusterStore = 0x0;
}
+
+
+//_____________________________________________________________________________
+void
+AliMUONTracker::SetupClusterServer(AliMUONVClusterServer& clusterServer)
+{
+ /// Setup the cluster server
+
+ if ( AliMUONReconstructor::GetRecoParam()->BypassSt45() )
+ {
+ Bool_t ok = clusterServer.UseTriggerTrackStore(TriggerTrackStore());
+
+ if ( ok )
+
+ {
+ AliWarning("WILL USE TRIGGER TRACKS TO GENERATE CLUSTERS IN STATIONS 4 AND 5, THUS BYPASSING REAL CLUSTERS IN THOSE TWO STATIONS !!!");
+ }
+ else
+ {
+ AliWarning("BYPASSING OF ST45 REQUESTED, BUT CLUSTERSERVER DOES NOT SEEM TO SUPPORT IT !!!");
+ }
+ }
+}
+
+
/// \class AliMUONTracker
/// \brief MUON base Tracker
///
-// Author: Christian Finck, SUBATECH Nantes
+// Authors: Christian Finck, Laurent Aphecetche, SUBATECH Nantes
#include "AliTracker.h"
class AliMUONGeometryTransformer;
class AliMUONTrackHitPattern;
class AliMUONTriggerCircuit;
+class AliMUONVClusterServer;
class AliMUONVClusterStore;
+class AliMUONVDigitStore;
class AliMUONVTrackReconstructor;
class AliMUONVTrackStore;
class AliMUONVTriggerStore;
-class AliMUONVClusterServer;
-class AliMUONVDigitStore;
+class AliMUONVTriggerTrackStore;
class AliMUONTracker : public AliTracker
{
public:
- AliMUONTracker(AliMUONVClusterServer& clusterServer,
- const AliMUONVDigitStore& digitStore,
+ AliMUONTracker(AliMUONVClusterServer* clusterServer,
+ const AliMUONVDigitStore& digitStore,
const AliMUONDigitMaker* digitMaker=0,
const AliMUONGeometryTransformer* transformer=0,
const AliMUONTriggerCircuit* triggerCircuit=0);
/// Dummy implementation
virtual AliCluster *GetCluster(Int_t /*index*/) const {return 0;}
+ static AliMUONVTrackReconstructor* CreateTrackReconstructor(const char* trackingMode, AliMUONVClusterServer* clusterServer);
+
private:
/// Not implemented
AliMUONTracker(const AliMUONTracker& rhs);
AliMUONVClusterStore* ClusterStore() const;
- void CreateTrackReconstructor();
+ AliMUONVTriggerTrackStore* TriggerTrackStore() const;
void FillESD(AliMUONVTrackStore& trackStore, AliESDEvent* esd) const;
+ void SetupClusterServer(AliMUONVClusterServer& clusterServer);
+
private:
const AliMUONDigitMaker* fDigitMaker; //!< digit maker (not owner)
const AliMUONGeometryTransformer* fTransformer; //!< geometry transformer (not owner)
AliMUONVTrackReconstructor* fTrackReco; //!< track reconstructor
mutable AliMUONVClusterStore* fClusterStore; //!< cluster container
AliMUONVTriggerStore* fTriggerStore; //!< trigger information
- AliMUONVClusterServer& fClusterServer; //!< to get clusters
+ AliMUONVClusterServer* fClusterServer; //!< to get clusters
+ Bool_t fIsOwnerOfClusterServer; //!< whether we are owner of the cluster server
const AliMUONVDigitStore& fDigitStore; //!< digit info to fill in ESD
+ mutable AliMUONVClusterStore* fInputClusterStore; //!< cluster container
+ mutable AliMUONVTriggerTrackStore* fTriggerTrackStore; //!< trigger track store
ClassDef(AliMUONTracker,0) //tracker base class for MUON
};
--- /dev/null
+/**************************************************************************
+* 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. *
+**************************************************************************/
+
+// $Id$
+
+#include "AliMUONTriggerTrackToTrackerClusters.h"
+
+///\class AliMUONTriggerTrackToTrackerClusters
+///
+/// Class to convert trigger tracks into "fake" clusters in stations 4 and 5
+///
+/// Only intent is to be able to reconstruct data where stations 4 and 5 were
+/// not functionning, typically early cosmic runs
+///
+///\author Laurent Aphecetche, Subatech
+
+#include "AliCodeTimer.h"
+#include "AliLog.h"
+#include "AliMUONConstants.h"
+#include "AliMUONGeometryTransformer.h"
+#include "AliMUONTrack.h"
+#include "AliMUONTrackExtrap.h"
+#include "AliMUONTriggerTrack.h"
+#include "AliMUONVCluster.h"
+#include "AliMUONVClusterStore.h"
+#include "AliMUONVTriggerTrackStore.h"
+#include "AliMpArea.h"
+#include "AliMpDEManager.h"
+#include <TMath.h>
+
+///\cond CLASSIMP
+ClassImp(AliMUONTriggerTrackToTrackerClusters)
+///\endcond
+
+//_____________________________________________________________________________
+AliMUONTriggerTrackToTrackerClusters::AliMUONTriggerTrackToTrackerClusters(const AliMUONGeometryTransformer& transformer,
+ AliMUONVTriggerTrackStore* trackStore)
+: TObject(), fTransformer(transformer), fTriggerTrackStore(trackStore)
+{
+ /// ctor. We do not take ownership of the trigger track store.
+}
+
+//_____________________________________________________________________________
+AliMUONTriggerTrackToTrackerClusters::~AliMUONTriggerTrackToTrackerClusters()
+{
+ /// dtor
+}
+
+//_____________________________________________________________________________
+Int_t
+AliMUONTriggerTrackToTrackerClusters::DetElemId(Int_t chamber, Double_t x, Double_t y,
+ Double_t ex, Double_t ey,
+ Double_t& z) const
+{
+ /// Find in which detection element (x,y) (global) position is.
+
+ AliMpDEIterator it;
+
+ AliMpArea a( TVector2(x,y), TVector2(ex,ey) );
+
+ it.First(chamber);
+
+ while ( !it.IsDone() )
+ {
+ Int_t detElemId = it.CurrentDEId();
+
+ AliMpArea* area = fTransformer.GetDEArea(detElemId);
+
+ if ( area->Overlap(a) )
+ {
+ // get z of the center of that DE.
+ Double_t dummyx, dummyy;
+ fTransformer.Local2Global(detElemId,0,0,0,dummyx,dummyy,z);
+ return detElemId;
+ }
+ it.Next();
+ }
+
+ return -1;
+}
+
+//_____________________________________________________________________________
+Int_t
+AliMUONTriggerTrackToTrackerClusters::GenerateClusters(Int_t iChamber,
+ AliMUONVClusterStore& clusterStore) const
+{
+ /// Generate clusters in given chamber
+ /// Return the number of clusters added to the clusterStore
+
+ AliCodeTimerAuto(Form("Chamber %d",iChamber));
+
+ TIter next(fTriggerTrackStore->CreateIterator());
+
+ AliMUONTriggerTrack* track;
+ Int_t nadded(0);
+
+ while ( ( track = static_cast<AliMUONTriggerTrack*>(next()) ) )
+ {
+ nadded += GenerateClusters(iChamber,*track,clusterStore);
+ }
+ return nadded;
+}
+
+//_____________________________________________________________________________
+Int_t
+AliMUONTriggerTrackToTrackerClusters::GenerateClusters(Int_t iChamber,
+ const AliMUONTriggerTrack& track,
+ AliMUONVClusterStore& clusterStore) const
+{
+ /// From a trigger track, generate 1 cluster in given chamber
+
+ /// Get a (rough) guestimate of the track momentum
+
+ Int_t nadded(0);
+
+ Double_t z = AliMUONConstants::DefaultChamberZ(10);
+
+ Double_t bendingCoord = track.GetY11();
+ Double_t bendingSlope = TMath::Tan(track.GetThetay());
+
+ Double_t bendingImpact = bendingCoord - z * bendingSlope;
+
+ AliDebug(1,Form("TriggerTrack impact parameter=%e",bendingImpact));
+
+ // StdoutToAliDebug(1,track.Print());
+
+ Double_t inverseBendingMomentum = 1. / AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(bendingImpact);
+
+ // Construct an AliMUONTrackParam from the trigger track, in order to be able to extrapolate it
+ // to chambers 6..9 planes.
+
+ AliMUONTrackParam trackParam;
+
+ trackParam.SetZ(z);
+ trackParam.SetNonBendingCoor(track.GetX11());
+ trackParam.SetNonBendingSlope(TMath::Tan(track.GetThetax()));
+ trackParam.SetBendingCoor(bendingCoord);
+ trackParam.SetBendingSlope(bendingSlope);
+ trackParam.SetInverseBendingMomentum(inverseBendingMomentum);
+
+ Double_t dZ = TMath::Abs(AliMUONConstants::DefaultChamberZ(12) - AliMUONConstants::DefaultChamberZ(10));
+
+ Double_t sigmaX = AliMUONConstants::TriggerNonBendingReso();
+
+ Double_t sigmaY = AliMUONConstants::TriggerBendingReso();
+
+ // Compute and set track parameters covariances
+ TMatrixD paramCov(5,5);
+ paramCov.Zero();
+
+ // Non bending plane
+ paramCov(0,0) = sigmaX*sigmaX;
+ paramCov(0,1) = -sigmaX/dZ;
+ paramCov(1,0) = paramCov(0,1);
+
+ paramCov(1,1) = 2.0*sigmaX/dZ/dZ;
+
+ // Bending plane
+ paramCov(2,2) = sigmaY*sigmaY;
+ paramCov(2,3) = -sigmaY/dZ;
+ paramCov(3,2) = paramCov(2,3);
+
+ paramCov(3,3) = 2.0*sigmaY/dZ/dZ;
+
+ // Inverse bending momentum (50% error)
+ paramCov(4,4) = 0.5*inverseBendingMomentum * 0.5*inverseBendingMomentum;
+
+ // Set covariances
+ trackParam.SetCovariances(paramCov);
+
+ // Now we extrapolate this trackParam to chambers 6 -> 9
+
+ const Float_t kFilterThickness = TMath::Abs(AliMUONConstants::MuonFilterZEnd()-AliMUONConstants::MuonFilterZBeg()); // cm
+
+ Int_t nclusters = clusterStore.GetSize();
+
+ AliMUONTrackParam tp(trackParam);
+
+ Double_t zg = AliMUONConstants::DefaultChamberZ(iChamber);
+ AliMUONTrackExtrap::ExtrapToZCov(&tp, zg); // Extrap to iChamber
+
+ AliMUONTrackExtrap::AddMCSEffect(&tp, kFilterThickness, AliMUONConstants::MuonFilterX0()); // Add MCS effects
+
+ AliDebug(1,Form("iChamber=%d",iChamber));
+
+ StdoutToAliDebug(1,tp.Print("FULLCOV"););
+
+ Double_t x = tp.GetNonBendingCoor();
+ Double_t y = tp.GetBendingCoor();
+ const TMatrixD& cov = tp.GetCovariances();
+ Double_t ex = TMath::Sqrt(cov(0,0));
+ Double_t ey = TMath::Sqrt(cov(2,2));
+
+ Double_t zde;
+
+ Int_t detElemId = DetElemId(iChamber,x,y,ex,ey,zde);
+
+ AliDebug(1,Form("zg = %e zde = %e",zg,zde));
+
+ if ( AliMpDEManager::IsValidDetElemId(detElemId) )
+ {
+ AliMUONVCluster* rawCluster = clusterStore.Add(AliMpDEManager::GetChamberId(detElemId), detElemId, nclusters);
+
+ ++nclusters;
+ ++nadded;
+
+ rawCluster->SetCharge(100.0);
+ rawCluster->SetXYZ(x, y, zg);
+ rawCluster->SetErrXY(ex,ey);
+ }
+ else
+ {
+ AliWarning(Form("No DE found at xg=%e yg=%e",detElemId,x,y));
+ }
+
+ return nadded;
+}
--- /dev/null
+#ifndef ALIMUONTRIGGERTRACKTOTRACKERCLUSTERS_H
+#define ALIMUONTRIGGERTRACKTOTRACKERCLUSTERS_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice */
+
+// $Id$
+
+/// \ingroup rec
+/// \class AliMUONTriggerTrackToTrackerClusters
+/// \brief Convertor of trigger track to tracker clusters
+///
+// Author Laurent Aphecetche, Subatech
+
+#ifndef ROOT_TObject
+# include "TObject.h"
+#endif
+
+class AliMUONTriggerTrack;
+class AliMUONVClusterStore;
+class AliMUONVTriggerTrackStore;
+class AliMUONGeometryTransformer;
+
+class AliMUONTriggerTrackToTrackerClusters : public TObject
+{
+public:
+ AliMUONTriggerTrackToTrackerClusters(const AliMUONGeometryTransformer& transformer, AliMUONVTriggerTrackStore* trackStore);
+ virtual ~AliMUONTriggerTrackToTrackerClusters();
+
+ Int_t GenerateClusters(Int_t iChamber, AliMUONVClusterStore& clusterStore) const;
+
+ Int_t GenerateClusters(Int_t iChamber,
+ const AliMUONTriggerTrack& track,
+ AliMUONVClusterStore& clusterStore) const;
+
+ Int_t DetElemId(Int_t chamber, Double_t x, Double_t y,
+ Double_t ex, Double_t ey, Double_t& z) const;
+
+private:
+ /// not defined
+ AliMUONTriggerTrackToTrackerClusters(const AliMUONTriggerTrackToTrackerClusters& rhs);
+ /// not defined
+ AliMUONTriggerTrackToTrackerClusters& operator=(const AliMUONTriggerTrackToTrackerClusters& rhs);
+
+private:
+ const AliMUONGeometryTransformer& fTransformer; ///< to go from local to global
+ AliMUONVTriggerTrackStore* fTriggerTrackStore; ///< not owner
+
+ ClassDef(AliMUONTriggerTrackToTrackerClusters,1) // Convertor of trigger tracks to tracker clusters
+};
+
+#endif
#endif
class AliMUONVClusterStore;
+class AliMUONVTriggerTrackStore;
class AliMpArea;
class TIter;
AliMUONVClusterStore& clusterStore,
const AliMpArea& area) = 0;
- /// Use digits from the given digitstore to perform our job.
+ /// Specify an iterator to loop over the digits needed to perform our job.
virtual void UseDigits(TIter& next) = 0;
+ /// Use trigger tracks. Return kFALSE if not used.
+ virtual Bool_t UseTriggerTrackStore(AliMUONVTriggerTrackStore* /*trackStore*/) { return kFALSE; }
+
ClassDef(AliMUONVClusterServer,1) // Cluster server interface
};
// Reset array of tracks
ResetTracks();
- // Look for candidates from at least 3 aligned points in stations(1..) 4 and 5
+ // Look for candidates from clusters in stations(1..) 4 and 5
MakeTrackCandidates(clusterStore);
+ // Look for extra candidates from clusters in stations(1..) 4 and 5
+ if (AliMUONReconstructor::GetRecoParam()->MakeMoreTrackCandidates()) MakeMoreTrackCandidates(clusterStore);
+
// Stop tracking if no candidate found
if (fRecTracksPtr->GetEntriesFast() == 0) return;
}
//__________________________________________________________________________
-TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsInStation(const AliMUONVClusterStore& clusterStore, Int_t station)
+TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsBetweenChambers(const AliMUONVClusterStore& clusterStore, Int_t ch1, Int_t ch2)
{
- /// To make the list of segments in station(0..) "Station" from the list of clusters to be reconstructed.
+ /// To make the list of segments from the list of clusters in the 2 given chambers.
/// Return a new TClonesArray of segments.
/// It is the responsibility of the user to delete it afterward.
- AliDebug(1,Form("Enter MakeSegmentsPerStation (1..) %d",station+1));
+ AliDebug(1,Form("Enter MakeSegmentsBetweenChambers (1..) %d-%d", ch1+1, ch2+1));
AliMUONVCluster *cluster1, *cluster2;
AliMUONObjectPair *segment;
- Double_t bendingSlope = 0, impactParam = 0., bendingMomentum = 0.; // to avoid compilation warning
- Int_t ch1 = 2 * station;
- Int_t ch2 = ch1 + 1;
+ Double_t nonBendingSlope = 0, bendingSlope = 0, impactParam = 0., bendingMomentum = 0.; // to avoid compilation warning
// Create iterators to loop over clusters in both chambers
TIter nextInCh1(clusterStore.CreateChamberIterator(ch1,ch1));
// Loop over clusters in the second chamber of the station
while ( ( cluster2 = static_cast<AliMUONVCluster*>(nextInCh2()) ) ) {
+ // non bending slope
+ nonBendingSlope = (cluster1->GetX() - cluster2->GetX()) / (cluster1->GetZ() - cluster2->GetZ());
+
// bending slope
bendingSlope = (cluster1->GetY() - cluster2->GetY()) / (cluster1->GetZ() - cluster2->GetZ());
// absolute value of bending momentum
bendingMomentum = TMath::Abs(AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(impactParam));
- // check for bending momentum within tolerances
- if ((bendingMomentum < AliMUONReconstructor::GetRecoParam()->GetMaxBendingMomentum()) &&
- (bendingMomentum > AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum())) {
+ // check for non bending slope and bending momentum within tolerances
+ if (TMath::Abs(nonBendingSlope) < AliMUONReconstructor::GetRecoParam()->GetMaxNonBendingSlope() &&
+ bendingMomentum < AliMUONReconstructor::GetRecoParam()->GetMaxBendingMomentum() &&
+ bendingMomentum > AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum()) {
// make new segment
segment = new ((*segments)[segments->GetLast()+1]) AliMUONObjectPair(cluster1, cluster2, kFALSE, kFALSE);
}
// Printout for debug
- AliDebug(1,Form("Station: %d NSegments: %d ", station+1, segments->GetEntriesFast()));
+ AliDebug(1,Form("chambers%d-%d: NSegments = %d ", ch1+1, ch2+1, segments->GetEntriesFast()));
return segments;
}
}
//__________________________________________________________________________
-void AliMUONVTrackReconstructor::AskForNewClustersInStation(const AliMUONTrackParam &trackParam,
- AliMUONVClusterStore& clusterStore, Int_t station)
+void AliMUONVTrackReconstructor::AskForNewClustersInChamber(const AliMUONTrackParam &trackParam,
+ AliMUONVClusterStore& clusterStore, Int_t chamber)
{
/// Ask the clustering to reconstruct new clusters around the track candidate position
- /// in the 2 chambers of the given station
- // maximum shift of the searching area due to distance between detection elements and the track slope
- static const Double_t kgMaxShift = 2.; // 2 cm
+ // check if the current chamber is useable
+ if (!AliMUONReconstructor::GetRecoParam()->UseChamber(chamber)) return;
- // extrapolate track parameters to the second chamber of the station
- AliMUONTrackParam extrapTrackParam(trackParam);
- AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(2*station+1));
+ // maximum distance between the center of the chamber and a detection element
+ // (accounting for the inclination of the chamber)
+ static const Double_t gkMaxDZ = 15.; // 15 cm
- // build the searching area
+ // extrapolate track parameters to the chamber
+ AliMUONTrackParam extrapTrackParam(trackParam);
+ AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(chamber));
+
+ // build the searching area using the track resolution and the maximum-distance-to-track value
+ const TMatrixD& kParamCov = extrapTrackParam.GetCovariances();
+ Double_t errX2 = kParamCov(0,0) + gkMaxDZ * gkMaxDZ * kParamCov(1,1) + 2. * gkMaxDZ * TMath::Abs(kParamCov(0,1));
+ Double_t errY2 = kParamCov(2,2) + gkMaxDZ * gkMaxDZ * kParamCov(3,3) + 2. * gkMaxDZ * TMath::Abs(kParamCov(2,3));
+ Double_t dX = TMath::Abs(trackParam.GetNonBendingSlope()) * gkMaxDZ +
+ AliMUONReconstructor::GetRecoParam()->GetMaxNonBendingDistanceToTrack() +
+ AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * TMath::Sqrt(errX2);
+ Double_t dY = TMath::Abs(trackParam.GetBendingSlope()) * gkMaxDZ +
+ AliMUONReconstructor::GetRecoParam()->GetMaxBendingDistanceToTrack() +
+ AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * TMath::Sqrt(errY2);
+ TVector2 dimensions(dX, dY);
TVector2 position(extrapTrackParam.GetNonBendingCoor(), extrapTrackParam.GetBendingCoor());
- TVector2 dimensions(AliMUONReconstructor::GetRecoParam()->GetMaxNonBendingDistanceToTrack() + kgMaxShift,
- AliMUONReconstructor::GetRecoParam()->GetMaxBendingDistanceToTrack() + kgMaxShift);
- AliMpArea area2(position, dimensions);
+ AliMpArea area(position, dimensions);
// ask to cluterize in the given area of the given chamber
- fClusterServer.Clusterize(2*station+1, clusterStore, area2);
+ fClusterServer.Clusterize(chamber, clusterStore, area);
- // extrapolate track parameters to the first chamber of the station
- AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(2*station));
-
- // build the searching area
- position.Set(extrapTrackParam.GetNonBendingCoor(), extrapTrackParam.GetBendingCoor());
- AliMpArea area1(position, dimensions);
-
- // ask to cluterize in the given area of the given chamber
- fClusterServer.Clusterize(2*station, clusterStore, area1);
+}
+
+ //__________________________________________________________________________
+void AliMUONVTrackReconstructor::AskForNewClustersInStation(const AliMUONTrackParam &trackParam,
+ AliMUONVClusterStore& clusterStore, Int_t station)
+{
+ /// Ask the clustering to reconstruct new clusters around the track candidate position
+ /// in the 2 chambers of the given station
+ AskForNewClustersInChamber(trackParam, clusterStore, 2*station+1);
+ AskForNewClustersInChamber(trackParam, clusterStore, 2*station);
}
//__________________________________________________________________________
//__________________________________________________________________________
Bool_t AliMUONVTrackReconstructor::TryOneClusterFast(const AliMUONTrackParam &trackParam, AliMUONVCluster* cluster)
{
-/// Test the compatibility between the track and the cluster within a wide fix window
-/// assuming linear propagation of the track:
+/// Test the compatibility between the track and the cluster
+/// given the track resolution + the maximum-distance-to-track value
+/// and assuming linear propagation of the track:
/// return kTRUE if they are compatibles
Double_t dZ = cluster->GetZ() - trackParam.GetZ();
Double_t dX = cluster->GetX() - (trackParam.GetNonBendingCoor() + trackParam.GetNonBendingSlope() * dZ);
Double_t dY = cluster->GetY() - (trackParam.GetBendingCoor() + trackParam.GetBendingSlope() * dZ);
+ const TMatrixD& kParamCov = trackParam.GetCovariances();
+ Double_t errX2 = kParamCov(0,0) + dZ * dZ * kParamCov(1,1) + 2. * dZ * kParamCov(0,1);
+ Double_t errY2 = kParamCov(2,2) + dZ * dZ * kParamCov(3,3) + 2. * dZ * kParamCov(2,3);
+
+ Double_t dXmax = AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * TMath::Sqrt(errX2) +
+ AliMUONReconstructor::GetRecoParam()->GetMaxNonBendingDistanceToTrack();
+ Double_t dYmax = AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * TMath::Sqrt(errY2) +
+ AliMUONReconstructor::GetRecoParam()->GetMaxBendingDistanceToTrack();
- if (TMath::Abs(dX) > AliMUONReconstructor::GetRecoParam()->GetMaxNonBendingDistanceToTrack() ||
- TMath::Abs(dY) > AliMUONReconstructor::GetRecoParam()->GetMaxBendingDistanceToTrack()) return kFALSE;
+ if (TMath::Abs(dX) > dXmax || TMath::Abs(dY) > dYmax) return kFALSE;
return kTRUE;
}
//__________________________________________________________________________
+Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInChamber(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore,
+ Int_t nextChamber)
+{
+ /// Follow trackCandidate in chamber(0..) nextChamber assuming linear propagation, and search for compatible cluster(s)
+ /// Keep all possibilities or only the best one(s) according to the flag fgkTrackAllTracks:
+ /// kTRUE: duplicate "trackCandidate" if there are several possibilities and add the new tracks at the end of
+ /// fRecTracksPtr to avoid conficts with other track candidates at this current stage of the tracking procedure.
+ /// Remove the obsolete "trackCandidate" at the end.
+ /// kFALSE: add only the best cluster(s) to the "trackCandidate". Try to add a couple of clusters in priority.
+ /// return kTRUE if new cluster(s) have been found (otherwise return kFALSE)
+ AliDebug(1,Form("Enter FollowLinearTrackInChamber(1..) %d", nextChamber+1));
+
+ Double_t chi2WithOneCluster = 1.e10;
+ Double_t maxChi2WithOneCluster = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
+ AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
+ Double_t bestChi2WithOneCluster = maxChi2WithOneCluster;
+ Bool_t foundOneCluster = kFALSE;
+ AliMUONTrack *newTrack = 0x0;
+ AliMUONVCluster *cluster;
+ AliMUONTrackParam trackParam;
+ AliMUONTrackParam extrapTrackParamAtCluster;
+ AliMUONTrackParam bestTrackParamAtCluster;
+
+ // Get track parameters according to the propagation direction
+ if (nextChamber > 7) trackParam = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->Last();
+ else trackParam = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First();
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
+ cout<<endl<<"Track parameters and covariances at first cluster:"<<endl;
+ trackParam.GetParameters().Print();
+ trackParam.GetCovariances().Print();
+ }
+
+ // Add MCS effect
+ AliMUONTrackExtrap::AddMCSEffect(&trackParam,AliMUONConstants::ChamberThicknessInX0(),1.);
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+ cout << "FollowLinearTrackInChamber: look for cluster in chamber(1..): " << nextChamber+1 << endl;
+ }
+
+ // Create iterators to loop over clusters in chamber
+ TIter next(clusterStore.CreateChamberIterator(nextChamber,nextChamber));
+
+ // look for candidates in chamber
+ while ( ( cluster = static_cast<AliMUONVCluster*>(next()) ) ) {
+
+ // try to add the current cluster fast
+ if (!TryOneClusterFast(trackParam, cluster)) continue;
+
+ // try to add the current cluster accuratly
+ extrapTrackParamAtCluster = trackParam;
+ AliMUONTrackExtrap::LinearExtrapToZ(&extrapTrackParamAtCluster, cluster->GetZ());
+ chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCluster, cluster, extrapTrackParamAtCluster);
+
+ // if good chi2 then consider to add cluster
+ if (chi2WithOneCluster < maxChi2WithOneCluster) {
+ foundOneCluster = kTRUE;
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+ cout << "FollowLinearTrackInChamber: found one cluster in chamber(1..): " << nextChamber+1
+ << " (Chi2 = " << chi2WithOneCluster << ")" << endl;
+ cluster->Print();
+ }
+
+ if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
+ // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
+ newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
+ if (AliMUONReconstructor::GetRecoParam()->RequestStation(nextChamber/2))
+ extrapTrackParamAtCluster.SetRemovable(kFALSE);
+ else extrapTrackParamAtCluster.SetRemovable(kTRUE);
+ newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster,*cluster);
+ fNRecTracks++;
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+ cout << "FollowLinearTrackInChamber: added one cluster in chamber(1..): " << nextChamber+1 << endl;
+ if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
+ }
+
+ } else if (chi2WithOneCluster < bestChi2WithOneCluster) {
+ // keep track of the best cluster
+ bestChi2WithOneCluster = chi2WithOneCluster;
+ bestTrackParamAtCluster = extrapTrackParamAtCluster;
+ }
+
+ }
+
+ }
+
+ // fill out the best track if required else clean up the fRecTracksPtr array
+ if (!AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
+ if (foundOneCluster) {
+ if (AliMUONReconstructor::GetRecoParam()->RequestStation(nextChamber/2))
+ bestTrackParamAtCluster.SetRemovable(kFALSE);
+ else bestTrackParamAtCluster.SetRemovable(kTRUE);
+ trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster,*(bestTrackParamAtCluster.GetClusterPtr()));
+
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+ cout << "FollowLinearTrackInChamber: added the best cluster in chamber(1..): " << bestTrackParamAtCluster.GetClusterPtr()->GetChamberId()+1 << endl;
+ if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
+ }
+
+ } else return kFALSE;
+
+ } else if (foundOneCluster) {
+
+ // remove obsolete track
+ fRecTracksPtr->Remove(&trackCandidate);
+ fNRecTracks--;
+
+ } else return kFALSE;
+
+ return kTRUE;
+
+}
+
+//__________________________________________________________________________
Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore,
Int_t nextStation)
{
if (nextStation==4) trackParam = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->Last();
else trackParam = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First();
+ // Printout for debuging
+ if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
+ cout<<endl<<"Track parameters and covariances at first cluster:"<<endl;
+ trackParam.GetParameters().Print();
+ trackParam.GetCovariances().Print();
+ }
+
// Add MCS effect
AliMUONTrackExtrap::AddMCSEffect(&trackParam,AliMUONConstants::ChamberThicknessInX0(),1.);
if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
cout << "FollowLinearTrackInStation: found one cluster in chamber(1..): " << ch2+1
<< " (Chi2 = " << chi2WithOneCluster << ")" << endl;
+ clusterCh2->Print();
cout << " look for second clusters in chamber(1..): " << ch1+1 << " ..." << endl;
}
// Printout for debuging
if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
cout << "FollowLinearTrackInStation: found one cluster in chamber(1..): " << ch1+1
- << " (Chi2 = " << chi2WithTwoClusters << ")" << endl;
+ << " (Chi2 = " << chi2WithTwoClusters << ")" << endl;
+ clusterCh1->Print();
}
if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
// copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
- extrapTrackParamAtCluster2.SetRemovable(kFALSE);
+ if (AliMUONReconstructor::GetRecoParam()->RequestStation(nextStation))
+ extrapTrackParamAtCluster2.SetRemovable(kFALSE);
+ else extrapTrackParamAtCluster2.SetRemovable(kTRUE);
newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster2,*clusterCh2);
fNRecTracks++;
// add MCS effect for next step
AliMUONTrackExtrap::AddMCSEffect(&trackParam,AliMUONConstants::ChamberThicknessInX0(),1.);
-
+
// reset cluster iterator of chamber 1
nextInCh1.Reset();
iCluster1 = -1;
// try to add the current cluster fast
if (!TryOneClusterFast(trackParam, clusterCh1)) continue;
-
+
// try to add the current cluster accuratly
extrapTrackParamAtCluster1 = trackParam;
AliMUONTrackExtrap::LinearExtrapToZ(&extrapTrackParamAtCluster1, clusterCh1->GetZ());
chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCluster1, clusterCh1, extrapTrackParamAtCluster1);
-
+
// if good chi2 then consider to add clusterCh1
// We do not try to attach a cluster in the other chamber too since it has already been done above
if (chi2WithOneCluster < maxChi2WithOneCluster) {
if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
cout << "FollowLinearTrackInStation: found one cluster in chamber(1..): " << ch1+1
<< " (Chi2 = " << chi2WithOneCluster << ")" << endl;
+ clusterCh1->Print();
}
if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
// copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
- extrapTrackParamAtCluster1.SetRemovable(kFALSE);
+ if (AliMUONReconstructor::GetRecoParam()->RequestStation(nextStation))
+ extrapTrackParamAtCluster1.SetRemovable(kFALSE);
+ else extrapTrackParamAtCluster1.SetRemovable(kTRUE);
newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster1,*clusterCh1);
fNRecTracks++;
}
} else if (foundOneCluster) {
- bestTrackParamAtCluster1.SetRemovable(kFALSE);
+ if (AliMUONReconstructor::GetRecoParam()->RequestStation(nextStation))
+ bestTrackParamAtCluster1.SetRemovable(kFALSE);
+ else bestTrackParamAtCluster1.SetRemovable(kTRUE);
trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster1,*(bestTrackParamAtCluster1.GetClusterPtr()));
// Printout for debuging
AliMUONVTrackReconstructor (const AliMUONVTrackReconstructor& rhs); ///< copy constructor
AliMUONVTrackReconstructor& operator=(const AliMUONVTrackReconstructor& rhs); ///< assignment operator
- /// Make track candidats from clusters in stations(1..) 4 and 5
+ /// Make track candidates from clusters in stations(1..) 4 and 5
virtual void MakeTrackCandidates(AliMUONVClusterStore& clusterStore) = 0;
+ /// Make extra track candidates from clusters in stations(1..) 4 and 5
+ virtual void MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore) = 0;
/// Follow tracks in stations(1..) 3, 2 and 1
virtual void FollowTracks(AliMUONVClusterStore& clusterStore) = 0;
/// Complement the reconstructed tracks
/// Finalize the given track
virtual void FinalizeTrack(AliMUONTrack &track) = 0;
- TClonesArray* MakeSegmentsInStation(const AliMUONVClusterStore& clusterStore, Int_t station);
+ TClonesArray* MakeSegmentsBetweenChambers(const AliMUONVClusterStore& clusterStore, Int_t ch1, Int_t ch2);
void RemoveIdenticalTracks();
void RemoveDoubleTracks();
void AskForNewClustersInStation(const AliMUONTrackParam &trackParam,
AliMUONVClusterStore& clusterStore, Int_t station);
+ void AskForNewClustersInChamber(const AliMUONTrackParam &trackParam,
+ AliMUONVClusterStore& clusterStore, Int_t chamber);
Double_t TryOneCluster(const AliMUONTrackParam &trackParam, AliMUONVCluster* cluster,
AliMUONTrackParam &trackParamAtCluster, Bool_t updatePropagator = kFALSE);
Double_t TryTwoClustersFast(const AliMUONTrackParam &trackParamAtCluster1, AliMUONVCluster* cluster2,
AliMUONTrackParam &trackParamAtCluster2);
- Bool_t FollowLinearTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore,
- Int_t nextStation);
+ Bool_t FollowLinearTrackInChamber(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, Int_t nextChamber);
+ Bool_t FollowLinearTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, Int_t nextStation);
private:
#include <Riostream.h>
#include <TGeoManager.h>
#include <TROOT.h>
+#include <TF1.h>
#endif
cout << "Chi2Cut for muon tracks = " << Chi2Cut << endl;
cout << "PtCutMin for muon tracks = " << PtCutMin << endl;
cout << "PtCutMax for muon tracks = " << PtCutMax << endl;
+
+ hInvMassAll->Fit("gaus","q0");
+
+ TF1* f1 = hInvMassAll->GetFunction("gaus");
+
+ cout << "Entries (unlike sign dimuons) : " << hInvMassAll->GetEntries()
+ << Form(". Rough sigma = %7.2f MeV/c2",f1->GetParameter(2)*1000.0) << endl;
+
cout << "Entries (unlike sign dimuons) in the mass range ["<<invMassMinInPeak<<";"<<invMassMaxInPeak<<"] : " << EventInMass <<endl;
+
if (ptTrig==0x800) cout << "Unlike Pair - All Pt" ;
if (ptTrig==0x400) cout << "Unlike Pair - High Pt" ;
if (ptTrig==0x200) cout << "Unlike Pair - Low Pt" ;
#pragma link C++ class AliMUONVClusterServer+;
#pragma link C++ class AliMUONSimpleClusterServer+;
+#pragma link C++ class AliMUONLegacyClusterServer+;
+#pragma link C++ class AliMUONTriggerTrackToTrackerClusters+;
#pragma link C++ class AliMUONESDInterface+;
AliMUONClusterFinderPeakCOG.cxx \
AliMUONClusterFinderPeakFit.cxx \
AliMUONRefitter.cxx \
- AliMUONESDInterface.cxx
+ AliMUONESDInterface.cxx \
+ AliMUONLegacyClusterServer.cxx \
+ AliMUONTriggerTrackToTrackerClusters.cxx
HDRS:= $(SRCS:.cxx=.h)
// MuonRec->SetEventRange(319,319);
MuonRec->SetWriteAOD();
- AliMUONRecoParam *muonRecoParam = AliMUONRecoParam::GetLowFluxParam();
- muonRecoParam->CombineClusterTrackReco(kTRUE);
- //muonRecoParam->SetClusteringMode("PEAKFIT");
- //muonRecoParam->SetClusteringMode("PEAKCOG");
+ AliMUONRecoParam* muonRecoParam = AliMUONRecoParam::GetLowFluxParam();
+ muonRecoParam->CombineClusterTrackReco(kFALSE);
+ muonRecoParam->BypassSt45(kTRUE);
+ // muonRecoParam->SetMaxBendingMomentum(10000000.0);
+ // muonRecoParam->SetMaxNonBendingDistanceToTrack(200.0);
+ // muonRecoParam->SetMaxBendingDistanceToTrack(200.0);
+ muonRecoParam->SetSigmaCutForTracking(20.0);
+ // muonRecoParam->UseSmoother(kFALSE);
+ muonRecoParam->RequestStation(2,kFALSE);
+ muonRecoParam->ImproveTracks(kFALSE);
muonRecoParam->Print("FULL");
+
AliRecoParam::Instance()->RegisterRecoParam(muonRecoParam);
MuonRec->Run();
//gObjectTable->Print();
}
-