1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 //-----------------------------
18 // Class AliMUONReconstructor //
19 //----------------------------- //
21 // MUON track reconstruction
23 #include "AliMUONReconstructor.h"
26 #include "AliESDMuonTrack.h"
29 #include "AliMUONConstants.h"
30 #include "AliMUONCalibrationData.h"
31 #include "AliMUONClusterFinderAZ.h"
32 #include "AliMUONClusterReconstructor.h"
33 #include "AliMUONData.h"
34 #include "AliMUONDigitCalibrator.h"
35 #include "AliMUONEventRecoCombi.h"
36 #include "AliMUONDigitMaker.h"
37 #include "AliMUONTrack.h"
38 #include "AliMUONTrackParam.h"
39 #include "AliMUONTrackReconstructor.h"
40 #include "AliMUONTriggerTrack.h"
41 #include "AliMUONTriggerCircuitNew.h"
42 #include "AliMUONTriggerCrateStore.h"
44 #include "AliMpSegmentation.h"
46 #include "AliRawReader.h"
48 #include "AliRunLoader.h"
50 #include "TStopwatch.h"
53 ClassImp(AliMUONReconstructor)
56 //_____________________________________________________________________________
57 AliMUONReconstructor::AliMUONReconstructor()
60 fDigitMaker(new AliMUONDigitMaker()),
61 fCalibrationData(0x0),
62 fCrateManager(new AliMUONTriggerCrateStore()),
63 fTriggerCircuit(new TClonesArray("AliMUONTriggerCircuitNew", 234)),
64 fTransformer(new AliMUONGeometryTransformer(kTRUE))
67 /// Default constructor
71 fCrateManager->ReadFromFile();
74 fDigitMaker->SetCrateManager(fCrateManager);
77 fTransformer->ReadGeometryData("volpath.dat", "geometry.root");
80 for (Int_t i = 0; i < AliMUONConstants::NTriggerCircuit(); i++) {
81 AliMUONTriggerCircuitNew* c = new AliMUONTriggerCircuitNew();
82 c->SetTransformer(fTransformer);
83 c->Init(i,*fCrateManager);
84 TClonesArray& circuit = *fTriggerCircuit;
85 new(circuit[circuit.GetEntriesFast()])AliMUONTriggerCircuitNew(*c);
92 //_____________________________________________________________________________
93 AliMUONReconstructor::~AliMUONReconstructor()
98 delete fCalibrationData;
100 delete fCrateManager;
101 delete fTriggerCircuit;
105 //_____________________________________________________________________________
107 AliMUONReconstructor::GetCalibrationTask(AliMUONData* data) const
109 /// Create the calibration task(s).
111 const AliRun* run = fRunLoader->GetAliRun();
113 AliInfo("Calibration will occur.");
114 Int_t runNumber = run->GetRunNumber();
115 fCalibrationData = new AliMUONCalibrationData(runNumber);
116 if ( !fCalibrationData->IsValid() )
118 AliError("Could not retrieve calibrations !");
119 delete fCalibrationData;
120 fCalibrationData = 0x0;
123 TTask* calibration = new TTask("MUONCalibrator","MUON Digit calibrator");
124 calibration->Add(new AliMUONDigitCalibrator(data,fCalibrationData));
125 //FIXME: calibration->Add(something about dead channels should go here).
130 //_____________________________________________________________________________
132 AliMUONReconstructor::Init(AliRunLoader* runLoader)
136 fRunLoader = runLoader;
139 //_____________________________________________________________________________
140 void AliMUONReconstructor::Reconstruct(AliRunLoader* runLoader) const
145 AliLoader* loader = runLoader->GetLoader("MUONLoader");
146 Int_t nEvents = runLoader->GetNumberOfEvents();
148 AliMUONData* data = new AliMUONData(loader,"MUON","MUON");
150 // passing loader as argument.
151 AliMUONTrackReconstructor* recoEvent = new AliMUONTrackReconstructor(data);
152 recoEvent->SetTriggerCircuit(fTriggerCircuit);
154 if (strstr(GetOption(),"Original"))
155 recoEvent->SetTrackMethod(kOriginal); // Original tracking
156 else if (strstr(GetOption(),"Combi"))
157 recoEvent->SetTrackMethod(kCombi); // Combined cluster / track
159 recoEvent->SetTrackMethod(kKalman); // Kalman
161 AliMUONClusterReconstructor* recoCluster = new AliMUONClusterReconstructor(data);
163 AliMUONClusterFinderVS *recModel = recoCluster->GetRecoModel();
165 if (!strstr(GetOption(),"VS")) {
166 recModel = (AliMUONClusterFinderVS*) new AliMUONClusterFinderAZ();
167 recoCluster->SetRecoModel(recModel);
169 recModel->SetGhostChi2Cut(10);
171 loader->LoadDigits("READ");
172 loader->LoadRecPoints("RECREATE");
173 loader->LoadTracks("RECREATE");
175 TTask* calibration = GetCalibrationTask(data);
177 Int_t chBeg = (recoEvent->GetTrackMethod() == kCombi ? 6 : 0);
180 for(Int_t ievent = 0; ievent < nEvents; ievent++) {
182 AliDebug(1,Form("Event %d",ievent));
184 runLoader->GetEvent(ievent);
186 //----------------------- digit2cluster & Trigger2Trigger -------------------
187 if (!loader->TreeR()) loader->MakeRecPointsContainer();
190 if (recoEvent->GetTrackMethod() != kCombi) {
191 data->MakeBranch("RC");
192 data->SetTreeAddress("D,RC");
194 data->SetTreeAddress("D");
195 data->SetTreeAddress("RCC");
197 // Important for avoiding a memory leak when reading digits ( to be investigated more in detail)
198 // In any case the reading of GLT is needed for the Trigger2Tigger method below
199 data->SetTreeAddress("GLT");
205 calibration->ExecuteTask();
208 recoCluster->Digits2Clusters(chBeg);
210 if (recoEvent->GetTrackMethod() == kCombi) {
211 // Combined cluster / track finder
212 AliMUONEventRecoCombi::Instance()->FillEvent(data, (AliMUONClusterFinderAZ*)recModel);
213 ((AliMUONClusterFinderAZ*) recModel)->SetReco(2);
215 else data->Fill("RC");
218 data->MakeBranch("TC");
219 data->SetTreeAddress("TC");
220 recoCluster->Trigger2Trigger();
223 //AZ loader->WriteRecPoints("OVERWRITE");
225 //---------------------------- Track & TriggerTrack ---------------------
226 if (!loader->TreeT()) loader->MakeTracksContainer();
229 data->MakeBranch("RL"); //trigger track
230 data->SetTreeAddress("RL");
231 recoEvent->EventReconstructTrigger();
235 data->MakeBranch("RT"); //track
236 data->SetTreeAddress("RT");
237 recoEvent->EventReconstruct();
240 loader->WriteTracks("OVERWRITE");
242 if (recoEvent->GetTrackMethod() == kCombi) {
243 // Combined cluster / track
244 ((AliMUONClusterFinderAZ*) recModel)->SetReco(1);
245 data->MakeBranch("RC");
246 data->SetTreeAddress("RC");
247 AliMUONEventRecoCombi::Instance()->FillRecP(data, recoEvent);
250 loader->WriteRecPoints("OVERWRITE");
252 //--------------------------- Resetting branches -----------------------
254 data->ResetRawClusters();
255 data->ResetTrigger();
256 data->ResetRecTracks();
257 data->ResetRecTriggerTracks();
260 loader->UnloadDigits();
261 loader->UnloadRecPoints();
262 loader->UnloadTracks();
270 //_____________________________________________________________________________
271 void AliMUONReconstructor::Reconstruct(AliRunLoader* runLoader, AliRawReader* rawReader) const
277 AliLoader* loader = runLoader->GetLoader("MUONLoader");
278 AliMUONData data(loader,"MUON","MUON");
280 // passing loader as argument.
281 AliMUONTrackReconstructor recoEvent(&data);
282 recoEvent.SetTriggerCircuit(fTriggerCircuit);
284 fDigitMaker->SetMUONData(&data);
286 AliMUONClusterReconstructor recoCluster(&data);
288 if (strstr(GetOption(),"Original"))
290 recoEvent.SetTrackMethod(kOriginal); // Original tracking
294 recoEvent.SetTrackMethod(kKalman);
297 AliMUONClusterFinderVS *recModel = recoCluster.GetRecoModel();
298 if (!strstr(GetOption(),"VS"))
300 recModel = (AliMUONClusterFinderVS*) new AliMUONClusterFinderAZ();
301 recoCluster.SetRecoModel(recModel);
303 recModel->SetGhostChi2Cut(10);
305 TTask* calibration = GetCalibrationTask(&data);
307 loader->LoadRecPoints("RECREATE");
308 loader->LoadTracks("RECREATE");
309 loader->LoadDigits("READ");
314 TStopwatch totalTimer;
316 TStopwatch calibTimer;
317 TStopwatch clusterTimer;
318 TStopwatch trackingTimer;
320 rawTimer.Start(kTRUE); rawTimer.Stop();
321 calibTimer.Start(kTRUE); calibTimer.Stop();
322 clusterTimer.Start(kTRUE); clusterTimer.Stop();
323 trackingTimer.Start(kTRUE); trackingTimer.Stop();
325 totalTimer.Start(kTRUE);
327 while (rawReader->NextEvent())
329 AliDebug(1,Form("Event %d",iEvent));
331 runLoader->GetEvent(iEvent++);
333 //----------------------- raw2digits & raw2trigger-------------------
334 if (!loader->TreeD())
336 AliDebug(1,Form("Making Digit Container for event %d",iEvent));
337 loader->MakeDigitsContainer();
340 data.SetTreeAddress("D,GLT");
341 rawTimer.Start(kFALSE);
342 fDigitMaker->Raw2Digits(rawReader);
347 calibTimer.Start(kFALSE);
348 calibration->ExecuteTask();
352 //----------------------- digit2cluster & Trigger2Trigger -------------------
353 clusterTimer.Start(kFALSE);
355 if (!loader->TreeR()) loader->MakeRecPointsContainer();
358 data.MakeBranch("RC");
359 data.SetTreeAddress("RC");
360 recoCluster.Digits2Clusters();
364 data.MakeBranch("TC");
365 data.SetTreeAddress("TC");
366 recoCluster.Trigger2Trigger();
369 loader->WriteRecPoints("OVERWRITE");
373 //---------------------------- Track & TriggerTrack ---------------------
374 trackingTimer.Start(kFALSE);
375 if (!loader->TreeT()) loader->MakeTracksContainer();
378 data.MakeBranch("RL"); //trigger track
379 data.SetTreeAddress("RL");
380 recoEvent.EventReconstructTrigger();
384 data.MakeBranch("RT"); //track
385 data.SetTreeAddress("RT");
386 recoEvent.EventReconstruct();
389 loader->WriteTracks("OVERWRITE");
390 trackingTimer.Stop();
392 //--------------------------- Resetting branches -----------------------
394 data.ResetRawClusters();
396 data.ResetRecTracks();
397 data.ResetRecTriggerTracks();
403 loader->UnloadRecPoints();
404 loader->UnloadTracks();
405 loader->UnloadDigits();
407 AliInfo(Form("Execution time for converting RAW data to digits in MUON : R:%.2fs C:%.2fs",
408 rawTimer.RealTime(),rawTimer.CpuTime()));
409 AliInfo(Form("Execution time for calibrating MUON : R:%.2fs C:%.2fs",
410 calibTimer.RealTime(),calibTimer.CpuTime()));
411 AliInfo(Form("Execution time for clusterizing MUON : R:%.2fs C:%.2fs",
412 clusterTimer.RealTime(),clusterTimer.CpuTime()));
413 AliInfo(Form("Execution time for tracking MUON : R:%.2fs C:%.2fs",
414 trackingTimer.RealTime(),trackingTimer.CpuTime()));
415 AliInfo(Form("Total Execution time for Reconstruct(from raw) MUON : R:%.2fs C:%.2fs",
416 totalTimer.RealTime(),totalTimer.CpuTime()));
419 //_____________________________________________________________________________
420 void AliMUONReconstructor::FillESD(AliRunLoader* runLoader, AliESD* esd) const
425 TClonesArray* recTracksArray = 0;
426 TClonesArray* recTrigTracksArray = 0;
428 AliLoader* loader = runLoader->GetLoader("MUONLoader");
429 loader->LoadTracks("READ");
430 AliMUONData* muonData = new AliMUONData(loader,"MUON","MUON");
433 Int_t iEvent;// nPart;
434 Int_t nTrackHits;// nPrimary;
437 Double_t bendingSlope, nonBendingSlope, inverseBendingMomentum;
438 Double_t xRec, yRec, zRec, chi2MatchTrigger;
441 // setting pointer for tracks, triggertracks & trackparam at vertex
442 AliMUONTrack* recTrack = 0;
443 AliMUONTrackParam* trackParam = 0;
444 AliMUONTriggerTrack* recTriggerTrack = 0;
446 iEvent = runLoader->GetEventNumber();
447 runLoader->GetEvent(iEvent);
450 Double_t vertex[3] = {0};
451 const AliESDVertex *esdVert = esd->GetVertex();
452 if (esdVert->GetNContributors()) {
453 esdVert->GetXYZ(vertex);
454 printf("find vertex\n");
456 // setting ESD MUON class
457 AliESDMuonTrack* theESDTrack = new AliESDMuonTrack() ;
459 //-------------------- trigger tracks-------------
461 muonData->SetTreeAddress("RL");
462 muonData->GetRecTriggerTracks();
463 recTrigTracksArray = muonData->RecTriggerTracks();
465 // ready global trigger pattern from first track
466 if (recTrigTracksArray)
467 recTriggerTrack = (AliMUONTriggerTrack*) recTrigTracksArray->First();
468 if (recTriggerTrack) trigPat = recTriggerTrack->GetGTPattern();
470 //printf(">>> Event %d Number of Recconstructed tracks %d \n",iEvent, nrectracks);
472 // -------------------- tracks-------------
473 muonData->SetTreeAddress("RT");
474 muonData->GetRecTracks();
475 recTracksArray = muonData->RecTracks();
477 Int_t nRecTracks = 0;
479 nRecTracks = (Int_t) recTracksArray->GetEntriesFast(); //
482 for (Int_t iRecTracks = 0; iRecTracks < nRecTracks; iRecTracks++) {
484 // reading info from tracks
485 recTrack = (AliMUONTrack*) recTracksArray->At(iRecTracks);
487 trackParam = (AliMUONTrackParam*) (recTrack->GetTrackParamAtHit())->First();
489 if (esdVert->GetNContributors())
490 trackParam->ExtrapToVertex(vertex[0],vertex[1],vertex[2]);
492 bendingSlope = trackParam->GetBendingSlope();
493 nonBendingSlope = trackParam->GetNonBendingSlope();
494 inverseBendingMomentum = trackParam->GetInverseBendingMomentum();
495 xRec = trackParam->GetNonBendingCoor();
496 yRec = trackParam->GetBendingCoor();
497 zRec = trackParam->GetZ();
499 nTrackHits = recTrack->GetNTrackHits();
500 fitFmin = recTrack->GetFitFMin();
501 matchTrigger = recTrack->GetMatchTrigger();
502 chi2MatchTrigger = recTrack->GetChi2MatchTrigger();
504 // setting data member of ESD MUON
505 theESDTrack->SetInverseBendingMomentum(inverseBendingMomentum);
506 theESDTrack->SetThetaX(TMath::ATan(nonBendingSlope));
507 theESDTrack->SetThetaY(TMath::ATan(bendingSlope));
508 theESDTrack->SetZ(zRec);
509 theESDTrack->SetBendingCoor(yRec); // calculate vertex at ESD or Tracking level ?
510 theESDTrack->SetNonBendingCoor(xRec);
511 theESDTrack->SetChi2(fitFmin);
512 theESDTrack->SetNHit(nTrackHits);
513 theESDTrack->SetMatchTrigger(matchTrigger);
514 theESDTrack->SetChi2MatchTrigger(chi2MatchTrigger);
516 // storing ESD MUON Track into ESD Event
518 esd->AddMuonTrack(theESDTrack);
522 muonData->ResetRecTracks();
523 muonData->ResetRecTriggerTracks();
525 //} // end loop on event
526 loader->UnloadTracks();
530 }//_____________________________________________________________________________
531 void AliMUONReconstructor::FillESD(AliRunLoader* runLoader, AliRawReader* /*rawReader*/, AliESD* esd) const
536 // don't need rawReader ???
537 FillESD(runLoader, esd);