]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDdEdxUtils.cxx
par file fix
[u/mrichter/AliRoot.git] / TRD / AliTRDdEdxUtils.cxx
CommitLineData
fb3d369e 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// class to calculate TRD dEdx
18// xx
19// xx
20// xx
21// xx
22//
23// Xianguo Lu
24// lu@physi.uni-heidelberg.de
25// Xianguo.Lu@cern.ch
26//
27//
28
29
30#include "TF1.h"
31#include "TFile.h"
32#include "TH1D.h"
33#include "TH2D.h"
d1d15abc 34#include "THn.h"
fb3d369e 35#include "THnSparse.h"
36#include "TMath.h"
37#include "TMatrixD.h"
38#include "TMinuit.h"
39#include "TObjArray.h"
40#include "TRandom3.h"
41#include "TStopwatch.h"
42#include "TVectorD.h"
43
44#include "TTreeStream.h"
45
46#include "AliCDBId.h"
47#include "AliCDBMetaData.h"
48#include "AliCDBStorage.h"
49#include "AliESDEvent.h"
50#include "AliESDfriendTrack.h"
51#include "AliESDtrack.h"
d0037ea4 52#include "AliTRDcalibDB.h"
53#include "AliTRDCalROC.h"
fb3d369e 54#include "AliTRDtrackV1.h"
55
d0037ea4 56
fb3d369e 57#include "AliTRDdEdxUtils.h"
58
59#define EPSILON 1e-12
60
d1d15abc 61THnF * AliTRDdEdxUtils::fgHistGain=0x0;
62THnF * AliTRDdEdxUtils::fgHistT0=0x0;
63THnF * AliTRDdEdxUtils::fgHistVd=0x0;
fb3d369e 64TObjArray * AliTRDdEdxUtils::fgHistPHQ=new TObjArray(8);
65
66TString AliTRDdEdxUtils::fgCalibFile;
67TObjArray * AliTRDdEdxUtils::fgObjGain = 0x0;
68TObjArray * AliTRDdEdxUtils::fgObjT0 = 0x0;
69TObjArray * AliTRDdEdxUtils::fgObjVd = 0x0;
70TObjArray * AliTRDdEdxUtils::fgObjPHQ = 0x0;
71
72Int_t AliTRDdEdxUtils::fgNchamber = -999;
73Double_t AliTRDdEdxUtils::fgChamberQ[6];
74Double_t AliTRDdEdxUtils::fgChamberTmean[6];
75
76Double_t AliTRDdEdxUtils::fgTrackTmean = -999;
77
d0037ea4 78Bool_t AliTRDdEdxUtils::fgPadGainOn = kTRUE;
9a8b0e85 79Bool_t AliTRDdEdxUtils::fgExBOn = kTRUE;
d0037ea4 80Double_t AliTRDdEdxUtils::fgQScale = 45;
9a8b0e85 81Double_t AliTRDdEdxUtils::fgQ0Frac = 0.3;
82Double_t AliTRDdEdxUtils::fgQ1Frac = 0.5;
83Double_t AliTRDdEdxUtils::fgTimeBinCountCut = 0.0;
84Int_t AliTRDdEdxUtils::fgCalibTPCnclsCut = 70;
85
fb3d369e 86//===================================================================================
87// Math and Histogram
88//===================================================================================
89void AliTRDdEdxUtils::GetCDFCuts(const TH1D *hh, const Int_t ncut, Double_t cuts[], const Double_t cdfs[], const Double_t thres)
90{
91 //
92 //counts of hh is sorted
93 //
94
95 for(Int_t ii=0; ii<ncut; ii++){
96 cuts[ii] = -999;
97 }
98
99 Int_t nsel = 0;
100 const Int_t nbin = hh->GetNbinsX();
101 Double_t datas[nbin];
102 for(Int_t ii=1; ii<=nbin; ii++){
103 const Double_t res = hh->GetBinContent(ii);
104 if(res<thres){
105 continue;
106 }
107
108 datas[nsel] = res;
109 nsel++;
110 }
111 if(!nsel)
112 return;
113
114 Int_t id[nsel];
115 TMath::Sort(nsel, datas, id, kFALSE);
116
117 for(Int_t ii=0; ii<ncut; ii++){
118 const Double_t icdf = cdfs[ii];
119 if(icdf<0 || icdf>1){
120 printf("AliTRDdEdxUtils::GetCDFCuts error cdfs[%d] %15f out of range!\n", ii, icdf); exit(1);
121 }
122 cuts[ii] = datas[id[Int_t(icdf*nsel)]];
123 }
124}
125
126Double_t AliTRDdEdxUtils::GetMeanRMS(const Double_t nn, const Double_t sum, const Double_t w2s, Double_t * grms, Double_t * gerr)
127{
128 //
129 //calculate mean (with error) and rms from sum, w2s, nn
130 //if nn=0, mean, error, and rms all = 0
131 //
132
133 Double_t tmean = 0, trms = 0, terr = 0;
134
135 if(nn>EPSILON){
136 tmean = sum/nn;
137
138 const Double_t arg = w2s/nn-tmean*tmean;
139 if(TMath::Abs(arg)<EPSILON){
140 trms = 0;
141 }
142 else{
143 if( arg <0 ){
144 printf("AliTRDdEdxUtils::GetMeanRMS error negative sqrt argument!! %e -- %e %e %f\n", arg, w2s, sum, nn); exit(1);
145 }
146
147 trms = TMath::Sqrt(arg);
148 }
149
150 terr = trms/TMath::Sqrt(nn);
151 }
152
153 if(grms){
154 (*grms) = trms;
155 }
156
157 if(gerr){
158 (*gerr) = terr;
159 }
160
161 return tmean;
162}
163
164Double_t AliTRDdEdxUtils::TruncatedMean(const Int_t nx, const Double_t xdata[], const Double_t lowfrac, const Double_t highfrac, Double_t * grms, Double_t * gerr, Double_t *wws)
165{
166 //
167 //calculate truncated mean
168 //return <x*w>_{low-high according to x}
169 //
170
171 /*
172 //test->
173 for(Int_t ii=0; ii<nx; ii++){
174 printf("test %d/%d %f\n", ii, nx, xdata[ii]);
175 }
176 //<--test
177 */
178
179 Int_t index[nx];
180 TMath::Sort(nx, xdata, index, kFALSE);
181
182 Int_t nused = 0;
183 Double_t sum = 0;
184 Double_t w2s = 0;
185 const Int_t istart = Int_t (nx*lowfrac);
186 const Int_t istop = Int_t (nx*highfrac);
187
188 //=,< correct, because when low=0, high=1 it is correct
189 for(Int_t ii=istart; ii<istop; ii++){
190 Double_t weight = 1;
191 if(wws){
192 weight = wws[index[ii]];
193 }
194 const Double_t sx = xdata[index[ii]]*weight;
195
196 sum += sx;
197 w2s += sx*sx;
198
199 nused++;
200 //printf("test in loop %d/%d %f %f %f\n", ii, nused, sx, sum, w2s);
201
202 }
203
204 return GetMeanRMS(nused, sum, w2s, grms, gerr);
205}
206
207Double_t AliTRDdEdxUtils::TruncatedMean(const TH1 *hh, const Double_t lowfrac, const Double_t highfrac, Double_t * grms, Double_t * gerr)
208{
209 //
210 //do truncation on histogram
211 //
212 //if hh is scaled, be sure Sumw2 is called before scaling!! then mean, rms and err will all be correct
213
214 //with under-/over-flow
215 Double_t npreTrunc = 0;
216 for(Int_t itmp=0; itmp<=hh->GetNbinsX()+1; itmp++){
217 const Double_t be = hh->GetBinError(itmp);
218 const Double_t bc = hh->GetBinContent(itmp);
219 if(be<EPSILON){
220 if(bc>EPSILON){
221 printf("AliTRDdEdxUtils::TruncatedMean (hist) error %e %e %d\n", bc, be, itmp); exit(1);
222 }
223 continue;
224 }
225 npreTrunc += bc*bc/be/be;
226 }
227
228 const Double_t nstart = npreTrunc*lowfrac;
229 const Double_t nstop = npreTrunc*highfrac;
230
231 //with Double_t this should also handle normalized hist
232 Double_t ntot = 0;
233 Double_t nused = 0;
234 Double_t sum = 0;
235 Double_t w2s = 0;
236 for(Int_t itmp=0; itmp<=hh->GetNbinsX()+1; itmp++){
237 const Double_t be = hh->GetBinError(itmp);
238 const Double_t bc = hh->GetBinContent(itmp);
239 if(be<EPSILON){
240 if(bc>EPSILON){
241 printf("AliTRDdEdxUtils::TruncatedMean (hist) error %e %e %d\n", bc, be, itmp); exit(1);
242 }
243 continue;
244 }
245 const Double_t weight = bc*bc/be/be;
246 ntot+=weight;
247 //<= correct, because when high=1, nstop has to be included
248 if(ntot>nstart && ntot<=nstop){
249
250 const Double_t val = hh->GetBinCenter(itmp);
251 sum += weight*val;
252 w2s += weight*val*val;
253
254 nused += weight;
255
256 //printf("test %d %f %f --- %f %f -- %f %f\n", itmp, weight, val, sum, w2s, nused, nsample);
257 }
258 else if(ntot>nstop){
259 if(itmp>=hh->GetNbinsX()){
260 printf("AliTRDdEdxUtils::TruncatedMean warning hist range too small %s %f %f %d %d, %15f %15f %15f; nused w2s sum set to 0\n", hh->GetName(), hh->GetBinLowEdge(1), hh->GetBinLowEdge(itmp), itmp, hh->GetNbinsX(), hh->GetBinContent(hh->GetNbinsX())/hh->Integral(0,hh->GetNbinsX()+1), hh->GetBinContent(hh->GetNbinsX()), hh->Integral(0,hh->GetNbinsX()+1)); //exit(1);
261 nused = 0;
262 w2s = sum = 0;
263 }
264 break;
265 }
266 }
267
268 return GetMeanRMS(nused, sum, w2s, grms, gerr);
269}
270
271void AliTRDdEdxUtils::FitSlicesY(const TH2D *hh, TH1D *&hnor, TH1D *&hmpv, TH1D *&hwid, TH1D *&hres, const Double_t thres, const Double_t lowfrac, const Double_t highfrac)
272{
273 //
274 //fit slices of hh using truncation
275 //
276
277 const Int_t x0 = hh->GetXaxis()->GetFirst();
278 const Int_t x1 = hh->GetXaxis()->GetLast();
279 const Int_t y0 = hh->GetYaxis()->GetFirst();
280 const Int_t y1 = hh->GetYaxis()->GetLast();
281
282 const Int_t nx = hh->GetNbinsX();
283 const Int_t ny = hh->GetNbinsY();
284 const Double_t xmin = hh->GetXaxis()->GetXmin();
285 const Double_t xmax = hh->GetXaxis()->GetXmax();
286 const Double_t ymin = hh->GetYaxis()->GetXmin();
287 const Double_t ymax = hh->GetYaxis()->GetXmax();
288
289 hnor = new TH1D(Form("%s_amp",hh->GetName()), "", nx, xmin, xmax);
290 hmpv = new TH1D(Form("%s_mpv",hh->GetName()), "", nx, xmin, xmax);
291 hwid = new TH1D(Form("%s_wid",hh->GetName()), "", nx, xmin, xmax);
292 hres = new TH1D(Form("%s_res",hh->GetName()), "", nx, xmin, xmax);
293
294 for(Int_t ix=x0; ix<=x1; ix++){
295 //to speed up
296 const Double_t rawcount = hh->Integral(ix,ix,0, ny+1);
297 if(rawcount<EPSILON){
298 continue;
299 }
300
301 TH1D *htmp = new TH1D(Form("FitSlicesY_%s_%d", hh->GetName(), ix),"",ny, ymin, ymax);
302 Double_t ntot = 0;
303 for(Int_t iy=y0; iy<=y1; iy++){
304 const Double_t be = hh->GetBinError(ix,iy);
305 const Double_t bc = hh->GetBinContent(ix, iy);
306
307 if(be<EPSILON){
308 if(bc>EPSILON){
309 printf("AliTRDdEdxUtils::FitSlicesY error %d %d %e %e\n", ix, iy, be, bc); exit(1);
310 }
311 continue;
312 }
313
314 htmp->SetBinContent(iy, bc);
315 htmp->SetBinError(iy, be);
316
317 ntot += (bc/be)*(bc/be);
318
319 //if(be) printf("test %d %d : %f %f %f\n", ix, iy, bc, be, pow(bc/be,2));
320 }
321
322 hnor->SetBinContent(ix, ntot);
323 hnor->SetBinError( ix, 0);
324
325 if(ntot<thres || htmp->GetRMS()<EPSILON){
326 delete htmp;
327 continue;
328 }
329
330 //test htmp->Draw();
331 Double_t trms = -999, terr = -999;
332 const Double_t tmean = TruncatedMean(htmp, lowfrac, highfrac, &trms, &terr);
333
334 hmpv->SetBinContent(ix, tmean);
335 hmpv->SetBinError( ix, terr);
336
337 hwid->SetBinContent(ix, trms);
338 hwid->SetBinError( ix, 0);
339
340 hres->SetBinContent(ix, tmean>EPSILON ? trms/tmean:0);
341 hres->SetBinError( ix, 0);
342
343 delete htmp;
344 }
345
346 TH1 *hhs[]={hnor, hmpv, hwid, hres};
347 const TString yt[]={"N", "MPV", "#sigma", "#sigma/MPV"};
348 const Int_t nh = sizeof(hhs)/sizeof(TH1*);
349 for(Int_t ii=0; ii<nh; ii++){
350 hhs[ii]->SetYTitle(Form("%s of %s", yt[ii].Data(), hh->GetYaxis()->GetTitle()));
351 hhs[ii]->SetXTitle(hh->GetXaxis()->GetTitle());
352 hhs[ii]->GetYaxis()->SetTitleOffset(hh->GetYaxis()->GetTitleOffset());
353 hhs[ii]->SetTitle(hh->GetTitle());
354 }
355}
356
357//===================================================================================
358// TRD Analysis Fast Tool
359//===================================================================================
360
361Int_t AliTRDdEdxUtils::GetNtracklet(const AliESDEvent *esd)
362{
363 //
364 //number of trd tracklet in one esd event
365 //
366 const Int_t ntrk0 = esd->GetNumberOfTracks();
367 Int_t ntrdv1=0;
368 for(Int_t ii=0; ii<ntrk0; ii++){
369 ntrdv1 += esd->GetTrack(ii)->GetTRDntracklets();
370 }
371 return ntrdv1;
372}
373
374AliTRDtrackV1 * AliTRDdEdxUtils::GetTRDtrackV1(const AliESDtrack * esdtrack)
375{
376 //
377 //Get TRD friend track
378 //
379
380 AliESDfriendTrack * friendtrk = (AliESDfriendTrack *)esdtrack->GetFriendTrack();
381 if(!friendtrk){
382 //printf("xlulog AliAnalysisTaskCosmicTRD::GetTRDtrack no friend!!\n"); exit(1);
383 return 0x0;
384 }
385
386 TObject *calibObject=0x0;
387 AliTRDtrackV1 * trdtrack=0x0;
388 for(Int_t l=0; (calibObject=friendtrk->GetCalibObject(l)); l++) {
389 if( (trdtrack=dynamic_cast<AliTRDtrackV1*>(calibObject)) )
390 break;
391 }
392
393 return trdtrack;
394}
395
396Bool_t AliTRDdEdxUtils::IsInSameStack(const AliTRDtrackV1 *trdtrack)
397{
398 //
399 // to check if all tracklets are in the same stack, useful in cosmic
400 //
401
402 TVectorD secs(18), stks(5);
403
404 for(Int_t ilayer = 0; ilayer < 6; ilayer++){
405 AliTRDseedV1 *tracklet=trdtrack->GetTracklet(ilayer);
406 if(!tracklet)
407 continue;
408
409 const Int_t det = tracklet->GetDetector();
410 const Int_t isector = AliTRDgeometry::GetSector(det);
411 const Int_t istack = AliTRDgeometry::GetStack(det);
412
413 secs[isector] = 1;
414 stks[istack] = 1;
415 }
416
417 if(secs.Sum()!=1 || stks.Sum()!=1){
418 return kFALSE;
419 }
420 else
421 return kTRUE;
422}
423
424Bool_t AliTRDdEdxUtils::GetFirstSectorStackMomentum(const AliTRDtrackV1 *trdtrack, Int_t & isec, Int_t & istk, Double_t & mom)
425{
426 //
427 //as function name
428 //
429 isec = istk = -999;
430 mom = -999;
431
432 for(Int_t ilayer = 0; ilayer < 6; ilayer++){
433 AliTRDseedV1 *tracklet=trdtrack->GetTracklet(ilayer);
434 if(!tracklet)
435 continue;
436
437 const Int_t det = tracklet->GetDetector();
438 isec = AliTRDgeometry::GetSector(det);
439 istk = AliTRDgeometry::GetStack(det);
440
441 mom = tracklet->GetMomentum();
442
443 break;
444 }
445
446 if(isec<0)
447 return kFALSE;
448 else
449 return kTRUE;
450}
451
452//===================================================================================
453// Calibration
454//===================================================================================
455Double_t AliTRDdEdxUtils::GetCalibTPCscale(const Int_t tpcncls, const Double_t tpcsig)
456{
457 //
458 //the scale used in calibration
459 //
460
461 if(tpcncls < CalibTPCnclsCut())
462 return -999;
463
464 if(tpcsig<EPSILON)
465 return -999;
466
467 return tpcsig/120;
468
469}
470
471Int_t AliTRDdEdxUtils::GetPHQIterator(const Bool_t kinvq, const Double_t mag, const Int_t charge)
472{
473 //
474 //iterator for calib obj and hist
475 //
476 return kinvq*4 + (mag>0)*2 + (charge>0);
477}
478
26733ed4 479TObjArray * AliTRDdEdxUtils::GetObjPHQ()
480{
481 //
482 //return fgObjPHQ, initialized if null
483 //
484
485 if(!fgObjPHQ){
486 fgObjPHQ = new TObjArray(8);
487 }
488
489 return fgObjPHQ;
490}
491
fb3d369e 492TObjArray * AliTRDdEdxUtils::GetObjPHQ(const Bool_t kinvq, const Double_t mag, const Int_t charge)
493{
494 //
495 //return calib obj
496 //
497 if(!fgObjPHQ){
26733ed4 498 printf("AliTRDdEdxUtils::GetObjPHQ(kinvq, mag, charge) error fgObjPHQ null!!\n"); exit(1);
fb3d369e 499 }
500
501 return (TObjArray*) fgObjPHQ->At(GetPHQIterator(kinvq, mag, charge));
502}
503
d1d15abc 504THnF * AliTRDdEdxUtils::GetHistPHQ(const Bool_t kinvq, const Double_t mag, const Int_t charge)
fb3d369e 505{
506 //
507 //return calib hist
508 //
d1d15abc 509 return (THnF*) fgHistPHQ->At(GetPHQIterator(kinvq, mag, charge));
fb3d369e 510}
511
512TString AliTRDdEdxUtils::GetPHQName(const Bool_t kobj, const Int_t iter)
513{
514 //
515 //get name of calib obj/hist of PHQ
516 //
517 return Form("TRDCalib%sPHQ%d", kobj?"Obj":"Hist", iter);
518}
519
520void AliTRDdEdxUtils::DeleteCalibObj()
521{
522 //
523 //delete calib obj
524 //
525 delete fgObjGain;
526 delete fgObjT0;
527 delete fgObjVd;
528
529 fgObjGain = 0x0;
530 fgObjT0 = 0x0;
531 fgObjVd = 0x0;
532
533 if(fgObjPHQ){
534 fgObjPHQ->SetOwner();
535 delete fgObjPHQ;
536 fgObjPHQ = 0x0;
537 }
538}
539
540Bool_t AliTRDdEdxUtils::GenerateDefaultPHQOCDB(const TString path)
541{
542 //
543 //generate default OCDB object PHQ, do like
544 //AliTRDdEdxUtils::GenerateDefaultPHQOCDB("local://./")
545 //
546
547 TObjArray * arr8 = new TObjArray(8);
548 arr8->SetOwner();
549
550 for(Int_t ii=0; ii<8; ii++){
551 TObjArray * arr1 = new TObjArray(1);
552 arr1->SetOwner();
553 arr1->SetName(GetPHQName(1, ii));
554
555 const Int_t nbins = NTRDtimebin();
556 TVectorD * vec = new TVectorD(nbins);
557 for(Int_t jj=0; jj<nbins; jj++){
558 (*vec)[jj] = 1;
559 }
560 arr1->Add(vec);
561 arr8->Add(arr1);
562 }
563
564 AliCDBMetaData *metaData= new AliCDBMetaData();
565 metaData->SetObjectClassName("TObjArray");
566 metaData->SetResponsible("Raphaelle Bailhache and Xianguo Lu");
567
568 AliCDBId id1("TRD/Calib/PHQ", 0, 999999999);
569 AliCDBStorage * gStorage = AliCDBManager::Instance()->GetStorage(path);
570 gStorage->Put(arr8, id1, metaData);
571
572 delete metaData;
573 delete arr8;
574
575 return kTRUE;
576}
577
578void AliTRDdEdxUtils::IniCalibObj()
579{
580 //
581 //set CalibObj from file, clone to static calib obj
582 //
583
584 DeleteCalibObj();
585
586 TFile *cfile=new TFile(fgCalibFile);
587 if(!cfile->IsOpen()){
588 printf("AliTRDdEdxUtils::IniCalibObj error fgCalibFile not open! %s\n", fgCalibFile.Data());exit(1);
589 }
590
591 printf("\nAliTRDdEdxUtils::IniCalibObj file: %s\n", fgCalibFile.Data());
592
593 //---
594 const TString objnames[] ={"TRDCalibObjGain", "TRDCalibObjT0", "TRDCalibObjVd"};
595 TObjArray ** gobjs[]={ &fgObjGain, &fgObjT0, &fgObjVd};
596
597 const Int_t nobj = sizeof(objnames)/sizeof(TString);
598 for(Int_t iobj=0; iobj<nobj; iobj++){
599 TObjArray *tmpo=0x0;
600 cfile->GetObject(objnames[iobj], tmpo);
601 if(!tmpo){
602 printf("AliTRDdEdxUtils::IniCalibObj error obj %s not found!\n", objnames[iobj].Data()); exit(1);
603 }
604
605 (*gobjs[iobj])=(TObjArray*)tmpo->Clone();
606 (*gobjs[iobj])->SetOwner();
607 }
608
609 fgObjPHQ = new TObjArray(8);
610 for(Int_t iter=0; iter<8; iter++){
611 const TString objn = GetPHQName(1, iter);
612 TObjArray *tmpo=0x0;
613 cfile->GetObject(objn, tmpo);
614 if(!tmpo){
615 printf("AliTRDdEdxUtils::IniCalibObj error obj %s not found!\n", objn.Data()); exit(1);
616 }
617
618 TObjArray *obji=(TObjArray*) tmpo->Clone();
619 obji->SetOwner();
620 fgObjPHQ->AddAt(obji, iter);
621 }
622
623 //---
624
625 cfile->Close();
626 delete cfile;
627}
628
629void AliTRDdEdxUtils::DeleteCalibHist()
630{
631 //
632 //delete calib hist
633 //
634 delete fgHistGain;
635 delete fgHistT0;
636 delete fgHistVd;
637
638 fgHistGain = 0x0;
639 fgHistT0 = 0x0;
640 fgHistVd = 0x0;
641
642 //fgHistPHQ owns the hists
643 fgHistPHQ->SetOwner();
644 fgHistPHQ->Clear();
645}
646
647void AliTRDdEdxUtils::IniCalibHist(TList *list, const Bool_t kPHQonly)
648{
649 //
650 //initialize calib hist, list should not own the hist, or list->Clear/delete hist should not be called
651 //
652
653 DeleteCalibHist();
654
655 Int_t nbin[2];
656 const Double_t xmin[2]={0, 0};
657 Double_t xmax[2];
658
659 nbin[0]=NTRDtimebin(); nbin[1]= 11250; xmax[0]=nbin[0]; xmax[1]=20;
660 for(Int_t iter=0; iter<8; iter++){
661 const TString hn = GetPHQName(0, iter);
d1d15abc 662 THnF *hi = new THnF(hn, "", 2, nbin, xmin, xmax);
fb3d369e 663 //fgHistPHQ owns the hists
664 fgHistPHQ->AddAt(hi, iter);
665 list->Add(hi);
666 }
667
668 if(kPHQonly)
669 return;
670
d1d15abc 671 nbin[0]=NTRDchamber(); nbin[1]= 11250; xmax[0]=nbin[0]; xmax[1]=20; fgHistGain = new THnF("TRDCalibHistGain", "", 2, nbin, xmin, xmax);
672 nbin[0]=NTRDchamber(); nbin[1]= 11250; xmax[0]=nbin[0]; xmax[1]=AliTRDseedV1::kNtb; fgHistT0 = new THnF("TRDCalibHistT0", "", 2, nbin, xmin, xmax);
673 nbin[0]=NTRDchamber(); nbin[1]= 11250; xmax[0]=nbin[0]; xmax[1]=AliTRDseedV1::kNtb; fgHistVd = new THnF("TRDCalibHistVd", "", 2, nbin, xmin, xmax);
fb3d369e 674
675 list->Add(fgHistGain);
676 list->Add(fgHistT0);
677 list->Add(fgHistVd);
678}
679
680Bool_t AliTRDdEdxUtils::ReadCalibHist(const TString filename, const TString listname)
681{
682 //
683 //used in AliTRDPreprocessorOffline
684 //read in calib hist from file, only for PHQ
685 //
686 DeleteCalibHist();
687
688 //maybe already open by others... don't close
689 TFile fcalib(filename);
690
691 TObjArray * array = (TObjArray*)fcalib.Get(listname);
692
693 for(Int_t iter=0; iter<8; iter++){
694 const TString hn = GetPHQName(0, iter);
d1d15abc 695 THnF * tmph=0x0;
fb3d369e 696 if(array){
d1d15abc 697 tmph = (THnF *) array->FindObject(hn);
fb3d369e 698 }
699 else{
d1d15abc 700 tmph = (THnF *) fcalib.Get(hn);
fb3d369e 701 }
702 if(!tmph){
703 printf("AliTRDdEdxUtils::ReadCalibHist warning calib hist not found! %s %s\n", filename.Data(), listname.Data());
704 fcalib.ls();
879b7730 705 if(array){
706 array->ls();
707 }
fb3d369e 708 return kFALSE;
709 }
d1d15abc 710 THnF *hi = (THnF*)tmph->Clone();
fb3d369e 711 fgHistPHQ->AddAt(hi, iter);
712 }
713
714 return kTRUE;
715}
716
d1d15abc 717void AliTRDdEdxUtils::FillCalibHist(const Int_t ncls, const TVectorD *arrayQ, const TVectorD *arrayX, THnF * hcalib, const Double_t scale)
fb3d369e 718{
719 //
720 //fill calibration hist
721 //
722 if(!hcalib){printf("AliTRDdEdxUtils::FillCalibHist errro hcalib null!!\n"); exit(1);}
723
724 for(Int_t ii=0; ii<ncls; ii++){
725 const Double_t dq = (*arrayQ)[ii];
726 const Double_t xx = (*arrayX)[ii];
727
728 const Double_t qmax = hcalib->GetAxis(1)->GetXmax() -0.5 * hcalib->GetAxis(1)->GetBinWidth(1);
729 const Double_t xmin = hcalib->GetAxis(0)->GetXmin();
730 const Double_t xmax = hcalib->GetAxis(0)->GetXmax();
731
732 if(xx>=xmax || xx<xmin){
733 printf("AliTRDdEdxUtils::FillCalibHist error x overflow or underflow! %s %15f %15f %15f\n", hcalib->GetName(), xx, xmin, xmax); exit(1);
734 }
735
736 const Double_t var[]={xx, TMath::Min(dq, qmax)/scale};
737 hcalib->Fill(var);
738 }
739}
740
741void AliTRDdEdxUtils::FillCalibHist(const AliTRDtrackV1 *trdv1, const Bool_t kinvq, const Double_t mag, const Int_t charge, const Double_t scale)
742{
743 //
744 //get cluster Q and fill calib hist, if kinvq = kTRUE, 1/Q is filled
745 //
746
d1d15abc 747 THnF * hcalib = AliTRDdEdxUtils::GetHistPHQ(kinvq, mag, charge);
fb3d369e 748
749 TVectorD arrayQ(200), arrayX(200);
750 const Int_t ncls = AliTRDdEdxUtils::GetArrayClusterQ(kinvq, &arrayQ, &arrayX, trdv1);
751 FillCalibHist(ncls, &arrayQ, &arrayX, hcalib, kinvq ? 1/scale : scale);
752
753 static Int_t kprint = 100;
754 if(kprint<0){
755 printf("\nAliTRDdEdxUtils::FillCalibHist summary: \n");
756 printf("\nkinvq= %d;\n", kinvq);
757 for(Int_t iq=0; iq<ncls; iq++){
758 printf("arrayX[%3d] = %15.0f; arrayQ[%3d] = %15f;\n", iq, arrayX[iq], iq, arrayQ[iq]);
759 }
760 printf("\n");
761 }
762 kprint++;
763}
764
765Int_t AliTRDdEdxUtils::ApplyCalib(const Int_t nc0, TVectorD *arrayQ, TVectorD *arrayX, const TObjArray *cobj)
766{
767 //
768 //apply calibration on arrayQ
769 //
770 if(!cobj){ printf("AliTRDdEdxUtils::ApplyCalib error gain array null!!\n"); exit(1);}
771
772 TVectorD tmpq(arrayQ->GetNrows());
773 TVectorD tmpx(arrayX->GetNrows());
774 Int_t ncls = 0;
775
776 const TVectorD * gain = (TVectorD*) cobj->At(0);
777 for(Int_t ii=0; ii<nc0; ii++){
778 const Double_t dq = (*arrayQ)[ii];
779 const Int_t xx = (Int_t)(*arrayX)[ii];
780 const Double_t gg = (*gain)[xx];
781
782 if(gg<EPSILON){
783 continue;
784 }
785
786 tmpq[ncls] = dq*gg;
787 tmpx[ncls] = xx;
788 ncls++;
789 }
790
791 (*arrayQ)=tmpq;
792 (*arrayX)=tmpx;
793
794 return ncls;
795}
796
797void AliTRDdEdxUtils::GetPHCountMeanRMS(const TH1D *hnor, TH1D *&hmean)
798{
799 //
800 //calculate from the ph calib hist the (mean-3sigma) ph-count in the chamber, save in the TH1D output
801 //
802 const Int_t ndet = 540;
803 TObjArray *obj=new TObjArray(ndet);
804 obj->SetOwner();
805 for(Int_t ii=0; ii<ndet; ii++){
806 obj->Add(new TVectorD(AliTRDseedV1::kNtb));
807 }
808
809 //ibin = binlowedge of bin(ibin+1) = the number fills this bin
810 for(Int_t ibin=0; ibin<hnor->GetNbinsX(); ibin++){
811 const Double_t stat = hnor->GetBinContent(ibin+1);
812 if(stat<EPSILON){
813 continue;
814 }
815
816 const Int_t idet = ToDetector(ibin);
817 const Int_t itb = ToTimeBin(ibin);
818 TVectorD *vec=(TVectorD *)obj->At(idet);
819 (*vec)[itb] = stat;
820 }
821
822 hmean = new TH1D(Form("%sdetmean", hnor->GetName()), "", hnor->GetNbinsX(), hnor->GetXaxis()->GetXmin(), hnor->GetXaxis()->GetXmax());
823 for(Int_t ibin=0; ibin<hnor->GetNbinsX(); ibin++){
824 const Int_t idet = ToDetector(ibin);
825 const TVectorD *vec=(TVectorD *)obj->At(idet);
826
827 Int_t nonzero = 0;
828 for(Int_t ii=0; ii<vec->GetNrows(); ii++){
829 if((*vec)[ii]>EPSILON){
830 nonzero++;
831 }
832 }
833
834 Double_t mean = 0;
835 const Double_t lowfrac = 0.6;
836 //if there are too many 0's, reject this chamber by settig mean=rms=0
837 if(nonzero> (AliTRDseedV1::kNtb*(1-lowfrac)) ){
838 //only highest (1-lowfrac)*31 timebins are used to estimate the mean and rms! important! otherwise the 0' will make rms very large!
839 mean = TruncatedMean(AliTRDseedV1::kNtb, vec->GetMatrixArray(), lowfrac, 1);
840 }
841
842 hmean->SetBinContent(ibin+1, mean);
843 }
844
845 delete obj;
846}
847
848void AliTRDdEdxUtils::CalibOutput(const TList *lin, Int_t run)
849{
850 //
851 //produce calibration objects
852 //
853
854 TString objnames("TRDCalibHistGain TRDCalibHistT0 TRDCalibHistVd ");
855 for(Int_t iter=0; iter<8; iter++){
856 objnames+= GetPHQName(0, iter)+" ";
857 }
858
859 TList * lout = new TList;
860 lout->SetOwner();
861
862 TTreeSRedirector *calibStream = new TTreeSRedirector(Form("TRDCalibStream_%010d.root", run));
863
864 const Int_t nh=lin->GetEntries();
865 for(Int_t ii=0; ii<nh; ii++){
d1d15abc 866 const THnF *hh=(THnF*)lin->At(ii);
fb3d369e 867 const TString hname = hh->GetName();
868 if(!objnames.Contains(hname))
869 continue;
870
871 TObjArray * cobj0 = GetCalibObj(hh, run, lout, calibStream);
872 lout->Add(cobj0);
873 }
874
875 //lout->ls();
876
877 //=============================================================
878 //=============================================================
879
880 TFile *fout=new TFile(Form("TRDCalibObj_%010d.root", run),"recreate");
881 fout->cd();
882 const Int_t nout=lout->GetEntries();
883 for(Int_t ii=0; ii<nout; ii++){
884 const TString oname = lout->At(ii)->GetName();
885 if(oname.Contains("Obj")){
886 TObjArray * cobj = (TObjArray*) lout->At(ii);
887 cobj->Write(oname, TObjArray::kSingleKey);
888 }
889 }
890 fout->Save();
891 fout->Close();
892 delete fout;
893
894 fout=new TFile(Form("TRDCalibList_%010d.root", run),"recreate");
895 fout->cd();
896 lin->Write();
897 lout->Write();
898 fout->Save();
899 fout->Close();
900 delete fout;
901
902 delete calibStream;
903
904 /*
905 http://root.cern.ch/root/html/TH1.html
906 When an histogram is created, a reference to it is automatically added to the list of in-memory objects for the current file or directory. This default behaviour can be changed by:
907
908 h->SetDirectory(0); for the current histogram h
909 TH1::AddDirectory(kFALSE); sets a global switch disabling the reference
910
911 When the histogram is deleted, the reference to it is removed from the list of objects in memory. When a file is closed, all histograms in memory associated with this file are automatically deleted.
912 */
913 delete lout;
914}
915
d1d15abc 916TObjArray* AliTRDdEdxUtils::GetCalibObj(const THnF *hh, Int_t run, TList *lout, TTreeSRedirector *calibStream)
fb3d369e 917{
918 //
919 //produce calibration objects
920 //
921
922 const TString hname = hh->GetName();
923 const Bool_t kinvq = TString(hname(hname.First('Q')+1,1)).Atoi()&4;
924
925 //----------------------------------------
926 // Define nbin, tag, cobj0
927 //----------------------------------------
928 Int_t nbin =-999;
929 if(hname.Contains("Gain") || hname.Contains("T0") || hname.Contains("Vd")){
930 nbin = NTRDchamber();
931 }
932 else if(hname.Contains("PHQ")){
933 nbin = NTRDtimebin();
934 }
935 else{
936 printf("AliTRDdEdxUtils::GetCalibObj error wrong hname!! %s\n", hname.Data()); exit(1);
937 }
938
939 TString tag(hname);
940 tag.ReplaceAll("Hist","Obj");
941
942 TObjArray * cobj0 = new TObjArray(1);
943 cobj0->SetOwner();
944 cobj0->SetName(tag);
945 cobj0->Add(new TVectorD(nbin));
946
947 //----------------------------------------
948 // Define lowFrac, highFrac
949 //----------------------------------------
950 Double_t lowFrac = -999, highFrac = -999;
951 if(hname.Contains("Gain") || (hname.Contains("PHQ") && !kinvq) ){
952 lowFrac = 0.01; highFrac = Q0Frac();
953 }
954 else if(hname.Contains("PHQ") && kinvq){
955 lowFrac = Q1Frac(); highFrac = 0.99;
956 }
957 else{
958 lowFrac = 0.01;
959 highFrac = 0.99;
960 }
961
962 //----------------------------------------
963 // Get analysis result
964 //----------------------------------------
965 TH1::AddDirectory(kFALSE);//important!
966 TH1D *hnor=0x0, *hmpv=0x0, *hres=0x0, *hwid=0x0, *htrdphmean = 0x0;//if(!lout), these have to be deleted
967 TH2D *hpj = hh->Projection(1,0);
968 FitSlicesY(hpj, hnor, hmpv, hwid, hres, 0, lowFrac, highFrac);
969 if(hname.Contains("PHQ")){
970 GetPHCountMeanRMS(hnor, htrdphmean);
971 if(lout){
972 lout->Add(htrdphmean);
973 }
974 }
975 delete hpj;
976
977 if(lout){
978 lout->Add(hnor);
979 lout->Add(hmpv);
980 lout->Add(hwid);
981 lout->Add(hres);
982 }
983
984 //----------------------------------------
985 // Define Counter
986 //----------------------------------------
987 TVectorD *countDet=0x0;
988 TObjArray *countSSL=0x0;
989
990 if(hname.Contains("PHQ") && !kinvq){
991 countDet=new TVectorD(540);
992 countSSL=new TObjArray(90);//SectorStackLayer
993 countSSL->SetOwner();
994 for(Int_t ii=0; ii<90; ii++){
995 countSSL->Add(new TVectorD(6));
996 }
997 }
998
999 //----------------------------------------
1000 // Fill cobj0
1001 //----------------------------------------
1002
1003 //ibin = binlowedge of bin(ibin+1) = the number fills this bin
1004 for(Int_t ibin=0; ibin<nbin; ibin++){
1005 Double_t gnor = hnor->GetBinContent(ibin+1);
1006 Double_t gmpv = hmpv->GetBinContent(ibin+1);
1007 Double_t gwid = hwid->GetBinContent(ibin+1);
1008 Double_t gres = hres->GetBinContent(ibin+1);
1009
1010 //--- set additional cut by kpass
1011 Bool_t kpass = kTRUE;
1012 Double_t gtrdphmean = -999;
1013 if(htrdphmean){
1014 gtrdphmean = htrdphmean->GetBinContent(ibin+1);
1015 //chamber no statistics (e.g. too many 0's), not usual, not seen in run 143237
1016 if(gtrdphmean<EPSILON){
1017 kpass = kFALSE;
1018 }
1019 if(gnor<TimeBinCountCut()*gtrdphmean){
1020 kpass = kFALSE;
1021 }
1022 }
1023
1024 //--- set calibration constant p0
1025 Double_t p0= 0;
1026
1027 //reason for gmpv=0:
1028 //1)gnor<=3; truncation in hist: (0, 0.6*ntot=1.8 with ntot=3]={1}, in hist entries can pile up so that ntot=2, or 3, and (ntot>nstart && ntot<=nstop) is skipped;
1029 //2)TruncatedMean(hist) out of range (only for Q0, not Q1).
1030
1031 if(gmpv>EPSILON && kpass){
1032 if(tag.Contains("T0")){
1033 p0 = gmpv;
1034 }
1035 else{
1036 p0 = 1/gmpv;
1037 }
1038 //printf("outcalibobj%s %d %15.6e\n", tag.Data(), ibin, p0);
1039 }
1040
1041 (*( (TVectorD*)cobj0->At(0) ))[ibin] = p0;
1042
1043 //--- save optional record
1044 if(p0>EPSILON && countDet && countSSL){
1045 const Int_t idet = ToDetector(ibin);
1046 (*countDet)[idet]=1;
1047
1048 const Int_t isector = ToSector(ibin);
1049 const Int_t istack = ToStack(ibin);
1050 const Int_t ilayer = ToLayer(ibin);
1051 TVectorD * vecsectorstack = (TVectorD*)countSSL->At(istack*18+isector);
1052 (*vecsectorstack)[ilayer]=1;
1053 }
1054
1055 if(calibStream){
1056 (*calibStream)<<tag<<
1057 "run="<<run<<
1058 "p0="<<p0<<
1059
1060 "nor="<<gnor<<
1061 "mpv="<<gmpv<<
1062 "wid="<<gwid<<
1063 "res="<<gres<<
1064 "gtrdphmean="<<gtrdphmean<<
1065
1066 "ibin="<<ibin<<
1067 "\n";
1068 }
1069 }
1070
1071 //----------------------------------------
1072 // Status Report
1073 //----------------------------------------
1074 if(countDet && countSSL){
1075 TVectorD count2Dstack(90);
1076 for(Int_t ii=0; ii<90; ii++){
1077 TVectorD * vecsectorstack = (TVectorD*)countSSL->At(ii);
1078 const Int_t nlayer = (Int_t)vecsectorstack->Sum();
1079 if(nlayer==6){
1080 count2Dstack[ii]=1;
1081 }
1082 }
1083
1084 printf("\nAliTRDdEdxUtils::GetCalibObj Summary run: %d name: %s entries: %.0f ndetector: %03.0f n2dstack %02.0f\n\n", run, hname.Data(), hh->GetEntries(), countDet->Sum(), count2Dstack.Sum());
1085 }
1086
1087 //----------------------------------------
1088 // Clean Up
1089 //----------------------------------------
1090
1091 TH1D **hhs[]={&hnor, &hmpv, &hwid, &hres, &htrdphmean};
1092 const Int_t nhh=sizeof(hhs)/sizeof(TH1D**);
1093 for(Int_t ihh=0; ihh<nhh; ihh++){
1094 if(!lout){
1095 delete (*hhs[ihh]);
1096 }
1097 }
1098
1099 delete countDet;
1100 delete countSSL;
1101
1102 //----------------------------------------
1103
1104 return cobj0;
1105}
1106
1107//===================================================================================
1108// dEdx calculation
1109//===================================================================================
fb3d369e 1110Double_t AliTRDdEdxUtils::ToyCook(const Bool_t kinvq, Int_t &ncluster, TVectorD *arrayQ, TVectorD *arrayX, const TObjArray *cobj)
1111{
1112 //
1113 //template for cookdedx
1114 //
1115 if(cobj){
1116 if(arrayQ && arrayX){
1117 ncluster = ApplyCalib(ncluster, arrayQ, arrayX, cobj);
1118 }
1119 else{
1120 printf("AliTRDdEdxUtils::ToyCook arrayQ arrayX null, applycalib can not be applied!\n"); exit(1);
1121 }
1122 }
1123
1124 Double_t lowFrac =-999, highFrac = -999;
1125 if(kinvq){
1126 lowFrac = Q1Frac(); highFrac = 0.99;
1127 }
1128 else{
1129 lowFrac = 0.01; highFrac = Q0Frac();
1130 }
1131
1132 Double_t meanQ = TruncatedMean(ncluster, arrayQ->GetMatrixArray(), lowFrac, highFrac);
1133 if(kinvq){
1134 if(meanQ>EPSILON){
1135 meanQ = 1/meanQ;
1136 }
1137 }
1138
1139 return meanQ;
1140}
1141
1142Double_t AliTRDdEdxUtils::CombineddEdx(const Bool_t kinvq, Int_t &concls, TVectorD *coarrayQ, TVectorD *coarrayX, const Int_t tpcncls, const TVectorD *tpcarrayQ, const TVectorD *tpcarrayX, const Int_t trdncls, const TVectorD *trdarrayQ, const TVectorD *trdarrayX)
1143{
1144 //
1145 //combine tpc and trd dedx
1146 //
1147
1148 for(Int_t iq=0; iq<tpcncls; iq++){
1149 (*coarrayQ)[iq]=(*tpcarrayQ)[iq];
1150 if(tpcarrayX && trdarrayX && coarrayX){
1151 (*coarrayX)[iq]=(*tpcarrayX)[iq];
1152 }
1153 }
1154 for(Int_t iq=0; iq<trdncls; iq++){
1155 (*coarrayQ)[tpcncls+iq]=(*trdarrayQ)[iq];
1156 if(tpcarrayX && trdarrayX && coarrayX){
1157 (*coarrayX)[tpcncls+iq]=159+(*trdarrayX)[iq];
1158 }
1159 }
1160
1161 concls=trdncls+tpcncls;
1162
1163 const Double_t coQ = ToyCook(kinvq, concls, coarrayQ, coarrayX);
1164
1165 return coQ;
1166}
1167
1168
1169//===================================================================================
1170// dEdx Getter and Setter
1171//===================================================================================
1172Double_t AliTRDdEdxUtils::GetAngularCorrection(const AliTRDseedV1 *seed)
1173{
1174 //
1175 //return angular normalization factor
1176 //
1177
1178 return TMath::Sqrt(1+seed->GetYref(1)*seed->GetYref(1)+seed->GetZref(1)*seed->GetZref(1));
1179}
1180
d0037ea4 1181Double_t AliTRDdEdxUtils::GetPadGain(const Int_t det, const Int_t icol, const Int_t irow)
1182{
1183 //
1184 //get pad calibration
1185 //
1186 AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
1187 if (!calibration) {
1188 printf("AliTRDdEdxUtils::GetPadCalib No AliTRDcalibDB instance available\n"); exit(1);
1189 }
1190 AliTRDCalROC * calGainFactorROC = calibration->GetGainFactorROC(det);
1191 if(!calGainFactorROC){
1192 printf("AliTRDdEdxUtils::GetPadCalib no calGainFactorROC!\n"); exit(1);
1193 }
1194
1195 Double_t padgain = -999;
1196 if( icol >= 0 &&
1197 icol < calGainFactorROC->GetNcols() &&
1198 irow >=0 &&
1199 irow < calGainFactorROC->GetNrows()){
1200 padgain = calGainFactorROC->GetValue(icol, irow);
1201 if(padgain<EPSILON){
1202 printf("AliTRDdEdxUtils::GetPadGain padgain 0! %f %f -- %d %d %d -- %d %d\n", padgain, EPSILON, det, icol, irow, calGainFactorROC->GetNcols(), calGainFactorROC->GetNrows()); exit(1);
1203 }
1204 }
1205 else{
1206 //printf("\nAliTRDdEdxUtils::GetPadGain warning!! indices out of range %d %d %d -- %d %d\n\n", det, icol, irow, calGainFactorROC->GetNcols(), calGainFactorROC->GetNrows() );
1207 }
1208
1209 return padgain;
1210}
1211
1212Double_t AliTRDdEdxUtils::GetRNDClusterQ(AliTRDcluster *cl)
1213{
1214 //
1215 //get cluter q from GetRawQ, apply baseline and Kr pad-calibration
1216 //
1217
1218 const Int_t det = cl->GetDetector();
1219 const Int_t pad3col = cl->GetPadCol();
1220 const Int_t padrow = cl->GetPadRow();
1221
1222 const Double_t baseline = 10;
1223
1224 Double_t rndqsum = 0;
1225 for(Int_t ii=0; ii<7; ii++){
25d9c307 1226 if(cl->GetSignals()[ii] < EPSILON){//bad pad marked by electronics
1227 continue;
1228 }
d0037ea4 1229
25d9c307 1230 const Int_t icol = pad3col+(ii-3);
1231 const Double_t padgain = GetPadGain(det, icol, padrow);
1232 if(padgain<0){//indices out of range, pad3col near boundary case
d0037ea4 1233 continue;
1234 }
1235
25d9c307 1236 const Double_t rndsignal = (cl->GetSignals()[ii] - baseline)/(IsPadGainOn()? padgain : 1);
d0037ea4 1237
1238 //sum it anyway even if signal below baseline, as long as the total is positive
1239 rndqsum += rndsignal;
1240 }
1241
1242 return rndqsum;
1243}
1244
fb3d369e 1245Double_t AliTRDdEdxUtils::GetClusterQ(const Bool_t kinvq, const AliTRDseedV1 * seed, const Int_t itb)
1246{
1247 //
1248 //get cluster charge
1249 //
1250 Double_t dq = 0;
d0037ea4 1251 AliTRDcluster *cl = 0x0;
fb3d369e 1252
25d9c307 1253 //GetRNDClusterQ(cl)>0 ensures that the total sum of q is above baseline*NsignalPhysical.
d0037ea4 1254 cl = seed->GetClusters(itb); if(cl && GetRNDClusterQ(cl)>0 ) dq+= GetRNDClusterQ(cl);//cl->GetRawQ();
1255 cl = seed->GetClusters(itb+AliTRDseedV1::kNtb); if(cl && GetRNDClusterQ(cl)>0 ) dq+= GetRNDClusterQ(cl);//cl->GetRawQ();
fb3d369e 1256
1257 dq /= GetAngularCorrection(seed);
1258
d0037ea4 1259 dq /= QScale();
fb3d369e 1260
1261 if(kinvq){
1262 if(dq>EPSILON){
1263 dq = 1/dq;
1264 }
1265 }
1266
1267 return dq;
1268}
1269
1270Int_t AliTRDdEdxUtils::GetArrayClusterQ(const Bool_t kinvq, TVectorD *arrayQ, TVectorD *arrayX, const AliTRDtrackV1 *trdtrack, Int_t timeBin0, Int_t timeBin1, Int_t tstep)
1271{
1272 //
1273 //return nclustter
1274 //(if kinvq, return 1/q array), size of array must be larger than 31*6
1275 //
1276 if(!arrayQ || arrayQ->GetNrows()< (AliTRDseedV1::kNtb*AliTRDtrackV1::kNplane)){
1277 printf("AliTRDdEdxUtils::GetArrayClusterQ error arrayQ null or size too small! %d\n", arrayQ? arrayQ->GetNrows() : -999); exit(1);
1278 }
879b7730 1279 if(!arrayX || arrayX->GetNrows()< (AliTRDseedV1::kNtb*AliTRDtrackV1::kNplane)){
fb3d369e 1280 printf("AliTRDdEdxUtils::GetArrayClusterQ error arrayX null or size too small! %d\n", arrayX? arrayX->GetNrows() : -999); exit(1);
1281 }
1282
1283 const Int_t mintb = 0;
1284 const Int_t maxtb = AliTRDseedV1::kNtb-1;
1285 if(timeBin0<mintb) timeBin0=mintb;
1286 if(timeBin1>maxtb) timeBin1=maxtb;
1287 if(tstep<=0) tstep=1;
1288
1289 //============
1290 Int_t tbN=0;
1291 Double_t tbQ[200];
1292 Int_t tbBin[200];
1293
1294 for(Int_t ichamber=0; ichamber < AliTRDtrackV1::kNplane; ichamber++){
1295 const AliTRDseedV1 * seed = trdtrack->GetTracklet(ichamber);
1296 if(!seed)
1297 continue;
1298
1299 const Int_t det = seed->GetDetector();
1300
1301 for(Int_t itb=timeBin0; itb<=timeBin1; itb+=tstep){
1302 const Double_t dq = GetClusterQ(kinvq, seed, itb);
1303 if(dq<EPSILON)
1304 continue;
1305
1306 const Int_t gtb = det * AliTRDseedV1::kNtb + itb;
1307
1308 tbQ[tbN]=dq;
1309 tbBin[tbN]=gtb;
1310 tbN++;
1311 }
1312 }
1313
1314 Int_t ncls = 0;
1315 for(Int_t iq=0; iq<tbN; iq++){
1316 if(tbQ[iq]<EPSILON)
1317 continue;
1318
1319 (*arrayQ)[ncls] = tbQ[iq];
1320 (*arrayX)[ncls] = tbBin[iq];
1321
1322 ncls++;
1323 }
1324
879b7730 1325 static Int_t kprint = 100;
fb3d369e 1326 if(kprint<0){
1327 printf("\nAliTRDdEdxUtils::GetArrayClusterQ raw cluster-Q\n");
1328 for(Int_t iq=0; iq<ncls; iq++){
1329 const Int_t ichamber = ToLayer((*arrayX)[iq]);
1330 const AliTRDseedV1 * seed = trdtrack->GetTracklet(ichamber);
1331 if(!seed){
1332 printf("error seed null!!\n"); exit(1);
1333 }
1334 const Double_t rawq = (*arrayQ)[iq] * 45. * GetAngularCorrection(seed);
1335 printf("esdid=%d; chamber=%d; timebin=%d; rawq= %.3f; myq[%d]= %e;\n", trdtrack->GetESDid(), ichamber, ToTimeBin((*arrayX)[iq]), rawq, iq, (*arrayQ)[iq]);
1336 }
1337 printf("\n");
1338 }
879b7730 1339 kprint++;
fb3d369e 1340
1341 return ncls;
1342}
1343
1344Int_t AliTRDdEdxUtils::UpdateArrayX(const Int_t ncls, TVectorD* arrayX)
1345{
1346 //
1347 //arrayX det*Ntb+itb -> itb
1348 //
1349
1350 TVectorD countChamber(6);
1351 for(Int_t ii = 0; ii<ncls; ii++){
1352 const Int_t xx = (Int_t)(*arrayX)[ii];
1353 const Int_t idet = ToDetector(xx);
1354
1355 const Double_t ich = AliTRDgeometry::GetLayer(idet);
1356 const Double_t itb = ToTimeBin(xx);
1357 (*arrayX)[ii] = ich*AliTRDseedV1::kNtb+itb;
1358
1359 countChamber[ich] = 1;
1360 }
1361
1362 const Double_t nch = countChamber.Sum();
1363 return (Int_t) nch;
1364}
1365
d1d15abc 1366void AliTRDdEdxUtils::SetChamberQT(const AliTRDtrackV1 *trdtrack, const Int_t kcalib, THnF * hgain, THnF * ht0, THnF * hvd)
fb3d369e 1367{
1368 //
1369 //CookdEdx at TRD track level, use chamber info, related calibrations: chamber-gain; T0, Vd based on raw PH distribution
1370 //
1371
1372 static Int_t kprint = 100;
1373
1374 fgNchamber = 0;
1375 for(Int_t ichamber=0; ichamber < AliTRDtrackV1::kNplane; ichamber++){
1376 //initialize output, default values: 0, so that summation and weighting will automatically discard default quantities
1377 fgChamberQ[ichamber] = fgChamberTmean[ichamber] = 0;
1378
1379 const AliTRDseedV1 *seed = trdtrack->GetTracklet(ichamber);
1380 if (!seed)
1381 continue;
1382
1383 const Int_t idet = seed->GetDetector();
1384
1385 //-------------------------------------------------------------------------
1386
1387 Double_t qsum = 0, qtsum = 0, w2sum = 0;
1388 for(Int_t itb=0; itb<AliTRDseedV1::kNtb; itb++){
1389 const Double_t dq = GetClusterQ(0, seed, itb);
1390 if(dq<EPSILON)
1391 continue;
1392
1393 qsum += dq;
1394 qtsum += dq*itb;
1395 w2sum += dq*itb*itb;
1396 }
1397 if(qsum<EPSILON)
1398 continue;
1399
1400 //-------------------------------------------------------------------------
1401
1402 Double_t tbm, tbr = 0;
1403 tbm = GetMeanRMS(qsum, qtsum, w2sum, &tbr);
1404
1405 qsum /= 1.25e3/45.;
1406
1407 if(hgain){
1408 const Double_t var[]={idet, qsum};
1409 hgain->Fill(var);
1410 }
1411 if(ht0){
1412 const Double_t var[]={idet, tbm};
1413 ht0->Fill(var);
1414 }
1415 if(hvd){
1416 const Double_t var[]={idet, tbr};
1417 hvd->Fill(var);
1418 }
1419
1420 Double_t gain = 1, t0 = 0, vd = 1;
1421 if(kcalib){
1422 if(!fgObjGain) {printf("AliTRDdEdxUtils::SetChamberQT error Gain array null!!\n"); exit(1);}
1423 if(! fgObjT0) {printf("AliTRDdEdxUtils::SetChamberQT error T0 array null!!\n"); exit(1);}
1424 if(! fgObjVd) {printf("AliTRDdEdxUtils::SetChamberQT error Vd array null!!\n"); exit(1);}
1425
1426 const TVectorD * gainvec = (TVectorD*) fgObjGain->At(0); gain = (*gainvec)[idet];
1427 const TVectorD * t0vec = (TVectorD*) fgObjT0->At(0); t0 = (* t0vec)[idet];
1428 const TVectorD * vdvec = (TVectorD*) fgObjVd->At(0); vd = (* vdvec)[idet];
1429 }
1430 if(kprint<0){
1431 printf("\nAliTRDdEdxUtils::CookdEdxV2\n");
1432 printf("idet = %d;\n", idet);
1433 printf("gain = %15f; t0 = %15f; vd = %15f;\n", gain, t0, vd);
1434 printf("\n");
1435 }
1436
1437 qsum *= gain;
1438 tbm = (tbm-t0)*vd;
1439
1440 if(qsum<EPSILON)
1441 continue;
1442
1443 //-------------------------------------------------------------------------
1444
1445 //should have non-zero value, initialized with default 0 (except for calibrated tbm, may be very close to 0)
1446 fgChamberQ[ichamber] = qsum;
1447 fgChamberTmean[ichamber] = tbm;
1448 fgNchamber++;
1449 }
1450
1451 if(kprint<0){
1452 printf("\nAliTRDdEdxUtils::CookdEdxV2 summary:\n");
1453
1454 printf("\nfgNchamber = %d\n", fgNchamber);
1455 for(Int_t ich=0; ich<AliTRDtrackV1::kNplane; ich++){
1456 printf("fgChamberTmean[%d] = %15f; fgChamberQ[%d] = %15f;\n", ich, fgChamberTmean[ich], ich, fgChamberQ[ich]);
1457 }
1458 }
1459
1460 fgTrackTmean = -999;
1461 if(fgNchamber){
1462 fgTrackTmean = 0;
1463 for(Int_t ich=0; ich<AliTRDtrackV1::kNplane; ich++){
1464 fgTrackTmean += fgChamberTmean[ich];
1465 }
1466 fgTrackTmean /= fgNchamber;
1467 }
1468
1469 if(kprint<0){
1470 printf("\nAliTRDdEdxUtils::CookdEdxV2\n");
1471 printf("GetTrackTmean() %15f\n", GetTrackTmean());
1472 printf("\n");
1473 }
1474 kprint++;
1475
1476 return;
1477}
1478
1479
1480//===================================================================================
1481// dEdx Parameterization
1482//===================================================================================
1483
1484Double_t AliTRDdEdxUtils::Q0MeanTRDpp(const Double_t bg)
1485{
1486 //
1487 //truncated Mean Q_{xx} in TRD
1488 //
1489
1490 Double_t par[8];
1491 //03132012161150
1492 //opt: ppQ0
1493par[0]= 2.397001e-01;
1494par[1]= 1.334697e+00;
1495par[2]= 6.967470e+00;
1496par[3]= 9.055289e-02;
1497par[4]= 9.388760e+00;
1498par[5]= 9.452742e-04;
1499par[6]= -1.866091e+00;
1500par[7]= 1.403545e+00;
1501
1502 ///u/xlu/.task/CommondEdx/myAnaData/Optimum/check11/Merged/LHC10e_plot/Separation/see2.log:hhtype2Q0b2c2 scale 0.428543 at ltbg 0.650000
1503 return 0.428543*MeandEdxTR(&bg, par);
1504}
1505
1506Double_t AliTRDdEdxUtils::Q0MeanTRDPbPb(const Double_t bg)
1507{
1508 //
1509 //truncated Mean Q_{xx} in TRD
1510 //
1511
1512 Double_t par[8];
1513
1514 //03132012161259
1515 //opt: PbPbQ0
1516par[0]= 1.844912e-01;
1517par[1]= 2.509702e+00;
1518par[2]= 6.744031e+00;
1519par[3]= 7.355123e-02;
1520par[4]= 1.166023e+01;
1521par[5]= 1.736186e-04;
1522par[6]= -1.716063e+00;
1523par[7]= 1.611366e+00;
1524
1525 ///u/xlu/.task/CommondEdx/myAnaData/Optimum/check11/Merged/LHC10e_plot/Separation/see4.log:hhtype4Q0b2c2 scale 0.460994 at ltbg 0.650000
1526 return 0.460994*MeandEdxTR(&bg, par);
1527}
1528
1529Double_t AliTRDdEdxUtils::Q1MeanTRDpp(const Double_t bg)
1530{
1531 //
1532 //truncated Mean 1/(1/Q)_{xx} in TRD
1533 //
1534
1535 Double_t par[8];
1536
1537