Update
[u/mrichter/AliRoot.git] / FMD / AliFMDPedestalDA.cxx
CommitLineData
3bd993ba 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 AliFMDPedestalDA.cxx
17 @author Hans Hjersing Dalsgaard <canute@nbi.dk>
18 @date Mon Mar 10 09:46:05 2008
19 @brief Derived class for the pedestal detector algorithm.
20*/
21//
e9c06036 22// This class implements the virtual functions of the AliFMDBaseDA
23// class. The most important of these functions, FillChannels(..) and
24// Analyse(...) collect and analyse the data of each channel. The
25// resulting pedestal and noise values are written to a comma
26// separated values (csv) file on the go. The csv files produced in
27// this way are the basic input to the AliFMDPreprocessor.
3bd993ba 28//
29
30#include "AliFMDPedestalDA.h"
5cf05dbb 31#include "AliFMDAltroMapping.h"
09b6c804 32#include "AliFMDParameters.h"
33#include "AliFMDCalibPedestal.h"
34#include "AliFMDDigit.h"
35#include "AliLog.h"
408bf2b4 36#include <iostream>
37#include <fstream>
45cffd06 38#include <iomanip>
09b6c804 39#include <TFile.h>
40#include <TF1.h>
41#include <TObject.h>
42#include <TMath.h>
408bf2b4 43#include <TSystem.h>
6cf6e7a0 44#include <TDatime.h>
2a082c96 45#include <TH2.h>
3bd993ba 46
47//_____________________________________________________________________
48ClassImp(AliFMDPedestalDA)
49
50//_____________________________________________________________________
2a082c96 51AliFMDPedestalDA::AliFMDPedestalDA()
52 : AliFMDBaseDA(),
53 fCurrentChannel(1),
54 fPedSummary("PedestalSummary","pedestals",51200,0,51200),
55 fNoiseSummary("NoiseSummary","noise",51200,0,51200),
56 fZSfileFMD1(),
57 fZSfileFMD2(),
58 fZSfileFMD3(),
59 fMinTimebin(3 * 4 * 3 * 16), // 3 ddls, 4 FECs, 3 Altros, 16 channels
60 fMaxTimebin(3 * 4 * 3 * 16), // 3 ddls, 4 FECs, 3 Altros, 16 channels
61 fSummaryFMD1i(0),
62 fSummaryFMD2i(0),
63 fSummaryFMD2o(0),
64 fSummaryFMD3i(0),
65 fSummaryFMD3o(0)
3bd993ba 66{
5cf05dbb 67 // Default constructor
6cf6e7a0 68 Rotate("peds.csv", 3);
3bd993ba 69 fOutputFile.open("peds.csv");
6cf6e7a0 70 Rotate("ddl3072.csv", 10);
7bce699b 71 fZSfileFMD1.open("ddl3072.csv");
6cf6e7a0 72 Rotate("ddl3073.csv", 10);
7bce699b 73 fZSfileFMD2.open("ddl3073.csv");
6cf6e7a0 74 Rotate("ddl3074.csv", 10);
7bce699b 75 fZSfileFMD3.open("ddl3074.csv");
3bd993ba 76}
77
78//_____________________________________________________________________
79AliFMDPedestalDA::AliFMDPedestalDA(const AliFMDPedestalDA & pedDA) :
f7f0b643 80 AliFMDBaseDA(pedDA),
f14ede67 81 fCurrentChannel(1),
f7f0b643 82 fPedSummary("PedestalSummary","pedestals",51200,0,51200),
7bce699b 83 fNoiseSummary("NoiseSummary","noise",51200,0,51200),
84 fZSfileFMD1(),
85 fZSfileFMD2(),
5cf05dbb 86 fZSfileFMD3(),
87 fMinTimebin(pedDA.fMinTimebin),
2a082c96 88 fMaxTimebin(pedDA.fMaxTimebin),
89 fSummaryFMD1i(pedDA.fSummaryFMD1i),
90 fSummaryFMD2i(pedDA.fSummaryFMD2i),
91 fSummaryFMD2o(pedDA.fSummaryFMD2o),
92 fSummaryFMD3i(pedDA.fSummaryFMD3i),
93 fSummaryFMD3o(pedDA.fSummaryFMD3o)
3bd993ba 94{
5cf05dbb 95 // Copy constructor
3bd993ba 96}
97
98//_____________________________________________________________________
e9c06036 99AliFMDPedestalDA::~AliFMDPedestalDA()
100{
5cf05dbb 101 // Destructor.
3bd993ba 102}
103
104//_____________________________________________________________________
e9c06036 105void AliFMDPedestalDA::Init()
106{
5cf05dbb 107 // Initialise
3bd993ba 108 SetRequiredEvents(1000);
5cf05dbb 109 fMinTimebin.Reset(1024);
110 fMaxTimebin.Reset(-1);
2a082c96 111
112
3bd993ba 113}
114
115//_____________________________________________________________________
116void AliFMDPedestalDA::AddChannelContainer(TObjArray* sectorArray,
117 UShort_t det,
e9c06036 118 Char_t ring,
3bd993ba 119 UShort_t sec,
e9c06036 120 UShort_t strip)
121{
5cf05dbb 122 // Add a channel to the containers.
123 //
124 // Parameters:
125 // sectorArray Array of sectors
126 // det Detector
127 // ring Ring
128 // sec Sector
129 // strip Strip
e9c06036 130 AliFMDParameters* pars = AliFMDParameters::Instance();
5cf05dbb 131 UInt_t samples = pars->GetSampleRate(det, ring, sec, strip);
e9c06036 132 TObjArray* sampleArray = new TObjArray(samples);
7bce699b 133 sampleArray->SetOwner();
134 for (UInt_t sample = 0; sample < samples; sample++) {
45cffd06 135 TString name(Form("FMD%d%c[%02d,%03d]_%d", det,ring,sec,strip,sample));
136 TH1S* hSample = new TH1S(name.Data(),name.Data(), 1024,-.5,1023.5);
e9c06036 137 hSample->SetXTitle("ADC");
138 hSample->SetYTitle("Events");
7bce699b 139 hSample->SetDirectory(0);
e9c06036 140 sampleArray->AddAt(hSample, sample);
141 }
142 sectorArray->AddAtAndExpand(sampleArray, strip);
3bd993ba 143}
144
145//_____________________________________________________________________
e9c06036 146void AliFMDPedestalDA::FillChannels(AliFMDDigit* digit)
147{
5cf05dbb 148 // Fill ADC values from a digit into the corresponding histogram.
149 //
150 // Parameters:
151 // digit Digit to fill ADC values for.
3bd993ba 152 UShort_t det = digit->Detector();
153 Char_t ring = digit->Ring();
154 UShort_t sec = digit->Sector();
155 UShort_t strip = digit->Strip();
15e37b0a 156
e9c06036 157 AliFMDParameters* pars = AliFMDParameters::Instance();
5cf05dbb 158 UInt_t samples = pars->GetSampleRate(det, ring, sec, strip);
7bce699b 159 for (UInt_t sample = 0; sample < samples; sample++) {
e9c06036 160 TH1S* hSample = GetChannel(det, ring, sec, strip, sample);
161 hSample->Fill(digit->Count(sample));
162 }
7bce699b 163
3bd993ba 164}
165
166//_____________________________________________________________________
2a082c96 167void AliFMDPedestalDA::MakeSummary(UShort_t det, Char_t ring)
168{
8e23c82d 169 //Create summary hists for FMD pedestals
2a082c96 170 std::cout << "Making summary for FMD" << det << ring << " ..." << std::endl;
171 switch (det) {
172 case 1:
173 fSummaryFMD1i = MakeSummaryHistogram("ped", "Pedestals", det, ring);
174 break;
175 case 2:
176 switch (ring) {
177 case 'I': case 'i':
178 fSummaryFMD2i = MakeSummaryHistogram("ped", "Pedestals", det, ring);
179 break;
180 case 'O': case 'o':
181 fSummaryFMD2o = MakeSummaryHistogram("ped", "Pedestals", det, ring);
182 break;
183 }
184 break;
185 case 3:
186 switch (ring) {
187 case 'I': case 'i':
188 fSummaryFMD3i = MakeSummaryHistogram("ped", "Pedestals", det, ring);
189 break;
190 case 'O': case 'o':
191 fSummaryFMD3o = MakeSummaryHistogram("ped", "Pedestals", det, ring);
192 break;
193 }
194 break;
195 }
196}
197
198//_____________________________________________________________________
3bd993ba 199void AliFMDPedestalDA::Analyse(UShort_t det,
e9c06036 200 Char_t ring,
3bd993ba 201 UShort_t sec,
5cf05dbb 202 UShort_t strip)
203{
204 // Analyse a strip. That is, compute the mean and spread of the ADC
205 // spectra for all strips. Also output on files the values.
206 //
207 // Parameters:
208 // det Detector
209 // ring Ring
210 // sec Sector
211 // strip Strip.
7bce699b 212 AliFMDParameters* pars = AliFMDParameters::Instance();
2a082c96 213 TH2* summary = 0;
214 switch (det) {
215 case 1: summary = fSummaryFMD1i; break;
216 case 2:
217 switch (ring) {
218 case 'I': summary = fSummaryFMD2i; break;
219 case 'O': summary = fSummaryFMD2o; break;
220 }
221 break;
222 case 3:
223 switch (ring) {
224 case 'I': summary = fSummaryFMD3i; break;
225 case 'O': summary = fSummaryFMD3o; break;
226 }
227 break;
228 }
229 static bool first = true;
230 if (summary && first) {
231 std::cout << "Filling summary " << summary->GetName() << std::endl;
232 first = false;
233 }
234
762e54b7 235 // Float_t factor = pars->GetPedestalFactor();
5cf05dbb 236 UInt_t samples = pars->GetSampleRate(det, ring, sec, strip);
7bce699b 237 for (UShort_t sample = 0; sample < samples; sample++) {
3bd993ba 238
5cf05dbb 239 TH1S* hChannel = GetChannel(det, ring, sec, strip,sample);
7bce699b 240 if(hChannel->GetEntries() == 0) {
241 //AliWarning(Form("No entries for FMD%d%c, sector %d, strip %d",
242 // det,ring,sec,strip));
243 return;
e9c06036 244 }
f7f0b643 245
a828379a 246 AliDebug(50, Form("Fitting FMD%d%c[%02d,%03d] with %d entries",
247 det,ring,sec,strip, int(hChannel->GetEntries())));
7bce699b 248 TF1 fitFunc("fitFunc","gausn",0,300);
249 fitFunc.SetParameters(100,100,1);
250 hChannel->Fit("fitFunc","Q0+","",10,200);
251
252 Float_t mean = hChannel->GetMean();
253 Float_t rms = hChannel->GetRMS();
254
f7f0b643 255
f7f0b643 256
7bce699b 257 hChannel->GetXaxis()->SetRangeUser(mean-5*rms,mean+5*rms);
f7f0b643 258
7bce699b 259 mean = hChannel->GetMean();
260 rms = hChannel->GetRMS();
93519ec4 261
7bce699b 262
263 UShort_t ddl, board, altro, channel;
264 UShort_t timebin;
265
5cf05dbb 266 pars->Detector2Hardware(det,ring,sec,strip,sample,
267 ddl,board,altro,channel,timebin);
268 Int_t idx = HWIndex(ddl, board, altro, channel);
269 if (idx >= 0) {
270 fMinTimebin[idx] = TMath::Min(Short_t(timebin), fMinTimebin[idx]);
271 fMaxTimebin[idx] = TMath::Max(Short_t(timebin+1), fMaxTimebin[idx]);
272 }
7bce699b 273
5cf05dbb 274 std::ostream* zsFile = 0;
7bce699b 275 switch(det) {
5cf05dbb 276 case 1: zsFile = &fZSfileFMD1; break;
277 case 2: zsFile = &fZSfileFMD2; break;
278 case 3: zsFile = &fZSfileFMD3; break;
279 default: AliWarning("Unknown sample!"); break;
7bce699b 280
281 }
5cf05dbb 282 *zsFile << board << ','
283 << altro << ','
284 << channel << ','
285 << timebin << ','
286 << mean << ','
276b1261 287 << rms << "\n";
7bce699b 288
289 Float_t chi2ndf = 0;
15e37b0a 290
291
7bce699b 292 if(fitFunc.GetNDF())
293 chi2ndf = fitFunc.GetChisquare() / fitFunc.GetNDF();
294
5cf05dbb 295
15e37b0a 296 Int_t sampleToWrite = 2;
5cf05dbb 297 if (samples == 2) sampleToWrite = 1;
298 else if (samples < 2) sampleToWrite = 0;
15e37b0a 299
5cf05dbb 300 if(sample != sampleToWrite) continue;
15e37b0a 301
15e37b0a 302
5cf05dbb 303 fOutputFile << det << ','
304 << ring << ','
305 << sec << ','
306 << strip << ','
307 << mean << ','
308 << rms << ','
309 << fitFunc.GetParameter(1) << ','
310 << fitFunc.GetParameter(2) << ','
311 << chi2ndf <<"\n";
2a082c96 312
313 if (summary) {
314 Int_t bin = summary->FindBin(sec, strip);
315 summary->SetBinContent(bin, mean);
316 summary->SetBinError(bin, rms);
317 }
318
5cf05dbb 319 if(fSaveHistograms ) {
320 gDirectory->cd(GetSectorPath(det, ring, sec, kTRUE));
321 TH1F* sumPed = dynamic_cast<TH1F*>(gDirectory->Get("Pedestals"));
322 TH1F* sumNoise = dynamic_cast<TH1F*>(gDirectory->Get("Noise"));
323 Int_t nStr = (ring == 'I' ? 512 : 256);
324 if (!sumPed) {
325 sumPed = new TH1F("Pedestals",
326 Form("Summary of pedestals in FMD%d%c[%02d]",
327 det, ring, sec),
328 nStr, -.5, nStr-.5);
329 sumPed->SetXTitle("Strip");
330 sumPed->SetYTitle("Pedestal [ADC]");
331 sumPed->SetDirectory(gDirectory);
332 }
333 if (!sumNoise) {
334 sumNoise = new TH1F("Noise",
335 Form("Summary of noise in FMD%d%c[%02d]",
7bce699b 336 det, ring, sec),
337 nStr, -.5, nStr-.5);
5cf05dbb 338 sumNoise->SetXTitle("Strip");
339 sumNoise->SetYTitle("Noise [ADC]");
7bce699b 340
5cf05dbb 341 sumNoise->SetDirectory(gDirectory);
7bce699b 342 }
5cf05dbb 343 sumPed->SetBinContent(strip+1, mean);
344 sumPed->SetBinError(strip+1, rms);
345 sumNoise->SetBinContent(strip+1, rms);
346
347 if(sumNoise->GetEntries() == nStr)
348 sumNoise->Write(sumNoise->GetName(),TObject::kOverwrite);
349 if(sumPed->GetEntries() == nStr)
350 sumPed->Write(sumPed->GetName(),TObject::kOverwrite);
351
352 fPedSummary.SetBinContent(fCurrentChannel,mean);
353
354 fNoiseSummary.SetBinContent(fCurrentChannel,rms);
355 fCurrentChannel++;
356
357 gDirectory->cd(GetStripPath(det, ring, sec, strip, kTRUE));
358 hChannel->GetXaxis()->SetRange(1,1024);
359
360 hChannel->Write();
7bce699b 361 }
362 }
3bd993ba 363}
364
365//_____________________________________________________________________
f7f0b643 366void AliFMDPedestalDA::Terminate(TFile* diagFile)
367{
5cf05dbb 368 // Called at the end of a job. Fills in missing time-bins and
369 // closes output files
7bce699b 370 if(fSaveHistograms) {
371 diagFile->cd();
372
373 fPedSummary.Write();
374 fNoiseSummary.Write();
375 }
5cf05dbb 376 AliFMDAltroMapping* map = AliFMDParameters::Instance()->GetAltroMap();
276b1261 377 for (Int_t i = 0; i < 3; i++) {
378 std::ofstream& out = (i == 0 ? fZSfileFMD1 :
379 i == 1 ? fZSfileFMD2 :
380 fZSfileFMD3);
381 if (out.is_open() && fSeenDetectors[i]) {
382 FillinTimebins(out, map->Detector2DDL(i+1));
383 }
408bf2b4 384 if (!fSeenDetectors[i]) {
385 TString n(Form("ddl%d.csv",3072+map->Detector2DDL(i+1)));
386 gSystem->Unlink(n.Data());
387 }
388 }
f7f0b643 389
5cf05dbb 390}
391
392//_____________________________________________________________________
7af3df7f 393void AliFMDPedestalDA::FillinTimebins(std::ofstream& out, UShort_t /*ddl*/)
5cf05dbb 394{
45cffd06 395 //
396 // Fill missing timebins
397 //
762e54b7 398#if 0
5cf05dbb 399 unsigned short boards[] = { 0x0, 0x1, 0x10, 0x11, 0xFFFF };
400 unsigned short* board = boards;
401 while ((*boards) != 0xFFFF) {
402 for (UShort_t altro = 0; altro < 3; altro++) {
403 for (UShort_t channel = 0; channel < 16; channel++) {
404 Int_t idx = HWIndex(ddl, *board, altro, channel);
405 if (idx < 0) {
406 AliWarning(Form("Invalid index for %4d/0x%02x/0x%x/0x%x: %d",
407 ddl, *board, altro, channel, idx));
408 continue;
409 }
410 Short_t min = fMinTimebin[idx];
411 Short_t max = fMaxTimebin[idx];
412
413 // Channel not seen at all.
414 if (min > 1023 || max < 0) continue;
415
416 out << "# Extra timebins for 0x" << std::hex
417 << board << ',' << altro << ',' << channel
418 << " got time-bins " << min << " to " << max-1
419 << std::dec << std::endl;
420
421 for (UShort_t t = 15; t < min; t++)
422 // Write a phony line
423 out << board << "," << altro << "," << channel << ","
424 << t << "," << 1023 << "," << 0 << std::endl;
425
426 for (UShort_t t = max; t < 1024; t++)
427 // Write a phony line
428 out << board << "," << altro << "," << channel << ","
429 << t << "," << 1023 << "," << 0 << std::endl;
430 } // channel loop
431 } // altro loop
432 } // board loop
433 // Write trailer, and close
762e54b7 434#endif
5cf05dbb 435 out.write("# EOF\n", 6);
436 out.close();
f7f0b643 437}
438
439//_____________________________________________________________________
e9c06036 440void AliFMDPedestalDA::WriteHeaderToFile()
441{
45cffd06 442 //
5cf05dbb 443 // Write headers to output files
45cffd06 444 //
80fdb9f3 445 AliFMDParameters* pars = AliFMDParameters::Instance();
446 fOutputFile.write(Form("# %s \n",pars->GetPedestalShuttleID()),13);
6cf6e7a0 447 TDatime now;
448 fOutputFile << "# This file created from run # " << fRunno
449 << " @ " << now.AsString() << std::endl;
f7f0b643 450 fOutputFile.write("# Detector, "
451 "Ring, "
452 "Sector, "
e9c06036 453 "Strip, "
e9c06036 454 "Pedestal, "
455 "Noise, "
456 "Mu, "
457 "Sigma, "
f7f0b643 458 "Chi2/NDF \n", 71);
5cf05dbb 459
460 std::ostream* zss[] = { &fZSfileFMD1, &fZSfileFMD2, &fZSfileFMD3, 0 };
6cf6e7a0 461 for (size_t i = 0; i < 3; i++) {
462 *(zss[i]) << "# FMD " << (i+1) << " pedestals \n"
5cf05dbb 463 << "# board, "
464 << "altro, "
465 << "channel, "
466 << "timebin, "
467 << "pedestal, "
762e54b7 468 << "noise\n";
6cf6e7a0 469 *(zss[i]) << "# This file created from run # " << fRunno
470 << " @ " << now.AsString() << std::endl;
471 }
3bd993ba 472}
473
474//_____________________________________________________________________
e9c06036 475TH1S* AliFMDPedestalDA::GetChannel(UShort_t det,
476 Char_t ring,
477 UShort_t sec,
7bce699b 478 UShort_t strip,
5cf05dbb 479 UInt_t sample)
e9c06036 480{
5cf05dbb 481 // Get the histogram corresponding to a strip sample.
482 //
483 // Parameters:
484 // det Detector
485 // ring Ring
486 // sec Sector
487 // strip Strip
488 // sample Sample
489 //
490 // Return:
491 // ADC spectra of a strip.
492 UShort_t iring = (ring == 'O' ? 0 : 1);
493 TObjArray* detArray = static_cast<TObjArray*>(fDetectorArray.At(det));
494 TObjArray* ringArray = static_cast<TObjArray*>(detArray->At(iring));
495 TObjArray* secArray = static_cast<TObjArray*>(ringArray->At(sec));
496 TObjArray* sampleArray = static_cast<TObjArray*>(secArray->At(strip));
497 TH1S* hSample = static_cast<TH1S*>(sampleArray->At(sample));
e9c06036 498 return hSample;
7bce699b 499
3bd993ba 500}
93519ec4 501
3bd993ba 502//_____________________________________________________________________
503//
504//EOF
505//