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 AliFMDBaseDA.cxx
17 @author Hans Hjersing Dalsgaard <canute@nbi.dk>
18 @date Wed Mar 26 11:30:45 2008
19 @brief Base class for detector algorithms.
22 // This is the implementation of the (virtual) base class for the FMD
23 // detector algorithms(DA). It implements the creation of the relevant
24 // containers and handles the loop over the raw data. The derived
25 // classes can control the parameters and action to be taken making
26 // this the base class for the Pedestal, Gain and Physics DA.
29 #include "AliFMDBaseDA.h"
30 #include "AliRawReader.h"
31 #include "AliFMDDigit.h"
32 #include "AliFMDParameters.h"
33 #include "AliFMDRawReader.h"
34 #include "AliFMDCalibSampleRate.h"
35 #include "AliFMDCalibStripRange.h"
37 #include "AliRawEventHeaderBase.h"
38 #include "AliFMDDigit.h"
39 #include <TClonesArray.h>
46 //_____________________________________________________________________
47 ClassImp(AliFMDBaseDA)
49 ; // Do not delete - to let Emacs for mat the code
52 //_____________________________________________________________________
54 AliFMDBaseDA::GetStripPath(UShort_t det,
63 // det Detector number
64 // ring Ring identifier
67 // full If true, return full path
71 return Form("%s%sFMD%d%c[%02d,%03d]",
72 (full ? GetSectorPath(det, ring, sec, full) : ""),
73 (full ? "/" : ""), det, ring, sec, str);
75 //_____________________________________________________________________
77 AliFMDBaseDA::GetSectorPath(UShort_t det,
85 // det Detector number
86 // ring Ring identifier
89 // full If true, return full path
93 return Form("%s%sFMD%d%c[%02d]",
94 (full ? GetRingPath(det, ring, full) : ""),
95 (full ? "/" : ""), det, ring, sec);
97 //_____________________________________________________________________
99 AliFMDBaseDA::GetRingPath(UShort_t det,
103 // Get the strip path
106 // det Detector number
107 // ring Ring identifier
110 // full If true, return full path
114 return Form("%s%sFMD%d%c",
115 (full ? GetDetectorPath(det, full) : ""),
116 (full ? "/" : ""), det, ring);
118 //_____________________________________________________________________
120 AliFMDBaseDA::GetDetectorPath(UShort_t det,
123 // Get the strip path
126 // det Detector number
127 // ring Ring identifier
130 // full If true, return full path
134 return Form("%s%sFMD%d",
135 (full ? fDiagnosticsFilename.Data() : ""),
136 (full ? ":/" : ""), det);
139 //_____________________________________________________________________
140 AliFMDBaseDA::AliFMDBaseDA() :
142 fDiagnosticsFilename("diagnosticsHistograms.root"),
145 fSaveHistograms(kFALSE),
146 fMakeSummaries(kFALSE),
156 fSeenDetectors[0] = fSeenDetectors[1] = fSeenDetectors[2] = kFALSE;
157 fDetectorArray.SetOwner();
158 Rotate("conditions.csv", 3);
159 fConditionsFile.open("conditions.csv");
161 //_____________________________________________________________________
162 AliFMDBaseDA::AliFMDBaseDA(const AliFMDBaseDA & baseDA) :
164 fDiagnosticsFilename(baseDA.fDiagnosticsFilename.Data()),
167 fSaveHistograms(baseDA.fSaveHistograms),
168 fMakeSummaries(baseDA.fMakeSummaries),
169 fDetectorArray(baseDA.fDetectorArray),
170 fPulseSize(baseDA.fPulseSize),
171 fPulseLength(baseDA.fPulseLength),
172 fRequiredEvents(baseDA.fRequiredEvents),
173 fCurrentEvent(baseDA.fCurrentEvent),
174 fRunno(baseDA.fRunno),
178 fSeenDetectors[0] = baseDA.fSeenDetectors[0];
179 fSeenDetectors[1] = baseDA.fSeenDetectors[1];
180 fSeenDetectors[2] = baseDA.fSeenDetectors[2];
182 fDetectorArray.SetOwner();
187 //_____________________________________________________________________
188 AliFMDBaseDA::~AliFMDBaseDA()
193 //_____________________________________________________________________
194 void AliFMDBaseDA::Run(AliRawReader* reader)
199 diagFile = TFile::Open(fDiagnosticsFilename.Data(),"RECREATE");
206 fRunno = reader->GetRunNumber();
208 AliFMDRawReader* fmdReader = new AliFMDRawReader(reader,0);
209 TClonesArray* digitArray = new TClonesArray("AliFMDDigit",0);
211 Bool_t sodread = kFALSE;
213 for(Int_t i=0;i<3;i++) {
214 if (!reader->NextEvent()) {
215 // Read Start-of-Run / Start-of-Files event
216 AliWarning(Form("Failed to read the %d%s event",
217 i+1, (i == 0 ? "st" : (i == 1 ? "nd" : "rd"))));
221 UInt_t eventType = reader->GetType();
222 if(eventType == AliRawEventHeaderBase::kStartOfData ||
223 eventType == AliRawEventHeaderBase::kFormatError) {
225 WriteConditionsData(fmdReader);
232 InitContainer(diagFile);
235 AliWarning("No SOD event detected!");
237 int lastProgress = 0;
241 for(Int_t n =1;n <= GetRequiredEvents(); n++) {
242 if(!reader->NextEvent()) continue;
245 fmdReader->ReadAdcs(digitArray);
247 for(Int_t i = 0; i<digitArray->GetEntriesFast();i++) {
248 AliFMDDigit* digit = static_cast<AliFMDDigit*>(digitArray->At(i));
249 fSeenDetectors[digit->Detector()-1] = kTRUE;
256 int progress = int((n *100)/ GetRequiredEvents()) ;
257 if (progress <= lastProgress) continue;
258 lastProgress = progress;
259 std::cout << "Progress: " << lastProgress << " / 100 " << std::endl;
263 AliInfo(Form("Looped over %d events",GetCurrentEvent()));
266 for(UShort_t det=1;det<=3;det++) {
267 if (!fSeenDetectors[det-1]) continue;
268 std::cout << "FMD" << det << std::endl;
269 UShort_t firstRing = (det == 1 ? 1 : 0);
270 for (UShort_t ir = firstRing; ir < 2; ir++) {
271 Char_t ring = (ir == 0 ? 'O' : 'I');
272 UShort_t nsec = (ir == 0 ? 40 : 20);
273 UShort_t nstr = (ir == 0 ? 256 : 512);
275 if (fMakeSummaries) MakeSummary(det, ring);
277 std::cout << " Ring " << ring << ": " << std::flush;
278 for(UShort_t sec =0; sec < nsec; sec++) {
279 for(UShort_t strip = 0; strip < nstr; strip++) {
280 Analyse(det,ring,sec,strip);
282 std::cout << '.' << std::flush;
286 std::cout << "done" << std::endl;
290 if(fOutputFile.is_open()) {
291 fOutputFile.write("# EOF\n",6);
297 if(fSaveHistograms ) {
299 AliInfo("Closing diagnostics file - please wait ...");
300 // diagFile->Write();
306 //_____________________________________________________________________
308 void AliFMDBaseDA::InitContainer(TDirectory* diagFile)
310 //Prepare container for diagnostics
312 TObjArray* ringArray;
313 TObjArray* sectorArray;
315 TDirectory* savDir = gDirectory;
317 for(UShort_t det=1;det<=3;det++) {
318 detArray = new TObjArray();
319 detArray->SetOwner();
320 fDetectorArray.AddAtAndExpand(detArray,det);
322 TDirectory* detDir = 0;
325 detDir = diagFile->mkdir(GetDetectorPath(det, kFALSE));
328 UShort_t FirstRing = (det == 1 ? 1 : 0);
329 for (UShort_t ir = FirstRing; ir < 2; ir++) {
330 Char_t ring = (ir == 0 ? 'O' : 'I');
331 UShort_t nsec = (ir == 0 ? 40 : 20);
332 UShort_t nstr = (ir == 0 ? 256 : 512);
333 ringArray = new TObjArray();
334 ringArray->SetOwner();
335 detArray->AddAtAndExpand(ringArray,ir);
338 TDirectory* ringDir = 0;
341 ringDir = detDir->mkdir(GetRingPath(det,ring, kFALSE));
345 for(UShort_t sec =0; sec < nsec; sec++) {
346 sectorArray = new TObjArray();
347 sectorArray->SetOwner();
348 ringArray->AddAtAndExpand(sectorArray,sec);
351 TDirectory* secDir = 0;
354 secDir = ringDir->mkdir(GetSectorPath(det, ring, sec, kFALSE));
357 for(UShort_t strip = 0; strip < nstr; strip++) {
360 secDir->mkdir(GetStripPath(det, ring, sec, strip, kFALSE));
362 AddChannelContainer(sectorArray, det, ring, sec, strip);
370 //_____________________________________________________________________
371 void AliFMDBaseDA::WriteConditionsData(AliFMDRawReader* fmdReader)
373 //Write the conditions data to file
374 AliFMDParameters* pars = AliFMDParameters::Instance();
375 fConditionsFile.write(Form("# %s \n",pars->GetConditionsShuttleID()),14);
377 fConditionsFile << "# This file created from run number " << fRunno
378 << " at " << now.AsString() << std::endl;
380 AliFMDCalibSampleRate* sampleRate = new AliFMDCalibSampleRate();
381 AliFMDCalibStripRange* stripRange = new AliFMDCalibStripRange();
383 fmdReader->ReadSODevent(sampleRate,stripRange,fPulseSize,fPulseLength,
386 sampleRate->WriteToFile(fConditionsFile, fSeenDetectors);
387 stripRange->WriteToFile(fConditionsFile, fSeenDetectors);
394 fConditionsFile.write("# Gain Events \n",15);
396 for(UShort_t det=1; det<=3;det++) {
397 if (!fSeenDetectors[det-1]) {
400 UShort_t firstring = (det == 1 ? 1 : 0);
401 for(UShort_t iring = firstring; iring <=1;iring++) {
402 Char_t ring = (iring == 1 ? 'I' : 'O');
403 for(UShort_t board =0 ; board <=1; board++) {
405 Int_t idx = GetHalfringIndex(det,ring,board);
407 fConditionsFile << det << ','
410 << fPulseLength.At(idx) << "\n";
416 fConditionsFile.write("# Gain Pulse \n",14);
418 for(UShort_t det=1; det<=3;det++) {
419 if (!fSeenDetectors[det-1]) {
422 UShort_t firstring = (det == 1 ? 1 : 0);
423 for(UShort_t iring = firstring; iring <=1;iring++) {
424 Char_t ring = (iring == 1 ? 'I' : 'O');
425 for(UShort_t board =0 ; board <=1; board++) {
427 Int_t idx = GetHalfringIndex(det,ring,board);
429 fConditionsFile << det << ','
432 << fPulseSize.At(idx) << "\n";
437 // sampleRate->WriteToFile(std::cout, fSeenDetectors);
438 // stripRange->WriteToFile(std::cout, fSeenDetectors);
440 if(fConditionsFile.is_open()) {
442 fConditionsFile.write("# EOF\n",6);
443 fConditionsFile.close();
448 //_____________________________________________________________________
449 Int_t AliFMDBaseDA::GetHalfringIndex(UShort_t det, Char_t ring,
450 UShort_t board) const
452 // Get the index corresponding to a half-ring
455 // det Detector number
456 // ring Ring identifier
457 // board Board number
460 // Internal index of the board
461 UShort_t iring = (ring == 'I' ? 1 : 0);
463 Int_t index = (((det-1) << 2) | (iring << 1) | (board << 0));
468 //_____________________________________________________________________
469 void AliFMDBaseDA::Rotate(const char* base, int max) const
472 // Rotate a set of files. base is the basic name of the files.
473 // If the file base.max exists it is removed.
474 // If the file base.n exists (where n < max) it is renamed to
476 // If the file base exists, it is renamed to base.1
479 // base Base name of the files
480 // max Maximum number to keep (minus one for the current).
482 // Note: TSystem::AccessPathName returns false if the condition is
485 // Check if we have base.max, and if so, remove it.
486 TString testName(Form("%s.%d", base, max));
487 if (!gSystem->AccessPathName(testName.Data()))
488 gSystem->Unlink(testName.Data());
490 // Loop down from max-1 to 1 and move files
491 for (int i = max-1; i >= 1; i--) {
492 testName = Form("%s.%d", base, i);
493 if (!gSystem->AccessPathName(testName.Data())) {
494 TString newName(Form("%s.%d", base, i+1));
495 gSystem->Rename(testName.Data(), newName.Data());
499 // If we have the file base, rename it to base.1
500 testName = Form("%s", base);
501 if (!gSystem->AccessPathName(testName.Data())){
502 TString newName(Form("%s.%d", base, 1));
503 gSystem->Rename(testName.Data(), newName.Data());
507 //_____________________________________________________________________
509 AliFMDBaseDA::MakeSummaryHistogram(const char* prefix, const char* title,
510 UShort_t d, Char_t r)
513 // Utility function for defining summary histograms
517 // ring Ring identifier
518 // prefix Histogram prefix
519 // title Histogram title
521 Int_t nX = ((d == 1 || r == 'I' || r == 'i') ? 20 : 40);
522 Int_t nY = ((d == 1 || r == 'I' || r == 'i') ? 512 : 256);
524 TH2* ret = new TH2F(Form("%sFMD%d%c", prefix, d, r),
525 Form("%s for FMD%d%c", title, d, r),
526 nX, -0.5, nX-0.5, nY, -0.5, nY-0.5);
527 ret->SetXTitle("Sector #");
528 ret->SetYTitle("Strip #");
530 // if (!fSummaries) fSummaries = new TObjArray;
535 //_____________________________________________________________________