]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDGainDA.cxx
Make use of list of active detectors from GRP to avoid trying misalignment for inacti...
[u/mrichter/AliRoot.git] / FMD / AliFMDGainDA.cxx
CommitLineData
f631f26d 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 AliFMDGainDA.cxx
17 @author Hans Hjersing Dalsgaard <canute@nbi.dk>
18 @date Mon Mar 13 13:46:05 2008
19 @brief Derived class for the pulse gain detector algorithm.
20*/
cf291b42 21//____________________________________________________________________
22//
23// This class contains the implementation of the gain detector
24// algorithms (DA) for the FMD. The data is collected in histograms
25// that are reset for each pulse length after the mean and standard
26// deviation are put into a TGraphErrors object. After a certain
27// number of pulses (usually 8) the graph is fitted to a straight
28// line. The gain is then slope of this line as it combines the known
29// pulse and the response of the detector.
30//
f631f26d 31#include "AliFMDGainDA.h"
32#include "iostream"
33#include "fstream"
34#include "AliLog.h"
35#include "TF1.h"
36#include "TH1.h"
37#include "TMath.h"
38#include "TGraphErrors.h"
39#include "AliFMDParameters.h"
40
41//_____________________________________________________________________
42ClassImp(AliFMDGainDA)
cf291b42 43#if 0 // Do not delete - here to let Emacs indent properly
44;
45#endif
f631f26d 46
47//_____________________________________________________________________
cf291b42 48AliFMDGainDA::AliFMDGainDA()
49 : AliFMDBaseDA(),
50 fGainArray(),
cf291b42 51 fHighPulse(256),
22017a7e 52 fEventsPerChannel(10),
53 fCurrentPulse(10),
54 fCurrentChannel(10),
3bae5d02 55 fNumberOfStripsPerChip(128),
56 fSummaryGains("GainsSummary","Summary of gains",51200,0,51200),
f14ede67 57 fCurrentSummaryStrip(1)
f631f26d 58{
427e8f99 59 fCurrentPulse.Reset(0);
60 fCurrentChannel.Reset(0);
f631f26d 61 fOutputFile.open("gains.csv");
cf291b42 62 fGainArray.SetOwner();
f631f26d 63}
64
65//_____________________________________________________________________
cf291b42 66AliFMDGainDA::AliFMDGainDA(const AliFMDGainDA & gainDA)
67 : AliFMDBaseDA(gainDA),
68 fGainArray(gainDA.fGainArray),
cf291b42 69 fHighPulse(gainDA.fHighPulse),
cf291b42 70 fEventsPerChannel(gainDA.fEventsPerChannel),
71 fCurrentPulse(gainDA.fCurrentPulse),
72 fCurrentChannel(gainDA.fCurrentChannel),
3bae5d02 73 fNumberOfStripsPerChip(gainDA.fNumberOfStripsPerChip),
74 fSummaryGains(gainDA.fSummaryGains),
75 fCurrentSummaryStrip(gainDA.fCurrentSummaryStrip)
cf291b42 76{
427e8f99 77 fCurrentPulse.Reset(0);
78 fCurrentChannel.Reset(0);
f631f26d 79}
80
81//_____________________________________________________________________
cf291b42 82AliFMDGainDA::~AliFMDGainDA()
83{
f631f26d 84}
85
86//_____________________________________________________________________
cf291b42 87void AliFMDGainDA::Init()
88{
f631f26d 89
427e8f99 90
91 Int_t nEventsRequired = 0;
22017a7e 92
93 //for(UShort_t det=1; det<=3;det++) {
94 // UShort_t firstring = (det == 1 ? 1 : 0);
95 // for(UShort_t iring = firstring; iring <=1;iring++) {
96 // Char_t ring = (iring == 1 ? 'I' : 'O');
97 // for(UShort_t board =0 ; board <=1; board++) {
98 // Int_t idx = GetHalfringIndex(det,ring,board);
99 for(Int_t idx = 0;idx<fEventsPerChannel.GetSize();idx++)
427e8f99 100 {
22017a7e 101
102 Int_t nEvents = 0;
103 if(fPulseSize.At(idx))
104 nEvents = (fPulseLength.At(idx)*fHighPulse) / fPulseSize.At(idx);
105 fEventsPerChannel.AddAt(nEvents,idx);
427e8f99 106 if(nEvents>nEventsRequired) nEventsRequired = nEvents * fNumberOfStripsPerChip;
107
108 }
22017a7e 109 //}
110 // }
54b167db 111
cf291b42 112 //8 pulser values * 128 strips * 100 samples
427e8f99 113
114
115 SetRequiredEvents(nEventsRequired);
22017a7e 116
f631f26d 117 TObjArray* detArray;
118 TObjArray* ringArray;
119 TObjArray* sectorArray;
120
121 for(UShort_t det=1;det<=3;det++) {
122 detArray = new TObjArray();
123 detArray->SetOwner();
124 fGainArray.AddAtAndExpand(detArray,det);
125 for (UShort_t ir = 0; ir < 2; ir++) {
126 Char_t ring = (ir == 0 ? 'O' : 'I');
127 UShort_t nsec = (ir == 0 ? 40 : 20);
128 UShort_t nstr = (ir == 0 ? 2 : 4);
129 ringArray = new TObjArray();
130 ringArray->SetOwner();
131 detArray->AddAtAndExpand(ringArray,ir);
132 for(UShort_t sec =0; sec < nsec; sec++) {
133 sectorArray = new TObjArray();
134 sectorArray->SetOwner();
135 ringArray->AddAtAndExpand(sectorArray,sec);
136 for(UShort_t strip = 0; strip < nstr; strip++) {
cf291b42 137 TH1S* hChannel = new TH1S(Form("hFMD%d%c_%d_%d",det,ring,sec,strip),
138 Form("hFMD%d%c_%d_%d",det,ring,sec,strip),
139 1024,0,1023);
f631f26d 140 hChannel->SetDirectory(0);
141 sectorArray->AddAtAndExpand(hChannel,strip);
142 }
143 }
144 }
145 }
146}
147
148//_____________________________________________________________________
149void AliFMDGainDA::AddChannelContainer(TObjArray* sectorArray,
cf291b42 150 UShort_t det ,
151 Char_t ring,
f631f26d 152 UShort_t sec,
cf291b42 153 UShort_t strip)
154{
f631f26d 155 TGraphErrors* hChannel = new TGraphErrors();
cf291b42 156 hChannel->SetName(Form("FMD%d%c[%02d,%03d]", det, ring, sec, strip));
157 hChannel->SetTitle(Form("FMD%d%c[%02d,%03d] ADC vs DAC",
158 det, ring, sec, strip));
f631f26d 159 sectorArray->AddAtAndExpand(hChannel,strip);
160}
161
162//_____________________________________________________________________
163void AliFMDGainDA::FillChannels(AliFMDDigit* digit) {
164
165 UShort_t det = digit->Detector();
166 Char_t ring = digit->Ring();
167 UShort_t sec = digit->Sector();
168 UShort_t strip = digit->Strip();
169
22017a7e 170 //Strip is always seen as the first in a VA chip. All other strips are junk
cf291b42 171 if(strip % fNumberOfStripsPerChip) return;
172 Int_t vaChip = strip / fNumberOfStripsPerChip;
173 TH1S* hChannel = GetChannelHistogram(det, ring, sec, vaChip);
22017a7e 174
f631f26d 175 hChannel->Fill(digit->Counts());
176 UpdatePulseAndADC(det,ring,sec,strip);
177}
178
179//_____________________________________________________________________
180void AliFMDGainDA::Analyse(UShort_t det,
e9c06036 181 Char_t ring,
f631f26d 182 UShort_t sec,
183 UShort_t strip) {
184 TGraphErrors* grChannel = GetChannel(det,ring,sec,strip);
185 if(!grChannel->GetN()) {
cf291b42 186 // AliWarning(Form("No entries for FMD%d%c, sector %d, strip %d",
187 // det, ring , sec, strip));
f631f26d 188 return;
189 }
9c958f2b 190 TF1 fitFunc("fitFunc","pol1",-10,280);
191 fitFunc.SetParameters(100,3);
e9c06036 192 grChannel->Fit("fitFunc","Q0+","",0,fHighPulse);
f7f0b643 193
4fa150a7 194 Float_t gain = -1;
195 Float_t error = -1;
196 Float_t chi2ndf = -1;
197 if((fitFunc.GetParameter(1)) == (fitFunc.GetParameter(1))) {
198 gain = fitFunc.GetParameter(1);
199 error = fitFunc.GetParError(1);
200 if(fitFunc.GetNDF())
201 chi2ndf = fitFunc.GetChisquare() / fitFunc.GetNDF();
202 }
203
f7f0b643 204 fOutputFile << det << ','
205 << ring << ','
206 << sec << ','
207 << strip << ','
4fa150a7 208 << gain << ','
209 << error << ','
f631f26d 210 << chi2ndf <<"\n";
211
22017a7e 212 //due to RCU trouble, first strips on VAs are excluded
213 if(strip%128 != 0) {
214
215 fSummaryGains.SetBinContent(fCurrentSummaryStrip,fitFunc.GetParameter(1));
216 fSummaryGains.SetBinError(fCurrentSummaryStrip,fitFunc.GetParError(1));
217
218 fCurrentSummaryStrip++;
219 }
f631f26d 220 if(fSaveHistograms) {
e9c06036 221 gDirectory->cd(GetSectorPath(det,ring, sec, kTRUE));
222
223 TH1F* summary = dynamic_cast<TH1F*>(gDirectory->Get("Summary"));
224 if (!summary) {
225 Int_t nStr = (ring == 'I' ? 512 : 256);
226 summary = new TH1F("Summary", Form("Summary of gains in FMD%d%c[%02d]",
227 det, ring, sec),
228 nStr, -.5, nStr-.5);
229 summary->SetXTitle("Strip");
230 summary->SetYTitle("Gain [ADC/DAC]");
231 summary->SetDirectory(gDirectory);
232 }
233 summary->SetBinContent(strip+1, fitFunc.GetParameter(1));
234 summary->SetBinError(strip+1, fitFunc.GetParError(1));
235
236 gDirectory->cd(GetStripPath(det,ring,sec,strip, kTRUE));
237 grChannel->SetName(Form("FMD%d%c[%02d,%03d]",det,ring,sec,strip));
238 // grChannel->SetDirectory(gDirectory);
239 grChannel->Write();
240 // grChannel->Write(Form("grFMD%d%c_%d_%d",det,ring,sec,strip));
241 }
f631f26d 242}
243
244//_____________________________________________________________________
3bae5d02 245void AliFMDGainDA::Terminate(TFile* diagFile)
246{
247 diagFile->cd();
248 fSummaryGains.Write();
249}
250
251//_____________________________________________________________________
e9c06036 252void AliFMDGainDA::WriteHeaderToFile()
253{
9c958f2b 254 AliFMDParameters* pars = AliFMDParameters::Instance();
255 fOutputFile.write(Form("# %s \n",pars->GetGainShuttleID()),9);
f7f0b643 256 fOutputFile.write("# Detector, "
257 "Ring, "
258 "Sector, "
e9c06036 259 "Strip, "
260 "Gain, "
261 "Error, "
f7f0b643 262 "Chi2/NDF \n",56);
f631f26d 263
264}
265
266//_____________________________________________________________________
267TH1S* AliFMDGainDA::GetChannelHistogram(UShort_t det,
e9c06036 268 Char_t ring,
f631f26d 269 UShort_t sec,
e9c06036 270 UShort_t strip)
271{
f631f26d 272
273 UShort_t Ring = 1;
274 if(ring == 'O')
275 Ring = 0;
276
277
278 TObjArray* detArray = static_cast<TObjArray*>(fGainArray.At(det));
279 TObjArray* ringArray = static_cast<TObjArray*>(detArray->At(Ring));
280 TObjArray* secArray = static_cast<TObjArray*>(ringArray->At(sec));
281 TH1S* hChannel = static_cast<TH1S*>(secArray->At(strip));
282
283 return hChannel;
284}
285
286//_____________________________________________________________________
cf291b42 287TGraphErrors* AliFMDGainDA::GetChannel(UShort_t det,
e9c06036 288 Char_t ring,
cf291b42 289 UShort_t sec,
e9c06036 290 UShort_t strip)
291{
cf291b42 292 UShort_t iring = (ring == 'O' ? 0 : 1);
293 TObjArray* detArray = static_cast<TObjArray*>(fDetectorArray.At(det));
294 TObjArray* ringArray = static_cast<TObjArray*>(detArray->At(iring));
295 TObjArray* secArray = static_cast<TObjArray*>(ringArray->At(sec));
296 TGraphErrors* hChannel = static_cast<TGraphErrors*>(secArray->At(strip));
f631f26d 297
298 return hChannel;
299}
300
301//_____________________________________________________________________
cf291b42 302void AliFMDGainDA::UpdatePulseAndADC(UShort_t det,
303 Char_t ring,
304 UShort_t sec,
305 UShort_t strip)
306{
f7f0b643 307
427e8f99 308 AliFMDParameters* pars = AliFMDParameters::Instance();
309 UInt_t ddl, board,chip,ch;
310 pars->Detector2Hardware(det,ring,sec,strip,ddl,board,chip,ch);
22017a7e 311 Int_t halfring = GetHalfringIndex(det,ring,board/16);
312
f7f0b643 313 if(GetCurrentEvent()> (fNumberOfStripsPerChip*fEventsPerChannel.At(halfring)))
aea2699c 314 return;
cf291b42 315 if(strip % fNumberOfStripsPerChip) return;
427e8f99 316 if(((GetCurrentEvent()) % fPulseLength.At(halfring)) && GetCurrentEvent() > 0) return;
317
cf291b42 318 Int_t vaChip = strip/fNumberOfStripsPerChip;
319 TH1S* hChannel = GetChannelHistogram(det,ring,sec,vaChip);
f631f26d 320
321 if(!hChannel->GetEntries()) {
cf291b42 322 AliWarning(Form("No entries for FMD%d%c, sector %d, strip %d",
323 det, ring , sec, strip));
f631f26d 324 return;
325 }
326 Double_t mean = hChannel->GetMean();
327 Double_t rms = hChannel->GetRMS();
427e8f99 328 Double_t pulse = Double_t(fCurrentPulse.At(halfring)) * fPulseSize.At(halfring);
cf291b42 329 Int_t firstBin = hChannel->GetXaxis()->GetFirst();
330 Int_t lastBin = hChannel->GetXaxis()->GetLast();
9c958f2b 331 hChannel->GetXaxis()->SetRangeUser(mean-4*rms,mean+4*rms);
f631f26d 332
cf291b42 333 mean = hChannel->GetMean();
334 rms = hChannel->GetRMS();
efd39294 335
336 hChannel->GetXaxis()->SetRange(firstBin,lastBin);
337
427e8f99 338 Int_t channelNumber = strip + (GetCurrentEvent()-1)/((fPulseLength.At(halfring)*fHighPulse)/fPulseSize.At(halfring));
f631f26d 339
340 TGraphErrors* channel = GetChannel(det,ring,sec,channelNumber);
341
427e8f99 342 channel->SetPoint(fCurrentPulse.At(halfring),pulse,mean);
343 channel->SetPointError(fCurrentPulse.At(halfring),0,rms);
f631f26d 344
345 if(fSaveHistograms) {
f7f0b643 346 gDirectory->cd(GetStripPath(det,ring,sec,channelNumber));
347 hChannel->Write(Form("%s_pulse_%03d",hChannel->GetName(),(Int_t)pulse));
348
f631f26d 349 }
22017a7e 350
f631f26d 351 hChannel->Reset();
352
353}
354
355//_____________________________________________________________________
cf291b42 356void AliFMDGainDA::ResetPulseAndUpdateChannel()
357{
427e8f99 358 fCurrentPulse.Reset(0);
f631f26d 359}
360
361//_____________________________________________________________________
cf291b42 362void AliFMDGainDA::FinishEvent()
363{
22017a7e 364 for(UShort_t det=1; det<=3;det++) {
365 UShort_t firstring = (det == 1 ? 1 : 0);
366 for(UShort_t iring = firstring; iring <=1;iring++) {
367 Char_t ring = (iring == 1 ? 'I' : 'O');
368 for(UShort_t board =0 ; board <=1; board++) {
369 Int_t idx = GetHalfringIndex(det,ring,board);
370
371 if( !fPulseLength.At(idx) || !fEventsPerChannel.At(idx))
372 continue;
373 if(GetCurrentEvent()>0 && ((GetCurrentEvent() % fPulseLength.At(idx)) == 0))
374 fCurrentPulse.AddAt(fCurrentPulse.At(idx)+1,idx);
375
376 if(GetCurrentEvent()>0 && ((GetCurrentEvent()) % fEventsPerChannel.At(idx)) == 0)
377 fCurrentPulse.AddAt(0,idx);
378 }
379 }
427e8f99 380 }
f631f26d 381}
382//_____________________________________________________________________
383//
384//EOF
385//