ROOT logo
/**************************************************************************
 * 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$ */

/// \ingroup macros
/// \file MUONRefit.C
/// \brief Macro for refitting ESD tracks from ESD pads
///
/// \author Philippe Pillot, SUBATECH

#if !defined(__CINT__) || defined(__MAKECINT__)
#include <TStopwatch.h>
#include <TFile.h>
#include <TTree.h>
#include <TString.h>
#include <Riostream.h>
#include <TGeoManager.h>
#include <TRandom.h>
#include <TROOT.h>

// STEER includes
#include "AliESDEvent.h"
#include "AliESDMuonTrack.h"
#include "AliCDBManager.h"
#include "AliGeomManager.h"

// MUON includes
#include "AliMUONCDB.h"
#include "AliMUONRecoParam.h"
#include "AliMUONESDInterface.h"
#include "AliMUONRefitter.h"
#include "AliMUONVDigit.h"
#include "AliMUONTrack.h"
#include "AliMUONVTrackStore.h"
#include "AliMUONTrackParam.h"
#endif

const Int_t printLevel = 1;
const Bool_t reconstructFromDigits = kTRUE; // kFALSE = reconstruct from clusters

TTree* GetESDTree(TFile *esdFile);

//-----------------------------------------------------------------------
void MUONRefit(Int_t nevents = -1, const char* esdFileNameIn = "AliESDs.root", const char* esdFileNameOut = "AliESDs_New.root",
	       const char* geoFilename = "geometry.root", const char* ocdbPath = "local://$ALICE_ROOT/OCDB")
{
  /// Example of muon refitting:
  /// refit ESD tracks from ESD pads (i.e. re-clusterized the attached ESD clusters);
  /// reset the charge of the digit using their raw charge before refitting;
  /// compare results with original ESD tracks; 
  /// write results in a new ESD file
  
  // open the ESD file and tree
  TFile* esdFile = TFile::Open(esdFileNameIn);
  TTree* esdTree = GetESDTree(esdFile);
  
  // connect ESD event to the ESD tree
  AliESDEvent* esd = new AliESDEvent();
  esd->ReadFromTree(esdTree);
  
  // create the ESD output file and tree
  TFile* newESDFile = TFile::Open(esdFileNameOut, "RECREATE");
  newESDFile->SetCompressionLevel(2);
  
  // connect ESD event to the ESD tree (recreate track branch for backward compatibility)
  esdTree->SetBranchStatus("*MuonTracks*",0);
  TTree* newESDTree = esdTree->CloneTree(0);
  esdTree->SetBranchStatus("*MuonTracks*",1);
  esd->WriteToTree(newESDTree);
  
  // get run number
  if (esdTree->GetEvent(0) <= 0) {
    Error("MUONRefit", "no ESD object found for event 0");
    return;
  }
  Int_t runNumber = esd->GetRunNumber();
  
  // Import TGeo geometry
  if (!gGeoManager) {
    AliGeomManager::LoadGeometry(geoFilename);
    if (!gGeoManager) {
      Error("MUONRefit", "getting geometry from file %s failed", "generated/galice.root");
      exit(-1);
    }
  }
  
  // load necessary data from OCDB
  AliCDBManager::Instance()->SetDefaultStorage(ocdbPath);
  AliCDBManager::Instance()->SetRun(runNumber);
  if (!AliMUONCDB::LoadField()) return;
  if (!AliMUONCDB::LoadMapping(kTRUE)) return;
  
  // reconstruction parameters for the refitting
  AliMUONRecoParam* recoParam = AliMUONRecoParam::GetLowFluxParam();
  Info("MUONRefit", "\n Reconstruction parameters for refitting:");
  recoParam->Print("FULL");
  
  AliMUONESDInterface esdInterface;
  AliMUONRefitter refitter(recoParam);
  refitter.Connect(&esdInterface);
  gRandom->SetSeed(1);
  
  // timer start...
  TStopwatch timer;
  
  // Loop over ESD events
  if (nevents > 0) nevents = TMath::Min(nevents,(Int_t)esdTree->GetEntries());
  else nevents = (Int_t)esdTree->GetEntries();
  for (Int_t iEvent = 0; iEvent < nevents; iEvent++) {
    if (printLevel>0) cout<<endl<<"            ****************event #"<<iEvent+1<<"****************"<<endl;
    
    //----------------------------------------------//
    // -------------- process event --------------- //
    //----------------------------------------------//
    // get the ESD of current event
    esdTree->GetEvent(iEvent);
    if (!esd) {
      Error("MUONRefit", "no ESD object found for event %d", iEvent);
      return;
    }
    Int_t nTracks = (Int_t)esd->GetNumberOfMuonTracks();
    if (nTracks < 1) continue;
    
    // load the current event
    esdInterface.LoadEvent(*esd, kFALSE);
    
    // remove digits and clusters from ESD
    esd->FindListObject("MuonClusters")->Clear("C");
    esd->FindListObject("MuonPads")->Clear("C");
    
    AliMUONVTrackStore* newTrackStore = 0x0;
    if (reconstructFromDigits) {
      
      // loop over digits to modify their charge
      AliMUONVDigit *digit;
      TIter next(esdInterface.CreateDigitIterator());
      while ((digit = static_cast<AliMUONVDigit*>(next()))) {
        digit->SetCharge(digit->ADC());
        digit->Calibrated(kFALSE);
      }
      
      // refit the tracks from digits
      refitter.SetFirstClusterIndex(0);
      newTrackStore = refitter.ReconstructFromDigits();
      
    } else {
      
      // refit the tracks from clusters
      newTrackStore = refitter.ReconstructFromClusters();
      
    }
    
    //----------------------------------------------//
    // ------ fill new ESD and print results ------ //
    //----------------------------------------------//
    // loop over the list of ESD tracks
    TClonesArray *esdTracks = (TClonesArray*) esd->FindListObject("MuonTracks");
    for (Int_t iTrack = 0; iTrack <  nTracks; iTrack++) {
      
      // get the ESD track
      AliESDMuonTrack* esdTrack = (AliESDMuonTrack*) esdTracks->UncheckedAt(iTrack);
      
      // skip ghost tracks (leave them unchanged in the new ESD file)
      if (!esdTrack->ContainTrackerData()) continue;
      
      // get the corresponding MUON track
      AliMUONTrack* track = esdInterface.FindTrack(esdTrack->GetUniqueID());
      
      // Find the corresponding re-fitted MUON track
      AliMUONTrack* newTrack = (AliMUONTrack*) newTrackStore->FindObject(esdTrack->GetUniqueID());
      
      // replace the content of the current ESD track or remove it if the refitting has failed
      if (newTrack && (!recoParam->ImproveTracks() || newTrack->IsImproved())) {
	
	// fill the track info
	Double_t vertex[3] = {esdTrack->GetNonBendingCoor(), esdTrack->GetBendingCoor(), esdTrack->GetZ()};
	AliMUONESDInterface::MUONToESD(*newTrack, *esdTrack, vertex);
	
	// add the clusters (and the digits if previously there)
	for (Int_t i = 0; i < newTrack->GetNClusters(); i++) {
	  AliMUONTrackParam *param = static_cast<AliMUONTrackParam*>(newTrack->GetTrackParamAtCluster()->UncheckedAt(i));
	  AliMUONESDInterface::MUONToESD(*(param->GetClusterPtr()), *esd, esdInterface.GetDigits());
	}
	
      } else esdTracks->Remove(esdTrack);
      
      // print initial and re-fitted track parameters at first cluster if any
      if (printLevel>0) {
	cout<<"            ----------------track #"<<iTrack+1<<"----------------"<<endl;
	cout<<"before refit:"<<endl;
	AliMUONTrackParam *param = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First();
	param->Print("FULL");
	if (printLevel>1) param->GetCovariances().Print();
	if (!newTrack) continue;
	cout<<"after refit:"<<endl;
	param = (AliMUONTrackParam*) newTrack->GetTrackParamAtCluster()->First();
	param->Print("FULL");
	if (printLevel>1) param->GetCovariances().Print();
	cout<<"            ----------------------------------------"<<endl;
      }
      
    }
    
    // free memory
    delete newTrackStore;
    
    // fill new ESD tree with new tracks
    esdTracks->Compress();
    newESDTree->Fill();
    
    if (printLevel>0) cout<<"            ****************************************"<<endl;
  }
  
  // ...timer stop
  timer.Stop();
  
  // write output ESD tree
  newESDFile->cd();
  newESDTree->Write();
  delete newESDTree;
  newESDFile->Close();
  
  // free memory
  esdFile->Close();
  delete esd;
  delete recoParam;
  
  cout<<endl<<"time to refit: R:"<<timer.RealTime()<<" C:"<<timer.CpuTime()<<endl<<endl;
}

