Do not fail if the corresponding pedestal run was obviously bad, i.e. if the number...
[u/mrichter/AliRoot.git] / MUON / AliMUONPedestalSubprocessor.cxx
1 /**************************************************************************
2 * Copyright(c) 1998-1999, 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 // $Id$
17
18 #include "AliMUONPedestalSubprocessor.h"
19
20 #include "AliCDBMetaData.h"
21 #include "AliCDBEntry.h"
22 #include "AliDAQ.h"
23 #include "AliLog.h"
24 #include "AliMUON2DMap.h"
25 #include "AliMUON2DStoreValidator.h"
26 #include "AliMUONCalibParamNF.h"
27 #include "AliMUONPreprocessor.h"
28 #include "AliMUONTrackerIO.h"
29 #include "AliMpConstants.h"
30 #include "AliMpDDLStore.h"
31 #include "TObjString.h"
32 #include <Riostream.h>
33 #include <TList.h>
34 #include <TObjString.h>
35 #include <TSystem.h>
36 #include <sstream>
37
38 //-----------------------------------------------------------------------------
39 /// \class AliMUONPedestalSubprocessor
40 ///
41 /// Implementation of AliMUONVSubprocessor class to deal with MUON TRK pedestals.
42 ///
43 /// Pedestals are read in from an ascii file, with the format :               \n
44 ///---------------------------------------------------------------------------\n
45 /// BUS_PATCH MANU_ADDR CHANNEL      MEAN       SIGMA                         \n
46 ///---------------------------------------------------------------------------\n
47 ///
48 /// \author L. Aphecetche
49 //-----------------------------------------------------------------------------
50
51 /// \cond CLASSIMP
52 ClassImp(AliMUONPedestalSubprocessor)
53 /// \endcond
54
55 //_____________________________________________________________________________
56 AliMUONPedestalSubprocessor::AliMUONPedestalSubprocessor(AliMUONPreprocessor* master)
57 : AliMUONVSubprocessor(master,
58                        "Pedestals",
59                        "Upload MUON Tracker pedestals to OCDB"),
60 fPedestals(0x0),
61 fConfig(0x0),
62 fConfigChanged(kFALSE)
63 {
64   /// default ctor
65 }
66
67 //_____________________________________________________________________________
68 AliMUONPedestalSubprocessor::~AliMUONPedestalSubprocessor()
69 {
70   /// dtor
71   delete fPedestals;
72   delete fConfig;
73 }
74
75 //_____________________________________________________________________________
76 Bool_t
77 AliMUONPedestalSubprocessor::HasConfigChanged(const AliMUONVStore& newConfig) const
78 {
79   /// Check whether the config changed. 
80   /// Any error will return kTRUE to trig a config upload (safer way).
81   
82   AliCDBEntry* entry = Master()->GetFromOCDB("Calib","Config");
83   if (!entry)
84   {
85     AliError("Could not get MUON/Calib/Config entry for current run ! That's not OK !");
86     return kTRUE;
87   }
88   AliMUONVStore* oldConfig = dynamic_cast<AliMUONVStore*>(entry->GetObject());
89   if (!oldConfig)
90   {
91     AliError("Could not get MUON/Calib/Config object for current run (wrong type ?) ! That's not OK !");
92     return kTRUE;
93   }
94   
95   if ( oldConfig->GetSize() != newConfig.GetSize() ) 
96   {
97     return kTRUE;
98   }
99   
100   TIter next(oldConfig->CreateIterator());
101   AliMUONVCalibParam* old;
102   
103   while ( ( old = static_cast<AliMUONVCalibParam*>(next()) ) )
104   {
105     Int_t detElemId = old->ID0();
106     Int_t manuId = old->ID1();
107     
108     if ( ! newConfig.FindObject(detElemId,manuId) )
109     {
110       // not found in new. Configurations are different. Return right now.
111       return kTRUE;
112     }
113   }
114   
115   // all tests OK. Configuration has not changed.
116   return kFALSE;
117 }
118
119
120 //_____________________________________________________________________________
121 Bool_t 
122 AliMUONPedestalSubprocessor::Initialize(Int_t run, UInt_t startTime, UInt_t endTime)
123 {
124   /// When starting a new run, reads in the pedestals ASCII files.
125   
126   const Int_t kSystem = AliMUONPreprocessor::kDAQ;
127   const char* kId = "PEDESTALS";
128   
129   delete fPedestals;
130   fPedestals = new AliMUON2DMap(kTRUE);
131   
132   delete fConfig;
133   fConfig = new AliMUON2DMap(kTRUE);
134   
135   Master()->Log(Form("Reading pedestal files for Run %d startTime %ld endTime %ld",
136                      run,startTime,endTime));
137   
138   TList* sources = Master()->GetFileSources(kSystem,kId);
139   TIter next(sources);
140   TObjString* o(0x0);
141   Int_t n(0);
142   Int_t npedFiles(0);
143   
144   while ( ( o = static_cast<TObjString*>(next()) ) )
145   {
146     TString fileName(Master()->GetFile(kSystem,kId,o->GetName()));
147     Int_t ok = ReadPedestalFile(fileName.Data());
148     if (ok>0)
149     {
150       n += ok;
151       ++npedFiles;
152     }
153   }
154
155   delete sources;
156   
157   if (!n)
158   {
159     Master()->Log("Failed to read any pedestals");
160
161     delete fPedestals;
162     fPedestals = 0;
163     delete fConfig;
164     fConfig = 0;
165
166     // OK, we did not get our pedestals. Check if the ped run itself
167     // was bad, i.e. too few events
168     TString nevents(Master()->GetRunParameter("totalEvents"));
169     
170     if ( nevents.Atoi() < 50 ) 
171     {
172       Master()->Log(Form("The run had only %d events, so the failure to read pedestals is normal",nevents.Atoi()));
173       // too few events, failure is normal, returns OK.
174       return kTRUE;
175     }
176     
177     // no ped, but run looks clean, that's an error
178     return kFALSE;
179   }
180   
181   const char* kIdConf = "CONFIG";
182
183   sources = Master()->GetFileSources(kSystem,kIdConf);
184   TIter nextConf(sources);
185   Int_t nconf(0);
186   Int_t nconfFiles(0);
187   
188   while ( ( o = static_cast<TObjString*>(nextConf()) ) )
189   {
190     TString fileName(Master()->GetFile(kSystem,kIdConf,o->GetName()));
191     Int_t ok = ReadConfigFile(fileName.Data());
192     if (ok>0)
193     {
194       nconf += ok;
195       ++nconfFiles;
196     }
197   }
198   
199   delete sources;
200   
201   if ( npedFiles != nconfFiles )
202   {
203     Master()->Log(Form("ERROR : Number of config files (%d) different from number of pedestal files (%d)",nconfFiles,npedFiles));
204     delete fPedestals;
205     fPedestals = 0;
206     delete fConfig;
207     fConfig = 0;
208     return kFALSE;
209   }
210   
211   fConfigChanged = HasConfigChanged(*fConfig);
212   
213   return kTRUE;
214 }
215
216 //_____________________________________________________________________________
217 UInt_t 
218 AliMUONPedestalSubprocessor::Process(TMap* /*dcsAliasMap*/)
219 {
220   /// Store the pedestals into the CDB
221   
222   if (!fPedestals || !fConfig) 
223   {
224     // this is the only reason to fail for the moment : getting no pedestal or no config
225     // at all.
226     return 1;
227   }
228     
229   AliMUON2DStoreValidator validator;
230
231   Master()->Log("Validating");
232
233   TObjArray* chambers = validator.Validate(*fPedestals,fConfig);
234   
235   if (chambers)
236   {
237     // we hereby report what's missing, but this is not a reason to fail ;-)
238     // the only reason to fail would be if we got no pedestal at all
239     TList lines;
240     lines.SetOwner(kTRUE);
241   
242     validator.Report(lines,*chambers);
243   
244     TIter next(&lines);
245     TObjString* line;
246   
247     while ( ( line = static_cast<TObjString*>(next()) ) )
248     {
249       Master()->Log(line->String().Data());
250     }
251   }
252   
253   Master()->Log("Storing pedestals...");
254   if ( fConfigChanged ) 
255   {
256     Master()->Log("...and configuration, as it has changed");
257   }
258   
259   AliCDBMetaData metaData;
260         metaData.SetBeamPeriod(0);
261         metaData.SetResponsible("MUON TRK");
262   TString comment("Computed by AliMUONPedestalSubprocessor $Id$");
263   comment.ReplaceAll("$","");
264         metaData.SetComment(comment.Data());
265   
266   Bool_t validToInfinity = kTRUE;
267         Bool_t result = Master()->Store("Calib", "Pedestals", fPedestals, &metaData, 0, validToInfinity);
268   if ( fConfigChanged ) 
269   {
270     result = result && Master()->Store("Calib", "Config", fConfig, &metaData, 0, validToInfinity);
271   }
272   return ( result != kTRUE ); // return 0 if everything is ok.  
273 }
274
275 //_____________________________________________________________________________
276 Int_t
277 AliMUONPedestalSubprocessor::ReadPedestalFile(const char* filename)
278 {
279   /// Read the pedestals from an ASCII file.                                  \n
280   /// Format of that file is one line per channel :                           \n
281   ///-------------------------------------------------------------------------\n
282   /// BUS_PATCH MANU_ADDR CHANNEL      MEAN       SIGMA                       \n
283   ///-------------------------------------------------------------------------\n
284   ///                                                                         \n
285   /// Return kFALSE if reading was not successfull.                           \n
286   ///
287   
288   TString sFilename(gSystem->ExpandPathName(filename));
289   
290   Master()->Log(Form("Reading %s",sFilename.Data()));
291   
292   Int_t n = AliMUONTrackerIO::ReadPedestals(sFilename.Data(),*fPedestals);
293   
294   switch (n)
295   {
296     case -1:
297       Master()->Log(Form("Could not open %s",sFilename.Data()));
298       break;
299   }
300   
301   return n;
302 }
303
304 //_____________________________________________________________________________
305 Int_t
306 AliMUONPedestalSubprocessor::ReadConfigFile(const char* filename)
307 {
308   /// Read the configuration from an ASCII file.                              
309   /// Format of that file is one line per manu :                              
310   /// BUS_PATCH MANU_ADDR
311   /// Return kFALSE if reading was not successfull.                           
312   ///
313   
314   TString sFilename(gSystem->ExpandPathName(filename));
315   
316   Master()->Log(Form("Reading %s",sFilename.Data()));
317   
318   Int_t n = AliMUONTrackerIO::ReadConfig(sFilename.Data(),*fConfig);
319   
320   switch (n)
321   {
322     case -1:
323       Master()->Log(Form("Could not open %s",sFilename.Data()));
324       break;
325   }
326   
327   return n;
328 }
329
330
331 //_____________________________________________________________________________
332 void
333 AliMUONPedestalSubprocessor::Print(Option_t* opt) const
334 {
335   /// ouput to screen
336   if (fPedestals) fPedestals->Print("",opt);
337   if (fConfig) fConfig->Print("",opt);
338 }
339