]>
Commit | Line | Data |
---|---|---|
892226be | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, 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 | ||
17 | /////////////////////////////////////////////////////////////////////////////// | |
18 | // // | |
19 | // Class providing the calculation of derived quantities (mean,rms,fits,...) // | |
20 | // of calibration entries // | |
21 | /* | |
22 | ||
23 | ||
24 | */ | |
25 | //////////////////////////////////////////////////////////////////////////////// | |
26 | ||
27 | #include <TMath.h> | |
28 | #include <TVectorT.h> | |
29 | #include <TObjArray.h> | |
30 | #include <TGraph.h> | |
7390f655 | 31 | #include <TFile.h> |
32 | #include <TDirectory.h> | |
892226be | 33 | |
34 | #include <AliDCSSensorArray.h> | |
35 | #include <AliDCSSensor.h> | |
36 | #include "AliTPCcalibDB.h" | |
37 | #include "AliTPCCalPad.h" | |
38 | #include "AliTPCCalROC.h" | |
39 | #include "AliTPCROC.h" | |
40 | #include "AliTPCmapper.h" | |
41 | #include "AliTPCParam.h" | |
6e7d7dc4 | 42 | #include "AliTPCCalibRaw.h" |
892226be | 43 | |
44 | #include "AliTPCcalibDButil.h" | |
45 | ||
46 | ClassImp(AliTPCcalibDButil) | |
47 | AliTPCcalibDButil::AliTPCcalibDButil() : | |
48 | TObject(), | |
49 | fCalibDB(AliTPCcalibDB::Instance()), | |
50 | fPadNoise(0x0), | |
51 | fPedestals(0x0), | |
52 | fPulserTmean(0x0), | |
53 | fPulserTrms(0x0), | |
54 | fPulserQmean(0x0), | |
55 | fPulserOutlier(new AliTPCCalPad("PulserOutliers","PulserOutliers")), | |
56 | fCETmean(0x0), | |
57 | fCETrms(0x0), | |
58 | fCEQmean(0x0), | |
59 | fALTROMasked(0x0), | |
6e7d7dc4 | 60 | fCalibRaw(0x0), |
7390f655 | 61 | fRefPadNoise(0x0), |
62 | fRefPedestals(0x0), | |
63 | fRefPulserTmean(0x0), | |
64 | fRefPulserTrms(0x0), | |
65 | fRefPulserQmean(0x0), | |
66 | fRefPulserOutlier(new AliTPCCalPad("RefPulserOutliers","RefPulserOutliers")), | |
67 | fRefCETmean(0x0), | |
68 | fRefCETrms(0x0), | |
69 | fRefCEQmean(0x0), | |
70 | fRefALTROMasked(0x0), | |
71 | fRefCalibRaw(0x0), | |
892226be | 72 | fGoofieArray(0x0), |
73 | fMapper(new AliTPCmapper(0x0)), | |
74 | fNpulserOutliers(-1), | |
7390f655 | 75 | fIrocTimeOffset(0), |
892226be | 76 | fCETmaxLimitAbs(1.5), |
77 | fPulTmaxLimitAbs(1.5), | |
78 | fPulQmaxLimitAbs(5), | |
79 | fPulQminLimit(11) | |
80 | { | |
81 | // | |
82 | // Default ctor | |
83 | // | |
84 | } | |
85 | //_____________________________________________________________________________________ | |
86 | AliTPCcalibDButil::~AliTPCcalibDButil() | |
87 | { | |
88 | // | |
89 | // dtor | |
90 | // | |
91 | delete fPulserOutlier; | |
7390f655 | 92 | delete fRefPulserOutlier; |
892226be | 93 | delete fMapper; |
7390f655 | 94 | if (fRefPadNoise) delete fRefPadNoise; |
95 | if (fRefPedestals) delete fRefPedestals; | |
96 | if (fRefPulserTmean) delete fRefPulserTmean; | |
97 | if (fRefPulserTrms) delete fRefPulserTrms; | |
98 | if (fRefPulserQmean) delete fRefPulserQmean; | |
99 | if (fRefCETmean) delete fRefCETmean; | |
100 | if (fRefCETrms) delete fRefCETrms; | |
101 | if (fRefCEQmean) delete fRefCEQmean; | |
102 | if (fRefALTROMasked) delete fRefALTROMasked; | |
103 | if (fRefCalibRaw) delete fRefCalibRaw; | |
104 | ||
892226be | 105 | } |
106 | //_____________________________________________________________________________________ | |
107 | void AliTPCcalibDButil::UpdateFromCalibDB() | |
108 | { | |
109 | // | |
110 | // Update pointers from calibDB | |
111 | // | |
112 | fPadNoise=fCalibDB->GetPadNoise(); | |
113 | fPedestals=fCalibDB->GetPedestals(); | |
114 | fPulserTmean=fCalibDB->GetPulserTmean(); | |
115 | fPulserTrms=fCalibDB->GetPulserTrms(); | |
116 | fPulserQmean=fCalibDB->GetPulserQmean(); | |
117 | fCETmean=fCalibDB->GetCETmean(); | |
118 | fCETrms=fCalibDB->GetCETrms(); | |
119 | fCEQmean=fCalibDB->GetCEQmean(); | |
120 | fALTROMasked=fCalibDB->GetALTROMasked(); | |
121 | fGoofieArray=fCalibDB->GetGoofieSensors(fCalibDB->GetRun()); | |
6e7d7dc4 | 122 | fCalibRaw=fCalibDB->GetCalibRaw(); |
892226be | 123 | UpdatePulserOutlierMap(); |
124 | } | |
125 | //_____________________________________________________________________________________ | |
7390f655 | 126 | void AliTPCcalibDButil::ProcessCEdata(const char* fitFormula, TVectorD &fitResultsA, TVectorD &fitResultsC, |
127 | Int_t &noutliersCE, AliTPCCalPad *outCE) | |
892226be | 128 | { |
129 | // | |
130 | // Process the CE data for this run | |
131 | // the return TVectorD arrays contian the results of the fit | |
132 | // noutliersCE contains the number of pads marked as outliers, | |
133 | // not including masked and edge pads | |
134 | // | |
135 | ||
136 | //retrieve CE and ALTRO data | |
137 | if (!fCETmean){ | |
138 | TString fitString(fitFormula); | |
139 | fitString.ReplaceAll("++","#"); | |
140 | Int_t ndim=fitString.CountChar('#')+2; | |
141 | fitResultsA.ResizeTo(ndim); | |
142 | fitResultsC.ResizeTo(ndim); | |
143 | fitResultsA.Zero(); | |
144 | fitResultsC.Zero(); | |
145 | noutliersCE=-1; | |
146 | return; | |
147 | } | |
148 | noutliersCE=0; | |
149 | //create outlier map | |
7390f655 | 150 | AliTPCCalPad *out=0; |
151 | if (outCE) out=outCE; | |
152 | else out=new AliTPCCalPad("outCE","outCE"); | |
892226be | 153 | AliTPCCalROC *rocMasked=0x0; |
154 | //loop over all channels | |
155 | for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){ | |
156 | AliTPCCalROC *rocData=fCETmean->GetCalROC(iroc); | |
157 | if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(iroc); | |
7390f655 | 158 | AliTPCCalROC *rocOut=out->GetCalROC(iroc); |
6e7d7dc4 | 159 | if (!rocData) { |
160 | noutliersCE+=AliTPCROC::Instance()->GetNChannels(iroc); | |
7390f655 | 161 | rocOut->Add(1.); |
6e7d7dc4 | 162 | continue; |
163 | } | |
892226be | 164 | //add time offset to IROCs |
165 | if (iroc<AliTPCROC::Instance()->GetNInnerSector()) | |
166 | rocData->Add(fIrocTimeOffset); | |
167 | //select outliers | |
168 | UInt_t nrows=rocData->GetNrows(); | |
169 | for (UInt_t irow=0;irow<nrows;++irow){ | |
170 | UInt_t npads=rocData->GetNPads(irow); | |
171 | for (UInt_t ipad=0;ipad<npads;++ipad){ | |
7390f655 | 172 | rocOut->SetValue(irow,ipad,0); |
892226be | 173 | //exclude masked pads |
174 | if (rocMasked && rocMasked->GetValue(irow,ipad)) { | |
7390f655 | 175 | rocOut->SetValue(irow,ipad,1); |
892226be | 176 | continue; |
177 | } | |
178 | //exclude edge pads | |
7390f655 | 179 | if (ipad==0||ipad==npads-1) rocOut->SetValue(irow,ipad,1); |
180 | Float_t valTmean=rocData->GetValue(irow,ipad); | |
892226be | 181 | //exclude values that are exactly 0 |
182 | if (valTmean==0) { | |
7390f655 | 183 | rocOut->SetValue(irow,ipad,1); |
892226be | 184 | ++noutliersCE; |
185 | } | |
186 | // exclude channels with too large variations | |
187 | if (TMath::Abs(valTmean)>fCETmaxLimitAbs) { | |
7390f655 | 188 | rocOut->SetValue(irow,ipad,1); |
892226be | 189 | ++noutliersCE; |
190 | } | |
191 | } | |
192 | } | |
193 | } | |
194 | //perform fit | |
195 | TMatrixD dummy; | |
196 | Float_t chi2A,chi2C; | |
7390f655 | 197 | fCETmean->GlobalSidesFit(out,fitFormula,fitResultsA,fitResultsC,dummy,dummy,chi2A,chi2C); |
198 | if (!outCE) delete out; | |
892226be | 199 | } |
200 | //_____________________________________________________________________________________ | |
201 | void AliTPCcalibDButil::ProcessCEgraphs(TVectorD &vecTEntries, TVectorD &vecTMean, TVectorD &vecTRMS, TVectorD &vecTMedian, | |
202 | TVectorD &vecQEntries, TVectorD &vecQMean, TVectorD &vecQRMS, TVectorD &vecQMedian, | |
203 | Float_t &driftTimeA, Float_t &driftTimeC ) | |
204 | { | |
205 | // | |
206 | // Calculate statistical information from the CE graphs for drift time and charge | |
207 | // | |
208 | ||
209 | //reset arrays | |
210 | vecTEntries.ResizeTo(72); | |
211 | vecTMean.ResizeTo(72); | |
212 | vecTRMS.ResizeTo(72); | |
213 | vecTMedian.ResizeTo(72); | |
214 | vecQEntries.ResizeTo(72); | |
215 | vecQMean.ResizeTo(72); | |
216 | vecQRMS.ResizeTo(72); | |
217 | vecQMedian.ResizeTo(72); | |
218 | vecTEntries.Zero(); | |
219 | vecTMean.Zero(); | |
220 | vecTRMS.Zero(); | |
221 | vecTMedian.Zero(); | |
222 | vecQEntries.Zero(); | |
223 | vecQMean.Zero(); | |
224 | vecQRMS.Zero(); | |
225 | vecQMedian.Zero(); | |
226 | driftTimeA=0; | |
227 | driftTimeC=0; | |
228 | TObjArray *arrT=fCalibDB->GetCErocTtime(); | |
229 | TObjArray *arrQ=fCalibDB->GetCErocQtime(); | |
230 | if (arrT){ | |
231 | for (Int_t isec=0;isec<74;++isec){ | |
232 | TGraph *gr=(TGraph*)arrT->At(isec); | |
233 | if (!gr) continue; | |
234 | TVectorD values; | |
235 | Int_t npoints = gr->GetN(); | |
236 | values.ResizeTo(npoints); | |
237 | Int_t nused =0; | |
6e7d7dc4 | 238 | //skip first points, theres always some problems with finding the CE position |
239 | for (Int_t ipoint=4; ipoint<npoints; ipoint++){ | |
240 | if (gr->GetY()[ipoint]>500 && gr->GetY()[ipoint]<1020 ){ | |
892226be | 241 | values[nused]=gr->GetY()[ipoint]; |
242 | nused++; | |
243 | } | |
244 | } | |
245 | // | |
246 | if (isec<72) vecTEntries[isec]= nused; | |
247 | if (nused>1){ | |
248 | if (isec<72){ | |
249 | vecTMedian[isec] = TMath::Median(nused,values.GetMatrixArray()); | |
250 | vecTMean[isec] = TMath::Mean(nused,values.GetMatrixArray()); | |
251 | vecTRMS[isec] = TMath::RMS(nused,values.GetMatrixArray()); | |
252 | } else if (isec==72){ | |
253 | driftTimeA=TMath::Median(nused,values.GetMatrixArray()); | |
254 | } else if (isec==73){ | |
255 | driftTimeC=TMath::Median(nused,values.GetMatrixArray()); | |
256 | } | |
257 | } | |
258 | } | |
259 | } | |
260 | if (arrQ){ | |
6e7d7dc4 | 261 | for (Int_t isec=0;isec<arrQ->GetEntriesFast();++isec){ |
892226be | 262 | TGraph *gr=(TGraph*)arrQ->At(isec); |
263 | if (!gr) continue; | |
264 | TVectorD values; | |
265 | Int_t npoints = gr->GetN(); | |
266 | values.ResizeTo(npoints); | |
267 | Int_t nused =0; | |
268 | for (Int_t ipoint=0; ipoint<npoints; ipoint++){ | |
269 | if (gr->GetY()[ipoint]>500 && gr->GetY()[ipoint]<1000 ){ | |
270 | values[nused]=gr->GetY()[ipoint]; | |
271 | nused++; | |
272 | } | |
273 | } | |
274 | // | |
6e7d7dc4 | 275 | vecQEntries[isec]= nused; |
892226be | 276 | if (nused>1){ |
277 | vecQMedian[isec] = TMath::Median(nused,values.GetMatrixArray()); | |
278 | vecQMean[isec] = TMath::Mean(nused,values.GetMatrixArray()); | |
279 | vecQRMS[isec] = TMath::RMS(nused,values.GetMatrixArray()); | |
280 | } | |
281 | } | |
282 | } | |
283 | } | |
284 | ||
285 | //_____________________________________________________________________________________ | |
286 | void AliTPCcalibDButil::ProcessNoiseData(TVectorD &vNoiseMean, TVectorD &vNoiseMeanSenRegions, | |
287 | TVectorD &vNoiseRMS, TVectorD &vNoiseRMSSenRegions, | |
288 | Int_t &nonMaskedZero) | |
289 | { | |
290 | // | |
291 | // process noise data | |
292 | // vNoiseMean/RMS contains the Mean/RMS noise of the complete TPC [0], IROCs only [1], | |
293 | // OROCs small pads [2] and OROCs large pads [3] | |
294 | // vNoiseMean/RMSsenRegions constains the same information, but only for the sensitive regions (edge pads, corners, IROC spot) | |
295 | // nonMaskedZero contains the number of pads which show zero noise and were not masked. This might indicate an error | |
296 | // | |
297 | ||
298 | //set proper size and reset | |
299 | const UInt_t infoSize=4; | |
300 | vNoiseMean.ResizeTo(infoSize); | |
301 | vNoiseMeanSenRegions.ResizeTo(infoSize); | |
302 | vNoiseRMS.ResizeTo(infoSize); | |
303 | vNoiseRMSSenRegions.ResizeTo(infoSize); | |
304 | vNoiseMean.Zero(); | |
305 | vNoiseMeanSenRegions.Zero(); | |
306 | vNoiseRMS.Zero(); | |
307 | vNoiseRMSSenRegions.Zero(); | |
308 | nonMaskedZero=0; | |
309 | //counters | |
310 | TVectorD c(infoSize); | |
311 | TVectorD cs(infoSize); | |
312 | //tpc parameters | |
313 | AliTPCParam par; | |
314 | par.Update(); | |
315 | //retrieve noise and ALTRO data | |
316 | if (!fPadNoise) return; | |
317 | AliTPCCalROC *rocMasked=0x0; | |
318 | //create IROC, OROC1, OROC2 and sensitive region masks | |
319 | for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){ | |
320 | AliTPCCalROC *noiseROC=fPadNoise->GetCalROC(isec); | |
321 | if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec); | |
322 | UInt_t nrows=noiseROC->GetNrows(); | |
323 | for (UInt_t irow=0;irow<nrows;++irow){ | |
324 | UInt_t npads=noiseROC->GetNPads(irow); | |
325 | for (UInt_t ipad=0;ipad<npads;++ipad){ | |
326 | //don't use masked channels; | |
327 | if (rocMasked && rocMasked->GetValue(irow,ipad)) continue; | |
328 | Float_t noiseVal=noiseROC->GetValue(irow,ipad); | |
329 | //check if noise==0 | |
330 | if (noiseVal==0) { | |
331 | ++nonMaskedZero; | |
332 | continue; | |
333 | } | |
334 | //check for nan | |
335 | if ( !(noiseVal<10000000) ){ | |
336 | printf ("Warning: nan detected in (sec,row,pad - val): %02d,%02d,%03d - %.1f\n",isec,irow,ipad,noiseVal); | |
337 | continue; | |
338 | } | |
339 | Int_t cpad=(Int_t)ipad-(Int_t)npads/2; | |
340 | Int_t masksen=1; // sensitive pards are not masked (0) | |
341 | if (ipad<2||npads-ipad-1<2) masksen=0; //don't mask edge pads (sensitive) | |
342 | if (isec<AliTPCROC::Instance()->GetNInnerSector()){ | |
343 | //IROCs | |
344 | if (irow>19&&irow<46){ | |
345 | if (TMath::Abs(cpad)<7) masksen=0; //IROC spot | |
346 | } | |
347 | Int_t type=1; | |
348 | vNoiseMean[type]+=noiseVal; | |
349 | vNoiseRMS[type]+=noiseVal*noiseVal; | |
350 | ++c[type]; | |
351 | if (!masksen){ | |
352 | vNoiseMeanSenRegions[type]+=noiseVal; | |
353 | vNoiseRMSSenRegions[type]+=noiseVal*noiseVal; | |
354 | ++cs[type]; | |
355 | } | |
356 | } else { | |
357 | //OROCs | |
358 | //define sensive regions | |
359 | if ((nrows-irow-1)<3) masksen=0; //last three rows in OROCs are sensitive | |
360 | if ( irow>75 ){ | |
361 | Int_t padEdge=(Int_t)TMath::Min(ipad,npads-ipad); | |
362 | if (padEdge<((((Int_t)irow-76)/4+1))*2) masksen=0; //OROC outer corners are sensitive | |
363 | } | |
364 | if ((Int_t)irow<par.GetNRowUp1()){ | |
365 | //OROC1 | |
366 | Int_t type=2; | |
367 | vNoiseMean[type]+=noiseVal; | |
368 | vNoiseRMS[type]+=noiseVal*noiseVal; | |
369 | ++c[type]; | |
370 | if (!masksen){ | |
371 | vNoiseMeanSenRegions[type]+=noiseVal; | |
372 | vNoiseRMSSenRegions[type]+=noiseVal*noiseVal; | |
373 | ++cs[type]; | |
374 | } | |
375 | }else{ | |
376 | //OROC2 | |
377 | Int_t type=3; | |
378 | vNoiseMean[type]+=noiseVal; | |
379 | vNoiseRMS[type]+=noiseVal*noiseVal; | |
380 | ++c[type]; | |
381 | if (!masksen){ | |
382 | vNoiseMeanSenRegions[type]+=noiseVal; | |
383 | vNoiseRMSSenRegions[type]+=noiseVal*noiseVal; | |
384 | ++cs[type]; | |
385 | } | |
386 | } | |
387 | } | |
388 | //whole tpc | |
389 | Int_t type=0; | |
390 | vNoiseMean[type]+=noiseVal; | |
391 | vNoiseRMS[type]+=noiseVal*noiseVal; | |
392 | ++c[type]; | |
393 | if (!masksen){ | |
394 | vNoiseMeanSenRegions[type]+=noiseVal; | |
395 | vNoiseRMSSenRegions[type]+=noiseVal*noiseVal; | |
396 | ++cs[type]; | |
397 | } | |
398 | }//end loop pads | |
399 | }//end loop rows | |
400 | }//end loop sectors (rocs) | |
401 | ||
402 | //calculate mean and RMS | |
403 | const Double_t verySmall=0.0000000001; | |
404 | for (UInt_t i=0;i<infoSize;++i){ | |
405 | Double_t mean=0; | |
406 | Double_t rms=0; | |
407 | Double_t meanSen=0; | |
408 | Double_t rmsSen=0; | |
409 | ||
410 | if (c[i]>verySmall){ | |
411 | // printf ("i: %d - m: %.3f, c: %.0f, r: %.3f\n",i,vNoiseMean[i],c[i],vNoiseRMS[i]); | |
412 | mean=vNoiseMean[i]/c[i]; | |
413 | rms=vNoiseRMS[i]; | |
414 | rms=TMath::Sqrt(TMath::Abs(rms/c[i]-mean*mean)); | |
415 | } | |
416 | vNoiseMean[i]=mean; | |
417 | vNoiseRMS[i]=rms; | |
418 | ||
419 | if (cs[i]>verySmall){ | |
420 | meanSen=vNoiseMeanSenRegions[i]/cs[i]; | |
421 | rmsSen=vNoiseRMSSenRegions[i]; | |
422 | rmsSen=TMath::Sqrt(TMath::Abs(rmsSen/cs[i]-meanSen*meanSen)); | |
423 | } | |
424 | vNoiseMeanSenRegions[i]=meanSen; | |
425 | vNoiseRMSSenRegions[i]=rmsSen; | |
426 | } | |
427 | } | |
428 | ||
429 | //_____________________________________________________________________________________ | |
430 | void AliTPCcalibDButil::ProcessPulser(TVectorD &vMeanTime) | |
431 | { | |
432 | // | |
433 | // Process the Pulser information | |
434 | // vMeanTime: pulser mean time position in IROC-A, IROC-C, OROC-A, OROC-C | |
435 | // | |
436 | ||
437 | const UInt_t infoSize=4; | |
438 | //reset counters to error number | |
439 | vMeanTime.ResizeTo(infoSize); | |
440 | vMeanTime.Zero(); | |
441 | //counter | |
442 | TVectorD c(infoSize); | |
443 | //retrieve pulser and ALTRO data | |
444 | if (!fPulserTmean) return; | |
445 | // | |
446 | //get Outliers | |
447 | AliTPCCalROC *rocOut=0x0; | |
448 | for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){ | |
449 | AliTPCCalROC *tmeanROC=fPulserTmean->GetCalROC(isec); | |
450 | if (!tmeanROC) continue; | |
451 | rocOut=fPulserOutlier->GetCalROC(isec); | |
452 | UInt_t nchannels=tmeanROC->GetNchannels(); | |
453 | for (UInt_t ichannel=0;ichannel<nchannels;++ichannel){ | |
454 | if (rocOut && rocOut->GetValue(ichannel)) continue; | |
455 | Float_t val=tmeanROC->GetValue(ichannel); | |
456 | Int_t type=isec/18; | |
457 | vMeanTime[type]+=val; | |
458 | ++c[type]; | |
459 | } | |
460 | } | |
461 | //calculate mean | |
462 | for (UInt_t itype=0; itype<infoSize; ++itype){ | |
463 | if (c[itype]>0) vMeanTime[itype]/=c[itype]; | |
464 | else vMeanTime[itype]=0; | |
465 | } | |
466 | } | |
467 | //_____________________________________________________________________________________ | |
468 | void AliTPCcalibDButil::ProcessALTROConfig(Int_t &nMasked) | |
469 | { | |
470 | // | |
471 | // Get Values from ALTRO configuration data | |
472 | // | |
473 | nMasked=-1; | |
474 | if (!fALTROMasked) return; | |
475 | nMasked=0; | |
476 | for (Int_t isec=0;isec<fALTROMasked->kNsec; ++isec){ | |
477 | AliTPCCalROC *rocMasked=fALTROMasked->GetCalROC(isec); | |
478 | for (UInt_t ichannel=0; ichannel<rocMasked->GetNchannels();++ichannel){ | |
479 | if (rocMasked->GetValue(ichannel)) ++nMasked; | |
480 | } | |
481 | } | |
482 | } | |
483 | //_____________________________________________________________________________________ | |
484 | void AliTPCcalibDButil::ProcessGoofie(TVectorD & vecEntries, TVectorD & vecMedian, TVectorD &vecMean, TVectorD &vecRMS) | |
485 | { | |
486 | // | |
487 | // Proces Goofie values, return statistical information of the currently set goofieArray | |
488 | // The meaning of the entries are given below | |
489 | /* | |
490 | 1 TPC_ANODE_I_A00_STAT | |
491 | 2 TPC_DVM_CO2 | |
492 | 3 TPC_DVM_DriftVelocity | |
493 | 4 TPC_DVM_FCageHV | |
494 | 5 TPC_DVM_GainFar | |
495 | 6 TPC_DVM_GainNear | |
496 | 7 TPC_DVM_N2 | |
497 | 8 TPC_DVM_NumberOfSparks | |
498 | 9 TPC_DVM_PeakAreaFar | |
499 | 10 TPC_DVM_PeakAreaNear | |
500 | 11 TPC_DVM_PeakPosFar | |
501 | 12 TPC_DVM_PeakPosNear | |
502 | 13 TPC_DVM_PickupHV | |
503 | 14 TPC_DVM_Pressure | |
504 | 15 TPC_DVM_T1_Over_P | |
505 | 16 TPC_DVM_T2_Over_P | |
506 | 17 TPC_DVM_T_Over_P | |
507 | 18 TPC_DVM_TemperatureS1 | |
508 | */ | |
509 | if (!fGoofieArray){ | |
510 | Int_t nsensors=19; | |
511 | vecEntries.ResizeTo(nsensors); | |
512 | vecMedian.ResizeTo(nsensors); | |
513 | vecMean.ResizeTo(nsensors); | |
514 | vecRMS.ResizeTo(nsensors); | |
515 | vecEntries.Zero(); | |
516 | vecMedian.Zero(); | |
517 | vecMean.Zero(); | |
518 | vecRMS.Zero(); | |
519 | return; | |
520 | } | |
521 | Double_t kEpsilon=0.0000000001; | |
522 | Double_t kBig=100000000000.; | |
523 | Int_t nsensors = fGoofieArray->NumSensors(); | |
524 | vecEntries.ResizeTo(nsensors); | |
525 | vecMedian.ResizeTo(nsensors); | |
526 | vecMean.ResizeTo(nsensors); | |
527 | vecRMS.ResizeTo(nsensors); | |
528 | TVectorF values; | |
529 | for (Int_t isensor=0; isensor<fGoofieArray->NumSensors();isensor++){ | |
530 | AliDCSSensor *gsensor = fGoofieArray->GetSensor(isensor); | |
531 | if (gsensor && gsensor->GetGraph()){ | |
532 | Int_t npoints = gsensor->GetGraph()->GetN(); | |
533 | // filter zeroes | |
534 | values.ResizeTo(npoints); | |
535 | Int_t nused =0; | |
536 | for (Int_t ipoint=0; ipoint<npoints; ipoint++){ | |
537 | if (TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])>kEpsilon && | |
538 | TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])<kBig ){ | |
539 | values[nused]=gsensor->GetGraph()->GetY()[ipoint]; | |
540 | nused++; | |
541 | } | |
542 | } | |
543 | // | |
544 | vecEntries[isensor]= nused; | |
545 | if (nused>1){ | |
546 | vecMedian[isensor] = TMath::Median(nused,values.GetMatrixArray()); | |
547 | vecMean[isensor] = TMath::Mean(nused,values.GetMatrixArray()); | |
548 | vecRMS[isensor] = TMath::RMS(nused,values.GetMatrixArray()); | |
549 | } | |
550 | } | |
551 | } | |
552 | } | |
7390f655 | 553 | //_____________________________________________________________________________________ |
554 | void AliTPCcalibDButil::ProcessPedestalVariations(TVectorF &pedestalDeviations) | |
555 | { | |
556 | // | |
557 | // check the variations of the pedestal data to the reference pedestal data | |
558 | // thresholds are 0.5, 1.0, 1.5 and 2 timebins respectively. | |
559 | // | |
560 | const Int_t npar=4; | |
561 | TVectorF vThres(npar); //thresholds | |
562 | Int_t nActive=0; //number of active channels | |
563 | ||
564 | //reset and set thresholds | |
565 | pedestalDeviations.ResizeTo(npar); | |
566 | for (Int_t i=0;i<npar;++i){ | |
567 | pedestalDeviations.GetMatrixArray()[i]=0; | |
568 | vThres.GetMatrixArray()[i]=(i+1)*.5; | |
569 | } | |
570 | //check all needed data is available | |
571 | if (!fRefPedestals || !fPedestals || !fALTROMasked || !fRefALTROMasked) return; | |
572 | //loop over all channels | |
573 | for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){ | |
574 | AliTPCCalROC *pROC=fPedestals->GetCalROC(isec); | |
575 | AliTPCCalROC *pRefROC=fRefPedestals->GetCalROC(isec); | |
576 | AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec); | |
577 | AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec); | |
578 | UInt_t nrows=mROC->GetNrows(); | |
579 | for (UInt_t irow=0;irow<nrows;++irow){ | |
580 | UInt_t npads=mROC->GetNPads(irow); | |
581 | for (UInt_t ipad=0;ipad<npads;++ipad){ | |
582 | //don't use masked channels; | |
583 | if (mROC ->GetValue(irow,ipad)) continue; | |
584 | if (mRefROC->GetValue(irow,ipad)) continue; | |
585 | Float_t deviation=TMath::Abs(pROC->GetValue(irow,ipad)-pRefROC->GetValue(irow,ipad)); | |
586 | for (Int_t i=0;i<npar;++i){ | |
587 | if (deviation>vThres[i]) | |
588 | ++pedestalDeviations.GetMatrixArray()[i]; | |
589 | } | |
590 | ++nActive; | |
591 | }//end ipad | |
592 | }//ind irow | |
593 | }//end isec | |
594 | if (nActive>0){ | |
595 | for (Int_t i=0;i<npar;++i){ | |
596 | pedestalDeviations.GetMatrixArray()[i]/=nActive; | |
597 | } | |
598 | } | |
599 | } | |
600 | //_____________________________________________________________________________________ | |
601 | void AliTPCcalibDButil::ProcessNoiseVariations(TVectorF &noiseDeviations) | |
602 | { | |
603 | // | |
604 | // check the variations of the noise data to the reference noise data | |
605 | // thresholds are 5, 10, 15 and 20 percent respectively. | |
606 | // | |
607 | const Int_t npar=4; | |
608 | TVectorF vThres(npar); //thresholds | |
609 | Int_t nActive=0; //number of active channels | |
610 | ||
611 | //reset and set thresholds | |
612 | noiseDeviations.ResizeTo(npar); | |
613 | for (Int_t i=0;i<npar;++i){ | |
614 | noiseDeviations.GetMatrixArray()[i]=0; | |
615 | vThres.GetMatrixArray()[i]=(i+1)*.05; | |
616 | } | |
617 | //check all needed data is available | |
618 | if (!fRefPadNoise || !fPadNoise || !fALTROMasked || !fRefALTROMasked) return; | |
619 | //loop over all channels | |
620 | for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){ | |
621 | AliTPCCalROC *nROC=fPadNoise->GetCalROC(isec); | |
622 | AliTPCCalROC *nRefROC=fRefPadNoise->GetCalROC(isec); | |
623 | AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec); | |
624 | AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec); | |
625 | UInt_t nrows=mROC->GetNrows(); | |
626 | for (UInt_t irow=0;irow<nrows;++irow){ | |
627 | UInt_t npads=mROC->GetNPads(irow); | |
628 | for (UInt_t ipad=0;ipad<npads;++ipad){ | |
629 | //don't use masked channels; | |
630 | if (mROC ->GetValue(irow,ipad)) continue; | |
631 | if (mRefROC->GetValue(irow,ipad)) continue; | |
632 | Float_t deviation=(nROC->GetValue(irow,ipad)/nRefROC->GetValue(irow,ipad))-1; | |
633 | for (Int_t i=0;i<npar;++i){ | |
634 | if (deviation>vThres[i]) | |
635 | ++noiseDeviations.GetMatrixArray()[i]; | |
636 | } | |
637 | ++nActive; | |
638 | }//end ipad | |
639 | }//ind irow | |
640 | }//end isec | |
641 | if (nActive>0){ | |
642 | for (Int_t i=0;i<npar;++i){ | |
643 | noiseDeviations.GetMatrixArray()[i]/=nActive; | |
644 | } | |
645 | } | |
646 | } | |
647 | //_____________________________________________________________________________________ | |
648 | void AliTPCcalibDButil::ProcessPulserVariations(TVectorF &pulserQdeviations, Float_t &varQMean, | |
649 | Int_t &npadsOutOneTB, Int_t &npadsOffAdd) | |
650 | { | |
651 | // | |
652 | // check the variations of the pulserQmean data to the reference pulserQmean data: pulserQdeviations | |
653 | // thresholds are .5, 1, 5 and 10 percent respectively. | |
654 | // | |
655 | // | |
656 | const Int_t npar=4; | |
657 | TVectorF vThres(npar); //thresholds | |
658 | Int_t nActive=0; //number of active channels | |
659 | ||
660 | //reset and set thresholds | |
661 | pulserQdeviations.ResizeTo(npar); | |
662 | for (Int_t i=0;i<npar;++i){ | |
663 | pulserQdeviations.GetMatrixArray()[i]=0; | |
664 | } | |
665 | npadsOutOneTB=0; | |
666 | npadsOffAdd=0; | |
667 | varQMean=0; | |
668 | vThres.GetMatrixArray()[0]=.005; | |
669 | vThres.GetMatrixArray()[1]=.01; | |
670 | vThres.GetMatrixArray()[2]=.05; | |
671 | vThres.GetMatrixArray()[3]=.1; | |
672 | //check all needed data is available | |
673 | if (!fRefPulserTmean || !fPulserTmean || !fPulserQmean || !fRefPulserQmean || !fALTROMasked || !fRefALTROMasked) return; | |
674 | // | |
675 | UpdateRefPulserOutlierMap(); | |
676 | //loop over all channels | |
677 | for (UInt_t isec=0;isec<(UInt_t)AliTPCCalPad::kNsec;++isec){ | |
678 | AliTPCCalROC *pqROC=fPulserQmean->GetCalROC(isec); | |
679 | AliTPCCalROC *pqRefROC=fRefPulserQmean->GetCalROC(isec); | |
680 | AliTPCCalROC *ptROC=fPulserTmean->GetCalROC(isec); | |
681 | //AliTPCCalROC *ptRefROC=fRefPulserTmean->GetCalROC(isec); | |
682 | AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec); | |
683 | AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec); | |
684 | AliTPCCalROC *oROC=fPulserOutlier->GetCalROC(isec); | |
685 | Float_t pt_mean=ptROC->GetMean(oROC); | |
686 | UInt_t nrows=mROC->GetNrows(); | |
687 | for (UInt_t irow=0;irow<nrows;++irow){ | |
688 | UInt_t npads=mROC->GetNPads(irow); | |
689 | for (UInt_t ipad=0;ipad<npads;++ipad){ | |
690 | //don't use masked channels; | |
691 | if (mROC ->GetValue(irow,ipad)) continue; | |
692 | if (mRefROC->GetValue(irow,ipad)) continue; | |
693 | //don't user edge pads | |
694 | if (ipad==0||ipad==npads-1) continue; | |
695 | //data | |
696 | Float_t pq=pqROC->GetValue(irow,ipad); | |
697 | Float_t pqRef=pqRefROC->GetValue(irow,ipad); | |
698 | Float_t pt=ptROC->GetValue(irow,ipad); | |
699 | // Float_t ptRef=ptRefROC->GetValue(irow,ipad); | |
700 | //comparisons q | |
701 | Float_t deviation=TMath::Abs(pq/pqRef-1); | |
702 | for (Int_t i=0;i<npar;++i){ | |
703 | if (deviation>vThres[i]) | |
704 | ++pulserQdeviations.GetMatrixArray()[i]; | |
705 | } | |
706 | if (pqRef>11&&pq<11) ++npadsOffAdd; | |
707 | varQMean+=pq-pqRef; | |
708 | //comparisons t | |
709 | if (TMath::Abs(pt-pt_mean)>1) ++npadsOutOneTB; | |
710 | ++nActive; | |
711 | }//end ipad | |
712 | }//ind irow | |
713 | }//end isec | |
714 | if (nActive>0){ | |
715 | for (Int_t i=0;i<npar;++i){ | |
716 | pulserQdeviations.GetMatrixArray()[i]/=nActive; | |
717 | varQMean/=nActive; | |
718 | } | |
719 | } | |
720 | } | |
892226be | 721 | //_____________________________________________________________________________________ |
722 | void AliTPCcalibDButil::UpdatePulserOutlierMap() | |
7390f655 | 723 | { |
724 | // | |
725 | // | |
726 | // | |
727 | PulserOutlierMap(fPulserOutlier,fPulserTmean, fPulserQmean); | |
728 | } | |
729 | //_____________________________________________________________________________________ | |
730 | void AliTPCcalibDButil::UpdateRefPulserOutlierMap() | |
731 | { | |
732 | // | |
733 | // | |
734 | // | |
735 | PulserOutlierMap(fRefPulserOutlier,fRefPulserTmean, fRefPulserQmean); | |
736 | } | |
737 | //_____________________________________________________________________________________ | |
738 | void AliTPCcalibDButil::PulserOutlierMap(AliTPCCalPad *pulOut, const AliTPCCalPad *pulT, const AliTPCCalPad *pulQ) | |
892226be | 739 | { |
740 | // | |
741 | // Create a map that contains outliers from the Pulser calibration data. | |
742 | // The outliers include masked channels, edge pads and pads with | |
743 | // too large timing and charge variations. | |
7390f655 | 744 | // fNpulserOutliers is the number of outliers in the Pulser calibration data. |
892226be | 745 | // those do not contain masked and edge pads |
746 | // | |
7390f655 | 747 | if (!pulT||!pulQ) { |
892226be | 748 | //reset map |
7390f655 | 749 | pulOut->Multiply(0.); |
892226be | 750 | fNpulserOutliers=-1; |
751 | return; | |
752 | } | |
753 | AliTPCCalROC *rocMasked=0x0; | |
754 | fNpulserOutliers=0; | |
755 | ||
756 | //Create Outlier Map | |
757 | for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){ | |
7390f655 | 758 | AliTPCCalROC *tmeanROC=pulT->GetCalROC(isec); |
759 | AliTPCCalROC *qmeanROC=pulQ->GetCalROC(isec); | |
760 | AliTPCCalROC *outROC=pulOut->GetCalROC(isec); | |
892226be | 761 | if (!tmeanROC||!qmeanROC) { |
762 | //reset outliers in this ROC | |
763 | outROC->Multiply(0.); | |
764 | continue; | |
765 | } | |
766 | if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec); | |
767 | // Double_t dummy=0; | |
768 | // Float_t qmedian=qmeanROC->GetLTM(&dummy,.5); | |
769 | // Float_t tmedian=tmeanROC->GetLTM(&dummy,.5); | |
770 | UInt_t nrows=tmeanROC->GetNrows(); | |
771 | for (UInt_t irow=0;irow<nrows;++irow){ | |
772 | UInt_t npads=tmeanROC->GetNPads(irow); | |
773 | for (UInt_t ipad=0;ipad<npads;++ipad){ | |
774 | Int_t outlier=0,masked=0; | |
775 | Float_t q=qmeanROC->GetValue(irow,ipad); | |
776 | Float_t t=tmeanROC->GetValue(irow,ipad); | |
777 | //masked channels are outliers | |
778 | if (rocMasked && rocMasked->GetValue(irow,ipad)) masked=1; | |
779 | //edge pads are outliers | |
780 | if (ipad==0||ipad==npads-1) masked=1; | |
781 | //channels with too large charge or timing deviation from the meadian are outliers | |
782 | // if (TMath::Abs(q-qmedian)>fPulQmaxLimitAbs || TMath::Abs(t-tmedian)>fPulTmaxLimitAbs) outlier=1; | |
783 | if (q<fPulQminLimit && !masked) outlier=1; | |
784 | //check for nan | |
785 | if ( !(q<10000000) || !(t<10000000)) outlier=1; | |
786 | outROC->SetValue(irow,ipad,outlier+masked); | |
787 | fNpulserOutliers+=outlier; | |
788 | } | |
789 | } | |
790 | } | |
791 | } | |
792 | //_____________________________________________________________________________________ | |
793 | AliTPCCalPad* AliTPCcalibDButil::CreatePadTime0(Int_t model) | |
794 | { | |
795 | // | |
796 | // Create pad time0 object from pulser and/or CE data, depending on the selected model | |
797 | // Model 0: normalise each readout chamber to its mean, outlier cutted, only Pulser | |
798 | // Model 1: normalise IROCs/OROCs of each readout side to its mean, only Pulser | |
799 | // | |
800 | // | |
801 | ||
802 | AliTPCCalPad *padTime0=new AliTPCCalPad("PadTime0",Form("PadTime0-Model_%d",model)); | |
803 | // decide between different models | |
804 | if (model==0||model==1){ | |
805 | TVectorD vMean; | |
806 | if (model==1) ProcessPulser(vMean); | |
807 | for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){ | |
808 | AliTPCCalROC *rocPulTmean=fPulserTmean->GetCalROC(isec); | |
809 | if (!rocPulTmean) continue; | |
810 | AliTPCCalROC *rocTime0=padTime0->GetCalROC(isec); | |
811 | AliTPCCalROC *rocOut=fPulserOutlier->GetCalROC(isec); | |
812 | Float_t mean=rocPulTmean->GetMean(rocOut); | |
813 | //treat case where a whole partition is masked | |
814 | if (mean==0) mean=rocPulTmean->GetMean(); | |
815 | if (model==1) { | |
816 | Int_t type=isec/18; | |
817 | mean=vMean[type]; | |
818 | } | |
819 | UInt_t nrows=rocTime0->GetNrows(); | |
820 | for (UInt_t irow=0;irow<nrows;++irow){ | |
821 | UInt_t npads=rocTime0->GetNPads(irow); | |
822 | for (UInt_t ipad=0;ipad<npads;++ipad){ | |
823 | Float_t time=rocPulTmean->GetValue(irow,ipad); | |
824 | //in case of an outlier pad use the mean of the altro values. | |
825 | //This should be the most precise guess in that case. | |
826 | if (rocOut->GetValue(irow,ipad)) { | |
827 | time=GetMeanAltro(rocPulTmean,irow,ipad,rocOut); | |
828 | if (time==0) time=mean; | |
829 | } | |
830 | Float_t val=time-mean; | |
831 | rocTime0->SetValue(irow,ipad,val); | |
832 | } | |
833 | } | |
834 | } | |
835 | } | |
836 | ||
837 | ||
838 | ||
839 | return padTime0; | |
840 | } | |
841 | //_____________________________________________________________________________________ | |
842 | Float_t AliTPCcalibDButil::GetMeanAltro(const AliTPCCalROC *roc, const Int_t row, const Int_t pad, AliTPCCalROC *rocOut) | |
843 | { | |
844 | if (roc==0) return 0.; | |
845 | const Int_t sector=roc->GetSector(); | |
846 | AliTPCROC *tpcRoc=AliTPCROC::Instance(); | |
847 | const UInt_t altroRoc=fMapper->GetFEC(sector,row,pad)*8+fMapper->GetChip(sector,row,pad); | |
848 | Float_t mean=0; | |
849 | Int_t n=0; | |
850 | ||
851 | //loop over a small range around the requested pad (+-10 rows/pads) | |
852 | for (Int_t irow=row-10;irow<row+10;++irow){ | |
853 | if (irow<0||irow>(Int_t)tpcRoc->GetNRows(sector)-1) continue; | |
854 | for (Int_t ipad=pad-10; ipad<pad+10;++ipad){ | |
855 | if (ipad<0||ipad>(Int_t)tpcRoc->GetNPads(sector,irow)-1) continue; | |
856 | const UInt_t altroCurr=fMapper->GetFEC(sector,irow,ipad)*8+fMapper->GetChip(sector,irow,ipad); | |
857 | if (altroRoc!=altroCurr) continue; | |
858 | if ( rocOut && rocOut->GetValue(irow,ipad) ) continue; | |
859 | Float_t val=roc->GetValue(irow,ipad); | |
860 | mean+=val; | |
861 | ++n; | |
862 | } | |
863 | } | |
864 | if (n>0) mean/=n; | |
865 | return mean; | |
866 | } | |
7390f655 | 867 | //_____________________________________________________________________________________ |
868 | void AliTPCcalibDButil::SetRefFile(const char* filename) | |
869 | { | |
870 | // | |
871 | // load cal pad objects form the reference file | |
872 | // | |
873 | TDirectory *currDir=gDirectory; | |
874 | TFile f(filename); | |
875 | fRefPedestals=(AliTPCCalPad*)f.Get("Pedestals"); | |
876 | fRefPadNoise=(AliTPCCalPad*)f.Get("PadNoise"); | |
877 | //pulser data | |
878 | fRefPulserTmean=(AliTPCCalPad*)f.Get("PulserTmean"); | |
879 | fRefPulserTrms=(AliTPCCalPad*)f.Get("PulserTrms"); | |
880 | fRefPulserQmean=(AliTPCCalPad*)f.Get("PulserQmean"); | |
881 | //CE data | |
882 | fRefCETmean=(AliTPCCalPad*)f.Get("CETmean"); | |
883 | fRefCETrms=(AliTPCCalPad*)f.Get("CETrms"); | |
884 | fRefCEQmean=(AliTPCCalPad*)f.Get("CEQmean"); | |
885 | //Altro data | |
886 | // fRefALTROAcqStart=(AliTPCCalPad*)f.Get("ALTROAcqStart"); | |
887 | // fRefALTROZsThr=(AliTPCCalPad*)f.Get("ALTROZsThr"); | |
888 | // fRefALTROFPED=(AliTPCCalPad*)f.Get("ALTROFPED"); | |
889 | // fRefALTROAcqStop=(AliTPCCalPad*)f.Get("ALTROAcqStop"); | |
890 | fRefALTROMasked=(AliTPCCalPad*)f.Get("ALTROMasked"); | |
891 | f.Close(); | |
892 | currDir->cd(); | |
893 | } | |
894 |