bug fix
[u/mrichter/AliRoot.git] / FMD / AliFMDBaseDA.cxx
1 /**************************************************************************
2  * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15
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.
20 */
21 //
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.
27 //
28
29 #include "AliFMDBaseDA.h"
30 #include "iostream"
31 #include "AliFMDRawReader.h"
32 #include "AliFMDCalibSampleRate.h"
33 #include "AliFMDCalibStripRange.h"
34 #include "AliLog.h"
35 #include "AliRawEventHeaderBase.h"
36 #include <TDatime.h>
37 #include <TSystem.h>
38 #include <TH2F.h>
39
40 //_____________________________________________________________________
41 ClassImp(AliFMDBaseDA)
42 #if 0 
43 ; // Do not delete  - to let Emacs for mat the code
44 #endif
45
46 //_____________________________________________________________________
47 const char*
48 AliFMDBaseDA::GetStripPath(UShort_t det, 
49                            Char_t   ring, 
50                            UShort_t sec, 
51                            UShort_t str, 
52                            Bool_t   full) const
53 {
54   // Get the strip path 
55   // 
56   // Parameters 
57   //     det      Detector number
58   //     ring     Ring identifier 
59   //     sec      Sector number 
60   //     str      Strip number
61   //     full     If true, return full path 
62   // 
63   // Return 
64   //     The path
65   return Form("%s%sFMD%d%c[%02d,%03d]", 
66               (full ? GetSectorPath(det, ring, sec, full) : ""), 
67               (full ? "/" : ""), det, ring, sec, str);
68 }
69 //_____________________________________________________________________
70 const char*
71 AliFMDBaseDA::GetSectorPath(UShort_t det, 
72                             Char_t   ring, 
73                             UShort_t sec, 
74                             Bool_t   full) const
75 {
76   // Get the strip path 
77   // 
78   // Parameters 
79   //     det      Detector number
80   //     ring     Ring identifier 
81   //     sec      Sector number 
82   //     str      Strip number
83   //     full     If true, return full path 
84   // 
85   // Return 
86   //     The path
87   return Form("%s%sFMD%d%c[%02d]", 
88               (full ? GetRingPath(det, ring, full) : ""), 
89               (full ? "/" : ""), det, ring, sec);
90 }
91 //_____________________________________________________________________
92 const char*
93 AliFMDBaseDA::GetRingPath(UShort_t det, 
94                           Char_t   ring, 
95                           Bool_t   full) const
96 {
97   // Get the strip path 
98   // 
99   // Parameters 
100   //     det      Detector number
101   //     ring     Ring identifier 
102   //     sec      Sector number 
103   //     str      Strip number
104   //     full     If true, return full path 
105   // 
106   // Return 
107   //     The path
108   return Form("%s%sFMD%d%c", 
109               (full ? GetDetectorPath(det, full) : ""), 
110               (full ? "/" : ""), det, ring);
111 }
112 //_____________________________________________________________________
113 const char*
114 AliFMDBaseDA::GetDetectorPath(UShort_t det, 
115                               Bool_t   full) const
116 {
117   // Get the strip path 
118   // 
119   // Parameters 
120   //     det      Detector number
121   //     ring     Ring identifier 
122   //     sec      Sector number 
123   //     str      Strip number
124   //     full     If true, return full path 
125   // 
126   // Return 
127   //     The path
128   return Form("%s%sFMD%d", 
129               (full ? fDiagnosticsFilename.Data() : ""), 
130               (full ? ":/" : ""), det);
131 }
132
133 //_____________________________________________________________________
134 AliFMDBaseDA::AliFMDBaseDA() : 
135   TNamed(),
136   fDiagnosticsFilename("diagnosticsHistograms.root"),
137   fOutputFile(),
138   fConditionsFile(),
139   fSaveHistograms(kFALSE),
140   fMakeSummaries(kFALSE),
141   fDetectorArray(),
142   fPulseSize(10),
143   fPulseLength(10),
144   fRequiredEvents(0),
145   fCurrentEvent(0), 
146   fRunno(0),
147   fSummaries(0)
148 {
149   //Constructor
150   fSeenDetectors[0] = fSeenDetectors[1] = fSeenDetectors[2] = kFALSE;
151   fDetectorArray.SetOwner();
152   Rotate("conditions.csv", 3);
153   fConditionsFile.open("conditions.csv");
154 }
155 //_____________________________________________________________________
156 AliFMDBaseDA::AliFMDBaseDA(const AliFMDBaseDA & baseDA) : 
157   TNamed(baseDA),
158   fDiagnosticsFilename(baseDA.fDiagnosticsFilename.Data()),
159   fOutputFile(),
160   fConditionsFile(),
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),
169   fSummaries(0)
170 {
171   //Copy constructor
172   fSeenDetectors[0] = baseDA.fSeenDetectors[0];
173   fSeenDetectors[1] = baseDA.fSeenDetectors[1];
174   fSeenDetectors[2] = baseDA.fSeenDetectors[2];
175
176   fDetectorArray.SetOwner();
177   
178 }
179
180
181 //_____________________________________________________________________
182 AliFMDBaseDA::~AliFMDBaseDA() 
183 {
184   //destructor
185 }
186
187 //_____________________________________________________________________
188 void AliFMDBaseDA::Run(AliRawReader* reader) 
189 {
190   //Run the FMD DA
191   TFile* diagFile = 0;
192   if (fSaveHistograms)
193     diagFile = TFile::Open(fDiagnosticsFilename.Data(),"RECREATE");
194
195   
196   
197   
198   
199   reader->Reset();
200   fRunno = reader->GetRunNumber();
201
202   AliFMDRawReader* fmdReader  = new AliFMDRawReader(reader,0);
203   TClonesArray*    digitArray = new TClonesArray("AliFMDDigit",0);
204   
205   Bool_t sodread = kFALSE;
206   
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"))));
212       break;
213     }
214     
215     UInt_t eventType = reader->GetType();
216     if(eventType == AliRawEventHeaderBase::kStartOfData || 
217        eventType == AliRawEventHeaderBase::kFormatError) { 
218       
219       WriteConditionsData(fmdReader);
220       Init();
221       sodread = kTRUE;
222       break;
223     }
224   }
225   
226   InitContainer(diagFile);
227   
228   if(!sodread) 
229     AliWarning("No SOD event detected!");
230   
231   int lastProgress = 0;
232   
233   
234   
235   for(Int_t n =1;n <= GetRequiredEvents(); n++) {
236     if(!reader->NextEvent()) continue;
237     SetCurrentEvent(n);
238     digitArray->Clear();
239     fmdReader->ReadAdcs(digitArray);
240     
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;
244       FillChannels(digit);
245     }
246     
247    
248     FinishEvent();
249     
250     int progress = int((n *100)/ GetRequiredEvents()) ;
251     if (progress <= lastProgress) continue;
252     lastProgress = progress;
253     std::cout << "Progress: " << lastProgress << " / 100 " << std::endl;
254     
255   }
256   
257   AliInfo(Form("Looped over %d events",GetCurrentEvent()));
258   WriteHeaderToFile();
259   
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);
268
269       if (fMakeSummaries) MakeSummary(det, ring);
270
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);
275         }
276         std::cout << '.' << std::flush;
277       }
278       if(fSaveHistograms)
279         diagFile->Flush();
280       std::cout << "done" << std::endl;
281     }
282   }
283   
284   if(fOutputFile.is_open()) {
285     fOutputFile.write("# EOF\n",6);
286     fOutputFile.close();
287   }
288   
289   Terminate(diagFile);
290     
291   if(fSaveHistograms ) {
292     
293     AliInfo("Closing diagnostics file - please wait ...");
294     // diagFile->Write();
295     diagFile->Close();
296     AliInfo("done");
297     
298   }
299 }
300 //_____________________________________________________________________
301
302 void AliFMDBaseDA::InitContainer(TDirectory* diagFile)
303 {
304   //Prepare container for diagnostics
305   TObjArray* detArray;
306   TObjArray* ringArray;
307   TObjArray* sectorArray;
308     
309   TDirectory* savDir   = gDirectory;
310
311   for(UShort_t det=1;det<=3;det++) {
312     detArray = new TObjArray();
313     detArray->SetOwner();
314     fDetectorArray.AddAtAndExpand(detArray,det);
315
316     TDirectory* detDir = 0;
317     if (diagFile) {
318       diagFile->cd();
319       detDir = diagFile->mkdir(GetDetectorPath(det, kFALSE));
320     }
321
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);
330
331
332       TDirectory* ringDir = 0;
333       if (detDir) { 
334         detDir->cd();
335         ringDir = detDir->mkdir(GetRingPath(det,ring, kFALSE));
336       }
337       
338
339       for(UShort_t sec =0; sec < nsec;  sec++)  {
340         sectorArray = new TObjArray();
341         sectorArray->SetOwner();
342         ringArray->AddAtAndExpand(sectorArray,sec);
343
344
345         TDirectory* secDir = 0;
346         if (ringDir) { 
347           ringDir->cd();
348           secDir = ringDir->mkdir(GetSectorPath(det, ring, sec, kFALSE));
349         }
350         
351         for(UShort_t strip = 0; strip < nstr; strip++) {
352           if (secDir) { 
353             secDir->cd();
354             secDir->mkdir(GetStripPath(det, ring, sec, strip, kFALSE));
355           }
356           AddChannelContainer(sectorArray, det, ring, sec, strip);
357         }
358       }
359     }
360   }
361   savDir->cd();
362 }
363
364 //_____________________________________________________________________ 
365 void AliFMDBaseDA::WriteConditionsData(AliFMDRawReader* fmdReader) 
366 {
367   //Write the conditions data to file
368   AliFMDParameters* pars       = AliFMDParameters::Instance();
369   fConditionsFile.write(Form("# %s \n",pars->GetConditionsShuttleID()),14);
370   TDatime now;
371   fConditionsFile << "# This file created from run number " << fRunno 
372                   << " at " << now.AsString() << std::endl;
373   
374   AliFMDCalibSampleRate* sampleRate = new AliFMDCalibSampleRate();
375   AliFMDCalibStripRange* stripRange = new AliFMDCalibStripRange();
376   
377   fmdReader->ReadSODevent(sampleRate,stripRange,fPulseSize,fPulseLength,
378                           fSeenDetectors);
379
380   sampleRate->WriteToFile(fConditionsFile, fSeenDetectors);
381   stripRange->WriteToFile(fConditionsFile, fSeenDetectors);
382
383  
384   // Zero Suppresion
385   
386   // Strip Range
387   
388   fConditionsFile.write("# Gain Events \n",15);
389   
390   for(UShort_t det=1; det<=3;det++) {
391     if (!fSeenDetectors[det-1]) { 
392       continue;
393     }
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++) {
398         
399         Int_t idx = GetHalfringIndex(det,ring,board);
400         
401         fConditionsFile << det                     << ','
402                         << ring                    << ','
403                         << board                   << ','
404                         << fPulseLength.At(idx)    << "\n";
405         
406       }
407     }
408   }
409   
410   fConditionsFile.write("# Gain Pulse \n",14);
411   
412   for(UShort_t det=1; det<=3;det++) {
413     if (!fSeenDetectors[det-1]) { 
414       continue;
415     }
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++) {
420         
421         Int_t idx = GetHalfringIndex(det,ring,board);
422         
423         fConditionsFile << det                     << ','
424                         << ring                    << ','
425                         << board                   << ','
426                         << fPulseSize.At(idx)      << "\n";
427         
428       }
429     }
430   }
431   // sampleRate->WriteToFile(std::cout, fSeenDetectors);
432   // stripRange->WriteToFile(std::cout, fSeenDetectors);
433
434   if(fConditionsFile.is_open()) {
435     
436     fConditionsFile.write("# EOF\n",6);
437     fConditionsFile.close();
438     
439   }
440   
441 }
442 //_____________________________________________________________________ 
443 Int_t AliFMDBaseDA::GetHalfringIndex(UShort_t det, Char_t ring, 
444                                      UShort_t board) const 
445 {
446   // Get the index corresponding to a half-ring 
447   // 
448   // Parameters: 
449   //   det    Detector number 
450   //   ring   Ring identifier 
451   //   board  Board number 
452   //
453   // Return 
454   //   Internal index of the board 
455   UShort_t iring  =  (ring == 'I' ? 1 : 0);
456   
457   Int_t index = (((det-1) << 2) | (iring << 1) | (board << 0));
458   
459   return index-2;
460   
461 }
462 //_____________________________________________________________________ 
463 void AliFMDBaseDA::Rotate(const char* base, int max) const
464 {
465   // 
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
469   // base.(n-1).  
470   // If the file base exists, it is renamed to base.1 
471   //
472   // Parameters:
473   //   base Base name of the files
474   //   max  Maximum number to keep (minus one for the current).
475
476   // Note:  TSystem::AccessPathName returns false if the condition is
477   // fulfilled! 
478
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());
483     
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());
490     }
491   }
492
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());
498   }
499 }
500
501 //_____________________________________________________________________ 
502 TH2*
503 AliFMDBaseDA::MakeSummaryHistogram(const char* prefix, const char* title, 
504                                    UShort_t d, Char_t r) 
505 {
506   Int_t nX = ((d == 1 || r == 'I' || r == 'i') ?  20 :  40);
507   Int_t nY = ((d == 1 || r == 'I' || r == 'i') ? 512 : 256);
508   
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 #");
514
515   // if (!fSummaries) fSummaries = new TObjArray;
516   fSummaries.Add(ret);
517   return ret;
518 }
519
520 //_____________________________________________________________________ 
521 //
522 // EOF
523 //