Line data Source code
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 12 : ClassImp(AliMUONPedestalSubprocessor)
53 : /// \endcond
54 :
55 : //_____________________________________________________________________________
56 : AliMUONPedestalSubprocessor::AliMUONPedestalSubprocessor(AliMUONPreprocessor* master)
57 0 : : AliMUONVSubprocessor(master,
58 : "Pedestals",
59 : "Upload MUON Tracker pedestals to OCDB"),
60 0 : fPedestals(0x0),
61 0 : fConfig(0x0),
62 0 : fConfigChanged(kFALSE),
63 0 : fTooFewEvents(kFALSE)
64 0 : {
65 : /// default ctor
66 0 : }
67 :
68 : //_____________________________________________________________________________
69 : AliMUONPedestalSubprocessor::~AliMUONPedestalSubprocessor()
70 0 : {
71 : /// dtor
72 0 : delete fPedestals;
73 0 : delete fConfig;
74 0 : }
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 0 : AliCDBEntry* entry = Master()->GetFromOCDB("Calib","Config");
84 0 : if (!entry)
85 : {
86 0 : AliError("Could not get MUON/Calib/Config entry for current run ! That's not OK !");
87 0 : return kTRUE;
88 : }
89 0 : AliMUONVStore* oldConfig = dynamic_cast<AliMUONVStore*>(entry->GetObject());
90 0 : if (!oldConfig)
91 : {
92 0 : AliError("Could not get MUON/Calib/Config object for current run (wrong type ?) ! That's not OK !");
93 0 : return kTRUE;
94 : }
95 :
96 0 : if ( oldConfig->GetSize() != newConfig.GetSize() )
97 : {
98 0 : return kTRUE;
99 : }
100 :
101 0 : TIter next(oldConfig->CreateIterator());
102 : AliMUONVCalibParam* old;
103 :
104 0 : while ( ( old = static_cast<AliMUONVCalibParam*>(next()) ) )
105 : {
106 0 : Int_t detElemId = old->ID0();
107 0 : Int_t manuId = old->ID1();
108 :
109 0 : if ( ! newConfig.FindObject(detElemId,manuId) )
110 : {
111 : // not found in new. Configurations are different. Return right now.
112 0 : return kTRUE;
113 : }
114 0 : }
115 :
116 : // all tests OK. Configuration has not changed.
117 0 : return kFALSE;
118 0 : }
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 0 : delete fPedestals;
131 0 : fPedestals = new AliMUON2DMap(kTRUE);
132 :
133 0 : delete fConfig;
134 0 : fConfig = new AliMUON2DMap(kTRUE);
135 :
136 0 : fTooFewEvents = kFALSE;
137 :
138 0 : Master()->Log(Form("Reading pedestal files for Run %d startTime %u endTime %u",
139 : run,startTime,endTime));
140 :
141 0 : TList* sources = Master()->GetFileSources(kSystem,kId);
142 0 : TIter next(sources);
143 : TObjString* o(0x0);
144 : Int_t n(0);
145 : Int_t npedFiles(0);
146 :
147 0 : while ( ( o = static_cast<TObjString*>(next()) ) )
148 : {
149 0 : TString fileName(Master()->GetFile(kSystem,kId,o->GetName()));
150 0 : Int_t ok = ReadPedestalFile(fileName.Data());
151 0 : if (ok>0)
152 : {
153 0 : n += ok;
154 0 : ++npedFiles;
155 0 : }
156 0 : }
157 :
158 0 : delete sources;
159 :
160 0 : if (!n)
161 : {
162 0 : Master()->Log("Failed to read any pedestals");
163 :
164 0 : delete fPedestals;
165 0 : fPedestals = 0;
166 0 : delete fConfig;
167 0 : 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 0 : TString nevents(Master()->GetRunParameter("totalEvents"));
172 :
173 0 : if ( nevents.Atoi() < 50 )
174 : {
175 0 : 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 0 : fTooFewEvents = kTRUE;
178 0 : return kTRUE;
179 : }
180 :
181 : // no ped, but run looks clean, that's an error
182 0 : return kFALSE;
183 0 : }
184 :
185 : const char* kIdConf = "CONFIG";
186 :
187 0 : sources = Master()->GetFileSources(kSystem,kIdConf);
188 0 : TIter nextConf(sources);
189 : Int_t nconf(0);
190 : Int_t nconfFiles(0);
191 :
192 0 : while ( ( o = static_cast<TObjString*>(nextConf()) ) )
193 : {
194 0 : TString fileName(Master()->GetFile(kSystem,kIdConf,o->GetName()));
195 0 : Int_t ok = ReadConfigFile(fileName.Data());
196 0 : if (ok>0)
197 : {
198 0 : nconf += ok;
199 0 : ++nconfFiles;
200 0 : }
201 0 : }
202 :
203 0 : delete sources;
204 :
205 0 : if ( npedFiles != nconfFiles )
206 : {
207 0 : Master()->Log(Form("ERROR : Number of config files (%d) different from number of pedestal files (%d)",nconfFiles,npedFiles));
208 0 : delete fPedestals;
209 0 : fPedestals = 0;
210 0 : delete fConfig;
211 0 : fConfig = 0;
212 0 : return kFALSE;
213 : }
214 :
215 0 : fConfigChanged = HasConfigChanged(*fConfig);
216 :
217 0 : return kTRUE;
218 0 : }
219 :
220 : //_____________________________________________________________________________
221 : UInt_t
222 : AliMUONPedestalSubprocessor::Process(TMap* /*dcsAliasMap*/)
223 : {
224 : /// Store the pedestals into the CDB
225 :
226 0 : if (!fPedestals || !fConfig)
227 : {
228 0 : 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 0 : 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 0 : return 1;
239 : }
240 : }
241 :
242 0 : AliMUON2DStoreValidator validator;
243 :
244 0 : Master()->Log("Validating");
245 :
246 0 : TObjArray* chambers = validator.Validate(*fPedestals,fConfig);
247 :
248 0 : 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 0 : TList lines;
253 0 : lines.SetOwner(kTRUE);
254 :
255 0 : validator.Report(lines,*chambers);
256 :
257 0 : TIter next(&lines);
258 : TObjString* line;
259 :
260 0 : while ( ( line = static_cast<TObjString*>(next()) ) )
261 : {
262 0 : Master()->Log(line->String().Data());
263 : }
264 0 : }
265 :
266 0 : Master()->Log("Storing pedestals...");
267 0 : if ( fConfigChanged )
268 : {
269 0 : Master()->Log("...and configuration, as it has changed");
270 : }
271 :
272 0 : AliCDBMetaData metaData;
273 0 : metaData.SetBeamPeriod(0);
274 0 : metaData.SetResponsible("MUON TRK");
275 0 : TString comment("Computed by AliMUONPedestalSubprocessor $Id$");
276 0 : comment.ReplaceAll("$","");
277 0 : metaData.SetComment(comment.Data());
278 :
279 : Bool_t validToInfinity = kTRUE;
280 0 : Bool_t result = Master()->Store("Calib", "Pedestals", fPedestals, &metaData, 0, validToInfinity);
281 0 : if ( fConfigChanged )
282 : {
283 0 : result = result && Master()->Store("Calib", "Config", fConfig, &metaData, 0, validToInfinity);
284 0 : }
285 0 : return ( result != kTRUE ); // return 0 if everything is ok.
286 0 : }
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 0 : TString sFilename(gSystem->ExpandPathName(filename));
302 :
303 0 : Master()->Log(Form("Reading %s",sFilename.Data()));
304 :
305 0 : Int_t n = AliMUONTrackerIO::ReadPedestals(sFilename.Data(),*fPedestals);
306 :
307 0 : switch (n)
308 : {
309 : case -1:
310 0 : Master()->Log(Form("Could not open %s",sFilename.Data()));
311 : break;
312 : }
313 :
314 : return n;
315 0 : }
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 0 : TString sFilename(gSystem->ExpandPathName(filename));
328 :
329 0 : Master()->Log(Form("Reading %s",sFilename.Data()));
330 :
331 0 : Int_t n = AliMUONTrackerIO::ReadConfig(sFilename.Data(),*fConfig);
332 :
333 0 : switch (n)
334 : {
335 : case -1:
336 0 : Master()->Log(Form("Could not open %s",sFilename.Data()));
337 : break;
338 : }
339 :
340 : return n;
341 0 : }
342 :
343 :
344 : //_____________________________________________________________________________
345 : void
346 : AliMUONPedestalSubprocessor::Print(Option_t* opt) const
347 : {
348 : /// ouput to screen
349 0 : if (fPedestals) fPedestals->Print("",opt);
350 0 : if (fConfig) fConfig->Print("",opt);
351 0 : }
352 :
|