From 9bf6860bdd8c933089cab44a94c95664875e5c5f Mon Sep 17 00:00:00 2001 From: laphecet Date: Sun, 30 Mar 2008 22:06:05 +0000 Subject: [PATCH] Re-establishing creation of RecPoints in TreeR (Laurent) Introducing tracking mode starting from trigger tracks (Laurent) New options for tracking and some bugs fixed (Philippe P.) ======================================================== New classes : - AliMUONLegacyClusterServer (Laurent) A cluster server which is doing no more than serving clusters from an existing cluster store. Used to re-establish clustering in local reconstruction (see AliMUONReconstructor's changes) - AliMUONTriggerTrackToTrackerClusters (Laurent) A class to replace clusters in stations 4 and 5 (that are discarded (if they exist)) by "fake" ones, created from the extrapolation of trigger tracks to st45. Created to allow reconstruction of data taken during Feb. 08 cosmic run where st45 were not ready yet. ======================================================== AliMUONReconstructor.cxx (Laurent) Re-establishing, in the case of non-combined tracking, the filling of the TreeR with the clusters, i.e. clustering is done in local reconstruction in that case, and not in tracking phase. AliMUONClusterFinderMLEM.cxx (Laurent) Fixing a small memory leak libMUONrec.pkg (Laurent) MUONrecLinkDef.h Adding new classes AliMUONClusterStoreV2.cxx (Laurent) Fixing a memory leak in ReMap AliMUONRawClusterV2.cxx (Laurent) AliMUONCluster.cxx Fixing errors found by valgrind AliMUONSimpleClusterServer (Laurent) Changing ctor parameter from ref to pointer, as we're taking ownership of that object, and adding a method to find out in which DE a global (x,y) position is. AliMUONVClusterServer.h (Laurent) Changing comment which did not follow interface change... AliMUONTracker (Laurent) If no cluster server given, use legacy one (see also changes in AliMUONReconstructor) AliMUONRecoParam (Laurent & Philippe P.) New options AliMUONRefitter (Laurent) Avoids code duplication and use new SimpleClusterServer interface. AliMUON*Tracker* (Philippe P.) - solved the problem of divergence in the tracking of low momentum muons - added a reconstruction parameter defining the maximum non bending slope of the primary track candidates - added the possibility to disable one or more chambers in the reconstruction (new option) - added the possibility to reconstruct a track even if it has no cluster in one or more stations (new option) - added the possibility to make a primary track candidate starting from one cluster on station 4 and one on station 5 (new option) --- MUON/AliMUONCluster.cxx | 1 + MUON/AliMUONClusterFinderMLEM.cxx | 8 +- MUON/AliMUONClusterStoreV2.cxx | 31 +- MUON/AliMUONGeometryTransformer.cxx | 106 ++++- MUON/AliMUONGeometryTransformer.h | 12 +- MUON/AliMUONLegacyClusterServer.cxx | 126 ++++++ MUON/AliMUONLegacyClusterServer.h | 53 +++ MUON/AliMUONRawClusterV2.cxx | 2 +- MUON/AliMUONRecoParam.cxx | 77 +++- MUON/AliMUONRecoParam.h | 47 +- MUON/AliMUONReconstructor.cxx | 85 +++- MUON/AliMUONReconstructor.h | 7 +- MUON/AliMUONRefitter.cxx | 53 +-- MUON/AliMUONSimpleClusterServer.cxx | 119 ++--- MUON/AliMUONSimpleClusterServer.h | 17 +- MUON/AliMUONTrack.cxx | 109 ++--- MUON/AliMUONTrackExtrap.cxx | 12 +- MUON/AliMUONTrackReconstructor.cxx | 428 ++++++++++++++---- MUON/AliMUONTrackReconstructor.h | 2 + MUON/AliMUONTrackReconstructorK.cxx | 424 ++++++++++++++--- MUON/AliMUONTrackReconstructorK.h | 2 + MUON/AliMUONTracker.cxx | 157 +++++-- MUON/AliMUONTracker.h | 22 +- MUON/AliMUONTriggerTrackToTrackerClusters.cxx | 229 ++++++++++ MUON/AliMUONTriggerTrackToTrackerClusters.h | 52 +++ MUON/AliMUONVClusterServer.h | 6 +- MUON/AliMUONVTrackReconstructor.cxx | 250 ++++++++-- MUON/AliMUONVTrackReconstructor.h | 12 +- MUON/MUONefficiency.C | 10 + MUON/MUONrecLinkDef.h | 2 + MUON/libMUONrec.pkg | 4 +- MUON/runReconstruction.C | 16 +- 32 files changed, 1979 insertions(+), 502 deletions(-) create mode 100644 MUON/AliMUONLegacyClusterServer.cxx create mode 100644 MUON/AliMUONLegacyClusterServer.h create mode 100644 MUON/AliMUONTriggerTrackToTrackerClusters.cxx create mode 100644 MUON/AliMUONTriggerTrackToTrackerClusters.h diff --git a/MUON/AliMUONCluster.cxx b/MUON/AliMUONCluster.cxx index 3fb8fe5504d..642c462fb52 100644 --- a/MUON/AliMUONCluster.cxx +++ b/MUON/AliMUONCluster.cxx @@ -346,6 +346,7 @@ AliMUONCluster::Copy(TObject& obj) const /// TObject::Copy(obj); AliMUONCluster& dest = static_cast(obj); + delete dest.fPads; dest.fPads = 0x0; if ( fPads ) { diff --git a/MUON/AliMUONClusterFinderMLEM.cxx b/MUON/AliMUONClusterFinderMLEM.cxx index c4142b0ca36..24254a87041 100644 --- a/MUON/AliMUONClusterFinderMLEM.cxx +++ b/MUON/AliMUONClusterFinderMLEM.cxx @@ -161,16 +161,16 @@ AliMUONClusterFinderMLEM::NextCluster() // 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 diff --git a/MUON/AliMUONClusterStoreV2.cxx b/MUON/AliMUONClusterStoreV2.cxx index 9774a3eb51b..aa0b9f31fb0 100644 --- a/MUON/AliMUONClusterStoreV2.cxx +++ b/MUON/AliMUONClusterStoreV2.cxx @@ -191,10 +191,15 @@ AliMUONVCluster* AliMUONClusterStoreV2::Remove(AliMUONVCluster& cluster) /// Remove a cluster AliMUONVCluster* c = static_cast(fClusters->Remove(&cluster)); - if (c) { + if (c) + { fClusters->Compress(); fMapped = kFALSE; } + else + { + AliError("Could not remove cluster from array"); + } return c; } @@ -207,16 +212,24 @@ void AliMUONClusterStoreV2::ReMap() // 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; chamberSetOwner(kFALSE); + if (!fMap) { + fMap = new TClonesArray("AliMpExMap",nChamber); + + // Create one map per chamber + AliMpExMap *map; + for (Int_t chamber=0; chamberSetOwner(kFALSE); + } } - + else { + for (Int_t chamber=0; chamber(fMap->At(chamber)); + map->Clear("C"); + } + } + // Fill the maps TIter next(fClusters); AliMUONVCluster* cluster; diff --git a/MUON/AliMUONGeometryTransformer.cxx b/MUON/AliMUONGeometryTransformer.cxx index 8adc9680067..0f81ee8a29d 100644 --- a/MUON/AliMUONGeometryTransformer.cxx +++ b/MUON/AliMUONGeometryTransformer.cxx @@ -31,6 +31,14 @@ #include "AliMpConstants.h" #include "AliMpExMap.h" #include "AliMpCDB.h" +#include "AliMpArea.h" +#include +#include "AliMpVPadIterator.h" +#include "AliMpPad.h" +#include "AliMpDEIterator.h" +#include +#include "AliMpVSegmentation.h" +#include "AliMpSegmentation.h" #include "AliLog.h" #include "AliAlignObjMatrix.h" @@ -58,7 +66,8 @@ AliMUONGeometryTransformer::AliMUONGeometryTransformer() : TObject(), fDetectorName(fgkDefaultDetectorName), fModuleTransformers(0), - fMisAlignArray(0) + fMisAlignArray(0), + fDEAreas(0x0) { /// Standard constructor @@ -72,7 +81,8 @@ AliMUONGeometryTransformer::AliMUONGeometryTransformer(TRootIOCtor* /*ioCtor*/) : TObject(), fDetectorName(), fModuleTransformers(0), - fMisAlignArray(0) + fMisAlignArray(0), + fDEAreas(0x0) { /// Default constructor } @@ -84,12 +94,104 @@ AliMUONGeometryTransformer::~AliMUONGeometryTransformer() 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(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 { diff --git a/MUON/AliMUONGeometryTransformer.h b/MUON/AliMUONGeometryTransformer.h index 07566edb7bb..14a4f4871dd 100644 --- a/MUON/AliMUONGeometryTransformer.h +++ b/MUON/AliMUONGeometryTransformer.h @@ -30,6 +30,8 @@ class AliMUONGeometryDetElement; class TGeoManager; class TClonesArray; +class AliMpExMap; +class AliMpArea; class AliMUONGeometryTransformer : public TObject { @@ -92,6 +94,8 @@ class AliMUONGeometryTransformer : public TObject Bool_t HasDE(Int_t detElemId) const; + AliMpArea* GetDEArea(Int_t detElemId) const; + protected: /// Not implemented AliMUONGeometryTransformer(const AliMUONGeometryTransformer& right); @@ -100,6 +104,9 @@ class AliMUONGeometryTransformer : public TObject private: // methods + + void CreateDEAreas() const; + Bool_t LoadMapping() const; AliMUONGeometryModuleTransformer* GetModuleTransformerNonConst( Int_t index, Bool_t warn = true) const; @@ -138,8 +145,9 @@ class AliMUONGeometryTransformer : public TObject 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 diff --git a/MUON/AliMUONLegacyClusterServer.cxx b/MUON/AliMUONLegacyClusterServer.cxx new file mode 100644 index 00000000000..8ad26ba0fea --- /dev/null +++ b/MUON/AliMUONLegacyClusterServer.cxx @@ -0,0 +1,126 @@ +/************************************************************************** +* 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 + +/// \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(next()) ) ) + { + clusterStore.Add(*cluster); + a.Add(cluster); + ++n; + } + + TIter remove(&a); + while ( ( cluster = static_cast(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 !"); +} + diff --git a/MUON/AliMUONLegacyClusterServer.h b/MUON/AliMUONLegacyClusterServer.h new file mode 100644 index 00000000000..316325f7fc8 --- /dev/null +++ b/MUON/AliMUONLegacyClusterServer.h @@ -0,0 +1,53 @@ +#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; //= 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: @@ -139,6 +163,7 @@ class AliMUONRecoParam : public AliDetectorRecoParam 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) @@ -164,6 +189,8 @@ class AliMUONRecoParam : public AliDetectorRecoParam 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 @@ -172,15 +199,21 @@ class AliMUONRecoParam : public AliDetectorRecoParam 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 diff --git a/MUON/AliMUONReconstructor.cxx b/MUON/AliMUONReconstructor.cxx index 59f0c1e5de0..36294ed48f7 100644 --- a/MUON/AliMUONReconstructor.cxx +++ b/MUON/AliMUONReconstructor.cxx @@ -83,6 +83,8 @@ #include "AliMUONClusterFinderSimpleFit.h" #include "AliMUONClusterFinderPeakCOG.h" #include "AliMUONClusterFinderPeakFit.h" +#include "AliMUONClusterStoreV1.h" +#include "AliMUONClusterStoreV2.h" #include "AliMUONConstants.h" #include "AliMUONDigitCalibrator.h" #include "AliMUONDigitMaker.h" @@ -310,29 +312,37 @@ AliMUONReconstructor::CreateTracker() const 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); @@ -389,7 +399,7 @@ AliMUONReconstructor::CreateClusterFinder(const char* clusterFinderType) const } else { - AliError(Form("clustering mode \"%s\" does not exist",opt.Data())); + AliErrorClass(Form("clustering mode \"%s\" does not exist",opt.Data())); return 0x0; } @@ -404,17 +414,15 @@ AliMUONReconstructor::CreateClusterServer() const 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); } //_____________________________________________________________________________ @@ -503,19 +511,62 @@ AliMUONReconstructor::FillTreeR(AliMUONVTriggerStore* triggerStore, 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; } //_____________________________________________________________________________ diff --git a/MUON/AliMUONReconstructor.h b/MUON/AliMUONReconstructor.h index 62a7b3aa191..0994b9d9e59 100644 --- a/MUON/AliMUONReconstructor.h +++ b/MUON/AliMUONReconstructor.h @@ -57,6 +57,8 @@ public: static const AliMUONRecoParam* GetRecoParam(); + static AliMUONVClusterFinder* CreateClusterFinder(const char* clusterFinderType); + private: /// Not implemented AliMUONReconstructor(const AliMUONReconstructor&); @@ -69,7 +71,6 @@ private: 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; @@ -78,7 +79,7 @@ private: AliMUONVDigitStore* DigitStore() const; AliMUONVTriggerStore* TriggerStore() const; - + private: mutable AliMUONTriggerCrateStore* fCrateManager; //!< Trigger Crate manager mutable AliMUONDigitMaker* fDigitMaker; //!< Raw to Digits converter @@ -93,7 +94,7 @@ private: static AliMUONRecoParam* fgRecoParam; //!< parameters used to tune the MUON reconstruction - ClassDef(AliMUONReconstructor,5) // Implementation of AliReconstructor + ClassDef(AliMUONReconstructor,6) // Implementation of AliReconstructor }; #endif diff --git a/MUON/AliMUONRefitter.cxx b/MUON/AliMUONRefitter.cxx index 8764784fee2..865256f089a 100644 --- a/MUON/AliMUONRefitter.cxx +++ b/MUON/AliMUONRefitter.cxx @@ -31,7 +31,7 @@ #include "AliMUONVClusterStore.h" #include "AliMUONVTrackStore.h" #include "AliMUONTrack.h" - +#include "AliMUONTracker.h" #include "AliLog.h" //----------------------------------------------------------------------------- @@ -68,7 +68,7 @@ AliMUONRefitter::AliMUONRefitter() /// 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); @@ -339,53 +339,8 @@ void AliMUONRefitter::CreateGeometryTransformer() 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; } //_____________________________________________________________________________ diff --git a/MUON/AliMUONSimpleClusterServer.cxx b/MUON/AliMUONSimpleClusterServer.cxx index 853df2ba724..401b57ed6b2 100644 --- a/MUON/AliMUONSimpleClusterServer.cxx +++ b/MUON/AliMUONSimpleClusterServer.cxx @@ -17,10 +17,13 @@ #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" @@ -29,16 +32,13 @@ #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 #include #include #include - +#include /// \class AliMUONSimpleClusterServer /// @@ -64,95 +64,31 @@ namespace } //_____________________________________________________________________________ -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; } //_____________________________________________________________________________ @@ -167,6 +103,13 @@ AliMUONSimpleClusterServer::Clusterize(Int_t chamberId, /// 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); @@ -200,17 +143,17 @@ AliMUONSimpleClusterServer::Clusterize(Int_t 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)", @@ -220,7 +163,7 @@ AliMUONSimpleClusterServer::Clusterize(Int_t chamberId, 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 @@ -267,6 +210,7 @@ AliMUONSimpleClusterServer::Clusterize(Int_t chamberId, return nofAddedClusters; } + //_____________________________________________________________________________ void AliMUONSimpleClusterServer::Global2Local(Int_t detElemId, const AliMpArea& globalArea, @@ -297,7 +241,9 @@ AliMUONSimpleClusterServer::Overlap(Int_t detElemId, Bool_t overlap(kFALSE); - AliMpArea* globalDEArea = static_cast(fDEAreas->GetValue(detElemId)); + AliMpArea* globalDEArea = fTransformer.GetDEArea(detElemId); + + if (!globalDEArea) return kFALSE; AliMpArea overlapArea; @@ -332,6 +278,17 @@ AliMUONSimpleClusterServer::PadArray(Int_t detElemId, Int_t cathode) const return static_cast(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) diff --git a/MUON/AliMUONSimpleClusterServer.h b/MUON/AliMUONSimpleClusterServer.h index 042da88bf78..74612e402b2 100644 --- a/MUON/AliMUONSimpleClusterServer.h +++ b/MUON/AliMUONSimpleClusterServer.h @@ -16,16 +16,17 @@ # 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(); @@ -37,7 +38,10 @@ public: 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); @@ -51,10 +55,11 @@ private: 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 }; diff --git a/MUON/AliMUONTrack.cxx b/MUON/AliMUONTrack.cxx index 8a38f42b8f0..804ca8446b6 100644 --- a/MUON/AliMUONTrack.cxx +++ b/MUON/AliMUONTrack.cxx @@ -23,6 +23,8 @@ #include "AliMUONTrack.h" +#include "AliMUONReconstructor.h" +#include "AliMUONRecoParam.h" #include "AliMUONVCluster.h" #include "AliMUONVClusterStore.h" #include "AliMUONObjectPair.h" @@ -89,26 +91,8 @@ AliMUONTrack::AliMUONTrack(AliMUONObjectPair *segment) 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(); @@ -126,8 +110,7 @@ AliMUONTrack::AliMUONTrack(AliMUONObjectPair *segment) 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); @@ -136,8 +119,7 @@ AliMUONTrack::AliMUONTrack(AliMUONObjectPair *segment) 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); @@ -146,43 +128,40 @@ AliMUONTrack::AliMUONTrack(AliMUONObjectPair *segment) 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); @@ -451,7 +430,7 @@ void AliMUONTrack::UpdateCovTrackParamAtCluster() //__________________________________________________________________________ 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; @@ -460,6 +439,10 @@ Bool_t AliMUONTrack::IsValid() 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 @@ -470,23 +453,25 @@ Bool_t AliMUONTrack::IsValid() } - 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 @@ -949,7 +934,7 @@ Double_t AliMUONTrack::GetNormalizedChi2() const Double_t numberOfDegFree = (2. * GetNClusters() - 5.); if (numberOfDegFree > 0.) return fGlobalChi2 / numberOfDegFree; - else return 1.e10; + else return fGlobalChi2; // system is under-constraint } //__________________________________________________________________________ diff --git a/MUON/AliMUONTrackExtrap.cxx b/MUON/AliMUONTrackExtrap.cxx index 8c9b5615dc0..94fa55ddb14 100644 --- a/MUON/AliMUONTrackExtrap.cxx +++ b/MUON/AliMUONTrackExtrap.cxx @@ -53,9 +53,10 @@ Double_t AliMUONTrackExtrap::GetImpactParamFromBendingMomentum(Double_t bendingM 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"<Field(x,b); else { cout<<"F-AliMUONTrackExtrap::GetField: fgkField = 0x0"<GetCovariances(); - + // Extrapolate track parameters to "zEnd" ExtrapToZ(trackParam,zEnd); diff --git a/MUON/AliMUONTrackReconstructor.cxx b/MUON/AliMUONTrackReconstructor.cxx index 2570f74954e..59dc5384189 100644 --- a/MUON/AliMUONTrackReconstructor.cxx +++ b/MUON/AliMUONTrackReconstructor.cxx @@ -92,14 +92,14 @@ void AliMUONTrackReconstructor::MakeTrackCandidates(AliMUONVClusterStore& cluste 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; isegGetEntriesFast(); iseg++) @@ -110,19 +110,13 @@ void AliMUONTrackReconstructor::MakeTrackCandidates(AliMUONVClusterStore& cluste track = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack((AliMUONObjectPair*)((*segments)[iseg])); fNRecTracks++; - // Printout for debuging - if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { - cout<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--; } @@ -141,6 +135,77 @@ void AliMUONTrackReconstructor::MakeTrackCandidates(AliMUONVClusterStore& cluste 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; isegGetEntriesFast(); 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)); + } //__________________________________________________________________________ @@ -152,7 +217,6 @@ void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore) AliMUONTrack *track, *nextTrack; AliMUONTrackParam *trackParam, *nextTrackParam; Int_t currentNRecTracks; - Bool_t clusterFound; Double_t sigmaCut2 = AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); @@ -172,13 +236,18 @@ void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore) // 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; } @@ -201,26 +270,30 @@ void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore) } 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()); + + } } @@ -228,23 +301,32 @@ void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore) } - // Printout for debuging - if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { - cout<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--; + } + } } @@ -285,26 +367,30 @@ void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore) // 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()); + + } } @@ -316,6 +402,144 @@ void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore) 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<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<= 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(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; + } //__________________________________________________________________________ @@ -369,13 +593,22 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid 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<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.); } @@ -385,7 +618,8 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { - cout<= 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; } @@ -455,7 +690,8 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid // 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()) { @@ -516,17 +752,24 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid // 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<= 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; @@ -542,16 +785,17 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid // 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()) { @@ -737,7 +981,9 @@ void AliMUONTrackReconstructor::UpdateTrack(AliMUONTrack &track, AliMUONTrackPar 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 @@ -797,25 +1043,32 @@ Bool_t AliMUONTrackReconstructor::RecoverTrack(AliMUONTrack &trackCandidate, Ali 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)); @@ -910,15 +1163,14 @@ void AliMUONTrackReconstructor::Fit(AliMUONTrack &track, Bool_t includeMCS, Bool 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); @@ -1156,7 +1408,7 @@ void AliMUONTrackReconstructor::FinalizeTrack(AliMUONTrack &track) if (!track.IsImproved()) track.UpdateCovTrackParamAtCluster(); } -//__________________________________________________________________________ + //__________________________________________________________________________ Bool_t AliMUONTrackReconstructor::RefitTrack(AliMUONTrack &track) { /// re-fit the given track diff --git a/MUON/AliMUONTrackReconstructor.h b/MUON/AliMUONTrackReconstructor.h index d4b63e8cf20..0048ecefd08 100644 --- a/MUON/AliMUONTrackReconstructor.h +++ b/MUON/AliMUONTrackReconstructor.h @@ -31,6 +31,7 @@ class AliMUONTrackReconstructor : public AliMUONVTrackReconstructor // 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); @@ -44,6 +45,7 @@ class AliMUONTrackReconstructor : public AliMUONVTrackReconstructor /// 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); diff --git a/MUON/AliMUONTrackReconstructorK.cxx b/MUON/AliMUONTrackReconstructorK.cxx index b996cc4a4b9..e15560e7762 100644 --- a/MUON/AliMUONTrackReconstructorK.cxx +++ b/MUON/AliMUONTrackReconstructorK.cxx @@ -68,7 +68,7 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates(AliMUONVClusterStore& clust { /// 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; @@ -90,14 +90,14 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates(AliMUONVClusterStore& clust 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; isegGetEntriesFast(); iseg++) { @@ -107,26 +107,25 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates(AliMUONVClusterStore& clust track = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack((AliMUONObjectPair*)((*segments)[iseg])); fNRecTracks++; - // Printout for debuging - if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { - cout<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); + } } } @@ -165,6 +164,98 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates(AliMUONVClusterStore& clust 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; isegGetEntriesFast(); 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)); + } //__________________________________________________________________________ @@ -199,7 +290,8 @@ void AliMUONTrackReconstructorK::RetraceTrack(AliMUONTrack &trackCandidate, Bool 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); @@ -210,8 +302,11 @@ void AliMUONTrackReconstructorK::RetraceTrack(AliMUONTrack &trackCandidate, Bool // 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 @@ -256,7 +351,7 @@ void AliMUONTrackReconstructorK::RetracePartialTrack(AliMUONTrack &trackCandidat // 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) @@ -279,7 +374,7 @@ void AliMUONTrackReconstructorK::RetracePartialTrack(AliMUONTrack &trackCandidat 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 @@ -307,7 +402,6 @@ void AliMUONTrackReconstructorK::FollowTracks(AliMUONVClusterStore& clusterStore AliMUONTrack *track; Int_t currentNRecTracks; - Bool_t clusterFound; for (Int_t station = 2; station >= 0; station--) { @@ -321,23 +415,32 @@ void AliMUONTrackReconstructorK::FollowTracks(AliMUONVClusterStore& clusterStore track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iRecTrack); - // Printout for debuging - if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { - cout<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--; + } + } } @@ -349,6 +452,168 @@ void AliMUONTrackReconstructorK::FollowTracks(AliMUONVClusterStore& clusterStore } +} + + //__________________________________________________________________________ +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<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<= 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(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; + } //__________________________________________________________________________ @@ -375,6 +640,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi 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 @@ -403,16 +669,25 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi 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<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.); @@ -424,7 +699,8 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { - cout<= 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; } @@ -475,6 +752,11 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // 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; @@ -501,7 +783,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // 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) { @@ -511,7 +793,8 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // 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()) { @@ -525,6 +808,11 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // 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); @@ -592,11 +880,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // 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.); @@ -604,6 +887,18 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch1), AliMUONReconstructor::GetRecoParam()->UseSmoother()); + // Printout for debuging + if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { + cout<= 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; @@ -630,6 +925,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi 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()) { @@ -643,6 +939,11 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // 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); @@ -679,7 +980,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // 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; @@ -692,7 +993,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // 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; @@ -703,6 +1004,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi delete [] clusterCh1Used; return kFALSE; } + } else if (foundOneCluster || foundTwoClusters) { // remove obsolete track @@ -712,7 +1014,8 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi } else { delete [] clusterCh1Used; return kFALSE; - } + } + delete [] clusterCh1Used; return kTRUE; @@ -791,8 +1094,10 @@ void AliMUONTrackReconstructorK::UpdateTrack(AliMUONTrack &track, AliMUONTrackPa /// 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 @@ -864,15 +1169,21 @@ Bool_t AliMUONTrackReconstructorK::RecoverTrack(AliMUONTrack &trackCandidate, Al 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) { @@ -881,8 +1192,8 @@ Bool_t AliMUONTrackReconstructorK::RecoverTrack(AliMUONTrack &trackCandidate, Al } } - // 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)); @@ -890,6 +1201,11 @@ Bool_t AliMUONTrackReconstructorK::RecoverTrack(AliMUONTrack &trackCandidate, Al // 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); diff --git a/MUON/AliMUONTrackReconstructorK.h b/MUON/AliMUONTrackReconstructorK.h index 93d71abe7c7..d8142c42305 100644 --- a/MUON/AliMUONTrackReconstructorK.h +++ b/MUON/AliMUONTrackReconstructorK.h @@ -30,6 +30,7 @@ class AliMUONTrackReconstructorK : public AliMUONVTrackReconstructor // 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); @@ -46,6 +47,7 @@ class AliMUONTrackReconstructorK : public AliMUONVTrackReconstructor 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); diff --git a/MUON/AliMUONTracker.cxx b/MUON/AliMUONTracker.cxx index 45c299bd938..30053c969b6 100644 --- a/MUON/AliMUONTracker.cxx +++ b/MUON/AliMUONTracker.cxx @@ -33,32 +33,31 @@ #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 -#include #include +#include /// \cond CLASSIMP ClassImp(AliMUONTracker) @@ -66,8 +65,8 @@ 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) @@ -79,15 +78,28 @@ AliMUONTracker::AliMUONTracker(AliMUONVClusterServer& clusterServer, 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); + } } //_____________________________________________________________________________ @@ -98,6 +110,9 @@ AliMUONTracker::~AliMUONTracker() delete fTrackHitPatternMaker; delete fClusterStore; delete fTriggerStore; + if ( fIsOwnerOfClusterServer ) delete fClusterServer; + delete fInputClusterStore; + delete fTriggerTrackStore; } //_____________________________________________________________________________ @@ -112,14 +127,26 @@ AliMUONTracker::ClusterStore() const 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"); @@ -134,7 +161,20 @@ Int_t AliMUONTracker::LoadClusters(TTree* 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); @@ -149,7 +189,10 @@ Int_t AliMUONTracker::Clusters2Tracks(AliESDEvent* esd) 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; @@ -165,20 +208,21 @@ Int_t AliMUONTracker::Clusters2Tracks(AliESDEvent* esd) 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 @@ -186,7 +230,6 @@ Int_t AliMUONTracker::Clusters2Tracks(AliESDEvent* esd) // cleanup delete trackStore; - delete triggerTrackStore; return 0; } @@ -231,28 +274,32 @@ void AliMUONTracker::FillESD(AliMUONVTrackStore& trackStore, AliESDEvent* esd) c } //_____________________________________________________________________________ -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; } //_____________________________________________________________________________ @@ -260,5 +307,31 @@ void AliMUONTracker::UnloadClusters() { /// 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 !!!"); + } + } +} + + diff --git a/MUON/AliMUONTracker.h b/MUON/AliMUONTracker.h index 21fa72f369c..c55ff779afb 100644 --- a/MUON/AliMUONTracker.h +++ b/MUON/AliMUONTracker.h @@ -8,7 +8,7 @@ /// \class AliMUONTracker /// \brief MUON base Tracker /// -// Author: Christian Finck, SUBATECH Nantes +// Authors: Christian Finck, Laurent Aphecetche, SUBATECH Nantes #include "AliTracker.h" @@ -18,19 +18,20 @@ class AliMUONDigitMaker; 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); @@ -49,6 +50,8 @@ class AliMUONTracker : public AliTracker /// 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); @@ -57,10 +60,12 @@ private: 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) @@ -69,8 +74,11 @@ private: 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 }; diff --git a/MUON/AliMUONTriggerTrackToTrackerClusters.cxx b/MUON/AliMUONTriggerTrackToTrackerClusters.cxx new file mode 100644 index 00000000000..571e9c536a6 --- /dev/null +++ b/MUON/AliMUONTriggerTrackToTrackerClusters.cxx @@ -0,0 +1,229 @@ +/************************************************************************** +* 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 + +///\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(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; +} diff --git a/MUON/AliMUONTriggerTrackToTrackerClusters.h b/MUON/AliMUONTriggerTrackToTrackerClusters.h new file mode 100644 index 00000000000..ffe4669155d --- /dev/null +++ b/MUON/AliMUONTriggerTrackToTrackerClusters.h @@ -0,0 +1,52 @@ +#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 diff --git a/MUON/AliMUONVClusterServer.h b/MUON/AliMUONVClusterServer.h index 3de623c38e0..7a484208a4d 100644 --- a/MUON/AliMUONVClusterServer.h +++ b/MUON/AliMUONVClusterServer.h @@ -17,6 +17,7 @@ #endif class AliMUONVClusterStore; +class AliMUONVTriggerTrackStore; class AliMpArea; class TIter; @@ -31,9 +32,12 @@ public: 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 }; diff --git a/MUON/AliMUONVTrackReconstructor.cxx b/MUON/AliMUONVTrackReconstructor.cxx index 4b0e24ea2f8..6eedfe7bb1c 100644 --- a/MUON/AliMUONVTrackReconstructor.cxx +++ b/MUON/AliMUONVTrackReconstructor.cxx @@ -136,9 +136,12 @@ void AliMUONVTrackReconstructor::EventReconstruct(AliMUONVClusterStore& clusterS // 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; @@ -167,18 +170,16 @@ void AliMUONVTrackReconstructor::EventReconstruct(AliMUONVClusterStore& clusterS } //__________________________________________________________________________ -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)); @@ -196,6 +197,9 @@ TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsInStation(const AliMUONVCl // Loop over clusters in the second chamber of the station while ( ( cluster2 = static_cast(nextInCh2()) ) ) { + // non bending slope + nonBendingSlope = (cluster1->GetX() - cluster2->GetX()) / (cluster1->GetZ() - cluster2->GetZ()); + // bending slope bendingSlope = (cluster1->GetY() - cluster2->GetY()) / (cluster1->GetZ() - cluster2->GetZ()); @@ -205,9 +209,10 @@ TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsInStation(const AliMUONVCl // 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); @@ -229,7 +234,7 @@ TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsInStation(const AliMUONVCl } // 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; } @@ -333,37 +338,49 @@ void AliMUONVTrackReconstructor::RemoveDoubleTracks() } //__________________________________________________________________________ -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); } //__________________________________________________________________________ @@ -398,16 +415,24 @@ Double_t AliMUONVTrackReconstructor::TryOneCluster(const AliMUONTrackParam &trac //__________________________________________________________________________ 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; @@ -457,6 +482,127 @@ Double_t AliMUONVTrackReconstructor::TryTwoClustersFast(const AliMUONTrackParam } //__________________________________________________________________________ +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<= 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(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) { @@ -508,6 +654,13 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac 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<= 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; } @@ -567,7 +721,8 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac // 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()) { @@ -606,7 +761,9 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac 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++; @@ -642,7 +799,7 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac // add MCS effect for next step AliMUONTrackExtrap::AddMCSEffect(&trackParam,AliMUONConstants::ChamberThicknessInX0(),1.); - + // reset cluster iterator of chamber 1 nextInCh1.Reset(); iCluster1 = -1; @@ -655,12 +812,12 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac // 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) { @@ -670,12 +827,15 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac 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++; @@ -712,7 +872,9 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac } } 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 diff --git a/MUON/AliMUONVTrackReconstructor.h b/MUON/AliMUONVTrackReconstructor.h index 73264be6755..259072cae11 100644 --- a/MUON/AliMUONVTrackReconstructor.h +++ b/MUON/AliMUONVTrackReconstructor.h @@ -64,8 +64,10 @@ class AliMUONVTrackReconstructor : public TObject { 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 @@ -77,13 +79,15 @@ class AliMUONVTrackReconstructor : public TObject { /// 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); @@ -91,8 +95,8 @@ class AliMUONVTrackReconstructor : public TObject { 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: diff --git a/MUON/MUONefficiency.C b/MUON/MUONefficiency.C index dd78e036ff8..46adede4349 100644 --- a/MUON/MUONefficiency.C +++ b/MUON/MUONefficiency.C @@ -65,6 +65,7 @@ #include #include #include +#include #endif @@ -588,7 +589,16 @@ Bool_t MUONefficiency( char* filename = "galice.root", char* geoFilename = "geom 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 ["<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(); @@ -70,4 +77,3 @@ void runReconstruction(int seed, const char* input, const char* recoptions) //gObjectTable->Print(); } - -- 2.43.0