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 if (reader->NextEvent()) {
209 // Read Start-of-Run / Start-of-Files event
210 AliWarning(Form("Failed to read the %d%s event",
211 i+1, (i == 0 ? "st" : (i == 1 ? "nd" : "rd"))));
215 UInt_t eventType = reader->GetType();
216 if(eventType == AliRawEventHeaderBase::kStartOfData ||
217 eventType == AliRawEventHeaderBase::kFormatError) {
219 WriteConditionsData(fmdReader);
226 InitContainer(diagFile);
229 AliWarning("No SOD event detected!");
231 int lastProgress = 0;
235 for(Int_t n =1;n <= GetRequiredEvents(); n++) {
236 if(!reader->NextEvent()) continue;
239 fmdReader->ReadAdcs(digitArray);
241 for(Int_t i = 0; i<digitArray->GetEntriesFast();i++) {
242 AliFMDDigit* digit = static_cast<AliFMDDigit*>(digitArray->At(i));
243 fSeenDetectors[digit->Detector()-1] = kTRUE;
250 int progress = int((n *100)/ GetRequiredEvents()) ;
251 if (progress <= lastProgress) continue;
252 lastProgress = progress;
253 std::cout << "Progress: " << lastProgress << " / 100 " << std::endl;
257 AliInfo(Form("Looped over %d events",GetCurrentEvent()));
260 for(UShort_t det=1;det<=3;det++) {
261 if (!fSeenDetectors[det-1]) continue;
262 std::cout << "FMD" << det << std::endl;
263 UShort_t firstRing = (det == 1 ? 1 : 0);
264 for (UShort_t ir = firstRing; ir < 2; ir++) {
265 Char_t ring = (ir == 0 ? 'O' : 'I');
266 UShort_t nsec = (ir == 0 ? 40 : 20);
267 UShort_t nstr = (ir == 0 ? 256 : 512);
269 if (fMakeSummaries) MakeSummary(det, ring);
271 std::cout << " Ring " << ring << ": " << std::flush;
272 for(UShort_t sec =0; sec < nsec; sec++) {
273 for(UShort_t strip = 0; strip < nstr; strip++) {
274 Analyse(det,ring,sec,strip);
276 std::cout << '.' << std::flush;
280 std::cout << "done" << std::endl;
284 if(fOutputFile.is_open()) {
285 fOutputFile.write("# EOF\n",6);
291 if(fSaveHistograms ) {
293 AliInfo("Closing diagnostics file - please wait ...");
294 // diagFile->Write();
300 //_____________________________________________________________________
302 void AliFMDBaseDA::InitContainer(TDirectory* diagFile)
304 //Prepare container for diagnostics
306 TObjArray* ringArray;
307 TObjArray* sectorArray;
309 TDirectory* savDir = gDirectory;
311 for(UShort_t det=1;det<=3;det++) {
312 detArray = new TObjArray();
313 detArray->SetOwner();
314 fDetectorArray.AddAtAndExpand(detArray,det);
316 TDirectory* detDir = 0;
319 detDir = diagFile->mkdir(GetDetectorPath(det, kFALSE));
322 UShort_t FirstRing = (det == 1 ? 1 : 0);
323 for (UShort_t ir = FirstRing; ir < 2; ir++) {
324 Char_t ring = (ir == 0 ? 'O' : 'I');
325 UShort_t nsec = (ir == 0 ? 40 : 20);
326 UShort_t nstr = (ir == 0 ? 256 : 512);
327 ringArray = new TObjArray();
328 ringArray->SetOwner();
329 detArray->AddAtAndExpand(ringArray,ir);
332 TDirectory* ringDir = 0;
335 ringDir = detDir->mkdir(GetRingPath(det,ring, kFALSE));
339 for(UShort_t sec =0; sec < nsec; sec++) {
340 sectorArray = new TObjArray();
341 sectorArray->SetOwner();
342 ringArray->AddAtAndExpand(sectorArray,sec);
345 TDirectory* secDir = 0;
348 secDir = ringDir->mkdir(GetSectorPath(det, ring, sec, kFALSE));
351 for(UShort_t strip = 0; strip < nstr; strip++) {
354 secDir->mkdir(GetStripPath(det, ring, sec, strip, kFALSE));
356 AddChannelContainer(sectorArray, det, ring, sec, strip);
364 //_____________________________________________________________________
365 void AliFMDBaseDA::WriteConditionsData(AliFMDRawReader* fmdReader)
367 //Write the conditions data to file
368 AliFMDParameters* pars = AliFMDParameters::Instance();
369 fConditionsFile.write(Form("# %s \n",pars->GetConditionsShuttleID()),14);
371 fConditionsFile << "# This file created from run number " << fRunno
372 << " at " << now.AsString() << std::endl;
374 AliFMDCalibSampleRate* sampleRate = new AliFMDCalibSampleRate();
375 AliFMDCalibStripRange* stripRange = new AliFMDCalibStripRange();
377 fmdReader->ReadSODevent(sampleRate,stripRange,fPulseSize,fPulseLength,
380 sampleRate->WriteToFile(fConditionsFile, fSeenDetectors);
381 stripRange->WriteToFile(fConditionsFile, fSeenDetectors);
388 fConditionsFile.write("# Gain Events \n",15);
390 for(UShort_t det=1; det<=3;det++) {
391 if (!fSeenDetectors[det-1]) {
394 UShort_t firstring = (det == 1 ? 1 : 0);
395 for(UShort_t iring = firstring; iring <=1;iring++) {
396 Char_t ring = (iring == 1 ? 'I' : 'O');
397 for(UShort_t board =0 ; board <=1; board++) {
399 Int_t idx = GetHalfringIndex(det,ring,board);
401 fConditionsFile << det << ','
404 << fPulseLength.At(idx) << "\n";
410 fConditionsFile.write("# Gain Pulse \n",14);
412 for(UShort_t det=1; det<=3;det++) {
413 if (!fSeenDetectors[det-1]) {
416 UShort_t firstring = (det == 1 ? 1 : 0);
417 for(UShort_t iring = firstring; iring <=1;iring++) {
418 Char_t ring = (iring == 1 ? 'I' : 'O');
419 for(UShort_t board =0 ; board <=1; board++) {
421 Int_t idx = GetHalfringIndex(det,ring,board);
423 fConditionsFile << det << ','
426 << fPulseSize.At(idx) << "\n";
431 // sampleRate->WriteToFile(std::cout, fSeenDetectors);
432 // stripRange->WriteToFile(std::cout, fSeenDetectors);
434 if(fConditionsFile.is_open()) {
436 fConditionsFile.write("# EOF\n",6);
437 fConditionsFile.close();
442 //_____________________________________________________________________
443 Int_t AliFMDBaseDA::GetHalfringIndex(UShort_t det, Char_t ring,
444 UShort_t board) const
446 // Get the index corresponding to a half-ring
449 // det Detector number
450 // ring Ring identifier
451 // board Board number
454 // Internal index of the board
455 UShort_t iring = (ring == 'I' ? 1 : 0);
457 Int_t index = (((det-1) << 2) | (iring << 1) | (board << 0));
462 //_____________________________________________________________________
463 void AliFMDBaseDA::Rotate(const char* base, int max) const
466 // Rotate a set of files. base is the basic name of the files.
467 // If the file base.max exists it is removed.
468 // If the file base.n exists (where n < max) it is renamed to
470 // If the file base exists, it is renamed to base.1
473 // base Base name of the files
474 // max Maximum number to keep (minus one for the current).
476 // Note: TSystem::AccessPathName returns false if the condition is
479 // Check if we have base.max, and if so, remove it.
480 TString testName(Form("%s.%d", base, max));
481 if (!gSystem->AccessPathName(testName.Data()))
482 gSystem->Unlink(testName.Data());
484 // Loop down from max-1 to 1 and move files
485 for (int i = max-1; i >= 1; i--) {
486 testName = Form("%s.%d", base, i);
487 if (!gSystem->AccessPathName(testName.Data())) {
488 TString newName(Form("%s.%d", base, i+1));
489 gSystem->Rename(testName.Data(), newName.Data());
493 // If we have the file base, rename it to base.1
494 testName = Form("%s", base);
495 if (!gSystem->AccessPathName(testName.Data())){
496 TString newName(Form("%s.%d", base, 1));
497 gSystem->Rename(testName.Data(), newName.Data());
501 //_____________________________________________________________________
503 AliFMDBaseDA::MakeSummaryHistogram(const char* prefix, const char* title,
504 UShort_t d, Char_t r)
506 Int_t nX = ((d == 1 || r == 'I' || r == 'i') ? 20 : 40);
507 Int_t nY = ((d == 1 || r == 'I' || r == 'i') ? 512 : 256);
509 TH2* ret = new TH2F(Form("%sFMD%d%c", prefix, d, r),
510 Form("%s for FMD%d%c", title, d, r),
511 nX, -0.5, nX-0.5, nY, -0.5, nY-0.5);
512 ret->SetXTitle("Sector #");
513 ret->SetYTitle("Strip #");
515 // if (!fSummaries) fSummaries = new TObjArray;
520 //_____________________________________________________________________