1 /**************************************************************************
2 * Copyright(c) 2004, 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 **************************************************************************/
16 /** @file AliFMDInput.cxx
17 @author Christian Holm Christensen <cholm@nbi.dk>
18 @date Mon Mar 27 12:42:40 2006
19 @brief FMD utility classes for reading FMD data
21 //___________________________________________________________________
23 // The classes defined here, are utility classes for reading in data
24 // for the FMD. They are put in a seperate library to not polute the
25 // normal libraries. The classes are intended to be used as base
26 // classes for customized class that do some sort of analysis on the
27 // various types of data produced by the FMD.
29 // Latest changes by Christian Holm Christensen
31 #include "AliFMDInput.h" // ALIFMDHIT_H
32 #include "AliFMDDebug.h" // ALIFMDDEBUG_H ALILOG_H
33 #include "AliLoader.h" // ALILOADER_H
34 #include "AliRunLoader.h" // ALIRUNLOADER_H
35 #include "AliRun.h" // ALIRUN_H
36 #include "AliStack.h" // ALISTACK_H
37 #include "AliRawReaderFile.h" // ALIRAWREADERFILE_H
38 #include "AliRawReaderRoot.h" // ALIRAWREADERROOT_H
39 #include "AliRawReaderDate.h" // ALIRAWREADERDATE_H
40 #include "AliFMD.h" // ALIFMD_H
41 #include "AliFMDHit.h" // ALIFMDHIT_H
42 #include "AliFMDDigit.h" // ALIFMDDigit_H
43 #include "AliFMDSDigit.h" // ALIFMDDigit_H
44 #include "AliFMDRecPoint.h" // ALIFMDRECPOINT_H
45 #include "AliFMDRawReader.h" // ALIFMDRAWREADER_H
47 #include <AliESDFMD.h>
48 #include <AliESDEvent.h>
49 #include <AliCDBManager.h>
50 #include <AliCDBEntry.h>
51 #include <AliAlignObjParams.h>
52 #include <TTree.h> // ROOT_TTree
53 #include <TChain.h> // ROOT_TChain
54 #include <TParticle.h> // ROOT_TParticle
55 #include <TString.h> // ROOT_TString
56 #include <TDatabasePDG.h> // ROOT_TDatabasePDG
57 #include <TMath.h> // ROOT_TMath
58 #include <TGeoManager.h> // ROOT_TGeoManager
59 #include <TSystemDirectory.h> // ROOT_TSystemDirectory
60 #include <Riostream.h> // ROOT_Riostream
61 #include <TFile.h> // ROOT_TFile
62 #include <TStreamerInfo.h>
65 //____________________________________________________________________
68 ; // This is here to keep Emacs for indenting the next line
72 //____________________________________________________________________
73 AliFMDInput::AliFMDInput()
74 : TNamed("AliFMDInput", "Input handler for various FMD data"),
105 // Constructor of an FMD input object. Specify what data to read in
106 // using the AddLoad member function. Sub-classes should at a
107 // minimum overload the member function Event. A full job can be
108 // executed using the member function Run.
113 //____________________________________________________________________
114 AliFMDInput::AliFMDInput(const char* gAliceFile)
115 : TNamed("AliFMDInput", "Input handler for various FMD data"),
116 fGAliceFile(gAliceFile),
146 // Constructor of an FMD input object. Specify what data to read in
147 // using the AddLoad member function. Sub-classes should at a
148 // minimum overload the member function Event. A full job can be
149 // executed using the member function Run.
152 //____________________________________________________________________
154 AliFMDInput::NEvents() const
156 // Get number of events
157 if (TESTBIT(fTreeMask, kRaw)) return -1;
158 if (fTreeE) return fTreeE->GetEntries();
162 //____________________________________________________________________
166 // Initialize the object. Get the needed loaders, and such.
168 // Check if we have been initialized
170 AliWarning("Already initialized");
174 if (!TESTBIT(fTreeMask, kRaw)) {
175 if (fGAliceFile.IsNull()) fGAliceFile = "galice.root";
177 fLoader = AliRunLoader::Open(fGAliceFile.Data(), "Alice", "read");
179 AliError(Form("Coulnd't read the file %s", fGAliceFile.Data()));
183 if (fLoader->LoadgAlice()) return kFALSE;
184 fRun = fLoader->GetAliRun();
187 fFMD = static_cast<AliFMD*>(fRun->GetDetector("FMD"));
189 AliError("Failed to get detector FMD from loader");
193 // Get the FMD loader
194 fFMDLoader = fLoader->GetLoader("FMDLoader");
196 AliError("Failed to get detector FMD loader from loader");
199 if (fLoader->LoadHeader()) {
200 AliError("Failed to get event header information from loader");
203 fTreeE = fLoader->TreeE();
206 // Optionally, get the ESD files
207 if (TESTBIT(fTreeMask, kESD)) {
208 fChainE = new TChain("esdTree");
209 TSystemDirectory dir(".",".");
210 TList* files = dir.GetListOfFiles();
211 TSystemFile* file = 0;
213 AliError("No files");
218 while ((file = static_cast<TSystemFile*>(next()))) {
219 TString fname(file->GetName());
220 if (fname.Contains("AliESDs")) fChainE->AddFile(fname.Data());
222 fESDEvent = new AliESDEvent();
223 fESDEvent->ReadFromTree(fChainE);
224 // fChainE->SetBranchAddress("ESD", &fMainESD);
228 if (TESTBIT(fTreeMask, kRaw)) {
229 AliInfo("Getting FMD raw data digits");
230 fArrayA = new TClonesArray("AliFMDDigit");
231 if (!fRawFile.IsNull() && fRawFile.EndsWith(".root"))
232 fReader = new AliRawReaderRoot(fRawFile.Data());
233 else if (!fRawFile.IsNull() && fRawFile.EndsWith(".raw"))
234 fReader = new AliRawReaderDate(fRawFile.Data());
236 fReader = new AliRawReaderFile(-1);
240 // Optionally, get the geometry
241 if (TESTBIT(fTreeMask, kGeometry)) {
243 TString fname(fRun->GetGeometryFileName());
244 if (fname.IsNull()) {
245 Warning("Init", "No file name for the geometry from AliRun");
246 fname = gSystem->DirName(fGAliceFile);
247 fname.Append("/geometry.root");
249 fGeoManager = TGeoManager::Import(fname.Data());
251 Fatal("Init", "No geometry manager found");
256 AliGeomManager::LoadGeometry();
258 AliCDBManager* cdb = AliCDBManager::Instance();
259 AliCDBEntry* align = cdb->Get("FMD/Align/Data");
261 AliInfo("Got alignment data from CDB");
262 TClonesArray* array = dynamic_cast<TClonesArray*>(align->GetObject());
264 AliWarning("Invalid align data from CDB");
267 Int_t nAlign = array->GetEntries();
268 for (Int_t i = 0; i < nAlign; i++) {
269 AliAlignObjParams* a = static_cast<AliAlignObjParams*>(array->At(i));
270 if (!a->ApplyToGeometry()) {
271 AliWarning(Form("Failed to apply alignment to %s",
284 //____________________________________________________________________
286 AliFMDInput::Begin(Int_t event)
288 // Called at the begining of each event. Per default, it gets the
289 // data trees and gets pointers to the output arrays. Users can
290 // overload this, but should call this member function in the
291 // overloaded member function of the derived class.
293 // Check if we have been initialized
295 AliError("Not initialized");
300 if (fLoader && fLoader->GetEvent(event)) return kFALSE;
301 AliInfo(Form("Now in event %8d/%8d", event, NEvents()));
303 // Possibly load global kinematics information
304 if (TESTBIT(fTreeMask, kKinematics) || TESTBIT(fTreeMask, kTracks)) {
305 // AliInfo("Getting kinematics");
306 if (fLoader->LoadKinematics("READ")) return kFALSE;
307 fStack = fLoader->Stack();
310 // Possibly load FMD Hit information
311 if (TESTBIT(fTreeMask, kHits) || TESTBIT(fTreeMask, kTracks)) {
312 // AliInfo("Getting FMD hits");
313 if (!fFMDLoader || fFMDLoader->LoadHits("READ")) return kFALSE;
314 fTreeH = fFMDLoader->TreeH();
315 if (!fArrayH) fArrayH = fFMD->Hits();
318 // Possibly load heaedr information
319 if (TESTBIT(fTreeMask, kHeader)) {
320 // AliInfo("Getting FMD hits");
321 if (!fLoader /* || fLoader->LoadHeader()*/) return kFALSE;
322 fHeader = fLoader->GetHeader();
325 // Possibly load FMD Digit information
326 if (TESTBIT(fTreeMask, kDigits)) {
327 // AliInfo("Getting FMD digits");
328 if (!fFMDLoader || fFMDLoader->LoadDigits("READ")) return kFALSE;
329 fTreeD = fFMDLoader->TreeD();
331 if (!fArrayD) fArrayD = fFMD->Digits();
335 AliWarning(Form("Failed to load FMD Digits"));
339 // Possibly load FMD Sdigit information
340 if (TESTBIT(fTreeMask, kSDigits)) {
341 // AliInfo("Getting FMD summable digits");
342 if (!fFMDLoader || fFMDLoader->LoadSDigits("READ")) return kFALSE;
343 fTreeS = fFMDLoader->TreeS();
344 if (!fArrayS) fArrayS = fFMD->SDigits();
347 // Possibly load FMD RecPoints information
348 if (TESTBIT(fTreeMask, kRecPoints)) {
349 // AliInfo("Getting FMD reconstructed points");
350 if (!fFMDLoader || fFMDLoader->LoadRecPoints("READ")) return kFALSE;
351 fTreeR = fFMDLoader->TreeR();
352 if (!fArrayR) fArrayR = new TClonesArray("AliFMDRecPoint");
353 fTreeR->SetBranchAddress("FMD", &fArrayR);
356 // Possibly load FMD ESD information
357 if (TESTBIT(fTreeMask, kESD)) {
358 // AliInfo("Getting FMD event summary data");
359 Int_t read = fChainE->GetEntry(event);
360 if (read <= 0) return kFALSE;
361 fESD = fESDEvent->GetFMDData();
362 if (!fESD) return kFALSE;
364 TFile* f = fChainE->GetFile();
366 TObject* o = f->GetStreamerInfoList()->FindObject("AliFMDMap");
368 TStreamerInfo* info = static_cast<TStreamerInfo*>(o);
369 std::cout << "AliFMDMap class version read is "
370 << info->GetClassVersion() << std::endl;
373 // fESD->CheckNeedUShort(fChainE->GetFile());
377 // Possibly load FMD Digit information
378 if (TESTBIT(fTreeMask, kRaw)) {
379 AliInfo("Getting FMD raw data digits");
380 if (!fReader->NextEvent()) return kFALSE;
381 AliFMDRawReader r(fReader, 0);
384 AliFMDDebug(1, ("Got a total of %d digits", fArrayA->GetEntriesFast()));
391 //____________________________________________________________________
395 // Process one event. The default implementation one or more of
397 // - ProcessHits if the hits are loaded.
398 // - ProcessDigits if the digits are loaded.
399 // - ProcessSDigits if the sumbable digits are loaded.
400 // - ProcessRecPoints if the reconstructed points are loaded.
401 // - ProcessESD if the event summary data is loaded
403 if (TESTBIT(fTreeMask, kHits))
404 if (!ProcessHits()) return kFALSE;
405 if (TESTBIT(fTreeMask, kTracks))
406 if (!ProcessTracks()) return kFALSE;
407 if (TESTBIT(fTreeMask, kDigits))
408 if (!ProcessDigits()) return kFALSE;
409 if (TESTBIT(fTreeMask, kSDigits))
410 if (!ProcessSDigits()) return kFALSE;
411 if (TESTBIT(fTreeMask, kRaw))
412 if (!ProcessRawDigits()) return kFALSE;
413 if (TESTBIT(fTreeMask, kRecPoints))
414 if (!ProcessRecPoints()) return kFALSE;
415 if (TESTBIT(fTreeMask, kESD))
416 if (!ProcessESDs()) return kFALSE;
421 //____________________________________________________________________
423 AliFMDInput::ProcessHits()
425 // Read the hit tree, and pass each hit to the member function
428 AliError("No hit tree defined");
432 AliError("No hit array defined");
436 Int_t nTracks = fTreeH->GetEntries();
437 for (Int_t i = 0; i < nTracks; i++) {
438 Int_t hitRead = fTreeH->GetEntry(i);
439 if (hitRead <= 0) continue;
441 Int_t nHit = fArrayH->GetEntries();
442 if (nHit <= 0) continue;
444 for (Int_t j = 0; j < nHit; j++) {
445 AliFMDHit* hit = static_cast<AliFMDHit*>(fArrayH->At(j));
448 TParticle* track = 0;
449 if (TESTBIT(fTreeMask, kKinematics) && fStack) {
450 Int_t trackno = hit->Track();
451 track = fStack->Particle(trackno);
453 if (!ProcessHit(hit, track)) return kFALSE;
459 //____________________________________________________________________
461 AliFMDInput::ProcessTracks()
463 // Read the hit tree, and pass each hit to the member function
466 AliError("No track tree defined");
470 AliError("No hit tree defined");
474 AliError("No hit array defined");
478 // Int_t nTracks = fStack->GetNtrack();
479 Int_t nTracks = fTreeH->GetEntries();
480 for (Int_t i = 0; i < nTracks; i++) {
481 Int_t trackno = nTracks - i - 1;
482 TParticle* track = fStack->Particle(trackno);
483 if (!track) continue;
485 // Get the hits for this track.
486 Int_t hitRead = fTreeH->GetEntry(i);
487 Int_t nHit = fArrayH->GetEntries();
488 if (nHit == 0 || hitRead <= 0) {
489 // Let user code see the track, even if there's no hits.
490 if (!ProcessTrack(trackno, track, 0)) return kFALSE;
494 // Loop over the hits corresponding to this track.
495 for (Int_t j = 0; j < nHit; j++) {
496 AliFMDHit* hit = static_cast<AliFMDHit*>(fArrayH->At(j));
497 if (!ProcessTrack(trackno, track, hit)) return kFALSE;
503 //____________________________________________________________________
505 AliFMDInput::ProcessDigits()
507 // Read the digit tree, and pass each digit to the member function
510 AliError("No digit tree defined");
514 AliError("No digit array defined");
518 Int_t nEv = fTreeD->GetEntries();
519 for (Int_t i = 0; i < nEv; i++) {
520 Int_t digitRead = fTreeD->GetEntry(i);
521 if (digitRead <= 0) continue;
522 Int_t nDigit = fArrayD->GetEntries();
523 AliFMDDebug(0, ("Got %5d digits for this event", nDigit));
524 if (nDigit <= 0) continue;
525 for (Int_t j = 0; j < nDigit; j++) {
526 AliFMDDigit* digit = static_cast<AliFMDDigit*>(fArrayD->At(j));
527 if (!digit) continue;
528 if (!ProcessDigit(digit)) return kFALSE;
534 //____________________________________________________________________
536 AliFMDInput::ProcessSDigits()
538 // Read the summable digit tree, and pass each sumable digit to the
539 // member function ProcessSdigit.
541 AliWarning("No sdigit tree defined");
542 return kTRUE; // Empty SDigits is fine
545 AliWarning("No sdigit array defined");
546 return kTRUE; // Empty SDigits is fine
549 Int_t nEv = fTreeS->GetEntries();
550 for (Int_t i = 0; i < nEv; i++) {
551 Int_t sdigitRead = fTreeS->GetEntry(i);
552 if (sdigitRead <= 0) continue;
553 Int_t nSdigit = fArrayS->GetEntries();
554 AliFMDDebug(0, ("Got %5d digits for this event", nSdigit));
555 if (nSdigit <= 0) continue;
556 for (Int_t j = 0; j < nSdigit; j++) {
557 AliFMDSDigit* sdigit = static_cast<AliFMDSDigit*>(fArrayS->At(j));
558 if (!sdigit) continue;
559 if (!ProcessSDigit(sdigit)) return kFALSE;
565 //____________________________________________________________________
567 AliFMDInput::ProcessRawDigits()
569 // Read the digit tree, and pass each digit to the member function
572 AliError("No raw digit array defined");
576 Int_t nDigit = fArrayA->GetEntries();
577 if (nDigit <= 0) return kTRUE;
578 for (Int_t j = 0; j < nDigit; j++) {
579 AliFMDDigit* digit = static_cast<AliFMDDigit*>(fArrayA->At(j));
580 if (!digit) continue;
581 if (AliLog::GetDebugLevel("FMD","") >= 40 && j < 30)
583 if (!ProcessRawDigit(digit)) return kFALSE;
588 //____________________________________________________________________
590 AliFMDInput::ProcessRecPoints()
592 // Read the reconstrcted points tree, and pass each reconstruction
593 // object (AliFMDRecPoint) to either ProcessRecPoint.
595 AliError("No recpoint tree defined");
599 AliError("No recpoints array defined");
603 Int_t nEv = fTreeR->GetEntries();
604 for (Int_t i = 0; i < nEv; i++) {
605 Int_t recRead = fTreeR->GetEntry(i);
606 if (recRead <= 0) continue;
607 Int_t nRecPoint = fArrayR->GetEntries();
608 for (Int_t j = 0; j < nRecPoint; j++) {
609 AliFMDRecPoint* recPoint = static_cast<AliFMDRecPoint*>(fArrayR->At(j));
610 if (!recPoint) continue;
611 if (!ProcessRecPoint(recPoint)) return kFALSE;
617 //____________________________________________________________________
619 AliFMDInput::ProcessESDs()
621 // Process event summary data
622 if (!fESD) return kFALSE;
623 for (UShort_t det = 1; det <= 3; det++) {
624 Char_t rings[] = { 'I', (det == 1 ? '\0' : 'O'), '\0' };
625 for (Char_t* rng = rings; *rng != '\0'; rng++) {
626 UShort_t nsec = (*rng == 'I' ? 20 : 40);
627 UShort_t nstr = (*rng == 'I' ? 512 : 256);
628 for (UShort_t sec = 0; sec < nsec; sec++) {
629 for (UShort_t str = 0; str < nstr; str++) {
630 Float_t eta = fESD->Eta(det,*rng,sec,str);
631 Float_t mult = fESD->Multiplicity(det,*rng,sec,str);
632 if (!fESD->IsAngleCorrected())
633 mult *= TMath::Abs(TMath::Cos(2.*TMath::ATan(TMath::Exp(-eta))));
634 if (!ProcessESD(det, *rng, sec, str, eta, mult)) continue;
642 //____________________________________________________________________
646 // Called at the end of each event. Per default, it unloads the
647 // data trees and resets the pointers to the output arrays. Users
648 // can overload this, but should call this member function in the
649 // overloaded member function of the derived class.
651 // Check if we have been initialized
653 AliError("Not initialized");
656 // Possibly unload global kinematics information
657 if (TESTBIT(fTreeMask, kKinematics) || TESTBIT(fTreeMask, kTracks)) {
658 fLoader->UnloadKinematics();
662 // Possibly unload FMD Hit information
663 if (TESTBIT(fTreeMask, kHits) || TESTBIT(fTreeMask, kTracks)) {
664 fFMDLoader->UnloadHits();
667 // Possibly unload FMD Digit information
668 if (TESTBIT(fTreeMask, kDigits)) {
669 fFMDLoader->UnloadDigits();
672 // Possibly unload FMD Sdigit information
673 if (TESTBIT(fTreeMask, kSDigits)) {
674 fFMDLoader->UnloadSDigits();
677 // Possibly unload FMD RecPoints information
678 if (TESTBIT(fTreeMask, kRecPoints)) {
679 fFMDLoader->UnloadRecPoints();
682 // AliInfo("Now out event");
686 //____________________________________________________________________
690 // Run over all events and files references in galice.root
693 if (!(retval = Init())) return retval;
695 Int_t nEvents = NEvents();
696 for (Int_t event = 0; nEvents < 0 || event < nEvents; event++) {
697 if (!(retval = Begin(event))) break;
698 if (!(retval = Event())) break;
699 if (!(retval = End())) break;
701 if (!retval) return retval;
706 //__________________________________________________________________
708 AliFMDInput::MakeLogScale(Int_t n, Double_t min, Double_t max)
710 // Service function to define a logarithmic axis.
713 // min Minimum of axis
714 // max Maximum of axis
718 for (Int_t i = 1; i < n+1; i++) bins[i] = bins[i-1] + (max-min)/n;
721 Float_t dp = n / TMath::Log10(max / min);
722 Float_t pmin = TMath::Log10(min);
723 for (Int_t i = 1; i < n+1; i++) {
724 Float_t p = pmin + i / dp;
725 bins[i] = TMath::Power(10, p);
732 //____________________________________________________________________