MUON + CheckCompiler
[u/mrichter/AliRoot.git] / FMD / FMDutil / 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 <TStopwatch.h>
45 #include <TROOT.h>
46 #include <TPluginManager.h>
47 #include <iostream>
48 #include <fstream>
49
50 //_____________________________________________________________________
51 ClassImp(AliFMDBaseDA)
52 #if 0 
53 ; // Do not delete  - to let Emacs for mat the code
54 #endif
55
56 //_____________________________________________________________________
57 const char*
58 AliFMDBaseDA::GetStripPath(UShort_t det, 
59                            Char_t   ring, 
60                            UShort_t sec, 
61                            UShort_t str, 
62                            Bool_t   full) const
63 {
64   // Get the strip path 
65   // 
66   // Parameters 
67   //     det      Detector number
68   //     ring     Ring identifier 
69   //     sec      Sector number 
70   //     str      Strip number
71   //     full     If true, return full path 
72   // 
73   // Return 
74   //     The path
75   return Form("%s%sFMD%d%c[%02d,%03d]", 
76               (full ? GetSectorPath(det, ring, sec, full) : ""), 
77               (full ? "/" : ""), det, ring, sec, str);
78 }
79 //_____________________________________________________________________
80 const char*
81 AliFMDBaseDA::GetSectorPath(UShort_t det, 
82                             Char_t   ring, 
83                             UShort_t sec, 
84                             Bool_t   full) const
85 {
86   // Get the strip path 
87   // 
88   // Parameters 
89   //     det      Detector number
90   //     ring     Ring identifier 
91   //     sec      Sector number 
92   //     str      Strip number
93   //     full     If true, return full path 
94   // 
95   // Return 
96   //     The path
97   return Form("%s%sFMD%d%c[%02d]", 
98               (full ? GetRingPath(det, ring, full) : ""), 
99               (full ? "/" : ""), det, ring, sec);
100 }
101 //_____________________________________________________________________
102 const char*
103 AliFMDBaseDA::GetRingPath(UShort_t det, 
104                           Char_t   ring, 
105                           Bool_t   full) const
106 {
107   // Get the strip path 
108   // 
109   // Parameters 
110   //     det      Detector number
111   //     ring     Ring identifier 
112   //     sec      Sector number 
113   //     str      Strip number
114   //     full     If true, return full path 
115   // 
116   // Return 
117   //     The path
118   return Form("%s%sFMD%d%c", 
119               (full ? GetDetectorPath(det, full) : ""), 
120               (full ? "/" : ""), det, ring);
121 }
122 //_____________________________________________________________________
123 const char*
124 AliFMDBaseDA::GetDetectorPath(UShort_t det, 
125                               Bool_t   full) const
126 {
127   // Get the strip path 
128   // 
129   // Parameters 
130   //     det      Detector number
131   //     ring     Ring identifier 
132   //     sec      Sector number 
133   //     str      Strip number
134   //     full     If true, return full path 
135   // 
136   // Return 
137   //     The path
138   return Form("%s%sFMD%d", 
139               (full ? fDiagnosticsFilename.Data() : ""), 
140               (full ? ":/" : ""), det);
141 }
142
143 //_____________________________________________________________________
144 AliFMDBaseDA::AliFMDBaseDA() : 
145   TNamed(),
146   fDiagnosticsFilename("diagnosticsHistograms.root"),
147   fOutputFile(),
148   fConditionsFile(),
149   fSaveHistograms(kFALSE),
150   fMakeSummaries(kFALSE),
151   fDetectorArray(),
152   fPulseSize(10),
153   fPulseLength(10),
154   fRequiredEvents(0),
155   fCurrentEvent(0), 
156   fRunno(0),
157   fSummaries(0),
158   fAll(false)
159 {
160   //Constructor
161   for(Int_t i = 0; i< 3;i++) {
162     fSeenDetectors[i] = false;
163     fNEventsPerDetector[i] = 0;
164   }
165   fDetectorArray.SetOwner();
166   Rotate("conditions.csv", 3);
167   fConditionsFile.open("conditions.csv");
168 }
169 //_____________________________________________________________________
170 AliFMDBaseDA::AliFMDBaseDA(const AliFMDBaseDA & baseDA) : 
171   TNamed(baseDA),
172   fDiagnosticsFilename(baseDA.fDiagnosticsFilename.Data()),
173   fOutputFile(),
174   fConditionsFile(),
175   fSaveHistograms(baseDA.fSaveHistograms),
176   fMakeSummaries(baseDA.fMakeSummaries),
177   fDetectorArray(baseDA.fDetectorArray),
178   fPulseSize(baseDA.fPulseSize),
179   fPulseLength(baseDA.fPulseLength),
180   fRequiredEvents(baseDA.fRequiredEvents),
181   fCurrentEvent(baseDA.fCurrentEvent),
182   fRunno(baseDA.fRunno),
183   fSummaries(0),
184   fAll(baseDA.fAll)
185 {
186   //Copy constructor
187   for(Int_t i = 0; i< 3;i++) {
188     fSeenDetectors[i] = baseDA.fSeenDetectors[0];
189     fNEventsPerDetector[i] = baseDA.fNEventsPerDetector[i];
190   }
191
192   fDetectorArray.SetOwner();  
193 }
194
195
196 //_____________________________________________________________________
197 AliFMDBaseDA::~AliFMDBaseDA() 
198 {
199   //destructor
200 }
201
202 //_____________________________________________________________________
203 Bool_t AliFMDBaseDA::HaveEnough(Int_t nEvents) const
204 {
205   // if (!fAll) return nEvents > GetRequiredEvents();
206   if (nEvents <= 1) return false;
207
208   Bool_t ret = true; // Assume we have it 
209   for (Int_t i = 0; i < 3; i++) { 
210     if (!fSeenDetectors[i]) continue;
211     if (Int_t(fNEventsPerDetector[i]) <= GetRequiredEvents()) ret = false;
212   }
213   return ret;
214 }
215 //_____________________________________________________________________
216 UShort_t AliFMDBaseDA::GetProgress(Int_t nEvents) const
217 {
218   // if (!fAll) 
219   //  return UShort_t((nEvents *100)/ GetRequiredEvents());
220
221   if (nEvents <= 1) return 0;
222
223   Int_t got = 0;
224   Int_t total = 0;
225   for (Int_t i = 0; i < 3; i++) {
226     if (!fSeenDetectors[i]) continue;
227     got   += fNEventsPerDetector[i];
228     total += GetRequiredEvents();
229   }
230   return UShort_t(total > 0 ? (got * 100.) / total : 0);
231 }
232
233 //_____________________________________________________________________
234 void AliFMDBaseDA::Run(AliRawReader* reader) 
235 {
236   //Run the FMD DA
237   TFile* diagFile = 0;
238   // if (fSaveHistograms)
239   //  diagFile = TFile::Open(fDiagnosticsFilename.Data(),"RECREATE");
240   
241   reader->Reset();
242   fRunno = reader->GetRunNumber();
243
244   AliFMDRawReader* fmdReader  = new AliFMDRawReader(reader,0);
245   TClonesArray*    digitArray = new TClonesArray("AliFMDDigit",0);
246   
247   Bool_t sodread = kFALSE;
248   
249   for(Int_t i=0;i<3;i++) {
250     if (!reader->NextEvent()) { 
251       // Read Start-of-Run / Start-of-Files event
252       AliWarning(Form("Failed to read the %d%s event",
253                       i+1, (i == 0 ? "st" : (i == 1 ? "nd" : "rd"))));
254       break;
255     }
256     
257     UInt_t eventType = reader->GetType();
258     if(eventType == AliRawEventHeaderBase::kStartOfData || 
259        eventType == AliRawEventHeaderBase::kFormatError) { 
260       
261       WriteConditionsData(fmdReader);
262       Init();
263       sodread = kTRUE;
264       break;
265     }
266   }
267   
268   InitContainer(diagFile);
269   if (AliLog::GetDebugLevel("FMD","") >= 3) { 
270     fDetectorArray.ls();
271   }
272   
273   if(!sodread) 
274     AliWarning("No SOD event detected!");
275   
276   int lastProgress = 0;
277   
278   for(Int_t i = 0; i< 3;i++) fNEventsPerDetector[i] = 0;
279
280   for(Int_t n = 1; !HaveEnough(n); n++) {
281     AliInfoF("Get the next event %d", n);
282     if(!reader->NextEvent()) { n--; continue; }
283     UInt_t eventType = reader->GetType();
284     AliInfoF("Event type is %d", eventType);
285     if(eventType != AliRawEventHeaderBase::kPhysicsEvent) { n--; continue; }
286
287     SetCurrentEvent(n);
288     digitArray->Clear();
289     fmdReader->ReadAdcs(digitArray);
290     
291     Bool_t seen[] = { false, false, false };
292     for(Int_t i = 0; i<digitArray->GetEntriesFast();i++) {
293       AliFMDDigit* digit = static_cast<AliFMDDigit*>(digitArray->At(i));
294       UShort_t det = digit->Detector();
295       fSeenDetectors[det-1] = true;
296       seen[det-1]           = true;
297
298       // Only fill if we do not have enough for this detector 
299       if (Int_t(fNEventsPerDetector[det-1]) < GetRequiredEvents()) 
300         FillChannels(digit);
301     }
302     
303     for(Int_t i = 0; i< 3;i++) 
304       if (seen[i]) (fNEventsPerDetector[i])++;
305       
306     FinishEvent();
307     
308     Int_t nReq = GetRequiredEvents();
309     AliInfoF("%9d: %6d/%6d %6d/%6d %6d/%6d", n, 
310              fNEventsPerDetector[0], nReq,
311              fNEventsPerDetector[1], nReq,
312              fNEventsPerDetector[2], nReq);
313
314     int progress = GetProgress(n);
315     if (progress <= lastProgress) continue;
316     lastProgress = progress;
317     std::cout << "Progress: " << lastProgress << " / 100 " << std::endl;
318
319     if (AliLog::GetDebugLevel("FMD","") >= 0) { 
320     }
321     
322   }
323   
324   AliInfoF("Looped over %d events (%d,%d,%d)",GetCurrentEvent(),
325            fNEventsPerDetector[0], 
326            fNEventsPerDetector[1], 
327            fNEventsPerDetector[2]);
328   WriteHeaderToFile();
329   
330   for(UShort_t det=1;det<=3;det++) {
331     if (!fSeenDetectors[det-1]) continue;
332     std::cout << "FMD" << det << std::endl;
333     UShort_t firstRing = (det == 1 ? 1 : 0);
334     for (UShort_t ir = firstRing; ir < 2; ir++) {
335       Char_t   ring = (ir == 0 ? 'O' : 'I');
336       UShort_t nsec = (ir == 0 ? 40  : 20);
337       UShort_t nstr = (ir == 0 ? 256 : 512);
338
339       if (fMakeSummaries) MakeSummary(det, ring);
340
341       std::cout << " Ring " << ring << ": " << std::flush;
342       for(UShort_t sec =0; sec < nsec;  sec++)  {
343         for(UShort_t strip = 0; strip < nstr; strip++) {
344           Analyse(det,ring,sec,strip);
345         }
346         std::cout << '.' << std::flush;
347       }
348       // if(fSaveHistograms)
349       // diagFile->Flush();
350       std::cout << "done" << std::endl;
351     }
352   }
353   
354   if(fOutputFile.is_open()) {
355     fOutputFile.write("# EOF\n",6);
356     fOutputFile.close();
357   }
358   
359   Terminate(diagFile);
360     
361   if(fSaveHistograms ) {
362     diagFile = TFile::Open(fDiagnosticsFilename.Data(),"RECREATE");
363     fDetectorArray.Write("FMD", TObject::kSingleKey);
364     fSummaries.Write();
365     AliInfo("Closing diagnostics file - please wait ...");
366     // diagFile->Write();
367     diagFile->Close();
368     AliInfo("done");
369     
370   }
371 }
372 //_____________________________________________________________________
373
374 void AliFMDBaseDA::InitContainer(TDirectory* diagFile)
375 {
376   //Prepare container for diagnostics    
377   TDirectory* savDir   = gDirectory;
378
379   for(UShort_t det=1;det<=3;det++) {
380     TObjArray* detArray = new TObjArray(det == 1 ? 1 : 2);
381     detArray->SetOwner();
382     detArray->SetName(GetDetectorPath(det, false));
383     fDetectorArray.AddAtAndExpand(detArray,det);
384
385     TDirectory* detDir = 0;
386     if (diagFile) {
387       diagFile->cd();
388       detDir = diagFile->mkdir(GetDetectorPath(det, kFALSE));
389     }
390
391     UShort_t FirstRing = (det == 1 ? 1 : 0);
392     for (UShort_t ir = FirstRing; ir < 2; ir++) {
393       Char_t   ring = (ir == 0 ? 'O' : 'I');
394       UShort_t nsec = (ir == 0 ? 40  : 20);
395       UShort_t nstr = (ir == 0 ? 256 : 512);
396       TObjArray* ringArray = new TObjArray(nsec);
397       ringArray->SetOwner();
398       ringArray->SetName(GetRingPath(det, ring, false));
399       detArray->AddAtAndExpand(ringArray,ir);
400
401
402       TDirectory* ringDir = 0;
403       if (detDir) { 
404         detDir->cd();
405         ringDir = detDir->mkdir(GetRingPath(det,ring, kFALSE));
406       }
407       
408
409       for(UShort_t sec =0; sec < nsec;  sec++)  {
410         TObjArray* sectorArray = new TObjArray(nstr);
411         sectorArray->SetOwner();
412         sectorArray->SetName(GetSectorPath(det, ring, sec, false));
413         ringArray->AddAtAndExpand(sectorArray,sec);
414
415
416         TDirectory* secDir = 0;
417         if (ringDir) { 
418           ringDir->cd();
419           secDir = ringDir->mkdir(GetSectorPath(det, ring, sec, kFALSE));
420         }
421         
422         for(UShort_t strip = 0; strip < nstr; strip++) {
423           if (secDir) { 
424             secDir->cd();
425             secDir->mkdir(GetStripPath(det, ring, sec, strip, kFALSE));
426           }
427           TObjArray* stripArray = new TObjArray(0);
428           stripArray->SetOwner(true);
429           stripArray->SetName(GetStripPath(det, ring, sec, strip, false));
430           sectorArray->AddAtAndExpand(stripArray, strip);
431           AddChannelContainer(stripArray, det, ring, sec, strip);
432         }
433         AddSectorSummary(sectorArray, det, ring, sec, nstr);
434       }
435     }
436   }
437   savDir->cd();
438 }
439
440 //_____________________________________________________________________ 
441 void AliFMDBaseDA::WriteConditionsData(AliFMDRawReader* fmdReader) 
442 {
443   //Write the conditions data to file
444   AliFMDParameters* pars       = AliFMDParameters::Instance();
445   fConditionsFile.write(Form("# %s \n",pars->GetConditionsShuttleID()),14);
446   TDatime now;
447   fConditionsFile << "# This file created from run number " << fRunno 
448                   << " at " << now.AsString() << std::endl;
449   
450   AliFMDCalibSampleRate* sampleRate = new AliFMDCalibSampleRate();
451   AliFMDCalibStripRange* stripRange = new AliFMDCalibStripRange();
452   
453   fmdReader->ReadSODevent(sampleRate,stripRange,fPulseSize,fPulseLength,
454                           fSeenDetectors);
455
456   sampleRate->WriteToFile(fConditionsFile, fSeenDetectors);
457   stripRange->WriteToFile(fConditionsFile, fSeenDetectors);
458
459  
460   // Zero Suppresion
461   
462   // Strip Range
463   
464   fConditionsFile.write("# Gain Events \n",15);
465   
466   for(UShort_t det=1; det<=3;det++) {
467     if (!fSeenDetectors[det-1]) { 
468       continue;
469     }
470     UShort_t firstring = (det == 1 ? 1 : 0);
471     for(UShort_t iring = firstring; iring <=1;iring++) {
472       Char_t ring = (iring == 1 ? 'I' : 'O');
473       for(UShort_t board =0 ; board <=1; board++) {
474         
475         Int_t idx = GetHalfringIndex(det,ring,board);
476         
477         fConditionsFile << det                     << ','
478                         << ring                    << ','
479                         << board                   << ','
480                         << fPulseLength.At(idx)    << "\n";
481         
482       }
483     }
484   }
485   
486   fConditionsFile.write("# Gain Pulse \n",14);
487   
488   for(UShort_t det=1; det<=3;det++) {
489     if (!fSeenDetectors[det-1]) { 
490       continue;
491     }
492     UShort_t firstring = (det == 1 ? 1 : 0);
493     for(UShort_t iring = firstring; iring <=1;iring++) {
494       Char_t ring = (iring == 1 ? 'I' : 'O');
495       for(UShort_t board =0 ; board <=1; board++) {
496         
497         Int_t idx = GetHalfringIndex(det,ring,board);
498         
499         fConditionsFile << det                     << ','
500                         << ring                    << ','
501                         << board                   << ','
502                         << fPulseSize.At(idx)      << "\n";
503         
504       }
505     }
506   }
507   // sampleRate->WriteToFile(std::cout, fSeenDetectors);
508   // stripRange->WriteToFile(std::cout, fSeenDetectors);
509
510   if(fConditionsFile.is_open()) {
511     
512     fConditionsFile.write("# EOF\n",6);
513     fConditionsFile.close();
514     
515   }
516   
517 }
518 //_____________________________________________________________________ 
519 Int_t AliFMDBaseDA::GetHalfringIndex(UShort_t det, Char_t ring, 
520                                      UShort_t board) const 
521 {
522   // Get the index corresponding to a half-ring 
523   // 
524   // Parameters: 
525   //   det    Detector number 
526   //   ring   Ring identifier 
527   //   board  Board number 
528   //
529   // Return 
530   //   Internal index of the board 
531   UShort_t iring  =  (ring == 'I' ? 1 : 0);
532   
533   Int_t index = (((det-1) << 2) | (iring << 1) | (board << 0));
534   
535   return index-2;
536   
537 }
538 //_____________________________________________________________________ 
539 void AliFMDBaseDA::Rotate(const char* base, int max) const
540 {
541   // 
542   // Rotate a set of files.   base is the basic name of the files.
543   // If the file base.max exists it is removed. 
544   // If the file base.n exists (where n < max) it is renamed to
545   // base.(n-1).  
546   // If the file base exists, it is renamed to base.1 
547   //
548   // Parameters:
549   //   base Base name of the files
550   //   max  Maximum number to keep (minus one for the current).
551
552   // Note:  TSystem::AccessPathName returns false if the condition is
553   // fulfilled! 
554
555   // Check if we have base.max, and if so, remove it. 
556   TString testName(Form("%s.%d", base, max));
557   if (!gSystem->AccessPathName(testName.Data())) 
558     gSystem->Unlink(testName.Data());
559     
560   // Loop down from max-1 to 1 and move files 
561   for (int i = max-1; i >= 1; i--) { 
562     testName = Form("%s.%d", base, i);
563     if (!gSystem->AccessPathName(testName.Data())) {
564       TString newName(Form("%s.%d", base, i+1));
565       gSystem->Rename(testName.Data(), newName.Data());
566     }
567   }
568
569   // If we have the file base, rename it to base.1 
570   testName = Form("%s", base);
571   if (!gSystem->AccessPathName(testName.Data())){
572     TString newName(Form("%s.%d", base, 1));
573     gSystem->Rename(testName.Data(), newName.Data());
574   }
575 }
576
577 //_____________________________________________________________________ 
578 TH2*
579 AliFMDBaseDA::MakeSummaryHistogram(const char* prefix, const char* title, 
580                                    UShort_t d, Char_t r) 
581 {
582   // 
583   // Utility function for defining summary histograms 
584   // 
585   // Parameters:
586   //    det    Detector 
587   //    ring   Ring identifier 
588   //    prefix Histogram prefix 
589   //    title  Histogram title 
590   //
591   Int_t nX = ((d == 1 || r == 'I' || r == 'i') ?  20 :  40);
592   Int_t nY = ((d == 1 || r == 'I' || r == 'i') ? 512 : 256);
593   
594   TH2* ret = new TH2F(Form("%sFMD%d%c", prefix, d, r), 
595                       Form("%s for FMD%d%c", title, d, r), 
596                       nX, -0.5, nX-0.5, nY, -0.5, nY-0.5);
597   ret->SetXTitle("Sector #");
598   ret->SetYTitle("Strip #");
599   ret->SetDirectory(0);
600   // if (!fSummaries) fSummaries = new TObjArray;
601   fSummaries.Add(ret);
602   return ret;
603 }
604
605 //_____________________________________________________________________ 
606 TObjArray*
607 AliFMDBaseDA::GetDetectorArray(UShort_t det)
608 {
609   if (det < 1 || det > 3) { 
610     AliErrorF("Detector index %d out of bounds", det);
611     return 0;
612   }
613   return static_cast<TObjArray*>(fDetectorArray.At(det));
614 }
615 //_____________________________________________________________________ 
616 TObjArray*
617 AliFMDBaseDA::GetRingArray(UShort_t det, Char_t ring)
618 {
619   Int_t idx = (ring == 'O' || ring == 'o' ? 0 : 1);
620   TObjArray* array = GetDetectorArray(det);
621   if (!array) return 0;
622   array = static_cast<TObjArray*>(array->At(idx));
623   if (!array) AliErrorF("No ring array for FMD%d%c (%d)", det, ring, idx);
624   return array;
625 }
626 //_____________________________________________________________________ 
627 TObjArray*
628 AliFMDBaseDA::GetSectorArray(UShort_t det, Char_t ring, UShort_t sector)
629 {
630   TObjArray* array = GetRingArray(det,ring);
631   if (!array) return 0;
632   array = static_cast<TObjArray*>(array->At(sector));
633   if (!array) AliErrorF("No sector array for FMD%d%c[%02d]", det, ring, sector);
634   return array;
635 }
636 //_____________________________________________________________________ 
637 TObjArray*
638 AliFMDBaseDA::GetStripArray(UShort_t det, Char_t ring, 
639                             UShort_t sector, UShort_t strip)
640 {
641   TObjArray* array = GetSectorArray(det,ring,sector);
642   if (!array) return 0;
643   array = static_cast<TObjArray*>(array->At(strip));
644   if (!array) AliErrorF("No strip array for FMD%d%c[%02d,%03d]", 
645                         det, ring, sector, strip);
646   return array;
647 }
648
649 //=====================================================================
650 AliFMDBaseDA::Runner::Runner()
651   : fReader(0),
652     fDiagFile(""), 
653     fDiag(false),
654     fAll(false)
655 {}
656
657 //_____________________________________________________________________ 
658 void
659 AliFMDBaseDA::Runner::AddHandlers()
660 {
661   gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
662                                         "*",
663                                         "TStreamerInfo",
664                                         "RIO",
665                                         "TStreamerInfo()");
666   gROOT->GetPluginManager()->AddHandler("ROOT::Math::Minimizer", "Minuit", 
667                                         "TMinuitMinimizer",
668                                         "Minuit", 
669                                         "TMinuitMinimizer(const char *)");
670   gROOT->GetPluginManager()->AddHandler("ROOT::Math::Minimizer", 
671                                         "GSLMultiMin", 
672                                         "ROOT::Math::GSLMinimizer",
673                                         "MathMore", 
674                                         "GSLMinimizer(const char *)");
675   gROOT->GetPluginManager()->AddHandler("ROOT::Math::Minimizer", 
676                                         "GSLMultiFit", 
677                                         "ROOT::Math::GSLNLSMinimizer",
678                                         "MathMore", "GSLNLSMinimizer(int)");
679   gROOT->GetPluginManager()->AddHandler("ROOT::Math::Minimizer", 
680                                         "GSLSimAn", 
681                                         "ROOT::Math::GSLSimAnMinimizer",
682                                         "MathMore", 
683                                         "GSLSimAnMinimizer(int)");
684   gROOT->GetPluginManager()->AddHandler("ROOT::Math::Minimizer", 
685                                         "Linear", 
686                                         "TLinearMinimizer",
687                                         "Minuit", 
688                                         "TLinearMinimizer(const char *)");
689   gROOT->GetPluginManager()->AddHandler("ROOT::Math::Minimizer", 
690                                         "Fumili", 
691                                         "TFumiliMinimizer",
692                                         "Fumili", 
693                                         "TFumiliMinimizer(int)");
694 }
695 //_____________________________________________________________________ 
696 void
697 AliFMDBaseDA::Runner::ShowUsage(std::ostream& o, const char* progname)
698 {
699   o << "Usage: " << progname << " SOURCE [OPTIONS]\n\n"
700     << "Options:\n"
701     << "   -h,--help                Show this help\n"
702     << "   -d,--diagnostics[=FILE]  Write diagnostics to file\n"
703     << "   -D,--debug=LEVEL         Set the debug level\n"
704     << "   -A,--all                 Try to get data from all detectors\n\n"
705     << "SOURCE is one of\n"
706     << " * FILE.raw                Raw data file\n"
707     << " * FILE.root               ROOT'ified raw data file\n"
708     << " * collection://FILE.root  Event list in a ROOT file\n"
709     << " * collection://FILE       File containing list of ROOT files\n"
710     << " * ^FMD                    Monitor source\n"
711     << "There are other options too.  Check the AliRawReader docs\n"
712     << std::endl;
713 }
714  
715 //_____________________________________________________________________ 
716 namespace {
717   Bool_t ExtractValue(const TString& arg, TString& val)
718   {
719     val = "";
720     Int_t eq = arg.Index("=");
721     if (eq == kNPOS) return false;
722     
723     val = arg(eq+1, arg.Length()-eq-1);
724     return true;
725   }
726 }
727       
728 //_____________________________________________________________________ 
729 Int_t
730 AliFMDBaseDA::Runner::Init(int argc, char** argv)
731 {
732   AddHandlers();
733
734   // --- Process the command line ------------------------------------
735   TString source;
736   Int_t   debugLevel  = 0;
737   Bool_t  help        = false;
738
739   for (int i = 1; i < argc; i++) { 
740     TString arg(argv[i]);
741     Bool_t  badOption   = false;
742     
743     if (arg[0] == '-') { // It's an option 
744       if (arg[1] == '-') { // It's a long option 
745         TString val;
746         if      (arg.EqualTo("--help"))     help = true; 
747         else if (arg.BeginsWith("--debug")) {
748           if (ExtractValue(arg, val))
749             debugLevel = val.Atoi();
750         }
751         else if (arg.BeginsWith("--diagnostics")) { 
752           fDiag = true;
753           if (ExtractValue(arg, val)) 
754             fDiagFile = val;
755         }
756         else if (arg.EqualTo("--all"))  fAll = true;
757         else badOption = true;
758       }
759       else { // Short option 
760         TString next(i < argc-1 ? argv[i+1] : "");
761         switch (arg[1]) { 
762         case 'h': help = true; break;
763         case 'd': fDiag = true; 
764           if (!next.IsNull() && next[0] != '-') {
765             fDiagFile = next;
766             i++;
767           }
768           break;
769         case 'D': 
770           if (!next.IsNull() && next[0] != '-') {
771             debugLevel = next.Atoi();
772             i++;
773           }
774           break;
775         case 'A': fAll = true ; break ;
776         default: badOption = true;
777         }
778       } // End of options
779       if (badOption) { 
780         std::cerr << argv[0] << ": Unknown option " << argv[i] 
781                   << std::endl;
782         return -1;
783       }
784     }
785     else { // source or compatibility debug level 
786       if (source.IsNull()) source = arg;
787       else                 debugLevel = arg.Atoi();
788     }
789   }
790   
791   // --- Check if help was requested ---------------------------------
792   if (help) { 
793     ShowUsage(std::cout, argv[0]);
794     return 1;
795   }
796
797   // --- Check if we have a source -----------------------------------
798   if (source.IsNull()) { 
799     std::cerr << "No source given" << std::endl;
800     return -2;
801   }
802
803   // --- Initialize various things -----------------------------------
804   AliFMDParameters::Instance()->Init(kFALSE,0);
805
806   //This will only work for FDR 1 data. When newer data becomes
807   //available the ! must be removed!
808   Bool_t old = kTRUE;
809   AliFMDParameters::Instance()->UseCompleteHeader(old);
810   
811   AliLog::EnableDebug(debugLevel > 0);
812   AliLog::SetModuleDebugLevel("FMD", debugLevel);
813
814   // --- Make our reader ---------------------------------------------
815   fReader = AliRawReader::Create(source);
816   if (!fReader) { 
817     std::cerr << "Failed to make raw reader for source \"" << source 
818               << "\"" << std::endl;
819     return -3;
820   }
821   return 0;
822 }
823
824 //_____________________________________________________________________ 
825 Int_t
826 AliFMDBaseDA::Runner::RunNumber() const
827
828   if (!fReader) return -1;
829   return fReader->GetRunNumber(); 
830 }
831
832 //_____________________________________________________________________ 
833 void
834 AliFMDBaseDA::Runner::Exec(AliFMDBaseDA& da)
835 {
836   TStopwatch timer;
837   timer.Start();
838
839   da.SetSaveDiagnostics(fDiag || !fDiagFile.IsNull());
840   da.SetTryAll(fAll);
841   if (!fDiagFile.IsNull()) da.SetDiagnosticsFilename(fDiagFile);
842
843   da.Run(fReader);
844
845   timer.Stop();
846   timer.Print();
847
848 #ifdef ALI_AMORE
849   try { 
850     amore::da::AmoreDA myAmore(amore::da::AmoreDA::kSender);
851
852     for (UShort_t det = 1; det <= 3; det++) {
853       if (!da.HasSeenDetector(det)) continue;
854       TObject* runNo = new TObject;
855       runNo->SetUniqueID(fReader->GetRunNumber());
856       myAmore.Send(Form("gainRunNoFMD%d", det), runNo);
857     }
858     
859     TIter     next(&da.GetSummaries());
860     TObject*  obj = 0;
861     while ((obj = next())) 
862       myAmore.Send(obj->GetName(), obj);
863     
864   }
865   catch (exception& e) {
866     cerr << "Failed to make AMORE instance: " << e.what() << endl;
867   }
868                                
869 #endif
870 }
871
872
873   
874   
875   
876 //_____________________________________________________________________ 
877
878 //_____________________________________________________________________ 
879 //
880 // EOF
881 //