]>
Commit | Line | Data |
---|---|---|
f6449cc0 | 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 | /* $Id$ */ | |
16 | /** @file AliFMDPreprocessor.cxx | |
17 | @author Hans Hjersing Dalsgaard <canute@nbi.dk> | |
18 | @date Mon Mar 27 12:39:09 2006 | |
19 | @brief Shuttle "preprocessor" for the FMD | |
20 | */ | |
21 | //___________________________________________________________________ | |
22 | // | |
23 | // The class processes data points from DCS (via Amanada), and DAQ DA | |
24 | // files (via FXS) to make calibration data for the FMD. | |
25 | // | |
26 | // Data points: | |
27 | // * Nothing yet. | |
28 | // | |
29 | // DAQ FXS file: | |
30 | // * pedestals - a (ASCII) Comma Separated Values files with the | |
31 | // fields | |
32 | // rcu DDL number | |
33 | // board FEC board number | |
34 | // chip ALTRO chip number on FEC | |
35 | // channel ALTRO channel number | |
36 | // strip VA1 strip number | |
37 | // sample Sample number | |
38 | // ped Mean of ADC spectra | |
39 | // noise Spread of ADC spectra | |
40 | // mu Mean of Gaussian fit to ADC spectra | |
41 | // sigma Variance of Gaussian fit to ADC spectra | |
42 | // chi2 Chi^2 per degrees of freedom of fit | |
43 | // * Gains - a (ASCII) Comma Separated Values files with the | |
44 | // fields | |
45 | // rcu DDL number | |
46 | // board FEC board number | |
47 | // chip ALTRO chip number on FEC | |
48 | // channel ALTRO channel number | |
49 | // strip VA1 strip number | |
50 | // gain Slope of gain | |
51 | // error Error on gain | |
52 | // chi2 Chi^2 per degrees of freedom of fit | |
53 | // | |
826a3db2 | 54 | // See also |
55 | // | |
56 | // http://aliceinfo.cern.ch/Offline/Activities/Shuttle.html | |
57 | // | |
f6449cc0 | 58 | // Latest changes by Christian Holm Christensen |
59 | // | |
60 | ||
2f7fce12 | 61 | #include <iostream> |
f6449cc0 | 62 | |
63 | #include <fstream> | |
64 | #include "AliFMDPreprocessor.h" | |
65 | #include "AliFMDCalibPedestal.h" | |
66 | #include "AliFMDCalibGain.h" | |
dc02d468 | 67 | #include "AliFMDCalibStripRange.h" |
68 | #include "AliFMDCalibSampleRate.h" | |
f6449cc0 | 69 | #include "AliFMDParameters.h" |
70 | #include "AliCDBMetaData.h" | |
71 | #include "AliCDBManager.h" | |
72 | // #include "AliDCSValue.h" | |
73 | #include "AliLog.h" | |
74 | #include <TTimeStamp.h> | |
75 | // #include <TFile.h> | |
76 | #include <TObjString.h> | |
77 | #include <TString.h> | |
78 | #include <TNamed.h> | |
79 | ||
80 | ||
81 | ClassImp(AliFMDPreprocessor) | |
82 | #if 0 // Do not remove - here to make Emacs happy | |
83 | ; | |
84 | #endif | |
85 | ||
bece5229 | 86 | |
87 | //____________________________________________________ | |
88 | AliFMDPreprocessor::AliFMDPreprocessor(AliShuttleInterface* shuttle) | |
89 | : AliPreprocessor("FMD", shuttle) | |
90 | { | |
91 | AddRunType("PHYSICS"); | |
92 | AddRunType("STANDALONE"); | |
93 | AddRunType("PEDESTAL"); | |
94 | AddRunType("GAIN"); | |
95 | } | |
96 | ||
97 | ||
dc02d468 | 98 | //____________________________________________________ |
99 | Bool_t AliFMDPreprocessor::GetAndCheckFileSources(TList*& list, | |
100 | Int_t system, | |
101 | const char* id) | |
102 | { | |
103 | // Convinience function | |
104 | // Parameters: | |
105 | // list On return, list of files. | |
106 | // system Alice system (DAQ, DCS, ...) | |
107 | // id File id | |
108 | // Return: | |
109 | // kTRUE on success. | |
110 | list = GetFileSources(system, id); | |
111 | if (!list) { | |
112 | TString sys; | |
113 | switch (system) { | |
114 | case kDAQ: sys = "DAQ"; break; | |
115 | case kDCS: sys = "DCS"; break; | |
116 | default: sys = "unknown"; break; | |
117 | } | |
a828379a | 118 | Log(Form("Failed to get file sources for %s/%d", sys.Data(), system)); |
dc02d468 | 119 | return kFALSE; |
120 | } | |
121 | return kTRUE; | |
122 | } | |
123 | ||
124 | //____________________________________________________ | |
125 | AliCDBEntry* | |
126 | AliFMDPreprocessor::GetFromCDB(const char* second, const char* third) | |
127 | { | |
128 | return GetFromOCDB(second, third); | |
129 | } | |
130 | ||
131 | ||
f6449cc0 | 132 | //____________________________________________________ |
133 | UInt_t AliFMDPreprocessor::Process(TMap* /* dcsAliasMap */) | |
134 | { | |
135 | // Main member function. | |
136 | // Parameters: | |
137 | // dcsAliassMap Map of DCS data point aliases. | |
138 | // Return | |
826a3db2 | 139 | // 0 on success, >0 otherwise |
140 | Bool_t resultPed = kTRUE; | |
141 | Bool_t resultGain = kTRUE; | |
142 | Bool_t resultRange = kTRUE; | |
143 | Bool_t resultRate = kTRUE; | |
144 | Bool_t resultZero = kTRUE; | |
2f7fce12 | 145 | Bool_t infoCalib = kTRUE; |
d915e831 | 146 | Bool_t resultDead = kTRUE; |
f6449cc0 | 147 | // Do we need this ? |
148 | // if(!dcsAliasMap) return 1; | |
149 | // | |
150 | // Invoking the cdb manager and the FMD parameters class | |
151 | // AliCDBManager* cdb = AliCDBManager::Instance(); | |
162637e4 | 152 | // cdb->SetDefaultStorage("local://$ALICE_ROOT/OCDB"); |
f6449cc0 | 153 | // cdb->SetRun(0); |
d915e831 | 154 | |
155 | // Get the run type | |
156 | TString runType(GetRunType()); | |
157 | ||
f6449cc0 | 158 | AliFMDParameters* pars = AliFMDParameters::Instance(); |
d915e831 | 159 | if(runType.Contains("PEDESTAL", TString::kIgnoreCase)) |
160 | pars->Init(this, false, AliFMDParameters::kAltroMap|AliFMDParameters::kPulseGain); | |
161 | else if(runType.Contains("GAIN", TString::kIgnoreCase)) | |
162 | pars->Init(this, false, AliFMDParameters::kAltroMap|AliFMDParameters::kPedestal); | |
163 | else | |
164 | pars->Init(this, false, AliFMDParameters::kAltroMap); | |
165 | ||
dc02d468 | 166 | // This is if the SOR contains Fee parameters, and we run a DA to |
167 | // extract these parameters. The same code could work if we get | |
168 | // the information from DCS via the FXS | |
169 | TList* files = 0; | |
dc02d468 | 170 | AliFMDCalibSampleRate* calibRate = 0; |
171 | AliFMDCalibStripRange* calibRange = 0; | |
172 | AliFMDCalibZeroSuppression* calibZero = 0; | |
d915e831 | 173 | |
ae3f7f5f | 174 | if (GetAndCheckFileSources(files, kDAQ,pars->GetConditionsShuttleID())) |
2f7fce12 | 175 | infoCalib = GetInfoCalibration(files, calibRate, calibRange, calibZero); |
176 | ||
bd44b1d9 | 177 | resultRate = (!calibRate ? kFALSE : kTRUE); |
178 | resultRange = (!calibRange ? kFALSE : kTRUE); | |
179 | resultZero = (!calibZero ? kFALSE : kTRUE); | |
2f7fce12 | 180 | |
826a3db2 | 181 | |
d915e831 | 182 | |
f6449cc0 | 183 | //Creating calibration objects |
dc02d468 | 184 | AliFMDCalibPedestal* calibPed = 0; |
185 | AliFMDCalibGain* calibGain = 0; | |
d915e831 | 186 | AliFMDCalibDeadMap* calibDead = 0; |
bd44b1d9 | 187 | if (runType.Contains("PEDESTAL", TString::kIgnoreCase)) { |
ae3f7f5f | 188 | if (GetAndCheckFileSources(files, kDAQ, pars->GetPedestalShuttleID())) { |
bd44b1d9 | 189 | if(files->GetSize()) |
190 | calibPed = GetPedestalCalibration(files); | |
191 | } | |
192 | resultPed = (calibPed ? kTRUE : kFALSE); | |
193 | } | |
bece5229 | 194 | if (runType.Contains("GAIN", TString::kIgnoreCase)) { |
ae3f7f5f | 195 | if (GetAndCheckFileSources(files, kDAQ, pars->GetGainShuttleID())) { |
bd44b1d9 | 196 | if(files->GetSize()) |
197 | calibGain = GetGainCalibration(files); | |
198 | } | |
199 | resultGain = (calibGain ? kTRUE : kFALSE); | |
200 | } | |
d915e831 | 201 | if(runType.Contains("PEDESTAL", TString::kIgnoreCase) || runType.Contains("GAIN", TString::kIgnoreCase)) |
202 | calibDead = GetDeadChannelMap(calibPed,calibGain); | |
f6449cc0 | 203 | |
204 | //Storing Calibration objects | |
205 | AliCDBMetaData metaData; | |
206 | metaData.SetBeamPeriod(0); | |
207 | metaData.SetResponsible("Hans H. Dalsgaard"); | |
208 | metaData.SetComment("Preprocessor stores pedestals and gains for the FMD."); | |
209 | ||
dc02d468 | 210 | if(calibPed) { |
826a3db2 | 211 | resultPed = Store("Calib","Pedestal", calibPed, &metaData, 0, kTRUE); |
dc02d468 | 212 | delete calibPed; |
213 | } | |
214 | if(calibGain) { | |
826a3db2 | 215 | resultGain = Store("Calib","PulseGain", calibGain, &metaData, 0, kTRUE); |
dc02d468 | 216 | delete calibGain; |
217 | } | |
218 | if(calibRange) { | |
826a3db2 | 219 | resultRange = Store("Calib","StripRange", calibRange, &metaData, 0, kTRUE); |
dc02d468 | 220 | delete calibRange; |
221 | } | |
222 | if(calibRate) { | |
826a3db2 | 223 | resultRate = Store("Calib","SampleRate", calibRate, &metaData, 0, kTRUE); |
dc02d468 | 224 | delete calibRate; |
225 | } | |
226 | if(calibZero) { | |
bd44b1d9 | 227 | resultZero = Store("Calib","ZeroSuppression", calibZero,&metaData,0,kTRUE); |
dc02d468 | 228 | delete calibZero; |
229 | } | |
d915e831 | 230 | if(calibDead) { |
231 | resultDead = Store("Calib","Dead", calibDead,&metaData,0,kTRUE); | |
232 | delete calibDead; | |
233 | } | |
826a3db2 | 234 | |
826a3db2 | 235 | Bool_t success = (resultPed && resultGain && resultRange && |
d915e831 | 236 | resultRate && resultZero && resultDead && infoCalib); |
2f7fce12 | 237 | |
826a3db2 | 238 | Log(Form("FMD preprocessor was %s", (success ? "successful" : "failed"))); |
239 | return (success ? 0 : 1); | |
dc02d468 | 240 | } |
241 | ||
242 | //____________________________________________________________________ | |
243 | Bool_t | |
244 | AliFMDPreprocessor::GetInfoCalibration(TList* files, | |
245 | AliFMDCalibSampleRate*& s, | |
246 | AliFMDCalibStripRange*& r, | |
247 | AliFMDCalibZeroSuppression*& z) | |
248 | { | |
249 | // Get info calibrations. | |
250 | // Parameters: | |
251 | // files List of files. | |
252 | // s On return, newly allocated object | |
253 | // r On return, newly allocated object | |
254 | // z On return, newly allocated object | |
255 | // Return: | |
256 | // kTRUE on success | |
2f7fce12 | 257 | if (!files) return kFALSE; // Should really be false |
258 | if (files->GetEntries() <= 0) return kFALSE; | |
dc02d468 | 259 | |
260 | s = new AliFMDCalibSampleRate(); | |
261 | r = new AliFMDCalibStripRange(); | |
262 | z = new AliFMDCalibZeroSuppression(); | |
263 | ||
ae3f7f5f | 264 | AliFMDParameters* pars = AliFMDParameters::Instance(); |
dc02d468 | 265 | TIter iter(files); |
266 | TObjString* fileSource; | |
267 | ||
268 | while((fileSource = dynamic_cast<TObjString*>(iter.Next()))) { | |
ae3f7f5f | 269 | const Char_t* filename = GetFile(kDAQ, pars->GetConditionsShuttleID(), fileSource->GetName()); |
dc02d468 | 270 | std::ifstream in(filename); |
271 | if(!in) { | |
826a3db2 | 272 | Log(Form("File %s not found!", filename)); |
dc02d468 | 273 | continue; |
274 | } | |
b0dbd59f | 275 | s->ReadFromFile(in); |
276 | r->ReadFromFile(in); | |
dc02d468 | 277 | } |
278 | return kTRUE; | |
f6449cc0 | 279 | } |
280 | ||
dc02d468 | 281 | |
f6449cc0 | 282 | //____________________________________________________________________ |
283 | AliFMDCalibPedestal* | |
09b6c804 | 284 | AliFMDPreprocessor::GetPedestalCalibration(const TList* pedFiles) |
f6449cc0 | 285 | { |
286 | // Read DAQ DA produced CSV files of pedestals, and return a | |
287 | // calibration object. | |
288 | // Parameters: | |
289 | // pedFiles List of pedestal files | |
290 | // Return | |
291 | // A pointer to a newly allocated AliFMDCalibPedestal object, or | |
292 | // null in case of errors. | |
293 | if(!pedFiles) return 0; | |
294 | ||
295 | AliFMDCalibPedestal* calibPed = new AliFMDCalibPedestal(); | |
296 | AliFMDParameters* pars = AliFMDParameters::Instance(); | |
297 | TIter iter(pedFiles); | |
298 | TObjString* fileSource; | |
299 | ||
300 | while((fileSource = dynamic_cast<TObjString*>(iter.Next()))) { | |
09b6c804 | 301 | const Char_t* filename = GetFile(kDAQ, pars->GetPedestalShuttleID(), |
302 | fileSource->GetName()); | |
f6449cc0 | 303 | std::ifstream in(filename); |
304 | if(!in) { | |
826a3db2 | 305 | Log(Form("File %s not found!", filename)); |
f6449cc0 | 306 | continue; |
307 | } | |
f6449cc0 | 308 | // Loop until EOF |
9c3032e9 | 309 | int lineno = 0; |
310 | char cc; | |
311 | while((cc = in.peek())!=EOF) { | |
f6449cc0 | 312 | if(in.bad()) { |
826a3db2 | 313 | Log(Form("Bad read at line %d in %s", lineno, filename)); |
f6449cc0 | 314 | break; |
315 | } | |
9c3032e9 | 316 | if (cc == '#') { |
317 | TString line; | |
318 | line.ReadLine(in); | |
319 | lineno++; | |
320 | if (lineno == 1) { | |
321 | line.ToLower(); | |
322 | if(!line.Contains(pars->GetPedestalShuttleID())) { | |
323 | Log(Form("File header is not from pedestal!: %s", line.Data())); | |
324 | break; | |
325 | } | |
326 | Log("File contains data from pedestals"); | |
327 | } | |
328 | continue; | |
329 | } | |
3bae5d02 | 330 | UShort_t det, sec, strip; |
331 | Char_t ring; | |
f6449cc0 | 332 | Float_t ped, noise, mu, sigma, chi2ndf; |
3bae5d02 | 333 | Char_t c[8]; |
f6449cc0 | 334 | |
3bae5d02 | 335 | in >> det >> c[0] |
336 | >> ring >> c[1] | |
337 | >> sec >> c[2] | |
338 | >> strip >> c[3] | |
339 | >> ped >> c[4] | |
340 | >> noise >> c[5] | |
341 | >> mu >> c[6] | |
342 | >> sigma >> c[7] | |
f6449cc0 | 343 | >> chi2ndf; |
344 | lineno++; | |
bd44b1d9 | 345 | |
f6449cc0 | 346 | // Ignore trailing garbage |
3bae5d02 | 347 | // if (strip > 127) continue; |
f6449cc0 | 348 | |
bd44b1d9 | 349 | //Setting DDL to comply with the FMD in DAQ |
3bae5d02 | 350 | // UInt_t FmdDDLBase = 3072; |
351 | // ddl = ddl - FmdDDLBase; | |
f6449cc0 | 352 | //Setting the pedestals via the hardware address |
bd44b1d9 | 353 | |
3bae5d02 | 354 | |
355 | // pars->Hardware2Detector(ddl,board,chip,channel,det,ring,sec,str); | |
356 | // strip += str; | |
bd44b1d9 | 357 | |
f6449cc0 | 358 | calibPed->Set(det,ring,sec,strip,ped,noise); |
bd44b1d9 | 359 | |
f6449cc0 | 360 | } |
361 | } | |
362 | return calibPed; | |
363 | } | |
364 | ||
365 | //____________________________________________________________________ | |
366 | AliFMDCalibGain* | |
09b6c804 | 367 | AliFMDPreprocessor::GetGainCalibration(const TList* gainFiles) |
f6449cc0 | 368 | { |
369 | // Read DAQ DA produced CSV files of pedestals, and return a | |
370 | // calibration object. | |
371 | // Parameters: | |
372 | // pedFiles List of pedestal files | |
373 | // Return | |
374 | // A pointer to a newly allocated AliFMDCalibPedestal object, or | |
375 | // null in case of errors. | |
376 | if(!gainFiles) return 0; | |
377 | ||
378 | AliFMDCalibGain* calibGain = new AliFMDCalibGain(); | |
379 | AliFMDParameters* pars = AliFMDParameters::Instance(); | |
380 | TIter iter(gainFiles); | |
381 | TObjString* fileSource; | |
382 | while((fileSource = dynamic_cast<TObjString *>(iter.Next()))) { | |
09b6c804 | 383 | const Char_t* filename = GetFile(kDAQ, pars->GetGainShuttleID(), |
384 | fileSource->GetName()); | |
f6449cc0 | 385 | std::ifstream in(filename); |
386 | if(!in) { | |
826a3db2 | 387 | Log(Form("File %s not found!", filename)); |
f6449cc0 | 388 | continue; |
389 | } | |
9c3032e9 | 390 | // Loop until EOF |
391 | int lineno = 0; | |
392 | char cc; | |
393 | while((cc = in.peek())!=EOF) { | |
394 | if(in.bad()) { | |
395 | Log(Form("Bad read at line %d in %s", lineno, filename)); | |
396 | break; | |
397 | } | |
398 | if (cc == '#') { | |
399 | TString line; | |
400 | line.ReadLine(in); | |
401 | lineno++; | |
402 | if (lineno == 1) { | |
403 | line.ToLower(); | |
404 | if(!line.Contains(pars->GetGainShuttleID())) { | |
405 | Log(Form("File header is not from gains!: %s", line.Data())); | |
406 | break; | |
407 | } | |
408 | Log("File contains data from gains"); | |
409 | } | |
410 | continue; | |
f6449cc0 | 411 | } |
3bae5d02 | 412 | UShort_t det, sec, strip; |
413 | Char_t ring; | |
414 | ||
f6449cc0 | 415 | Float_t gain,error, chi2ndf; |
3bae5d02 | 416 | Char_t c[6]; |
417 | ||
418 | in >> det >> c[0] | |
419 | >> ring >> c[1] | |
420 | >> sec >> c[2] | |
421 | >> strip >> c[3] | |
422 | >> gain >> c[4] | |
423 | >> error >> c[5] | |
f6449cc0 | 424 | >> chi2ndf; |
425 | lineno++; | |
426 | // Ignore trailing garbage | |
3bae5d02 | 427 | //if(strip > 127) continue; |
f6449cc0 | 428 | |
bd44b1d9 | 429 | //Setting DDL to comply with the FMD in DAQ |
3bae5d02 | 430 | // UInt_t FmdDDLBase = 3072; |
431 | // ddl = ddl - FmdDDLBase; | |
f6449cc0 | 432 | //Setting the pedestals via the hardware address |
3bae5d02 | 433 | // pars->Hardware2Detector(ddl,board,chip,channel,det,ring,sec,str); |
f6449cc0 | 434 | |
3bae5d02 | 435 | // strip += str; |
f6449cc0 | 436 | calibGain->Set(det,ring,sec,strip,gain); |
437 | } | |
438 | } | |
439 | return calibGain; | |
440 | } | |
d915e831 | 441 | //____________________________________________________________________ |
442 | AliFMDCalibDeadMap* | |
443 | AliFMDPreprocessor::GetDeadChannelMap(AliFMDCalibPedestal* pedcalib, | |
444 | AliFMDCalibGain* gaincalib) { | |
445 | //creating dead channel map. '0' means 51200 entries | |
446 | AliFMDCalibDeadMap* deadmap = new AliFMDCalibDeadMap(0); | |
447 | //deadmap->Reset(kTRUE); | |
448 | Float_t noise = 0; | |
449 | Float_t gain = 0; | |
450 | ||
451 | AliFMDParameters* pars = AliFMDParameters::Instance(); | |
452 | //Looping over the channels. | |
453 | for(UShort_t det=1;det<=3;det++) { | |
454 | Int_t nRings = (det==1 ? 1 : 2); | |
455 | for (UShort_t ir = 0; ir < nRings; ir++) { | |
456 | Char_t ring = (ir == 0 ? 'I' : 'O'); | |
457 | UShort_t nsec = (ir == 0 ? 20 : 40); | |
458 | UShort_t nstr = (ir == 0 ? 512 : 256); | |
459 | ||
460 | for(UShort_t sec =0; sec < nsec; sec++) { | |
461 | ||
462 | for(UShort_t strip = 0; strip < nstr; strip++) { | |
463 | ||
464 | Bool_t isDead = kFALSE; | |
465 | if(pedcalib) | |
466 | noise = pedcalib->Width(det, ring, sec, strip); | |
467 | else | |
468 | noise = pars->GetPedestalWidth(det, ring, sec, strip); | |
469 | ||
470 | if(gaincalib) | |
471 | gain = gaincalib->Value(det, ring, sec, strip); | |
472 | else | |
473 | gain = pars->GetPulseGain(det, ring, sec, strip); | |
474 | ||
475 | //marking these channels dead. | |
476 | if (gain < 0.5 || gain > 5 || noise > 10 || noise == 0) isDead = kTRUE; | |
477 | ||
478 | deadmap->operator()(det, ring, sec, strip) = isDead; | |
479 | } | |
480 | } | |
481 | } | |
482 | } | |
f6449cc0 | 483 | |
d915e831 | 484 | return deadmap; |
485 | } | |
f6449cc0 | 486 | //____________________________________________________________________ |
487 | // | |
488 | // EOF | |
489 | // |