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 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.
21 //____________________________________________________________________
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.
31 #include "AliFMDGainDA.h"
38 #include "TGraphErrors.h"
39 #include "AliFMDParameters.h"
41 //_____________________________________________________________________
42 ClassImp(AliFMDGainDA)
43 #if 0 // Do not delete - here to let Emacs indent properly
47 //_____________________________________________________________________
48 AliFMDGainDA::AliFMDGainDA()
54 fEventsPerChannel(16),
57 fNumberOfStripsPerChip(128)
59 fCurrentPulse.Reset(0);
60 fCurrentChannel.Reset(0);
61 fOutputFile.open("gains.csv");
62 fGainArray.SetOwner();
65 //_____________________________________________________________________
66 AliFMDGainDA::AliFMDGainDA(const AliFMDGainDA & gainDA)
67 : AliFMDBaseDA(gainDA),
68 fGainArray(gainDA.fGainArray),
69 //fPulseSize(gainDA.fPulseSize),
70 fHighPulse(gainDA.fHighPulse),
71 //fPulseLength(gainDA.fPulseLength),
72 fEventsPerChannel(gainDA.fEventsPerChannel),
73 fCurrentPulse(gainDA.fCurrentPulse),
74 fCurrentChannel(gainDA.fCurrentChannel),
75 fNumberOfStripsPerChip(gainDA.fNumberOfStripsPerChip)
77 fCurrentPulse.Reset(0);
78 fCurrentChannel.Reset(0);
81 //_____________________________________________________________________
82 AliFMDGainDA::~AliFMDGainDA()
86 //_____________________________________________________________________
87 void AliFMDGainDA::Init()
91 Int_t nEventsRequired = 0;
92 for(Int_t i=0;i<fEventsPerChannel.GetSize();i++)
94 Int_t nEvents = (fPulseLength.At(i)*fHighPulse) / fPulseSize.At(i);
95 fEventsPerChannel.AddAt(nEvents,i);
96 if(nEvents>nEventsRequired) nEventsRequired = nEvents * fNumberOfStripsPerChip;
100 std::cout<<nEventsRequired<<std::endl;
101 //8 pulser values * 128 strips * 100 samples
104 SetRequiredEvents(nEventsRequired);
106 TObjArray* ringArray;
107 TObjArray* sectorArray;
109 for(UShort_t det=1;det<=3;det++) {
110 detArray = new TObjArray();
111 detArray->SetOwner();
112 fGainArray.AddAtAndExpand(detArray,det);
113 for (UShort_t ir = 0; ir < 2; ir++) {
114 Char_t ring = (ir == 0 ? 'O' : 'I');
115 UShort_t nsec = (ir == 0 ? 40 : 20);
116 UShort_t nstr = (ir == 0 ? 2 : 4);
117 ringArray = new TObjArray();
118 ringArray->SetOwner();
119 detArray->AddAtAndExpand(ringArray,ir);
120 for(UShort_t sec =0; sec < nsec; sec++) {
121 sectorArray = new TObjArray();
122 sectorArray->SetOwner();
123 ringArray->AddAtAndExpand(sectorArray,sec);
124 for(UShort_t strip = 0; strip < nstr; strip++) {
125 TH1S* hChannel = new TH1S(Form("hFMD%d%c_%d_%d",det,ring,sec,strip),
126 Form("hFMD%d%c_%d_%d",det,ring,sec,strip),
128 hChannel->SetDirectory(0);
129 sectorArray->AddAtAndExpand(hChannel,strip);
136 //_____________________________________________________________________
137 void AliFMDGainDA::AddChannelContainer(TObjArray* sectorArray,
143 TGraphErrors* hChannel = new TGraphErrors();
144 hChannel->SetName(Form("FMD%d%c[%02d,%03d]", det, ring, sec, strip));
145 hChannel->SetTitle(Form("FMD%d%c[%02d,%03d] ADC vs DAC",
146 det, ring, sec, strip));
147 sectorArray->AddAtAndExpand(hChannel,strip);
150 //_____________________________________________________________________
151 void AliFMDGainDA::FillChannels(AliFMDDigit* digit) {
153 UShort_t det = digit->Detector();
154 Char_t ring = digit->Ring();
155 UShort_t sec = digit->Sector();
156 UShort_t strip = digit->Strip();
159 if(strip % fNumberOfStripsPerChip) return;
160 Int_t vaChip = strip / fNumberOfStripsPerChip;
161 TH1S* hChannel = GetChannelHistogram(det, ring, sec, vaChip);
162 hChannel->Fill(digit->Counts());
163 UpdatePulseAndADC(det,ring,sec,strip);
166 //_____________________________________________________________________
167 void AliFMDGainDA::Analyse(UShort_t det,
171 TGraphErrors* grChannel = GetChannel(det,ring,sec,strip);
172 if(!grChannel->GetN()) {
173 // AliWarning(Form("No entries for FMD%d%c, sector %d, strip %d",
174 // det, ring , sec, strip));
177 TF1 fitFunc("fitFunc","pol1",-10,280);
178 fitFunc.SetParameters(100,3);
179 grChannel->Fit("fitFunc","Q0+","",0,fHighPulse);
183 chi2ndf = fitFunc.GetChisquare() / fitFunc.GetNDF();
185 fOutputFile << det << ','
189 << fitFunc.GetParameter(1) << ','
190 << fitFunc.GetParError(1) << ','
194 if(fSaveHistograms) {
195 gDirectory->cd(GetSectorPath(det,ring, sec, kTRUE));
197 TH1F* summary = dynamic_cast<TH1F*>(gDirectory->Get("Summary"));
199 Int_t nStr = (ring == 'I' ? 512 : 256);
200 summary = new TH1F("Summary", Form("Summary of gains in FMD%d%c[%02d]",
203 summary->SetXTitle("Strip");
204 summary->SetYTitle("Gain [ADC/DAC]");
205 summary->SetDirectory(gDirectory);
207 summary->SetBinContent(strip+1, fitFunc.GetParameter(1));
208 summary->SetBinError(strip+1, fitFunc.GetParError(1));
210 gDirectory->cd(GetStripPath(det,ring,sec,strip, kTRUE));
211 grChannel->SetName(Form("FMD%d%c[%02d,%03d]",det,ring,sec,strip));
212 // grChannel->SetDirectory(gDirectory);
214 // grChannel->Write(Form("grFMD%d%c_%d_%d",det,ring,sec,strip));
218 //_____________________________________________________________________
219 void AliFMDGainDA::WriteHeaderToFile()
221 AliFMDParameters* pars = AliFMDParameters::Instance();
222 fOutputFile.write(Form("# %s \n",pars->GetGainShuttleID()),9);
223 fOutputFile.write("# Detector, "
233 //_____________________________________________________________________
234 TH1S* AliFMDGainDA::GetChannelHistogram(UShort_t det,
245 TObjArray* detArray = static_cast<TObjArray*>(fGainArray.At(det));
246 TObjArray* ringArray = static_cast<TObjArray*>(detArray->At(Ring));
247 TObjArray* secArray = static_cast<TObjArray*>(ringArray->At(sec));
248 TH1S* hChannel = static_cast<TH1S*>(secArray->At(strip));
253 //_____________________________________________________________________
254 TGraphErrors* AliFMDGainDA::GetChannel(UShort_t det,
259 UShort_t iring = (ring == 'O' ? 0 : 1);
260 TObjArray* detArray = static_cast<TObjArray*>(fDetectorArray.At(det));
261 TObjArray* ringArray = static_cast<TObjArray*>(detArray->At(iring));
262 TObjArray* secArray = static_cast<TObjArray*>(ringArray->At(sec));
263 TGraphErrors* hChannel = static_cast<TGraphErrors*>(secArray->At(strip));
268 //_____________________________________________________________________
269 void AliFMDGainDA::UpdatePulseAndADC(UShort_t det,
275 AliFMDParameters* pars = AliFMDParameters::Instance();
276 UInt_t ddl, board,chip,ch;
277 pars->Detector2Hardware(det,ring,sec,strip,ddl,board,chip,ch);
278 Int_t halfring = GetHalfringIndex(det,ring,board%16);
279 if(GetCurrentEvent()> (fNumberOfStripsPerChip*fEventsPerChannel.At(halfring)))
281 if(strip % fNumberOfStripsPerChip) return;
282 if(((GetCurrentEvent()) % fPulseLength.At(halfring)) && GetCurrentEvent() > 0) return;
284 Int_t vaChip = strip/fNumberOfStripsPerChip;
285 TH1S* hChannel = GetChannelHistogram(det,ring,sec,vaChip);
287 if(!hChannel->GetEntries()) {
288 AliWarning(Form("No entries for FMD%d%c, sector %d, strip %d",
289 det, ring , sec, strip));
292 Double_t mean = hChannel->GetMean();
293 Double_t rms = hChannel->GetRMS();
294 Double_t pulse = Double_t(fCurrentPulse.At(halfring)) * fPulseSize.At(halfring);
295 Int_t firstBin = hChannel->GetXaxis()->GetFirst();
296 Int_t lastBin = hChannel->GetXaxis()->GetLast();
297 hChannel->GetXaxis()->SetRangeUser(mean-4*rms,mean+4*rms);
299 mean = hChannel->GetMean();
300 rms = hChannel->GetRMS();
302 hChannel->GetXaxis()->SetRange(firstBin,lastBin);
304 Int_t channelNumber = strip + (GetCurrentEvent()-1)/((fPulseLength.At(halfring)*fHighPulse)/fPulseSize.At(halfring));
306 TGraphErrors* channel = GetChannel(det,ring,sec,channelNumber);
308 channel->SetPoint(fCurrentPulse.At(halfring),pulse,mean);
309 channel->SetPointError(fCurrentPulse.At(halfring),0,rms);
311 if(fSaveHistograms) {
312 gDirectory->cd(GetStripPath(det,ring,sec,channelNumber));
313 hChannel->Write(Form("%s_pulse_%03d",hChannel->GetName(),(Int_t)pulse));
324 //_____________________________________________________________________
325 void AliFMDGainDA::ResetPulseAndUpdateChannel()
327 //for(Int_t i=0; i<fCurrentPulse.GetSize();i++)
328 fCurrentPulse.Reset(0);
331 //_____________________________________________________________________
332 void AliFMDGainDA::FinishEvent()
334 for(Int_t i = 0; i<fPulseLength.GetSize();i++) {
335 if(GetCurrentEvent()>0 && (GetCurrentEvent() % fPulseLength.At(i) == 0))
336 fCurrentPulse.AddAt(fCurrentPulse.At(i)+1,i);
338 if(GetCurrentEvent()>0 && (GetCurrentEvent()) % fEventsPerChannel.At(i) == 0)
339 fCurrentPulse.AddAt(0,i);
342 //_____________________________________________________________________