1 /**************************************************************************
2 * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
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.
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.
30 #include "AliFMDPedestalDA.h"
31 #include "AliFMDAltroMapping.h"
42 //_____________________________________________________________________
43 ClassImp(AliFMDPedestalDA)
45 //_____________________________________________________________________
46 AliFMDPedestalDA::AliFMDPedestalDA()
49 fPedSummary("PedestalSummary","pedestals",51200,0,51200),
50 fNoiseSummary("NoiseSummary","noise",51200,0,51200),
54 fMinTimebin(3 * 4 * 3 * 16), // 3 ddls, 4 FECs, 3 Altros, 16 channels
55 fMaxTimebin(3 * 4 * 3 * 16), // 3 ddls, 4 FECs, 3 Altros, 16 channels
62 // Default constructor
63 Rotate("peds.csv", 3);
64 fOutputFile.open("peds.csv");
65 Rotate("ddl3072.csv", 10);
66 fZSfileFMD1.open("ddl3072.csv");
67 Rotate("ddl3073.csv", 10);
68 fZSfileFMD2.open("ddl3073.csv");
69 Rotate("ddl3074.csv", 10);
70 fZSfileFMD3.open("ddl3074.csv");
73 //_____________________________________________________________________
74 AliFMDPedestalDA::AliFMDPedestalDA(const AliFMDPedestalDA & pedDA) :
77 fPedSummary("PedestalSummary","pedestals",51200,0,51200),
78 fNoiseSummary("NoiseSummary","noise",51200,0,51200),
82 fMinTimebin(pedDA.fMinTimebin),
83 fMaxTimebin(pedDA.fMaxTimebin),
84 fSummaryFMD1i(pedDA.fSummaryFMD1i),
85 fSummaryFMD2i(pedDA.fSummaryFMD2i),
86 fSummaryFMD2o(pedDA.fSummaryFMD2o),
87 fSummaryFMD3i(pedDA.fSummaryFMD3i),
88 fSummaryFMD3o(pedDA.fSummaryFMD3o)
93 //_____________________________________________________________________
94 AliFMDPedestalDA::~AliFMDPedestalDA()
99 //_____________________________________________________________________
100 void AliFMDPedestalDA::Init()
103 SetRequiredEvents(1000);
104 fMinTimebin.Reset(1024);
105 fMaxTimebin.Reset(-1);
110 //_____________________________________________________________________
111 void AliFMDPedestalDA::AddChannelContainer(TObjArray* sectorArray,
117 // Add a channel to the containers.
120 // sectorArray Array of sectors
125 AliFMDParameters* pars = AliFMDParameters::Instance();
126 UInt_t samples = pars->GetSampleRate(det, ring, sec, strip);
127 TObjArray* sampleArray = new TObjArray(samples);
128 sampleArray->SetOwner();
129 for (UInt_t sample = 0; sample < samples; sample++) {
130 TH1S* hSample = new TH1S(Form("FMD%d%c[%02d,03%d]_%d",
131 det,ring,sec,strip,sample),
132 Form("FMD%d%c[%02d,%03%d]_%d",
135 hSample->SetXTitle("ADC");
136 hSample->SetYTitle("Events");
137 hSample->SetDirectory(0);
138 sampleArray->AddAt(hSample, sample);
140 sectorArray->AddAtAndExpand(sampleArray, strip);
143 //_____________________________________________________________________
144 void AliFMDPedestalDA::FillChannels(AliFMDDigit* digit)
146 // Fill ADC values from a digit into the corresponding histogram.
149 // digit Digit to fill ADC values for.
150 UShort_t det = digit->Detector();
151 Char_t ring = digit->Ring();
152 UShort_t sec = digit->Sector();
153 UShort_t strip = digit->Strip();
155 AliFMDParameters* pars = AliFMDParameters::Instance();
156 UInt_t samples = pars->GetSampleRate(det, ring, sec, strip);
157 for (UInt_t sample = 0; sample < samples; sample++) {
158 TH1S* hSample = GetChannel(det, ring, sec, strip, sample);
159 hSample->Fill(digit->Count(sample));
164 //_____________________________________________________________________
165 void AliFMDPedestalDA::MakeSummary(UShort_t det, Char_t ring)
167 std::cout << "Making summary for FMD" << det << ring << " ..." << std::endl;
170 fSummaryFMD1i = MakeSummaryHistogram("ped", "Pedestals", det, ring);
175 fSummaryFMD2i = MakeSummaryHistogram("ped", "Pedestals", det, ring);
178 fSummaryFMD2o = MakeSummaryHistogram("ped", "Pedestals", det, ring);
185 fSummaryFMD3i = MakeSummaryHistogram("ped", "Pedestals", det, ring);
188 fSummaryFMD3o = MakeSummaryHistogram("ped", "Pedestals", det, ring);
195 //_____________________________________________________________________
196 void AliFMDPedestalDA::Analyse(UShort_t det,
201 // Analyse a strip. That is, compute the mean and spread of the ADC
202 // spectra for all strips. Also output on files the values.
209 AliFMDParameters* pars = AliFMDParameters::Instance();
212 case 1: summary = fSummaryFMD1i; break;
215 case 'I': summary = fSummaryFMD2i; break;
216 case 'O': summary = fSummaryFMD2o; break;
221 case 'I': summary = fSummaryFMD3i; break;
222 case 'O': summary = fSummaryFMD3o; break;
226 static bool first = true;
227 if (summary && first) {
228 std::cout << "Filling summary " << summary->GetName() << std::endl;
232 // Float_t factor = pars->GetPedestalFactor();
233 UInt_t samples = pars->GetSampleRate(det, ring, sec, strip);
234 for (UShort_t sample = 0; sample < samples; sample++) {
236 TH1S* hChannel = GetChannel(det, ring, sec, strip,sample);
237 if(hChannel->GetEntries() == 0) {
238 //AliWarning(Form("No entries for FMD%d%c, sector %d, strip %d",
239 // det,ring,sec,strip));
243 AliDebug(50, Form("Fitting FMD%d%c_%d_%d with %d entries",
244 det,ring,sec,strip, hChannel->GetEntries()));
245 TF1 fitFunc("fitFunc","gausn",0,300);
246 fitFunc.SetParameters(100,100,1);
247 hChannel->Fit("fitFunc","Q0+","",10,200);
249 Float_t mean = hChannel->GetMean();
250 Float_t rms = hChannel->GetRMS();
254 hChannel->GetXaxis()->SetRangeUser(mean-5*rms,mean+5*rms);
256 mean = hChannel->GetMean();
257 rms = hChannel->GetRMS();
260 UShort_t ddl, board, altro, channel;
263 pars->Detector2Hardware(det,ring,sec,strip,sample,
264 ddl,board,altro,channel,timebin);
265 Int_t idx = HWIndex(ddl, board, altro, channel);
267 fMinTimebin[idx] = TMath::Min(Short_t(timebin), fMinTimebin[idx]);
268 fMaxTimebin[idx] = TMath::Max(Short_t(timebin+1), fMaxTimebin[idx]);
271 std::ostream* zsFile = 0;
273 case 1: zsFile = &fZSfileFMD1; break;
274 case 2: zsFile = &fZSfileFMD2; break;
275 case 3: zsFile = &fZSfileFMD3; break;
276 default: AliWarning("Unknown sample!"); break;
279 *zsFile << board << ','
290 chi2ndf = fitFunc.GetChisquare() / fitFunc.GetNDF();
293 Int_t sampleToWrite = 2;
294 if (samples == 2) sampleToWrite = 1;
295 else if (samples < 2) sampleToWrite = 0;
297 if(sample != sampleToWrite) continue;
300 fOutputFile << det << ','
306 << fitFunc.GetParameter(1) << ','
307 << fitFunc.GetParameter(2) << ','
311 Int_t bin = summary->FindBin(sec, strip);
312 summary->SetBinContent(bin, mean);
313 summary->SetBinError(bin, rms);
316 if(fSaveHistograms ) {
317 gDirectory->cd(GetSectorPath(det, ring, sec, kTRUE));
318 TH1F* sumPed = dynamic_cast<TH1F*>(gDirectory->Get("Pedestals"));
319 TH1F* sumNoise = dynamic_cast<TH1F*>(gDirectory->Get("Noise"));
320 Int_t nStr = (ring == 'I' ? 512 : 256);
322 sumPed = new TH1F("Pedestals",
323 Form("Summary of pedestals in FMD%d%c[%02d]",
326 sumPed->SetXTitle("Strip");
327 sumPed->SetYTitle("Pedestal [ADC]");
328 sumPed->SetDirectory(gDirectory);
331 sumNoise = new TH1F("Noise",
332 Form("Summary of noise in FMD%d%c[%02d]",
335 sumNoise->SetXTitle("Strip");
336 sumNoise->SetYTitle("Noise [ADC]");
338 sumNoise->SetDirectory(gDirectory);
340 sumPed->SetBinContent(strip+1, mean);
341 sumPed->SetBinError(strip+1, rms);
342 sumNoise->SetBinContent(strip+1, rms);
344 if(sumNoise->GetEntries() == nStr)
345 sumNoise->Write(sumNoise->GetName(),TObject::kOverwrite);
346 if(sumPed->GetEntries() == nStr)
347 sumPed->Write(sumPed->GetName(),TObject::kOverwrite);
349 fPedSummary.SetBinContent(fCurrentChannel,mean);
351 fNoiseSummary.SetBinContent(fCurrentChannel,rms);
354 gDirectory->cd(GetStripPath(det, ring, sec, strip, kTRUE));
355 hChannel->GetXaxis()->SetRange(1,1024);
362 //_____________________________________________________________________
363 void AliFMDPedestalDA::Terminate(TFile* diagFile)
365 // Called at the end of a job. Fills in missing time-bins and
366 // closes output files
367 if(fSaveHistograms) {
371 fNoiseSummary.Write();
373 AliFMDAltroMapping* map = AliFMDParameters::Instance()->GetAltroMap();
374 for (Int_t i = 0; i < 3; i++) {
375 std::ofstream& out = (i == 0 ? fZSfileFMD1 :
376 i == 1 ? fZSfileFMD2 :
378 if (out.is_open() && fSeenDetectors[i]) {
379 FillinTimebins(out, map->Detector2DDL(i+1));
381 if (!fSeenDetectors[i]) {
382 TString n(Form("ddl%d.csv",3072+map->Detector2DDL(i+1)));
383 gSystem->Unlink(n.Data());
389 //_____________________________________________________________________
390 void AliFMDPedestalDA::FillinTimebins(std::ofstream& out, UShort_t /*ddl*/)
393 unsigned short boards[] = { 0x0, 0x1, 0x10, 0x11, 0xFFFF };
394 unsigned short* board = boards;
395 while ((*boards) != 0xFFFF) {
396 for (UShort_t altro = 0; altro < 3; altro++) {
397 for (UShort_t channel = 0; channel < 16; channel++) {
398 Int_t idx = HWIndex(ddl, *board, altro, channel);
400 AliWarning(Form("Invalid index for %4d/0x%02x/0x%x/0x%x: %d",
401 ddl, *board, altro, channel, idx));
404 Short_t min = fMinTimebin[idx];
405 Short_t max = fMaxTimebin[idx];
407 // Channel not seen at all.
408 if (min > 1023 || max < 0) continue;
410 out << "# Extra timebins for 0x" << std::hex
411 << board << ',' << altro << ',' << channel
412 << " got time-bins " << min << " to " << max-1
413 << std::dec << std::endl;
415 for (UShort_t t = 15; t < min; t++)
416 // Write a phony line
417 out << board << "," << altro << "," << channel << ","
418 << t << "," << 1023 << "," << 0 << std::endl;
420 for (UShort_t t = max; t < 1024; t++)
421 // Write a phony line
422 out << board << "," << altro << "," << channel << ","
423 << t << "," << 1023 << "," << 0 << std::endl;
427 // Write trailer, and close
429 out.write("# EOF\n", 6);
433 //_____________________________________________________________________
434 void AliFMDPedestalDA::WriteHeaderToFile()
436 // Write headers to output files
437 AliFMDParameters* pars = AliFMDParameters::Instance();
438 fOutputFile.write(Form("# %s \n",pars->GetPedestalShuttleID()),13);
440 fOutputFile << "# This file created from run # " << fRunno
441 << " @ " << now.AsString() << std::endl;
442 fOutputFile.write("# Detector, "
452 std::ostream* zss[] = { &fZSfileFMD1, &fZSfileFMD2, &fZSfileFMD3, 0 };
453 for (size_t i = 0; i < 3; i++) {
454 *(zss[i]) << "# FMD " << (i+1) << " pedestals \n"
461 *(zss[i]) << "# This file created from run # " << fRunno
462 << " @ " << now.AsString() << std::endl;
466 //_____________________________________________________________________
467 TH1S* AliFMDPedestalDA::GetChannel(UShort_t det,
473 // Get the histogram corresponding to a strip sample.
483 // ADC spectra of a strip.
484 UShort_t iring = (ring == 'O' ? 0 : 1);
485 TObjArray* detArray = static_cast<TObjArray*>(fDetectorArray.At(det));
486 TObjArray* ringArray = static_cast<TObjArray*>(detArray->At(iring));
487 TObjArray* secArray = static_cast<TObjArray*>(ringArray->At(sec));
488 TObjArray* sampleArray = static_cast<TObjArray*>(secArray->At(strip));
489 TH1S* hSample = static_cast<TH1S*>(sampleArray->At(sample));
494 //_____________________________________________________________________