//-----------------------------------------------------------------------
TTree* GetESDTree(TFile *esdFile)
{
  /// Check that the file is properly open
  /// Return pointer to the ESD Tree
  
  if (!esdFile || !esdFile->IsOpen()) {
    Error("GetESDTree", "opening ESD file failed");
    exit(-1);
  }
  
  TTree* tree = (TTree*) esdFile->Get("esdTree");
  if (!tree) {
    Error("GetESDTree", "no ESD tree found");
    exit(-1);
  }
  
  return tree;
  
}

 MUONRefit.C:1
 MUONRefit.C:2
 MUONRefit.C:3
 MUONRefit.C:4
 MUONRefit.C:5
 MUONRefit.C:6
 MUONRefit.C:7
 MUONRefit.C:8
 MUONRefit.C:9
 MUONRefit.C:10
 MUONRefit.C:11
 MUONRefit.C:12
 MUONRefit.C:13
 MUONRefit.C:14
 MUONRefit.C:15
 MUONRefit.C:16
 MUONRefit.C:17
 MUONRefit.C:18
 MUONRefit.C:19
 MUONRefit.C:20
 MUONRefit.C:21
 MUONRefit.C:22
 MUONRefit.C:23
 MUONRefit.C:24
 MUONRefit.C:25
 MUONRefit.C:26
 MUONRefit.C:27
 MUONRefit.C:28
 MUONRefit.C:29
 MUONRefit.C:30
 MUONRefit.C:31
 MUONRefit.C:32
 MUONRefit.C:33
 MUONRefit.C:34
 MUONRefit.C:35
 MUONRefit.C:36
 MUONRefit.C:37
 MUONRefit.C:38
 MUONRefit.C:39
 MUONRefit.C:40
 MUONRefit.C:41
 MUONRefit.C:42
 MUONRefit.C:43
 MUONRefit.C:44
 MUONRefit.C:45
 MUONRefit.C:46
 MUONRefit.C:47
 MUONRefit.C:48
 MUONRefit.C:49
 MUONRefit.C:50
 MUONRefit.C:51
 MUONRefit.C:52
 MUONRefit.C:53
 MUONRefit.C:54
 MUONRefit.C:55
 MUONRefit.C:56
 MUONRefit.C:57
 MUONRefit.C:58
 MUONRefit.C:59
 MUONRefit.C:60
 MUONRefit.C:61
 MUONRefit.C:62
 MUONRefit.C:63
 MUONRefit.C:64
 MUONRefit.C:65
 MUONRefit.C:66
 MUONRefit.C:67
 MUONRefit.C:68
 MUONRefit.C:69
 MUONRefit.C:70
 MUONRefit.C:71
 MUONRefit.C:72
 MUONRefit.C:73
 MUONRefit.C:74
 MUONRefit.C:75
 MUONRefit.C:76
 MUONRefit.C:77
 MUONRefit.C:78
 MUONRefit.C:79
 MUONRefit.C:80
 MUONRefit.C:81
 MUONRefit.C:82
 MUONRefit.C:83
 MUONRefit.C:84
 MUONRefit.C:85
 MUONRefit.C:86
 MUONRefit.C:87
 MUONRefit.C:88
 MUONRefit.C:89
 MUONRefit.C:90
 MUONRefit.C:91
 MUONRefit.C:92
 MUONRefit.C:93
 MUONRefit.C:94
 MUONRefit.C:95
 MUONRefit.C:96
 MUONRefit.C:97
 MUONRefit.C:98
 MUONRefit.C:99
 MUONRefit.C:100
 MUONRefit.C:101
 MUONRefit.C:102
 MUONRefit.C:103
 MUONRefit.C:104
 MUONRefit.C:105
 MUONRefit.C:106
 MUONRefit.C:107
 MUONRefit.C:108
 MUONRefit.C:109
 MUONRefit.C:110
 MUONRefit.C:111
 MUONRefit.C:112
 MUONRefit.C:113
 MUONRefit.C:114
 MUONRefit.C:115
 MUONRefit.C:116
 MUONRefit.C:117
 MUONRefit.C:118
 MUONRefit.C:119
 MUONRefit.C:120
 MUONRefit.C:121
 MUONRefit.C:122
 MUONRefit.C:123
 MUONRefit.C:124
 MUONRefit.C:125
 MUONRefit.C:126
 MUONRefit.C:127
 MUONRefit.C:128
 MUONRefit.C:129
 MUONRefit.C:130
 MUONRefit.C:131
 MUONRefit.C:132
 MUONRefit.C:133
 MUONRefit.C:134
 MUONRefit.C:135
 MUONRefit.C:136
 MUONRefit.C:137
 MUONRefit.C:138
 MUONRefit.C:139
 MUONRefit.C:140
 MUONRefit.C:141
 MUONRefit.C:142
 MUONRefit.C:143
 MUONRefit.C:144
 MUONRefit.C:145
 MUONRefit.C:146
 MUONRefit.C:147
 MUONRefit.C:148
 MUONRefit.C:149
 MUONRefit.C:150
 MUONRefit.C:151
 MUONRefit.C:152
 MUONRefit.C:153
 MUONRefit.C:154
 MUONRefit.C:155
 MUONRefit.C:156
 MUONRefit.C:157
 MUONRefit.C:158
 MUONRefit.C:159
 MUONRefit.C:160
 MUONRefit.C:161
 MUONRefit.C:162
 MUONRefit.C:163
 MUONRefit.C:164
 MUONRefit.C:165
 MUONRefit.C:166
 MUONRefit.C:167
 MUONRefit.C:168
 MUONRefit.C:169
 MUONRefit.C:170
 MUONRefit.C:171
 MUONRefit.C:172
 MUONRefit.C:173
 MUONRefit.C:174
 MUONRefit.C:175
 MUONRefit.C:176
 MUONRefit.C:177
 MUONRefit.C:178
 MUONRefit.C:179
 MUONRefit.C:180
 MUONRefit.C:181
 MUONRefit.C:182
 MUONRefit.C:183
 MUONRefit.C:184
 MUONRefit.C:185
 MUONRefit.C:186
 MUONRefit.C:187
 MUONRefit.C:188
 MUONRefit.C:189
 MUONRefit.C:190
 MUONRefit.C:191
 MUONRefit.C:192
 MUONRefit.C:193
 MUONRefit.C:194
 MUONRefit.C:195
 MUONRefit.C:196
 MUONRefit.C:197
 MUONRefit.C:198
 MUONRefit.C:199
 MUONRefit.C:200
 MUONRefit.C:201
 MUONRefit.C:202
 MUONRefit.C:203
 MUONRefit.C:204
 MUONRefit.C:205
 MUONRefit.C:206
 MUONRefit.C:207
 MUONRefit.C:208
 MUONRefit.C:209
 MUONRefit.C:210
 MUONRefit.C:211
 MUONRefit.C:212
 MUONRefit.C:213
 MUONRefit.C:214
 MUONRefit.C:215
 MUONRefit.C:216
 MUONRefit.C:217
 MUONRefit.C:218
 MUONRefit.C:219
 MUONRefit.C:220
 MUONRefit.C:221
 MUONRefit.C:222
 MUONRefit.C:223
 MUONRefit.C:224
 MUONRefit.C:225
 MUONRefit.C:226
 MUONRefit.C:227
 MUONRefit.C:228
 MUONRefit.C:229
 MUONRefit.C:230
 MUONRefit.C:231
 MUONRefit.C:232
 MUONRefit.C:233
 MUONRefit.C:234
 MUONRefit.C:235
 MUONRefit.C:236
 MUONRefit.C:237
 MUONRefit.C:238
 MUONRefit.C:239
 MUONRefit.C:240
 MUONRefit.C:241
 MUONRefit.C:242
 MUONRefit.C:243
 MUONRefit.C:244
 MUONRefit.C:245
 MUONRefit.C:246
 MUONRefit.C:247
 MUONRefit.C:248
 MUONRefit.C:249
 MUONRefit.C:250
 MUONRefit.C:251
 MUONRefit.C:252
 MUONRefit.C:253
 MUONRefit.C:254
 MUONRefit.C:255
 MUONRefit.C:256
 MUONRefit.C:257
 MUONRefit.C:258
 MUONRefit.C:259
 MUONRefit.C:260
 MUONRefit.C:261
 MUONRefit.C:262
 MUONRefit.C:263
 MUONRefit.C:264
 MUONRefit.C:265