#include "AliMUONPreClusterFinderV2.h"
#include "AliMUONPreClusterFinderV3.h"
#include "AliMUONSimpleClusterServer.h"
+#include "AliMUONReconstructor.h"
#include "AliMUONTrackReconstructor.h"
#include "AliMUONTrackReconstructorK.h"
#include "AliMUONRecoParam.h"
#include "AliMUONVTrackStore.h"
#include "AliMUONTrack.h"
#include "AliMUONTracker.h"
+#include "AliMUONTrackParam.h"
#include "AliLog.h"
//-----------------------------------------------------------------------------
/// \class AliMUONRefitter
///
-/// create new MUON object from ESD objects given as input (through the ESDInterface):
+/// This class has been developped to simplify the re-reconstruction of the MUON tracks
+/// stored into ESD with different recoParams and/or after having re-calibrated the digits.
+/// It creates new MUON object from ESD objects given as input (through the ESDInterface) then:
///
/// - re-clusterize the ESD clusters using the attached ESD pads
/// (several new clusters can be reconstructed per ESD cluster)
//_____________________________________________________________________________
AliMUONRefitter::AliMUONRefitter(const AliMUONRecoParam* recoParam)
: TObject(),
+ fkRecoParam(recoParam),
+ fkESDInterface(0x0),
fGeometryTransformer(0x0),
fClusterServer(0x0),
- fTracker(0x0),
- fESDInterface(0x0)
+ fTracker(0x0)
{
/// Default constructor
CreateGeometryTransformer();
/// re-reconstruct all tracks and attached clusters from the digits
/// it is the responsability of the user to delete the returned store
- if (!fESDInterface) {
+ if (!fkESDInterface) {
AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct");
return 0x0;
}
// loop over tracks and refit them (create new tracks)
AliMUONTrack *track;
- TIter next(fESDInterface->CreateTrackIterator());
+ TIter next(fkESDInterface->CreateTrackIterator());
while ((track = static_cast<AliMUONTrack*>(next()))) {
AliMUONTrack *newTrack = RetrackFromDigits(*track);
- newTrackStore->Add(newTrack);
+ if (newTrack) newTrackStore->Add(newTrack);
delete newTrack;
}
/// refit all tracks from the attached clusters
/// it is the responsability of the user to delete the returned store
- if (!fESDInterface) {
+ if (!fkESDInterface) {
AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct");
return 0x0;
}
// loop over tracks and refit them (create new tracks)
AliMUONTrack *track;
- TIter next(fESDInterface->CreateTrackIterator());
+ TIter next(fkESDInterface->CreateTrackIterator());
while ((track = static_cast<AliMUONTrack*>(next()))) {
AliMUONTrack* newTrack = newTrackStore->Add(*track);
if (!fTracker->RefitTrack(*newTrack)) newTrackStore->Remove(*newTrack);
/// refit track "trackId" from the digits (i.e. re-clusterized the attached clusters)
/// it is the responsability of the user to delete the returned track
- if (!fESDInterface) {
+ if (!fkESDInterface) {
AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct");
return 0x0;
}
// get the track to refit
- AliMUONTrack* track = fESDInterface->FindTrack(trackId);
+ AliMUONTrack* track = fkESDInterface->FindTrack(trackId);
return track ? RetrackFromDigits(*track) : 0x0;
}
//_____________________________________________________________________________
AliMUONTrack* AliMUONRefitter::RetrackFromClusters(UInt_t trackId)
{
- /// refit track "trackId" form the clusters (i.e. do not re-clusterize)
+ /// refit track "trackId" from the clusters (i.e. do not re-clusterize)
/// it is the responsability of the user to delete the returned track
- if (!fESDInterface) {
+ if (!fkESDInterface) {
AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct");
return 0x0;
}
// get the track to refit
- AliMUONTrack* track = fESDInterface->FindTrack(trackId);
+ AliMUONTrack* track = fkESDInterface->FindTrack(trackId);
if (!track) return 0x0;
// refit the track (create a new one)
/// several new clusters may be reconstructed
/// it is the responsability of the user to delete the returned store
- if (!fESDInterface) {
+ if (!fkESDInterface) {
AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct");
return 0x0;
}
// get the cluster to re-clusterize
- AliMUONVCluster* cluster = fESDInterface->FindCluster(trackId,clusterId);
+ AliMUONVCluster* cluster = fkESDInterface->FindCluster(trackId,clusterId);
if (!cluster) return 0x0;
// check if digits exist
if (!clusterStore) return 0x0;
// re-clusterize
- TIter next(fESDInterface->CreateDigitIterator(trackId, clusterId));
- fClusterServer->UseDigits(next);
- fClusterServer->Clusterize(cluster->GetChamberId(),*clusterStore,AliMpArea());
+ TIter next(fkESDInterface->CreateDigitIterator(trackId, clusterId));
+ fClusterServer->UseDigits(next,fkESDInterface->GetDigits());
+ fClusterServer->Clusterize(cluster->GetChamberId(),*clusterStore,AliMpArea(),fkRecoParam);
return clusterStore;
}
/// several new clusters may be reconstructed
/// it is the responsability of the user to delete the returned store
- if (!fESDInterface) {
+ if (!fkESDInterface) {
AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct");
return 0x0;
}
// get the cluster to re-clusterize
- AliMUONVCluster* cluster = fESDInterface->FindCluster(clusterId);
+ AliMUONVCluster* cluster = fkESDInterface->FindCluster(clusterId);
if (!cluster) return 0x0;
// check if digits exist
if (!clusterStore) return 0x0;
// re-clusterize
- TIter next(fESDInterface->CreateDigitIteratorInCluster(clusterId));
- fClusterServer->UseDigits(next);
- fClusterServer->Clusterize(cluster->GetChamberId(),*clusterStore,AliMpArea());
+ TIter next(fkESDInterface->CreateDigitIteratorInCluster(clusterId));
+ fClusterServer->UseDigits(next,fkESDInterface->GetDigits());
+ fClusterServer->Clusterize(cluster->GetChamberId(),*clusterStore,AliMpArea(),fkRecoParam);
return clusterStore;
}
void AliMUONRefitter::CreateClusterServer(AliMUONGeometryTransformer& transformer)
{
/// Create cluster server
- AliMUONVClusterFinder* clusterFinder = AliMUONReconstructor::CreateClusterFinder(GetRecoParam()->GetClusteringMode());
+ AliMUONVClusterFinder* clusterFinder = AliMUONReconstructor::CreateClusterFinder(fkRecoParam->GetClusteringMode());
fClusterServer = clusterFinder ? new AliMUONSimpleClusterServer(clusterFinder,transformer) : 0x0;
}
// check if digits exist
UInt_t trackId = track.GetUniqueID();
- if (fESDInterface->GetNDigits(trackId) == 0) {
+ if (fkESDInterface->GetNDigits(trackId) == 0) {
AliError(Form("no digit attached to track #%d",trackId));
return 0x0;
}
// loop over clusters, re-clusterize and build new tracks
AliMUONVCluster* cluster;
- TIter nextCluster(fESDInterface->CreateClusterIterator(trackId));
+ TIter nextCluster(fkESDInterface->CreateClusterIterator(trackId));
while ((cluster = static_cast<AliMUONVCluster*>(nextCluster()))) {
// reset the new cluster store
newClusterStore->Clear();
// re-clusterize current cluster
- TIter nextDigit(fESDInterface->CreateDigitIterator(trackId, cluster->GetUniqueID()));
- fClusterServer->UseDigits(nextDigit);
- Int_t nNewClusters = fClusterServer->Clusterize(cluster->GetChamberId(),*newClusterStore,AliMpArea());
+ TIter nextDigit(fkESDInterface->CreateDigitIterator(trackId, cluster->GetUniqueID()));
+ fClusterServer->UseDigits(nextDigit,fkESDInterface->GetDigits());
+ Int_t nNewClusters = fClusterServer->Clusterize(cluster->GetChamberId(),*newClusterStore,AliMpArea(),fkRecoParam);
// check that re-clusterizing succeeded
if (nNewClusters == 0) {
}
// add the new cluster(s) to the tracks
- AddClusterToTracks(*newClusterStore, *newTrackStore);
+ if (!AddClusterToTracks(*newClusterStore, *newTrackStore)) {
+ delete newClusterStore;
+ delete newTrackStore;
+ return 0x0;
+ }
}
+ if (newTrackStore->GetSize() > 1000) AliInfo(Form("%d tracks to refit... be patient!!",newTrackStore->GetSize()));
+
// refit the tracks and pick up the best one
AliMUONTrack *currentTrack, *bestTrack = 0x0;
- Double_t currentChi2, bestChi2 = 1.e10;
+ Double_t currentChi2, bestChi2 = AliMUONTrack::MaxChi2();
Int_t currentNCluster, bestNClusters = 0;
TIter next(newTrackStore->CreateIterator());
while ((currentTrack = static_cast<AliMUONTrack*>(next()))) {
if (param) *param = *((AliMUONTrackParam*) track.GetTrackParamAtCluster()->First());
// refit the track
- if (!fTracker->RefitTrack(*currentTrack)) break;
+ if (!fTracker->RefitTrack(*currentTrack)) continue;
// find best track (the one with the higher number of cluster or the best chi2 in case of equality)
currentNCluster = currentTrack->GetNClusters();
}
//_____________________________________________________________________________
-void AliMUONRefitter::AddClusterToTracks(const AliMUONVClusterStore &clusterStore, AliMUONVTrackStore &trackStore)
+Bool_t AliMUONRefitter::AddClusterToTracks(const AliMUONVClusterStore &clusterStore, AliMUONVTrackStore &trackStore)
{
/// add clusters to each of the given tracks
/// duplicate the tracks if there are several clusters and add one cluster per copy
// create new track store if there are more than 1 cluster to add per track
Int_t nClusters = clusterStore.GetSize();
- if (nClusters < 1) return;
+ if (nClusters < 1) return kTRUE;
+
+ // check if we will exceed the maximum allowed number of tracks
+ if (nClusters * trackStore.GetSize() > fkRecoParam->GetMaxTrackCandidates()) {
+ AliError(Form("Too many track candidates (%d tracks). Stop refitting.", nClusters * trackStore.GetSize()));
+ return kFALSE;
+ }
AliMUONTrackParam dummyParam;
AliMUONTrack *currentTrack, *track;
// add the new cluster(s) to the tracks
// duplicate the tracks if there are several clusters
- // the loop after loading the last cluster which is added to the current track
+ // stop the loop after loading the last cluster which is added to the current track
iCluster = 0;
TIter nextCluster(clusterStore.CreateIterator());
while ((newCluster = static_cast<AliMUONVCluster*>(nextCluster())) && (iCluster < nClusters - 1)) {
}
+ return kTRUE;
+
}