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"
31 #include "AliFMDRawReader.h"
32 #include "AliFMDCalibSampleRate.h"
33 #include "AliFMDCalibStripRange.h"
35 #include "AliRawEventHeaderBase.h"
40 //_____________________________________________________________________
41 ClassImp(AliFMDBaseDA)
43 ; // Do not delete - to let Emacs for mat the code
46 //_____________________________________________________________________
48 AliFMDBaseDA::GetStripPath(UShort_t det,
57 // det Detector number
58 // ring Ring identifier
61 // full If true, return full path
65 return Form("%s%sFMD%d%c[%02d,%03d]",
66 (full ? GetSectorPath(det, ring, sec, full) : ""),
67 (full ? "/" : ""), det, ring, sec, str);
69 //_____________________________________________________________________
71 AliFMDBaseDA::GetSectorPath(UShort_t det,
79 // det Detector number
80 // ring Ring identifier
83 // full If true, return full path
87 return Form("%s%sFMD%d%c[%02d]",
88 (full ? GetRingPath(det, ring, full) : ""),
89 (full ? "/" : ""), det, ring, sec);
91 //_____________________________________________________________________
93 AliFMDBaseDA::GetRingPath(UShort_t det,
100 // det Detector number
101 // ring Ring identifier
104 // full If true, return full path
108 return Form("%s%sFMD%d%c",
109 (full ? GetDetectorPath(det, full) : ""),
110 (full ? "/" : ""), det, ring);
112 //_____________________________________________________________________
114 AliFMDBaseDA::GetDetectorPath(UShort_t det,
117 // Get the strip path
120 // det Detector number
121 // ring Ring identifier
124 // full If true, return full path
128 return Form("%s%sFMD%d",
129 (full ? fDiagnosticsFilename.Data() : ""),
130 (full ? ":/" : ""), det);
133 //_____________________________________________________________________
134 AliFMDBaseDA::AliFMDBaseDA() :
136 fDiagnosticsFilename("diagnosticsHistograms.root"),
139 fSaveHistograms(kFALSE),
140 fMakeSummaries(kFALSE),
150 fSeenDetectors[0] = fSeenDetectors[1] = fSeenDetectors[2] = kFALSE;
151 fDetectorArray.SetOwner();
152 Rotate("conditions.csv", 3);
153 fConditionsFile.open("conditions.csv");
155 //_____________________________________________________________________
156 AliFMDBaseDA::AliFMDBaseDA(const AliFMDBaseDA & baseDA) :
158 fDiagnosticsFilename(baseDA.fDiagnosticsFilename.Data()),
161 fSaveHistograms(baseDA.fSaveHistograms),
162 fMakeSummaries(baseDA.fMakeSummaries),
163 fDetectorArray(baseDA.fDetectorArray),
164 fPulseSize(baseDA.fPulseSize),
165 fPulseLength(baseDA.fPulseLength),
166 fRequiredEvents(baseDA.fRequiredEvents),
167 fCurrentEvent(baseDA.fCurrentEvent),
168 fRunno(baseDA.fRunno),
172 fSeenDetectors[0] = baseDA.fSeenDetectors[0];
173 fSeenDetectors[1] = baseDA.fSeenDetectors[1];
174 fSeenDetectors[2] = baseDA.fSeenDetectors[2];
176 fDetectorArray.SetOwner();
181 //_____________________________________________________________________
182 AliFMDBaseDA::~AliFMDBaseDA()
187 //_____________________________________________________________________
188 void AliFMDBaseDA::Run(AliRawReader* reader)
193 diagFile = TFile::Open(fDiagnosticsFilename.Data(),"RECREATE");
200 fRunno = reader->GetRunNumber();
202 AliFMDRawReader* fmdReader = new AliFMDRawReader(reader,0);
203 TClonesArray* digitArray = new TClonesArray("AliFMDDigit",0);
205 Bool_t sodread = kFALSE;
207 for(Int_t i=0;i<3;i++) {
208 reader->NextEvent(); // Read Start-of-Run / Start-of-Files event
210 UInt_t eventType = reader->GetType();
211 if(eventType == AliRawEventHeaderBase::kStartOfData ||
212 eventType == AliRawEventHeaderBase::kFormatError) {
214 WriteConditionsData(fmdReader);
221 InitContainer(diagFile);
224 AliWarning("No SOD event detected!");
226 int lastProgress = 0;
230 for(Int_t n =1;n <= GetRequiredEvents(); n++) {
231 if(!reader->NextEvent()) continue;
234 fmdReader->ReadAdcs(digitArray);
236 for(Int_t i = 0; i<digitArray->GetEntriesFast();i++) {
237 AliFMDDigit* digit = static_cast<AliFMDDigit*>(digitArray->At(i));
238 fSeenDetectors[digit->Detector()-1] = kTRUE;
245 int progress = int((n *100)/ GetRequiredEvents()) ;
246 if (progress <= lastProgress) continue;
247 lastProgress = progress;
248 std::cout << "Progress: " << lastProgress << " / 100 " << std::endl;
252 AliInfo(Form("Looped over %d events",GetCurrentEvent()));
255 for(UShort_t det=1;det<=3;det++) {
256 if (!fSeenDetectors[det-1]) continue;
257 std::cout << "FMD" << det << std::endl;
258 UShort_t firstRing = (det == 1 ? 1 : 0);
259 for (UShort_t ir = firstRing; ir < 2; ir++) {
260 Char_t ring = (ir == 0 ? 'O' : 'I');
261 UShort_t nsec = (ir == 0 ? 40 : 20);
262 UShort_t nstr = (ir == 0 ? 256 : 512);
264 if (fMakeSummaries) MakeSummary(det, ring);
266 std::cout << " Ring " << ring << ": " << std::flush;
267 for(UShort_t sec =0; sec < nsec; sec++) {
268 for(UShort_t strip = 0; strip < nstr; strip++) {
269 Analyse(det,ring,sec,strip);
271 std::cout << '.' << std::flush;
275 std::cout << "done" << std::endl;
279 if(fOutputFile.is_open()) {
280 fOutputFile.write("# EOF\n",6);
286 if(fSaveHistograms ) {
288 AliInfo("Closing diagnostics file - please wait ...");
289 // diagFile->Write();
295 //_____________________________________________________________________
297 void AliFMDBaseDA::InitContainer(TDirectory* diagFile)
299 //Prepare container for diagnostics
301 TObjArray* ringArray;
302 TObjArray* sectorArray;
304 TDirectory* savDir = gDirectory;
306 for(UShort_t det=1;det<=3;det++) {
307 detArray = new TObjArray();
308 detArray->SetOwner();
309 fDetectorArray.AddAtAndExpand(detArray,det);
311 TDirectory* detDir = 0;
314 detDir = diagFile->mkdir(GetDetectorPath(det, kFALSE));
317 UShort_t FirstRing = (det == 1 ? 1 : 0);
318 for (UShort_t ir = FirstRing; ir < 2; ir++) {
319 Char_t ring = (ir == 0 ? 'O' : 'I');
320 UShort_t nsec = (ir == 0 ? 40 : 20);
321 UShort_t nstr = (ir == 0 ? 256 : 512);
322 ringArray = new TObjArray();
323 ringArray->SetOwner();
324 detArray->AddAtAndExpand(ringArray,ir);
327 TDirectory* ringDir = 0;
330 ringDir = detDir->mkdir(GetRingPath(det,ring, kFALSE));
334 for(UShort_t sec =0; sec < nsec; sec++) {
335 sectorArray = new TObjArray();
336 sectorArray->SetOwner();
337 ringArray->AddAtAndExpand(sectorArray,sec);
340 TDirectory* secDir = 0;
343 secDir = ringDir->mkdir(GetSectorPath(det, ring, sec, kFALSE));
346 for(UShort_t strip = 0; strip < nstr; strip++) {
349 secDir->mkdir(GetStripPath(det, ring, sec, strip, kFALSE));
351 AddChannelContainer(sectorArray, det, ring, sec, strip);
359 //_____________________________________________________________________
360 void AliFMDBaseDA::WriteConditionsData(AliFMDRawReader* fmdReader)
362 //Write the conditions data to file
363 AliFMDParameters* pars = AliFMDParameters::Instance();
364 fConditionsFile.write(Form("# %s \n",pars->GetConditionsShuttleID()),14);
366 fConditionsFile << "# This file created from run number " << fRunno
367 << " at " << now.AsString() << std::endl;
369 AliFMDCalibSampleRate* sampleRate = new AliFMDCalibSampleRate();
370 AliFMDCalibStripRange* stripRange = new AliFMDCalibStripRange();
372 fmdReader->ReadSODevent(sampleRate,stripRange,fPulseSize,fPulseLength,
375 sampleRate->WriteToFile(fConditionsFile, fSeenDetectors);
376 stripRange->WriteToFile(fConditionsFile, fSeenDetectors);
383 fConditionsFile.write("# Gain Events \n",15);
385 for(UShort_t det=1; det<=3;det++) {
386 if (!fSeenDetectors[det-1]) {
389 UShort_t firstring = (det == 1 ? 1 : 0);
390 for(UShort_t iring = firstring; iring <=1;iring++) {
391 Char_t ring = (iring == 1 ? 'I' : 'O');
392 for(UShort_t board =0 ; board <=1; board++) {
394 Int_t idx = GetHalfringIndex(det,ring,board);
396 fConditionsFile << det << ','
399 << fPulseLength.At(idx) << "\n";
405 fConditionsFile.write("# Gain Pulse \n",14);
407 for(UShort_t det=1; det<=3;det++) {
408 if (!fSeenDetectors[det-1]) {
411 UShort_t firstring = (det == 1 ? 1 : 0);
412 for(UShort_t iring = firstring; iring <=1;iring++) {
413 Char_t ring = (iring == 1 ? 'I' : 'O');
414 for(UShort_t board =0 ; board <=1; board++) {
416 Int_t idx = GetHalfringIndex(det,ring,board);
418 fConditionsFile << det << ','
421 << fPulseSize.At(idx) << "\n";
426 if(fConditionsFile.is_open()) {
428 fConditionsFile.write("# EOF\n",6);
429 fConditionsFile.close();
434 //_____________________________________________________________________
435 Int_t AliFMDBaseDA::GetHalfringIndex(UShort_t det, Char_t ring,
436 UShort_t board) const
438 // Get the index corresponding to a half-ring
441 // det Detector number
442 // ring Ring identifier
443 // board Board number
446 // Internal index of the board
447 UShort_t iring = (ring == 'I' ? 1 : 0);
449 Int_t index = (((det-1) << 2) | (iring << 1) | (board << 0));
454 //_____________________________________________________________________
455 void AliFMDBaseDA::Rotate(const char* base, int max) const
458 // Rotate a set of files. base is the basic name of the files.
459 // If the file base.max exists it is removed.
460 // If the file base.n exists (where n < max) it is renamed to
462 // If the file base exists, it is renamed to base.1
465 // base Base name of the files
466 // max Maximum number to keep (minus one for the current).
468 // Note: TSystem::AccessPathName returns false if the condition is
471 // Check if we have base.max, and if so, remove it.
472 TString testName(Form("%s.%d", base, max));
473 if (!gSystem->AccessPathName(testName.Data()))
474 gSystem->Unlink(testName.Data());
476 // Loop down from max-1 to 1 and move files
477 for (int i = max-1; i >= 1; i--) {
478 testName = Form("%s.%d", base, i);
479 if (!gSystem->AccessPathName(testName.Data())) {
480 TString newName(Form("%s.%d", base, i+1));
481 gSystem->Rename(testName.Data(), newName.Data());
485 // If we have the file base, rename it to base.1
486 testName = Form("%s", base);
487 if (!gSystem->AccessPathName(testName.Data())){
488 TString newName(Form("%s.%d", base, 1));
489 gSystem->Rename(testName.Data(), newName.Data());
493 //_____________________________________________________________________
495 AliFMDBaseDA::MakeSummaryHistogram(const char* prefix, const char* title,
496 UShort_t d, Char_t r)
498 Int_t nX = ((d == 1 || r == 'I' || r == 'i') ? 20 : 40);
499 Int_t nY = ((d == 1 || r == 'I' || r == 'i') ? 512 : 256);
501 TH2* ret = new TH2F(Form("%sFMD%d%c", prefix, d, r),
502 Form("%s for FMD%d%c", title, d, r),
503 nX, -0.5, nX-0.5, nY, -0.5, nY-0.5);
504 ret->SetXTitle("Sector #");
505 ret->SetYTitle("Strip #");
507 // if (!fSummaries) fSummaries = new TObjArray;
512 //_____________________________________________________________________