Merge branch 'feature-movesplit'
[u/mrichter/AliRoot.git] / FMD / FMDutil / 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");
a31ea3ce 76 fDiagnosticsFilename = "diagnosticsPedestal.root";
3bd993ba 77}
78
79//_____________________________________________________________________
80AliFMDPedestalDA::AliFMDPedestalDA(const AliFMDPedestalDA & pedDA) :
f7f0b643 81 AliFMDBaseDA(pedDA),
f14ede67 82 fCurrentChannel(1),
f7f0b643 83 fPedSummary("PedestalSummary","pedestals",51200,0,51200),
7bce699b 84 fNoiseSummary("NoiseSummary","noise",51200,0,51200),
85 fZSfileFMD1(),
86 fZSfileFMD2(),
5cf05dbb 87 fZSfileFMD3(),
88 fMinTimebin(pedDA.fMinTimebin),
2a082c96 89 fMaxTimebin(pedDA.fMaxTimebin),
90 fSummaryFMD1i(pedDA.fSummaryFMD1i),
91 fSummaryFMD2i(pedDA.fSummaryFMD2i),
92 fSummaryFMD2o(pedDA.fSummaryFMD2o),
93 fSummaryFMD3i(pedDA.fSummaryFMD3i),
94 fSummaryFMD3o(pedDA.fSummaryFMD3o)
3bd993ba 95{
5cf05dbb 96 // Copy constructor
3bd993ba 97}
98
99//_____________________________________________________________________
e9c06036 100AliFMDPedestalDA::~AliFMDPedestalDA()
101{
5cf05dbb 102 // Destructor.
3bd993ba 103}
104
105//_____________________________________________________________________
e9c06036 106void AliFMDPedestalDA::Init()
107{
5cf05dbb 108 // Initialise
3bd993ba 109 SetRequiredEvents(1000);
5cf05dbb 110 fMinTimebin.Reset(1024);
111 fMaxTimebin.Reset(-1);
2a082c96 112
113
3bd993ba 114}
115
116//_____________________________________________________________________
a31ea3ce 117void AliFMDPedestalDA::AddChannelContainer(TObjArray* sampleArray,
3bd993ba 118 UShort_t det,
e9c06036 119 Char_t ring,
3bd993ba 120 UShort_t sec,
e9c06036 121 UShort_t strip)
122{
5cf05dbb 123 // Add a channel to the containers.
124 //
125 // Parameters:
126 // sectorArray Array of sectors
127 // det Detector
128 // ring Ring
129 // sec Sector
130 // strip Strip
e9c06036 131 AliFMDParameters* pars = AliFMDParameters::Instance();
5cf05dbb 132 UInt_t samples = pars->GetSampleRate(det, ring, sec, strip);
7bce699b 133 for (UInt_t sample = 0; sample < samples; sample++) {
45cffd06 134 TString name(Form("FMD%d%c[%02d,%03d]_%d", det,ring,sec,strip,sample));
135 TH1S* hSample = new TH1S(name.Data(),name.Data(), 1024,-.5,1023.5);
e9c06036 136 hSample->SetXTitle("ADC");
137 hSample->SetYTitle("Events");
7bce699b 138 hSample->SetDirectory(0);
a31ea3ce 139 sampleArray->AddAtAndExpand(hSample, sample);
e9c06036 140 }
a31ea3ce 141}
142
143//_____________________________________________________________________
144void AliFMDPedestalDA::AddSectorSummary(TObjArray* sectorArray,
145 UShort_t det,
146 Char_t ring,
147 UShort_t sec,
148 UShort_t nStr)
149{
150 TH1F* sumPed = new TH1F("Pedestals",
151 Form("Summary of pedestals in FMD%d%c[%02d]",
152 det, ring, sec),
153 nStr, -.5, nStr-.5);
154 sumPed->SetXTitle("Strip");
155 sumPed->SetYTitle("Pedestal [ADC]");
156 sumPed->SetDirectory(0);
157
158 TH1F* sumNoise = static_cast<TH1F*>(sumPed->Clone("Noise"));
159 sumNoise->SetYTitle("Noise [ADC]");
160 sumNoise->SetDirectory(0);
161
162 Int_t n = sectorArray->GetEntriesFast();
163 sectorArray->AddAtAndExpand(sumPed, n + kPedestalOffset - 1);
164 sectorArray->AddAtAndExpand(sumNoise, n + kNoiseOffset - 1);
3bd993ba 165}
166
167//_____________________________________________________________________
e9c06036 168void AliFMDPedestalDA::FillChannels(AliFMDDigit* digit)
169{
5cf05dbb 170 // Fill ADC values from a digit into the corresponding histogram.
171 //
172 // Parameters:
173 // digit Digit to fill ADC values for.
3bd993ba 174 UShort_t det = digit->Detector();
175 Char_t ring = digit->Ring();
176 UShort_t sec = digit->Sector();
177 UShort_t strip = digit->Strip();
15e37b0a 178
e9c06036 179 AliFMDParameters* pars = AliFMDParameters::Instance();
5cf05dbb 180 UInt_t samples = pars->GetSampleRate(det, ring, sec, strip);
7bce699b 181 for (UInt_t sample = 0; sample < samples; sample++) {
e9c06036 182 TH1S* hSample = GetChannel(det, ring, sec, strip, sample);
a31ea3ce 183 if (!hSample) continue;
184
e9c06036 185 hSample->Fill(digit->Count(sample));
186 }
7bce699b 187
3bd993ba 188}
189
190//_____________________________________________________________________
2a082c96 191void AliFMDPedestalDA::MakeSummary(UShort_t det, Char_t ring)
192{
8e23c82d 193 //Create summary hists for FMD pedestals
a31ea3ce 194 // std::cout << "Making summary for FMD" << det << ring << " ..."
195 // << std::endl;
2a082c96 196 switch (det) {
197 case 1:
198 fSummaryFMD1i = MakeSummaryHistogram("ped", "Pedestals", det, ring);
199 break;
200 case 2:
201 switch (ring) {
202 case 'I': case 'i':
203 fSummaryFMD2i = MakeSummaryHistogram("ped", "Pedestals", det, ring);
204 break;
205 case 'O': case 'o':
206 fSummaryFMD2o = MakeSummaryHistogram("ped", "Pedestals", det, ring);
207 break;
208 }
209 break;
210 case 3:
211 switch (ring) {
212 case 'I': case 'i':
213 fSummaryFMD3i = MakeSummaryHistogram("ped", "Pedestals", det, ring);
214 break;
215 case 'O': case 'o':
216 fSummaryFMD3o = MakeSummaryHistogram("ped", "Pedestals", det, ring);
217 break;
218 }
219 break;
220 }
221}
222
223//_____________________________________________________________________
3bd993ba 224void AliFMDPedestalDA::Analyse(UShort_t det,
e9c06036 225 Char_t ring,
3bd993ba 226 UShort_t sec,
5cf05dbb 227 UShort_t strip)
228{
229 // Analyse a strip. That is, compute the mean and spread of the ADC
230 // spectra for all strips. Also output on files the values.
231 //
232 // Parameters:
233 // det Detector
234 // ring Ring
235 // sec Sector
236 // strip Strip.
7bce699b 237 AliFMDParameters* pars = AliFMDParameters::Instance();
2a082c96 238 TH2* summary = 0;
239 switch (det) {
240 case 1: summary = fSummaryFMD1i; break;
241 case 2:
242 switch (ring) {
243 case 'I': summary = fSummaryFMD2i; break;
244 case 'O': summary = fSummaryFMD2o; break;
245 }
246 break;
247 case 3:
248 switch (ring) {
249 case 'I': summary = fSummaryFMD3i; break;
250 case 'O': summary = fSummaryFMD3o; break;
251 }
252 break;
253 }
a31ea3ce 254#if 0
2a082c96 255 static bool first = true;
256 if (summary && first) {
257 std::cout << "Filling summary " << summary->GetName() << std::endl;
258 first = false;
259 }
a31ea3ce 260#endif
762e54b7 261 // Float_t factor = pars->GetPedestalFactor();
5cf05dbb 262 UInt_t samples = pars->GetSampleRate(det, ring, sec, strip);
7bce699b 263 for (UShort_t sample = 0; sample < samples; sample++) {
3bd993ba 264
5cf05dbb 265 TH1S* hChannel = GetChannel(det, ring, sec, strip,sample);
a31ea3ce 266 if(!hChannel || hChannel->GetEntries() == 0) {
7bce699b 267 //AliWarning(Form("No entries for FMD%d%c, sector %d, strip %d",
268 // det,ring,sec,strip));
269 return;
e9c06036 270 }
f7f0b643 271
a828379a 272 AliDebug(50, Form("Fitting FMD%d%c[%02d,%03d] with %d entries",
273 det,ring,sec,strip, int(hChannel->GetEntries())));
7bce699b 274 TF1 fitFunc("fitFunc","gausn",0,300);
275 fitFunc.SetParameters(100,100,1);
276 hChannel->Fit("fitFunc","Q0+","",10,200);
277
278 Float_t mean = hChannel->GetMean();
279 Float_t rms = hChannel->GetRMS();
280
f7f0b643 281
f7f0b643 282
7bce699b 283 hChannel->GetXaxis()->SetRangeUser(mean-5*rms,mean+5*rms);
f7f0b643 284
7bce699b 285 mean = hChannel->GetMean();
286 rms = hChannel->GetRMS();
93519ec4 287
7bce699b 288
289 UShort_t ddl, board, altro, channel;
290 UShort_t timebin;
291
5cf05dbb 292 pars->Detector2Hardware(det,ring,sec,strip,sample,
293 ddl,board,altro,channel,timebin);
294 Int_t idx = HWIndex(ddl, board, altro, channel);
295 if (idx >= 0) {
296 fMinTimebin[idx] = TMath::Min(Short_t(timebin), fMinTimebin[idx]);
297 fMaxTimebin[idx] = TMath::Max(Short_t(timebin+1), fMaxTimebin[idx]);
298 }
7bce699b 299
5cf05dbb 300 std::ostream* zsFile = 0;
7bce699b 301 switch(det) {
5cf05dbb 302 case 1: zsFile = &fZSfileFMD1; break;
303 case 2: zsFile = &fZSfileFMD2; break;
304 case 3: zsFile = &fZSfileFMD3; break;
305 default: AliWarning("Unknown sample!"); break;
7bce699b 306
307 }
5cf05dbb 308 *zsFile << board << ','
309 << altro << ','
310 << channel << ','
311 << timebin << ','
312 << mean << ','
276b1261 313 << rms << "\n";
7bce699b 314
315 Float_t chi2ndf = 0;
15e37b0a 316
317
7bce699b 318 if(fitFunc.GetNDF())
319 chi2ndf = fitFunc.GetChisquare() / fitFunc.GetNDF();
320
5cf05dbb 321
15e37b0a 322 Int_t sampleToWrite = 2;
5cf05dbb 323 if (samples == 2) sampleToWrite = 1;
324 else if (samples < 2) sampleToWrite = 0;
15e37b0a 325
a31ea3ce 326 hChannel->GetXaxis()->SetRange(1,1024);
327
5cf05dbb 328 if(sample != sampleToWrite) continue;
15e37b0a 329
15e37b0a 330
5cf05dbb 331 fOutputFile << det << ','
332 << ring << ','
333 << sec << ','
334 << strip << ','
335 << mean << ','
336 << rms << ','
337 << fitFunc.GetParameter(1) << ','
338 << fitFunc.GetParameter(2) << ','
339 << chi2ndf <<"\n";
2a082c96 340
341 if (summary) {
342 Int_t bin = summary->FindBin(sec, strip);
343 summary->SetBinContent(bin, mean);
344 summary->SetBinError(bin, rms);
345 }
346
5cf05dbb 347 if(fSaveHistograms ) {
a31ea3ce 348 TH1F* sumPed = GetSectorSummary(det, ring, sec, true);
349 TH1F* sumNoise = GetSectorSummary(det, ring, sec, false);
350#if 0
5cf05dbb 351 gDirectory->cd(GetSectorPath(det, ring, sec, kTRUE));
352 TH1F* sumPed = dynamic_cast<TH1F*>(gDirectory->Get("Pedestals"));
353 TH1F* sumNoise = dynamic_cast<TH1F*>(gDirectory->Get("Noise"));
354 Int_t nStr = (ring == 'I' ? 512 : 256);
355 if (!sumPed) {
356 sumPed = new TH1F("Pedestals",
357 Form("Summary of pedestals in FMD%d%c[%02d]",
358 det, ring, sec),
359 nStr, -.5, nStr-.5);
360 sumPed->SetXTitle("Strip");
361 sumPed->SetYTitle("Pedestal [ADC]");
362 sumPed->SetDirectory(gDirectory);
363 }
364 if (!sumNoise) {
365 sumNoise = new TH1F("Noise",
366 Form("Summary of noise in FMD%d%c[%02d]",
7bce699b 367 det, ring, sec),
368 nStr, -.5, nStr-.5);
5cf05dbb 369 sumNoise->SetXTitle("Strip");
370 sumNoise->SetYTitle("Noise [ADC]");
7bce699b 371
5cf05dbb 372 sumNoise->SetDirectory(gDirectory);
7bce699b 373 }
a31ea3ce 374#endif
5cf05dbb 375 sumPed->SetBinContent(strip+1, mean);
376 sumPed->SetBinError(strip+1, rms);
377 sumNoise->SetBinContent(strip+1, rms);
a31ea3ce 378
379#if 0
5cf05dbb 380 if(sumNoise->GetEntries() == nStr)
381 sumNoise->Write(sumNoise->GetName(),TObject::kOverwrite);
382 if(sumPed->GetEntries() == nStr)
383 sumPed->Write(sumPed->GetName(),TObject::kOverwrite);
a31ea3ce 384#endif
385
5cf05dbb 386 fPedSummary.SetBinContent(fCurrentChannel,mean);
387
388 fNoiseSummary.SetBinContent(fCurrentChannel,rms);
389 fCurrentChannel++;
a31ea3ce 390
391#if 0
5cf05dbb 392 gDirectory->cd(GetStripPath(det, ring, sec, strip, kTRUE));
393 hChannel->GetXaxis()->SetRange(1,1024);
394
395 hChannel->Write();
a31ea3ce 396#endif
7bce699b 397 }
398 }
3bd993ba 399}
400
401//_____________________________________________________________________
f7f0b643 402void AliFMDPedestalDA::Terminate(TFile* diagFile)
403{
5cf05dbb 404 // Called at the end of a job. Fills in missing time-bins and
405 // closes output files
a31ea3ce 406 if(fSaveHistograms && diagFile) {
7bce699b 407 diagFile->cd();
408
409 fPedSummary.Write();
410 fNoiseSummary.Write();
411 }
5cf05dbb 412 AliFMDAltroMapping* map = AliFMDParameters::Instance()->GetAltroMap();
276b1261 413 for (Int_t i = 0; i < 3; i++) {
414 std::ofstream& out = (i == 0 ? fZSfileFMD1 :
415 i == 1 ? fZSfileFMD2 :
416 fZSfileFMD3);
417 if (out.is_open() && fSeenDetectors[i]) {
418 FillinTimebins(out, map->Detector2DDL(i+1));
419 }
408bf2b4 420 if (!fSeenDetectors[i]) {
421 TString n(Form("ddl%d.csv",3072+map->Detector2DDL(i+1)));
422 gSystem->Unlink(n.Data());
423 }
424 }
f7f0b643 425
5cf05dbb 426}
427
428//_____________________________________________________________________
7af3df7f 429void AliFMDPedestalDA::FillinTimebins(std::ofstream& out, UShort_t /*ddl*/)
5cf05dbb 430{
45cffd06 431 //
432 // Fill missing timebins
433 //
762e54b7 434#if 0
5cf05dbb 435 unsigned short boards[] = { 0x0, 0x1, 0x10, 0x11, 0xFFFF };
436 unsigned short* board = boards;
437 while ((*boards) != 0xFFFF) {
438 for (UShort_t altro = 0; altro < 3; altro++) {
439 for (UShort_t channel = 0; channel < 16; channel++) {
440 Int_t idx = HWIndex(ddl, *board, altro, channel);
441 if (idx < 0) {
442 AliWarning(Form("Invalid index for %4d/0x%02x/0x%x/0x%x: %d",
443 ddl, *board, altro, channel, idx));
444 continue;
445 }
446 Short_t min = fMinTimebin[idx];
447 Short_t max = fMaxTimebin[idx];
448
449 // Channel not seen at all.
450 if (min > 1023 || max < 0) continue;
451
452 out << "# Extra timebins for 0x" << std::hex
453 << board << ',' << altro << ',' << channel
454 << " got time-bins " << min << " to " << max-1
455 << std::dec << std::endl;
456
457 for (UShort_t t = 15; t < min; t++)
458 // Write a phony line
459 out << board << "," << altro << "," << channel << ","
460 << t << "," << 1023 << "," << 0 << std::endl;
461
462 for (UShort_t t = max; t < 1024; t++)
463 // Write a phony line
464 out << board << "," << altro << "," << channel << ","
465 << t << "," << 1023 << "," << 0 << std::endl;
466 } // channel loop
467 } // altro loop
468 } // board loop
469 // Write trailer, and close
762e54b7 470#endif
5cf05dbb 471 out.write("# EOF\n", 6);
472 out.close();
f7f0b643 473}
474
475//_____________________________________________________________________
e9c06036 476void AliFMDPedestalDA::WriteHeaderToFile()
477{
45cffd06 478 //
5cf05dbb 479 // Write headers to output files
45cffd06 480 //
80fdb9f3 481 AliFMDParameters* pars = AliFMDParameters::Instance();
482 fOutputFile.write(Form("# %s \n",pars->GetPedestalShuttleID()),13);
6cf6e7a0 483 TDatime now;
484 fOutputFile << "# This file created from run # " << fRunno
485 << " @ " << now.AsString() << std::endl;
f7f0b643 486 fOutputFile.write("# Detector, "
487 "Ring, "
488 "Sector, "
e9c06036 489 "Strip, "
e9c06036 490 "Pedestal, "
491 "Noise, "
492 "Mu, "
493 "Sigma, "
f7f0b643 494 "Chi2/NDF \n", 71);
5cf05dbb 495
496 std::ostream* zss[] = { &fZSfileFMD1, &fZSfileFMD2, &fZSfileFMD3, 0 };
6cf6e7a0 497 for (size_t i = 0; i < 3; i++) {
498 *(zss[i]) << "# FMD " << (i+1) << " pedestals \n"
5cf05dbb 499 << "# board, "
500 << "altro, "
501 << "channel, "
502 << "timebin, "
503 << "pedestal, "
762e54b7 504 << "noise\n";
6cf6e7a0 505 *(zss[i]) << "# This file created from run # " << fRunno
506 << " @ " << now.AsString() << std::endl;
507 }
3bd993ba 508}
509
510//_____________________________________________________________________
e9c06036 511TH1S* AliFMDPedestalDA::GetChannel(UShort_t det,
512 Char_t ring,
513 UShort_t sec,
7bce699b 514 UShort_t strip,
5cf05dbb 515 UInt_t sample)
e9c06036 516{
5cf05dbb 517 // Get the histogram corresponding to a strip sample.
518 //
519 // Parameters:
520 // det Detector
521 // ring Ring
522 // sec Sector
523 // strip Strip
524 // sample Sample
525 //
526 // Return:
527 // ADC spectra of a strip.
a31ea3ce 528 TObjArray* sampleArray = GetStripArray(det, ring, sec, strip);
529 if (!sampleArray) return 0;
5cf05dbb 530 TH1S* hSample = static_cast<TH1S*>(sampleArray->At(sample));
a31ea3ce 531 if (!hSample) {
532 AliErrorF("No channel histogram for FMD%d%c[%02d,%03d]_%d",
533 det, ring, sec, strip, sample);
534 sampleArray->ls();
535 AliErrorF("Path is %s <- %s <- %s <- %s",
536 sampleArray->GetName(),
537 GetSectorArray(det, ring, sec)->GetName(),
538 GetRingArray(det, ring)->GetName(),
539 GetDetectorArray(det)->GetName());
540
541 }
e9c06036 542 return hSample;
7bce699b 543
3bd993ba 544}
a31ea3ce 545//_____________________________________________________________________
546TH1F* AliFMDPedestalDA::GetSectorSummary(UShort_t det,
547 Char_t ring,
548 UShort_t sec,
549 Bool_t pedNotNoise)
550{
551 TObjArray* secArray = GetSectorArray(det, ring, sec);
552 Int_t n = secArray->GetEntriesFast();
553 Int_t i = n - (pedNotNoise ? kNoiseOffset : kPedestalOffset);
554 return static_cast<TH1F*>(secArray->At(i));
555}
93519ec4 556
3bd993ba 557//_____________________________________________________________________
558//
559//EOF
560//