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