]>
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> | |
31 | ||
32 | #include <AliDCSSensorArray.h> | |
33 | #include <AliDCSSensor.h> | |
34 | #include "AliTPCcalibDB.h" | |
35 | #include "AliTPCCalPad.h" | |
36 | #include "AliTPCCalROC.h" | |
37 | #include "AliTPCROC.h" | |
38 | #include "AliTPCmapper.h" | |
39 | #include "AliTPCParam.h" | |
40 | ||
41 | #include "AliTPCcalibDButil.h" | |
42 | ||
43 | ClassImp(AliTPCcalibDButil) | |
44 | AliTPCcalibDButil::AliTPCcalibDButil() : | |
45 | TObject(), | |
46 | fCalibDB(AliTPCcalibDB::Instance()), | |
47 | fPadNoise(0x0), | |
48 | fPedestals(0x0), | |
49 | fPulserTmean(0x0), | |
50 | fPulserTrms(0x0), | |
51 | fPulserQmean(0x0), | |
52 | fPulserOutlier(new AliTPCCalPad("PulserOutliers","PulserOutliers")), | |
53 | fCETmean(0x0), | |
54 | fCETrms(0x0), | |
55 | fCEQmean(0x0), | |
56 | fALTROMasked(0x0), | |
57 | fGoofieArray(0x0), | |
58 | fMapper(new AliTPCmapper(0x0)), | |
59 | fNpulserOutliers(-1), | |
60 | fIrocTimeOffset(.2), | |
61 | fCETmaxLimitAbs(1.5), | |
62 | fPulTmaxLimitAbs(1.5), | |
63 | fPulQmaxLimitAbs(5), | |
64 | fPulQminLimit(11) | |
65 | { | |
66 | // | |
67 | // Default ctor | |
68 | // | |
69 | } | |
70 | //_____________________________________________________________________________________ | |
71 | AliTPCcalibDButil::~AliTPCcalibDButil() | |
72 | { | |
73 | // | |
74 | // dtor | |
75 | // | |
76 | delete fPulserOutlier; | |
77 | delete fMapper; | |
78 | } | |
79 | //_____________________________________________________________________________________ | |
80 | void AliTPCcalibDButil::UpdateFromCalibDB() | |
81 | { | |
82 | // | |
83 | // Update pointers from calibDB | |
84 | // | |
85 | fPadNoise=fCalibDB->GetPadNoise(); | |
86 | fPedestals=fCalibDB->GetPedestals(); | |
87 | fPulserTmean=fCalibDB->GetPulserTmean(); | |
88 | fPulserTrms=fCalibDB->GetPulserTrms(); | |
89 | fPulserQmean=fCalibDB->GetPulserQmean(); | |
90 | fCETmean=fCalibDB->GetCETmean(); | |
91 | fCETrms=fCalibDB->GetCETrms(); | |
92 | fCEQmean=fCalibDB->GetCEQmean(); | |
93 | fALTROMasked=fCalibDB->GetALTROMasked(); | |
94 | fGoofieArray=fCalibDB->GetGoofieSensors(fCalibDB->GetRun()); | |
95 | UpdatePulserOutlierMap(); | |
96 | } | |
97 | //_____________________________________________________________________________________ | |
98 | void AliTPCcalibDButil::ProcessCEdata(const char* fitFormula, TVectorD &fitResultsA, TVectorD &fitResultsC, Int_t &noutliersCE) | |
99 | { | |
100 | // | |
101 | // Process the CE data for this run | |
102 | // the return TVectorD arrays contian the results of the fit | |
103 | // noutliersCE contains the number of pads marked as outliers, | |
104 | // not including masked and edge pads | |
105 | // | |
106 | ||
107 | //retrieve CE and ALTRO data | |
108 | if (!fCETmean){ | |
109 | TString fitString(fitFormula); | |
110 | fitString.ReplaceAll("++","#"); | |
111 | Int_t ndim=fitString.CountChar('#')+2; | |
112 | fitResultsA.ResizeTo(ndim); | |
113 | fitResultsC.ResizeTo(ndim); | |
114 | fitResultsA.Zero(); | |
115 | fitResultsC.Zero(); | |
116 | noutliersCE=-1; | |
117 | return; | |
118 | } | |
119 | noutliersCE=0; | |
120 | //create outlier map | |
121 | AliTPCCalPad out("out","out"); | |
122 | AliTPCCalROC *rocMasked=0x0; | |
123 | //loop over all channels | |
124 | for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){ | |
125 | AliTPCCalROC *rocData=fCETmean->GetCalROC(iroc); | |
126 | if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(iroc); | |
127 | AliTPCCalROC *rocOut=out.GetCalROC(iroc); | |
128 | if (!rocData) continue; | |
129 | //add time offset to IROCs | |
130 | if (iroc<AliTPCROC::Instance()->GetNInnerSector()) | |
131 | rocData->Add(fIrocTimeOffset); | |
132 | //select outliers | |
133 | UInt_t nrows=rocData->GetNrows(); | |
134 | for (UInt_t irow=0;irow<nrows;++irow){ | |
135 | UInt_t npads=rocData->GetNPads(irow); | |
136 | for (UInt_t ipad=0;ipad<npads;++ipad){ | |
137 | //exclude masked pads | |
138 | if (rocMasked && rocMasked->GetValue(irow,ipad)) { | |
139 | rocOut->SetValue(iroc,ipad,1); | |
140 | continue; | |
141 | } | |
142 | //exclude edge pads | |
143 | if (ipad==0||ipad==npads-1) rocOut->SetValue(iroc,ipad,1); | |
144 | Float_t valTmean=rocData->GetValue(iroc,ipad); | |
145 | //exclude values that are exactly 0 | |
146 | if (valTmean==0) { | |
147 | rocOut->SetValue(iroc,ipad,1); | |
148 | ++noutliersCE; | |
149 | } | |
150 | // exclude channels with too large variations | |
151 | if (TMath::Abs(valTmean)>fCETmaxLimitAbs) { | |
152 | rocOut->SetValue(iroc,ipad,1); | |
153 | ++noutliersCE; | |
154 | } | |
155 | } | |
156 | } | |
157 | } | |
158 | //perform fit | |
159 | TMatrixD dummy; | |
160 | Float_t chi2A,chi2C; | |
161 | fCETmean->GlobalSidesFit(&out,fitFormula,fitResultsA,fitResultsC,dummy,dummy,chi2A,chi2C); | |
162 | } | |
163 | //_____________________________________________________________________________________ | |
164 | void AliTPCcalibDButil::ProcessCEgraphs(TVectorD &vecTEntries, TVectorD &vecTMean, TVectorD &vecTRMS, TVectorD &vecTMedian, | |
165 | TVectorD &vecQEntries, TVectorD &vecQMean, TVectorD &vecQRMS, TVectorD &vecQMedian, | |
166 | Float_t &driftTimeA, Float_t &driftTimeC ) | |
167 | { | |
168 | // | |
169 | // Calculate statistical information from the CE graphs for drift time and charge | |
170 | // | |
171 | ||
172 | //reset arrays | |
173 | vecTEntries.ResizeTo(72); | |
174 | vecTMean.ResizeTo(72); | |
175 | vecTRMS.ResizeTo(72); | |
176 | vecTMedian.ResizeTo(72); | |
177 | vecQEntries.ResizeTo(72); | |
178 | vecQMean.ResizeTo(72); | |
179 | vecQRMS.ResizeTo(72); | |
180 | vecQMedian.ResizeTo(72); | |
181 | vecTEntries.Zero(); | |
182 | vecTMean.Zero(); | |
183 | vecTRMS.Zero(); | |
184 | vecTMedian.Zero(); | |
185 | vecQEntries.Zero(); | |
186 | vecQMean.Zero(); | |
187 | vecQRMS.Zero(); | |
188 | vecQMedian.Zero(); | |
189 | driftTimeA=0; | |
190 | driftTimeC=0; | |
191 | TObjArray *arrT=fCalibDB->GetCErocTtime(); | |
192 | TObjArray *arrQ=fCalibDB->GetCErocQtime(); | |
193 | if (arrT){ | |
194 | for (Int_t isec=0;isec<74;++isec){ | |
195 | TGraph *gr=(TGraph*)arrT->At(isec); | |
196 | if (!gr) continue; | |
197 | TVectorD values; | |
198 | Int_t npoints = gr->GetN(); | |
199 | values.ResizeTo(npoints); | |
200 | Int_t nused =0; | |
201 | for (Int_t ipoint=0; ipoint<npoints; ipoint++){ | |
202 | if (gr->GetY()[ipoint]>500 && gr->GetY()[ipoint]<1000 ){ | |
203 | values[nused]=gr->GetY()[ipoint]; | |
204 | nused++; | |
205 | } | |
206 | } | |
207 | // | |
208 | if (isec<72) vecTEntries[isec]= nused; | |
209 | if (nused>1){ | |
210 | if (isec<72){ | |
211 | vecTMedian[isec] = TMath::Median(nused,values.GetMatrixArray()); | |
212 | vecTMean[isec] = TMath::Mean(nused,values.GetMatrixArray()); | |
213 | vecTRMS[isec] = TMath::RMS(nused,values.GetMatrixArray()); | |
214 | } else if (isec==72){ | |
215 | driftTimeA=TMath::Median(nused,values.GetMatrixArray()); | |
216 | } else if (isec==73){ | |
217 | driftTimeC=TMath::Median(nused,values.GetMatrixArray()); | |
218 | } | |
219 | } | |
220 | } | |
221 | } | |
222 | if (arrQ){ | |
223 | for (Int_t isec=0;isec<72;++isec){ | |
224 | TGraph *gr=(TGraph*)arrQ->At(isec); | |
225 | if (!gr) continue; | |
226 | TVectorD values; | |
227 | Int_t npoints = gr->GetN(); | |
228 | values.ResizeTo(npoints); | |
229 | Int_t nused =0; | |
230 | for (Int_t ipoint=0; ipoint<npoints; ipoint++){ | |
231 | if (gr->GetY()[ipoint]>500 && gr->GetY()[ipoint]<1000 ){ | |
232 | values[nused]=gr->GetY()[ipoint]; | |
233 | nused++; | |
234 | } | |
235 | } | |
236 | // | |
237 | vecTEntries[isec]= nused; | |
238 | if (nused>1){ | |
239 | vecQMedian[isec] = TMath::Median(nused,values.GetMatrixArray()); | |
240 | vecQMean[isec] = TMath::Mean(nused,values.GetMatrixArray()); | |
241 | vecQRMS[isec] = TMath::RMS(nused,values.GetMatrixArray()); | |
242 | } | |
243 | } | |
244 | } | |
245 | } | |
246 | ||
247 | //_____________________________________________________________________________________ | |
248 | void AliTPCcalibDButil::ProcessNoiseData(TVectorD &vNoiseMean, TVectorD &vNoiseMeanSenRegions, | |
249 | TVectorD &vNoiseRMS, TVectorD &vNoiseRMSSenRegions, | |
250 | Int_t &nonMaskedZero) | |
251 | { | |
252 | // | |
253 | // process noise data | |
254 | // vNoiseMean/RMS contains the Mean/RMS noise of the complete TPC [0], IROCs only [1], | |
255 | // OROCs small pads [2] and OROCs large pads [3] | |
256 | // vNoiseMean/RMSsenRegions constains the same information, but only for the sensitive regions (edge pads, corners, IROC spot) | |
257 | // nonMaskedZero contains the number of pads which show zero noise and were not masked. This might indicate an error | |
258 | // | |
259 | ||
260 | //set proper size and reset | |
261 | const UInt_t infoSize=4; | |
262 | vNoiseMean.ResizeTo(infoSize); | |
263 | vNoiseMeanSenRegions.ResizeTo(infoSize); | |
264 | vNoiseRMS.ResizeTo(infoSize); | |
265 | vNoiseRMSSenRegions.ResizeTo(infoSize); | |
266 | vNoiseMean.Zero(); | |
267 | vNoiseMeanSenRegions.Zero(); | |
268 | vNoiseRMS.Zero(); | |
269 | vNoiseRMSSenRegions.Zero(); | |
270 | nonMaskedZero=0; | |
271 | //counters | |
272 | TVectorD c(infoSize); | |
273 | TVectorD cs(infoSize); | |
274 | //tpc parameters | |
275 | AliTPCParam par; | |
276 | par.Update(); | |
277 | //retrieve noise and ALTRO data | |
278 | if (!fPadNoise) return; | |
279 | AliTPCCalROC *rocMasked=0x0; | |
280 | //create IROC, OROC1, OROC2 and sensitive region masks | |
281 | for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){ | |
282 | AliTPCCalROC *noiseROC=fPadNoise->GetCalROC(isec); | |
283 | if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec); | |
284 | UInt_t nrows=noiseROC->GetNrows(); | |
285 | for (UInt_t irow=0;irow<nrows;++irow){ | |
286 | UInt_t npads=noiseROC->GetNPads(irow); | |
287 | for (UInt_t ipad=0;ipad<npads;++ipad){ | |
288 | //don't use masked channels; | |
289 | if (rocMasked && rocMasked->GetValue(irow,ipad)) continue; | |
290 | Float_t noiseVal=noiseROC->GetValue(irow,ipad); | |
291 | //check if noise==0 | |
292 | if (noiseVal==0) { | |
293 | ++nonMaskedZero; | |
294 | continue; | |
295 | } | |
296 | //check for nan | |
297 | if ( !(noiseVal<10000000) ){ | |
298 | printf ("Warning: nan detected in (sec,row,pad - val): %02d,%02d,%03d - %.1f\n",isec,irow,ipad,noiseVal); | |
299 | continue; | |
300 | } | |
301 | Int_t cpad=(Int_t)ipad-(Int_t)npads/2; | |
302 | Int_t masksen=1; // sensitive pards are not masked (0) | |
303 | if (ipad<2||npads-ipad-1<2) masksen=0; //don't mask edge pads (sensitive) | |
304 | if (isec<AliTPCROC::Instance()->GetNInnerSector()){ | |
305 | //IROCs | |
306 | if (irow>19&&irow<46){ | |
307 | if (TMath::Abs(cpad)<7) masksen=0; //IROC spot | |
308 | } | |
309 | Int_t type=1; | |
310 | vNoiseMean[type]+=noiseVal; | |
311 | vNoiseRMS[type]+=noiseVal*noiseVal; | |
312 | ++c[type]; | |
313 | if (!masksen){ | |
314 | vNoiseMeanSenRegions[type]+=noiseVal; | |
315 | vNoiseRMSSenRegions[type]+=noiseVal*noiseVal; | |
316 | ++cs[type]; | |
317 | } | |
318 | } else { | |
319 | //OROCs | |
320 | //define sensive regions | |
321 | if ((nrows-irow-1)<3) masksen=0; //last three rows in OROCs are sensitive | |
322 | if ( irow>75 ){ | |
323 | Int_t padEdge=(Int_t)TMath::Min(ipad,npads-ipad); | |
324 | if (padEdge<((((Int_t)irow-76)/4+1))*2) masksen=0; //OROC outer corners are sensitive | |
325 | } | |
326 | if ((Int_t)irow<par.GetNRowUp1()){ | |
327 | //OROC1 | |
328 | Int_t type=2; | |
329 | vNoiseMean[type]+=noiseVal; | |
330 | vNoiseRMS[type]+=noiseVal*noiseVal; | |
331 | ++c[type]; | |
332 | if (!masksen){ | |
333 | vNoiseMeanSenRegions[type]+=noiseVal; | |
334 | vNoiseRMSSenRegions[type]+=noiseVal*noiseVal; | |
335 | ++cs[type]; | |
336 | } | |
337 | }else{ | |
338 | //OROC2 | |
339 | Int_t type=3; | |
340 | vNoiseMean[type]+=noiseVal; | |
341 | vNoiseRMS[type]+=noiseVal*noiseVal; | |
342 | ++c[type]; | |
343 | if (!masksen){ | |
344 | vNoiseMeanSenRegions[type]+=noiseVal; | |
345 | vNoiseRMSSenRegions[type]+=noiseVal*noiseVal; | |
346 | ++cs[type]; | |
347 | } | |
348 | } | |
349 | } | |
350 | //whole tpc | |
351 | Int_t type=0; | |
352 | vNoiseMean[type]+=noiseVal; | |
353 | vNoiseRMS[type]+=noiseVal*noiseVal; | |
354 | ++c[type]; | |
355 | if (!masksen){ | |
356 | vNoiseMeanSenRegions[type]+=noiseVal; | |
357 | vNoiseRMSSenRegions[type]+=noiseVal*noiseVal; | |
358 | ++cs[type]; | |
359 | } | |
360 | }//end loop pads | |
361 | }//end loop rows | |
362 | }//end loop sectors (rocs) | |
363 | ||
364 | //calculate mean and RMS | |
365 | const Double_t verySmall=0.0000000001; | |
366 | for (UInt_t i=0;i<infoSize;++i){ | |
367 | Double_t mean=0; | |
368 | Double_t rms=0; | |
369 | Double_t meanSen=0; | |
370 | Double_t rmsSen=0; | |
371 | ||
372 | if (c[i]>verySmall){ | |
373 | // printf ("i: %d - m: %.3f, c: %.0f, r: %.3f\n",i,vNoiseMean[i],c[i],vNoiseRMS[i]); | |
374 | mean=vNoiseMean[i]/c[i]; | |
375 | rms=vNoiseRMS[i]; | |
376 | rms=TMath::Sqrt(TMath::Abs(rms/c[i]-mean*mean)); | |
377 | } | |
378 | vNoiseMean[i]=mean; | |
379 | vNoiseRMS[i]=rms; | |
380 | ||
381 | if (cs[i]>verySmall){ | |
382 | meanSen=vNoiseMeanSenRegions[i]/cs[i]; | |
383 | rmsSen=vNoiseRMSSenRegions[i]; | |
384 | rmsSen=TMath::Sqrt(TMath::Abs(rmsSen/cs[i]-meanSen*meanSen)); | |
385 | } | |
386 | vNoiseMeanSenRegions[i]=meanSen; | |
387 | vNoiseRMSSenRegions[i]=rmsSen; | |
388 | } | |
389 | } | |
390 | ||
391 | //_____________________________________________________________________________________ | |
392 | void AliTPCcalibDButil::ProcessPulser(TVectorD &vMeanTime) | |
393 | { | |
394 | // | |
395 | // Process the Pulser information | |
396 | // vMeanTime: pulser mean time position in IROC-A, IROC-C, OROC-A, OROC-C | |
397 | // | |
398 | ||
399 | const UInt_t infoSize=4; | |
400 | //reset counters to error number | |
401 | vMeanTime.ResizeTo(infoSize); | |
402 | vMeanTime.Zero(); | |
403 | //counter | |
404 | TVectorD c(infoSize); | |
405 | //retrieve pulser and ALTRO data | |
406 | if (!fPulserTmean) return; | |
407 | // | |
408 | //get Outliers | |
409 | AliTPCCalROC *rocOut=0x0; | |
410 | for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){ | |
411 | AliTPCCalROC *tmeanROC=fPulserTmean->GetCalROC(isec); | |
412 | if (!tmeanROC) continue; | |
413 | rocOut=fPulserOutlier->GetCalROC(isec); | |
414 | UInt_t nchannels=tmeanROC->GetNchannels(); | |
415 | for (UInt_t ichannel=0;ichannel<nchannels;++ichannel){ | |
416 | if (rocOut && rocOut->GetValue(ichannel)) continue; | |
417 | Float_t val=tmeanROC->GetValue(ichannel); | |
418 | Int_t type=isec/18; | |
419 | vMeanTime[type]+=val; | |
420 | ++c[type]; | |
421 | } | |
422 | } | |
423 | //calculate mean | |
424 | for (UInt_t itype=0; itype<infoSize; ++itype){ | |
425 | if (c[itype]>0) vMeanTime[itype]/=c[itype]; | |
426 | else vMeanTime[itype]=0; | |
427 | } | |
428 | } | |
429 | //_____________________________________________________________________________________ | |
430 | void AliTPCcalibDButil::ProcessALTROConfig(Int_t &nMasked) | |
431 | { | |
432 | // | |
433 | // Get Values from ALTRO configuration data | |
434 | // | |
435 | nMasked=-1; | |
436 | if (!fALTROMasked) return; | |
437 | nMasked=0; | |
438 | for (Int_t isec=0;isec<fALTROMasked->kNsec; ++isec){ | |
439 | AliTPCCalROC *rocMasked=fALTROMasked->GetCalROC(isec); | |
440 | for (UInt_t ichannel=0; ichannel<rocMasked->GetNchannels();++ichannel){ | |
441 | if (rocMasked->GetValue(ichannel)) ++nMasked; | |
442 | } | |
443 | } | |
444 | } | |
445 | //_____________________________________________________________________________________ | |
446 | void AliTPCcalibDButil::ProcessGoofie(TVectorD & vecEntries, TVectorD & vecMedian, TVectorD &vecMean, TVectorD &vecRMS) | |
447 | { | |
448 | // | |
449 | // Proces Goofie values, return statistical information of the currently set goofieArray | |
450 | // The meaning of the entries are given below | |
451 | /* | |
452 | 1 TPC_ANODE_I_A00_STAT | |
453 | 2 TPC_DVM_CO2 | |
454 | 3 TPC_DVM_DriftVelocity | |
455 | 4 TPC_DVM_FCageHV | |
456 | 5 TPC_DVM_GainFar | |
457 | 6 TPC_DVM_GainNear | |
458 | 7 TPC_DVM_N2 | |
459 | 8 TPC_DVM_NumberOfSparks | |
460 | 9 TPC_DVM_PeakAreaFar | |
461 | 10 TPC_DVM_PeakAreaNear | |
462 | 11 TPC_DVM_PeakPosFar | |
463 | 12 TPC_DVM_PeakPosNear | |
464 | 13 TPC_DVM_PickupHV | |
465 | 14 TPC_DVM_Pressure | |
466 | 15 TPC_DVM_T1_Over_P | |
467 | 16 TPC_DVM_T2_Over_P | |
468 | 17 TPC_DVM_T_Over_P | |
469 | 18 TPC_DVM_TemperatureS1 | |
470 | */ | |
471 | if (!fGoofieArray){ | |
472 | Int_t nsensors=19; | |
473 | vecEntries.ResizeTo(nsensors); | |
474 | vecMedian.ResizeTo(nsensors); | |
475 | vecMean.ResizeTo(nsensors); | |
476 | vecRMS.ResizeTo(nsensors); | |
477 | vecEntries.Zero(); | |
478 | vecMedian.Zero(); | |
479 | vecMean.Zero(); | |
480 | vecRMS.Zero(); | |
481 | return; | |
482 | } | |
483 | Double_t kEpsilon=0.0000000001; | |
484 | Double_t kBig=100000000000.; | |
485 | Int_t nsensors = fGoofieArray->NumSensors(); | |
486 | vecEntries.ResizeTo(nsensors); | |
487 | vecMedian.ResizeTo(nsensors); | |
488 | vecMean.ResizeTo(nsensors); | |
489 | vecRMS.ResizeTo(nsensors); | |
490 | TVectorF values; | |
491 | for (Int_t isensor=0; isensor<fGoofieArray->NumSensors();isensor++){ | |
492 | AliDCSSensor *gsensor = fGoofieArray->GetSensor(isensor); | |
493 | if (gsensor && gsensor->GetGraph()){ | |
494 | Int_t npoints = gsensor->GetGraph()->GetN(); | |
495 | // filter zeroes | |
496 | values.ResizeTo(npoints); | |
497 | Int_t nused =0; | |
498 | for (Int_t ipoint=0; ipoint<npoints; ipoint++){ | |
499 | if (TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])>kEpsilon && | |
500 | TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])<kBig ){ | |
501 | values[nused]=gsensor->GetGraph()->GetY()[ipoint]; | |
502 | nused++; | |
503 | } | |
504 | } | |
505 | // | |
506 | vecEntries[isensor]= nused; | |
507 | if (nused>1){ | |
508 | vecMedian[isensor] = TMath::Median(nused,values.GetMatrixArray()); | |
509 | vecMean[isensor] = TMath::Mean(nused,values.GetMatrixArray()); | |
510 | vecRMS[isensor] = TMath::RMS(nused,values.GetMatrixArray()); | |
511 | } | |
512 | } | |
513 | } | |
514 | } | |
515 | ||
516 | //_____________________________________________________________________________________ | |
517 | void AliTPCcalibDButil::UpdatePulserOutlierMap() | |
518 | { | |
519 | // | |
520 | // Create a map that contains outliers from the Pulser calibration data. | |
521 | // The outliers include masked channels, edge pads and pads with | |
522 | // too large timing and charge variations. | |
523 | // nonMaskedZero is the number of outliers in the Pulser calibration data. | |
524 | // those do not contain masked and edge pads | |
525 | // | |
526 | if (!fPulserTmean||!fPulserQmean) { | |
527 | //reset map | |
528 | fPulserOutlier->Multiply(0.); | |
529 | fNpulserOutliers=-1; | |
530 | return; | |
531 | } | |
532 | AliTPCCalROC *rocMasked=0x0; | |
533 | fNpulserOutliers=0; | |
534 | ||
535 | //Create Outlier Map | |
536 | for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){ | |
537 | AliTPCCalROC *tmeanROC=fPulserTmean->GetCalROC(isec); | |
538 | AliTPCCalROC *qmeanROC=fPulserQmean->GetCalROC(isec); | |
539 | AliTPCCalROC *outROC=fPulserOutlier->GetCalROC(isec); | |
540 | if (!tmeanROC||!qmeanROC) { | |
541 | //reset outliers in this ROC | |
542 | outROC->Multiply(0.); | |
543 | continue; | |
544 | } | |
545 | if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec); | |
546 | // Double_t dummy=0; | |
547 | // Float_t qmedian=qmeanROC->GetLTM(&dummy,.5); | |
548 | // Float_t tmedian=tmeanROC->GetLTM(&dummy,.5); | |
549 | UInt_t nrows=tmeanROC->GetNrows(); | |
550 | for (UInt_t irow=0;irow<nrows;++irow){ | |
551 | UInt_t npads=tmeanROC->GetNPads(irow); | |
552 | for (UInt_t ipad=0;ipad<npads;++ipad){ | |
553 | Int_t outlier=0,masked=0; | |
554 | Float_t q=qmeanROC->GetValue(irow,ipad); | |
555 | Float_t t=tmeanROC->GetValue(irow,ipad); | |
556 | //masked channels are outliers | |
557 | if (rocMasked && rocMasked->GetValue(irow,ipad)) masked=1; | |
558 | //edge pads are outliers | |
559 | if (ipad==0||ipad==npads-1) masked=1; | |
560 | //channels with too large charge or timing deviation from the meadian are outliers | |
561 | // if (TMath::Abs(q-qmedian)>fPulQmaxLimitAbs || TMath::Abs(t-tmedian)>fPulTmaxLimitAbs) outlier=1; | |
562 | if (q<fPulQminLimit && !masked) outlier=1; | |
563 | //check for nan | |
564 | if ( !(q<10000000) || !(t<10000000)) outlier=1; | |
565 | outROC->SetValue(irow,ipad,outlier+masked); | |
566 | fNpulserOutliers+=outlier; | |
567 | } | |
568 | } | |
569 | } | |
570 | } | |
571 | //_____________________________________________________________________________________ | |
572 | AliTPCCalPad* AliTPCcalibDButil::CreatePadTime0(Int_t model) | |
573 | { | |
574 | // | |
575 | // Create pad time0 object from pulser and/or CE data, depending on the selected model | |
576 | // Model 0: normalise each readout chamber to its mean, outlier cutted, only Pulser | |
577 | // Model 1: normalise IROCs/OROCs of each readout side to its mean, only Pulser | |
578 | // | |
579 | // | |
580 | ||
581 | AliTPCCalPad *padTime0=new AliTPCCalPad("PadTime0",Form("PadTime0-Model_%d",model)); | |
582 | // decide between different models | |
583 | if (model==0||model==1){ | |
584 | TVectorD vMean; | |
585 | if (model==1) ProcessPulser(vMean); | |
586 | for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){ | |
587 | AliTPCCalROC *rocPulTmean=fPulserTmean->GetCalROC(isec); | |
588 | if (!rocPulTmean) continue; | |
589 | AliTPCCalROC *rocTime0=padTime0->GetCalROC(isec); | |
590 | AliTPCCalROC *rocOut=fPulserOutlier->GetCalROC(isec); | |
591 | Float_t mean=rocPulTmean->GetMean(rocOut); | |
592 | //treat case where a whole partition is masked | |
593 | if (mean==0) mean=rocPulTmean->GetMean(); | |
594 | if (model==1) { | |
595 | Int_t type=isec/18; | |
596 | mean=vMean[type]; | |
597 | } | |
598 | UInt_t nrows=rocTime0->GetNrows(); | |
599 | for (UInt_t irow=0;irow<nrows;++irow){ | |
600 | UInt_t npads=rocTime0->GetNPads(irow); | |
601 | for (UInt_t ipad=0;ipad<npads;++ipad){ | |
602 | Float_t time=rocPulTmean->GetValue(irow,ipad); | |
603 | //in case of an outlier pad use the mean of the altro values. | |
604 | //This should be the most precise guess in that case. | |
605 | if (rocOut->GetValue(irow,ipad)) { | |
606 | time=GetMeanAltro(rocPulTmean,irow,ipad,rocOut); | |
607 | if (time==0) time=mean; | |
608 | } | |
609 | Float_t val=time-mean; | |
610 | rocTime0->SetValue(irow,ipad,val); | |
611 | } | |
612 | } | |
613 | } | |
614 | } | |
615 | ||
616 | ||
617 | ||
618 | return padTime0; | |
619 | } | |
620 | //_____________________________________________________________________________________ | |
621 | Float_t AliTPCcalibDButil::GetMeanAltro(const AliTPCCalROC *roc, const Int_t row, const Int_t pad, AliTPCCalROC *rocOut) | |
622 | { | |
623 | if (roc==0) return 0.; | |
624 | const Int_t sector=roc->GetSector(); | |
625 | AliTPCROC *tpcRoc=AliTPCROC::Instance(); | |
626 | const UInt_t altroRoc=fMapper->GetFEC(sector,row,pad)*8+fMapper->GetChip(sector,row,pad); | |
627 | Float_t mean=0; | |
628 | Int_t n=0; | |
629 | ||
630 | //loop over a small range around the requested pad (+-10 rows/pads) | |
631 | for (Int_t irow=row-10;irow<row+10;++irow){ | |
632 | if (irow<0||irow>(Int_t)tpcRoc->GetNRows(sector)-1) continue; | |
633 | for (Int_t ipad=pad-10; ipad<pad+10;++ipad){ | |
634 | if (ipad<0||ipad>(Int_t)tpcRoc->GetNPads(sector,irow)-1) continue; | |
635 | const UInt_t altroCurr=fMapper->GetFEC(sector,irow,ipad)*8+fMapper->GetChip(sector,irow,ipad); | |
636 | if (altroRoc!=altroCurr) continue; | |
637 | if ( rocOut && rocOut->GetValue(irow,ipad) ) continue; | |
638 | Float_t val=roc->GetValue(irow,ipad); | |
639 | mean+=val; | |
640 | ++n; | |
641 | } | |
642 | } | |
643 | if (n>0) mean/=n; | |
644 | return mean; | |
645 | } |