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