1e76d440e13c4b7ff86d1da684c6ce7e6c7f61b4
[u/mrichter/AliRoot.git] / PWG / muondep / AliAnalysisTaskMuonRefit.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 // ROOT includes
19 #include <TString.h>
20 #include <TList.h>
21 #include <TGeoManager.h>
22
23 // STEER includes
24 #include "AliESDEvent.h"
25 #include "AliESDMuonTrack.h"
26 #include "AliCDBManager.h"
27 #include "AliCDBStorage.h"
28 #include "AliGeomManager.h"
29
30 // ANALYSIS includes
31 #include "AliAnalysisManager.h"
32 #include "AliInputEventHandler.h"
33 #include "AliAnalysisTaskMuonRefit.h"
34
35 // MUON includes
36 #include "AliMUONCDB.h"
37 #include "AliMUONConstants.h"
38 #include "AliMUONRecoParam.h"
39 #include "AliMUONESDInterface.h"
40 #include "AliMUONRefitter.h"
41 #include "AliMUONTrack.h"
42 #include "AliMUONTrackParam.h"
43 #include "AliMUONVCluster.h"
44 #include "AliMUONVTrackStore.h"
45 #include "AliMUONLocalTrigger.h"
46 #include "AliMUONGeometryTransformer.h"
47
48 #ifndef SafeDelete
49 #define SafeDelete(x) if (x != NULL) { delete x; x = NULL; }
50 #endif
51
52 ClassImp(AliAnalysisTaskMuonRefit)
53
54 //________________________________________________________________________
55 AliAnalysisTaskMuonRefit::AliAnalysisTaskMuonRefit() :
56 AliAnalysisTaskSE(),
57 fDefaultStorage(""),
58 fImproveTracks(kFALSE),
59 fSigmaCut(-1.),
60 fSigmaCutForTrigger(-1.),
61 fReAlign(kFALSE),
62 fOldAlignStorage(""),
63 fNewAlignStorage(""),
64 fOldGeoTransformer(NULL),
65 fNewGeoTransformer(NULL),
66 fESDInterface(NULL),
67 fRefitter(NULL)
68 {
69   /// Default constructor
70   for (Int_t i = 0; i < 10; i++) ResetClusterResolution(i, -1., -1.);
71 }
72
73 //________________________________________________________________________
74 AliAnalysisTaskMuonRefit::AliAnalysisTaskMuonRefit(const char *name) :
75 AliAnalysisTaskSE(name),
76 fDefaultStorage("raw://"),
77 fImproveTracks(kFALSE),
78 fSigmaCut(-1.),
79 fSigmaCutForTrigger(-1.),
80 fReAlign(kFALSE),
81 fOldAlignStorage(""),
82 fNewAlignStorage(""),
83 fOldGeoTransformer(NULL),
84 fNewGeoTransformer(NULL),
85 fESDInterface(NULL),
86 fRefitter(NULL)
87 {
88   /// Constructor
89   for (Int_t i = 0; i < 10; i++) ResetClusterResolution(i, -1., -1.);
90 }
91
92 //________________________________________________________________________
93 AliAnalysisTaskMuonRefit::~AliAnalysisTaskMuonRefit()
94 {
95   /// Destructor
96   SafeDelete(fOldGeoTransformer);
97   SafeDelete(fNewGeoTransformer);
98   SafeDelete(fESDInterface);
99   SafeDelete(fRefitter);
100 }
101
102 //___________________________________________________________________________
103 void AliAnalysisTaskMuonRefit::UserCreateOutputObjects()
104 {
105 }
106
107 //________________________________________________________________________
108 void AliAnalysisTaskMuonRefit::UserExec(Option_t *)
109 {
110   /// Main event loop
111   
112   // check if refitter properly created
113   if (!fRefitter) return;
114   
115   AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
116   if (!esd) return;
117   
118   Int_t nTracks = (Int_t)esd->GetNumberOfMuonTracks();
119   if (nTracks < 1) return;
120   
121   TList newGhosts;
122   newGhosts.SetOwner(kFALSE);
123   UInt_t firstGhostId = 0xFFFFFFFF - 1;
124   
125   // load the current event
126   fESDInterface->LoadEvent(*esd, kFALSE);
127   
128   // remove clusters from ESD (keep digits as they will not change, just eventually not used anymore)
129   esd->FindListObject("MuonClusters")->Clear("C");
130   
131   // modify clusters
132   AliMUONVCluster* cluster = 0x0;
133   TIter nextCluster(fESDInterface->CreateClusterIterator());
134   while ((cluster = static_cast<AliMUONVCluster*>(nextCluster()))) ModifyCluster(*cluster);
135   
136   // refit the tracks from clusters
137   AliMUONVTrackStore* newTrackStore = fRefitter->ReconstructFromClusters();
138   
139   // loop over the list of ESD tracks
140   TClonesArray *esdTracks = (TClonesArray*) esd->FindListObject("MuonTracks");
141   for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
142     
143     // get the ESD track
144     AliESDMuonTrack* esdTrack = (AliESDMuonTrack*) esdTracks->UncheckedAt(iTrack);
145     
146     // skip ghost tracks (leave them unchanged)
147     if (!esdTrack->ContainTrackerData()) {
148       if (esdTrack->GetUniqueID() <= firstGhostId) firstGhostId = esdTrack->GetUniqueID()-1;
149       continue;
150     }
151     
152     // Find the corresponding re-fitted MUON track
153     AliMUONTrack* newTrack = (AliMUONTrack*) newTrackStore->FindObject(esdTrack->GetUniqueID());
154     
155     // Find the corresponding locaTrigger if any
156     AliMUONLocalTrigger *locTrg = (esdTrack->ContainTriggerData()) ? fESDInterface->FindLocalTrigger(esdTrack->LoCircuit()) : 0x0;
157     if (locTrg && locTrg->IsNull()) locTrg = 0x0;
158     
159     // replace the content of the current ESD track or remove it
160     if (newTrack && (!fImproveTracks || newTrack->IsImproved())) {
161       
162       // eventually remove the trigger part if matching chi2 do not pass the new cut
163       if (locTrg && newTrack->GetChi2MatchTrigger() > fSigmaCutForTrigger*fSigmaCutForTrigger) {
164         newTrack->SetMatchTrigger(0);
165         newTrack->SetLocalTrigger(0,0,0,0,0,0,0);
166         newTrack->SetChi2MatchTrigger(0.);
167         newTrack->SetHitsPatternInTrigCh(0);
168         newGhosts.AddLast(locTrg);
169         locTrg = 0x0;
170       }
171       
172       // fill the track info
173       Double_t vertex[3] = {esdTrack->GetNonBendingCoor(), esdTrack->GetBendingCoor(), esdTrack->GetZ()};
174       AliMUONESDInterface::MUONToESD(*newTrack, *esdTrack, vertex, locTrg);
175       
176       // add the clusters if not already there
177       for (Int_t i = 0; i < newTrack->GetNClusters(); i++) {
178         AliMUONVCluster *cl = static_cast<AliMUONTrackParam*>(newTrack->GetTrackParamAtCluster()->UncheckedAt(i))->GetClusterPtr();
179         if (esd->FindMuonCluster(cl->GetUniqueID())) continue;
180         AliESDMuonCluster *esdCl = esd->NewMuonCluster();
181         AliMUONESDInterface::MUONToESD(*cl, *esdCl, kTRUE);
182       }
183       
184     } else {
185       
186       // keep the trigger part if any
187       if (locTrg) newGhosts.AddLast(locTrg);
188       
189       // remove the track
190       esdTracks->Remove(esdTrack);
191       
192     }
193     
194   }
195   
196   // free memory
197   delete newTrackStore;
198   
199   // compress the array of ESD tracks
200   esdTracks->Compress();
201   
202   // add new ghosts if not already there
203   TIter nextGhost(&newGhosts);
204   AliMUONLocalTrigger *locTrg = 0x0;
205   while ((locTrg = static_cast<AliMUONLocalTrigger*>(nextGhost()))) {
206     Bool_t alreadyThere = kFALSE;
207     for (Int_t iTrack = 0; iTrack < esdTracks->GetEntriesFast(); iTrack++) {
208       AliESDMuonTrack* esdTrack = (AliESDMuonTrack*) esdTracks->UncheckedAt(iTrack);
209       alreadyThere = (esdTrack->LoCircuit() == locTrg->LoCircuit());
210       if (alreadyThere) break;
211     }
212     if (!alreadyThere) AliMUONESDInterface::MUONToESD(*locTrg, *esd, firstGhostId--);
213   }
214   
215 }
216
217 //________________________________________________________________________
218 void AliAnalysisTaskMuonRefit::NotifyRun()
219 {
220   /// load necessary data from OCDB and create the refitter
221   
222   AliCDBManager* cdbm = AliCDBManager::Instance();
223   cdbm->SetDefaultStorage(fDefaultStorage.Data());
224   cdbm->SetRun(fCurrentRunNumber);
225   
226   if (!AliMUONCDB::LoadField()) return;
227   
228   if (!AliMUONCDB::LoadMapping(kTRUE)) return;
229   
230   AliMUONRecoParam* recoParam = AliMUONCDB::LoadRecoParam();
231   if (!recoParam) return;
232   
233   if (fImproveTracks) {
234     if (fSigmaCut > 0.) recoParam->ImproveTracks(kTRUE, fSigmaCut);
235     else recoParam->ImproveTracks(kTRUE);
236   } else recoParam->ImproveTracks(kFALSE);
237   
238   if (fSigmaCutForTrigger > 0.) recoParam->SetSigmaCutForTrigger(fSigmaCutForTrigger);
239   else fSigmaCutForTrigger = recoParam->GetSigmaCutForTrigger();
240   
241   for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) {
242     if (fClusterResNB[i] < 0.) fClusterResNB[i] = recoParam->GetDefaultNonBendingReso(i);
243     if (fClusterResB[i] < 0.) fClusterResB[i] = recoParam->GetDefaultBendingReso(i);
244   }
245   
246   if (fReAlign) {
247     
248     // recover default storage full name (raw:// cannot be used to set specific storage)
249     TString defaultStorage(cdbm->GetDefaultStorage()->GetType());
250     if (defaultStorage == "alien") defaultStorage += Form("://folder=%s", cdbm->GetDefaultStorage()->GetBaseFolder().Data());
251     else defaultStorage += Form("://%s", cdbm->GetDefaultStorage()->GetBaseFolder().Data());
252     
253     // reset existing geometry/alignment if any
254     if (cdbm->GetEntryCache()->Contains("GRP/Geometry/Data")) cdbm->UnloadFromCache("GRP/Geometry/Data");
255     if (cdbm->GetEntryCache()->Contains("MUON/Align/Data")) cdbm->UnloadFromCache("MUON/Align/Data");
256     if (AliGeomManager::GetGeometry()) AliGeomManager::GetGeometry()->UnlockGeometry();
257     
258     // get original geometry transformer
259     AliGeomManager::LoadGeometry();
260     if (!AliGeomManager::GetGeometry()) return;
261     if (fOldAlignStorage != "none") {
262       if (!fOldAlignStorage.IsNull()) cdbm->SetSpecificStorage("MUON/Align/Data",fOldAlignStorage.Data());
263       else cdbm->SetSpecificStorage("MUON/Align/Data",defaultStorage.Data());
264       AliGeomManager::ApplyAlignObjsFromCDB("MUON");
265     }
266     fOldGeoTransformer = new AliMUONGeometryTransformer();
267     fOldGeoTransformer->LoadGeometryData();
268     
269     // get new geometry transformer
270     cdbm->UnloadFromCache("GRP/Geometry/Data");
271     if (fOldAlignStorage != "none") cdbm->UnloadFromCache("MUON/Align/Data");
272     AliGeomManager::GetGeometry()->UnlockGeometry();
273     AliGeomManager::LoadGeometry();
274     if (!AliGeomManager::GetGeometry()) return;
275     if (!fNewAlignStorage.IsNull()) cdbm->SetSpecificStorage("MUON/Align/Data",fNewAlignStorage.Data());
276     else cdbm->SetSpecificStorage("MUON/Align/Data",defaultStorage.Data());
277     AliGeomManager::ApplyAlignObjsFromCDB("MUON");
278     fNewGeoTransformer = new AliMUONGeometryTransformer();
279     fNewGeoTransformer->LoadGeometryData();
280     
281   } else {
282     
283     // load geometry for track extrapolation to vertex
284     if (cdbm->GetEntryCache()->Contains("GRP/Geometry/Data")) cdbm->UnloadFromCache("GRP/Geometry/Data");
285     if (AliGeomManager::GetGeometry()) AliGeomManager::GetGeometry()->UnlockGeometry();
286     AliGeomManager::LoadGeometry();
287     if (!AliGeomManager::GetGeometry()) return;
288     
289   }
290   
291   fESDInterface = new AliMUONESDInterface();
292   fRefitter = new AliMUONRefitter(recoParam);
293   fRefitter->Connect(fESDInterface);
294 }
295
296 //________________________________________________________________________
297 void AliAnalysisTaskMuonRefit::Terminate(Option_t *)
298 {
299 }
300
301 //________________________________________________________________________
302 void AliAnalysisTaskMuonRefit::ModifyCluster(AliMUONVCluster& cl)
303 {
304   /// Reset the cluster resolution to the one given to the task and change
305   /// the cluster position according to the new alignment parameters if required
306   
307   Double_t gX,gY,gZ,lX,lY,lZ;
308   
309   // change their resolution
310   cl.SetErrXY(fClusterResNB[cl.GetChamberId()], fClusterResB[cl.GetChamberId()]);
311   
312   // change their position
313   if (fReAlign) {
314     gX = cl.GetX();
315     gY = cl.GetY();
316     gZ = cl.GetZ();
317     fOldGeoTransformer->Global2Local(cl.GetDetElemId(),gX,gY,gZ,lX,lY,lZ);
318     fNewGeoTransformer->Local2Global(cl.GetDetElemId(),lX,lY,lZ,gX,gY,gZ);
319     cl.SetXYZ(gX,gY,gZ);
320   }
321   
322 }
323