1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 ////////////////////////////////////////////////////////////////////////////
19 // Gain calibration using tracks
22 // 1.) Inner TPC gain alignement - (parabolic) parameterization (inside of one sector)
23 // 2.) Angular and z-position correction (parabolic) parameterization
24 // 3.) Sector gain alignment
26 // Following histograms are accumulated
27 // a.) Simple 1D histograms per chamber
28 // b.) Profile histograms per chamber - local x dependence
29 // c.) 2D Profile histograms - local x - fi dependence
31 // To get the gain map - the simple solution - use the histograms - is not enough
32 // The resulting mean amplitude map depends strongly on the track topology
33 // These dependence can be reduced, taking into account angular effect, and diffusion effect
34 // Using proper fit modeles
39 // === Calibration class for gain calibration using tracks ===
43 // A 6-parametric parabolic function
45 // G(x, y) = p0 + p1*x + p2*y + p3*x^2 + p4*y^2 + p5 * x*y
47 // is fitted to the maximum charge values or total charge values of
48 // all the clusters contained in the tracks that are added to this
49 // object. This fit is performed for each read out chamber, in fact even
50 // for each type of pad sizes (thus for one segment, which consists of
51 // an IROC and an OROC, there are three fitters used, corresponding to
52 // the three pad sizes). The coordinate origin is at the center of the
53 // particular pad size region on each ROC.
55 // Because of the Landau nature of the charge deposition we use
56 // different "types" of fitters instead of one to minimize the effect
57 // of the long Landau tail. The difference between the fitters is only
58 // the charge value, that is put into them, i.e. the charge is subject
59 // to a transformation. At this point we use three different fit types:
61 // a) simple: the charge is put in as it is
62 // b) sqrt: the square root of the charge is put into the fitter
63 // c) log: fgkM * Log(1+q/fgkM) is put into the fitter, with
64 // q being the untransformed charge and fgkM=25
66 // The results of the fits may be visualized and further used by
67 // creating an AliTPCCalROC or AliTPCCalPad. You may specify to undo
68 // the transformation and/or to normalize to the pad size.
70 // Not every track you add to this object is actually used for
71 // calibration. There are some cuts and conditions to exclude bad
72 // tracks, e.g. a pt cut to cut out tracks with too much charge
73 // deposition or a cut on edge clusters which are not fully
74 // registered and don't give a usable signal.
76 // 2) Interface / usage
77 // ====================
78 // For each track to be added you need to call Process().
79 // This method expects an AliTPCseed, which contains the necessary
80 // cluster information. At the moment of writing this information
81 // is stored in an AliESDfriend corresponding to an AliESD.
82 // You may also call AddTrack() if you don't want the cuts and
83 // other quality conditions to kick in (thus forcing the object to
84 // accept the track) or AddCluster() for adding single clusters.
85 // Call one of the Evaluate functions to evaluate the fitter(s) and
86 // to retrieve the fit parameters, erros and so on. You can also
87 // do this later on by using the different Getters.
89 // The visualization methods CreateFitCalPad() and CreateFitCalROC()
90 // are straight forward to use.
92 // Note: If you plan to write this object to a ROOT file, make sure
93 // you evaluate all the fitters *before* writing, because due
94 // to a bug in the fitter component writing fitters doesn't
95 // work properly (yet). Be aware that you cannot re-evaluate
96 // the fitters after loading this object from file.
97 // (This will be gone for a new ROOT version > v5-17-05)
99 ////////////////////////////////////////////////////////////////////////////
101 #include <TPDGCode.h>
104 #include "TMatrixD.h"
105 #include "TTreeStream.h"
107 #include "AliTPCParamSR.h"
108 #include "AliTPCClusterParam.h"
109 #include "AliTrackPointArray.h"
111 #include "AliTPCcalibTracksGain.h"
114 #include <TLinearFitter.h>
115 #include <TTreeStream.h>
117 #include <TCollection.h>
118 #include <TIterator.h>
124 #include "AliMathBase.h"
126 #include "AliTPCROC.h"
127 #include "AliTPCParamSR.h"
128 #include "AliTPCCalROC.h"
129 #include "AliTPCCalPad.h"
130 #include "AliTPCClusterParam.h"
132 #include "AliTracker.h"
134 #include "AliESDtrack.h"
135 #include "AliESDfriend.h"
136 #include "AliESDfriendTrack.h"
137 #include "AliTPCseed.h"
138 #include "AliTPCclusterMI.h"
139 #include "AliTPCcalibTracksCuts.h"
140 #include "AliTPCFitPad.h"
142 // REMOVE ALL OF THIS
144 #include "AliESDEvent.h"
148 TFile f("TPCCalibTracksGain.root")
150 gSystem->Load("libPWG1.so")
156 TString * str = comp.FitPlane("Cl.fQ/dedxQ.fElements[0]","Cl.fY++Cl.fX","Cl.fDetector<36",chi2,vec,mat)
160 ClassImp(AliTPCcalibTracksGain)
162 const Bool_t AliTPCcalibTracksGain::fgkUseTotalCharge = kTRUE;
163 const Double_t AliTPCcalibTracksGain::fgkM = 25.;
164 const char* AliTPCcalibTracksGain::fgkDebugStreamFileName = "TPCCalibTracksGain.root";
165 AliTPCParamSR* AliTPCcalibTracksGain::fgTPCparam = new AliTPCParamSR();
167 AliTPCcalibTracksGain::AliTPCcalibTracksGain() :
169 fCuts(0), // cuts that are used for sieving the tracks used for calibration
171 // Simple Array of histograms
173 fArrayQM(0), // Qmax normalized
174 fArrayQT(0), // Qtot normalized
175 fProfileArrayQM(0), // Qmax normalized versus local X
176 fProfileArrayQT(0), // Qtot normalized versus local X
177 fProfileArrayQM2D(0), // Qmax normalized versus local X and phi
178 fProfileArrayQT2D(0), // Qtot normalized versus local X and phi
182 fSimpleFitter(0), // simple fitter for short pads
183 fSqrtFitter(0), // sqrt fitter for medium pads
184 fLogFitter(0), // log fitter for long pads
185 fFitter0M(0), // fitting of the atenuation, angular correction, and mean chamber gain
186 fFitter1M(0), // fitting of the atenuation, angular correction, and mean chamber gain
187 fFitter2M(0), // fitting of the atenuation, angular correction, and mean chamber gain
188 fFitter0T(0), // fitting of the atenuation, angular correction, and mean chamber gain
189 fFitter1T(0), // fitting of the atenuation, angular correction, and mean chamber gain
190 fFitter2T(0), // fitting of the atenuation, angular correction, and mean chamber gain
191 fSingleSectorFitter(0), // just for debugging
195 fTotalTracks(0), // just for debugging
196 fAcceptedTracks(0), // just for debugging
197 fDebugCalPadRaw(0), // just for debugging
198 fDebugCalPadCorr(0), // just for debugging
199 fPrevIter(0) // the calibration object in its previous iteration (will not be owned by the new object, don't forget to delete it!)
203 // Default constructor.
207 AliTPCcalibTracksGain::AliTPCcalibTracksGain(const AliTPCcalibTracksGain& obj) :
208 AliTPCcalibBase(obj),
209 fCuts(obj.fCuts), // cuts that are used for sieving the tracks used for calibration
210 fArrayQM(0), // Qmax normalized
211 fArrayQT(0), // Qtot normalized
215 fProfileArrayQM(obj.fProfileArrayQM), // Qmax normalized versus local X
216 fProfileArrayQT(obj.fProfileArrayQT), // Qtot normalized versus local X
217 fProfileArrayQM2D(obj.fProfileArrayQM2D), // Qmax normalized versus local X and phi
218 fProfileArrayQT2D(obj.fProfileArrayQT2D), // Qtot normalized versus local X and phi
222 fSimpleFitter(obj.fSimpleFitter), // simple fitter for short pads
223 fSqrtFitter(obj.fSqrtFitter), // sqrt fitter for medium pads
224 fLogFitter(obj.fLogFitter), // log fitter for long pads
225 fFitter0M(obj.fFitter0M),
226 fFitter1M(obj.fFitter1M),
227 fFitter2M(obj.fFitter2M),
228 fFitter0T(obj.fFitter0T),
229 fFitter1T(obj.fFitter1T),
230 fFitter2T(obj.fFitter2T),
231 fSingleSectorFitter(obj.fSingleSectorFitter), // just for debugging
235 fTotalTracks(obj.fTotalTracks), // just for debugging
236 fAcceptedTracks(obj.fAcceptedTracks), // just for debugging
237 fDebugCalPadRaw(obj.fDebugCalPadRaw), // just for debugging
238 fDebugCalPadCorr(obj.fDebugCalPadCorr), // just for debugging
239 fPrevIter(obj.fPrevIter) // the calibration object in its previous iteration (will not be owned by the new object, don't forget to delete it!)
247 AliTPCcalibTracksGain& AliTPCcalibTracksGain::operator=(const AliTPCcalibTracksGain& rhs) {
249 // Assignment operator.
253 TNamed::operator=(rhs);
254 fDebugCalPadRaw = new AliTPCCalPad(*(rhs.fDebugCalPadRaw));
255 fDebugCalPadCorr = new AliTPCCalPad(*(rhs.fDebugCalPadCorr));
256 fSimpleFitter = new AliTPCFitPad(*(rhs.fSimpleFitter));
257 fSqrtFitter = new AliTPCFitPad(*(rhs.fSqrtFitter));
258 fLogFitter = new AliTPCFitPad(*(rhs.fLogFitter));
259 fSingleSectorFitter = new AliTPCFitPad(*(rhs.fSingleSectorFitter));
260 fPrevIter = new AliTPCcalibTracksGain(*(rhs.fPrevIter));
261 fCuts = new AliTPCcalibTracksCuts(*(rhs.fCuts));
266 AliTPCcalibTracksGain::AliTPCcalibTracksGain(const char* name, const char* title, AliTPCcalibTracksCuts* cuts, TNamed* /*debugStreamPrefix*/, AliTPCcalibTracksGain* prevIter) :
268 fCuts(0), // cuts that are used for sieving the tracks used for calibration
269 fArrayQM(0), // Qmax normalized
270 fArrayQT(0), // Qtot normalized
274 fProfileArrayQM(0), // Qmax normalized versus local X
275 fProfileArrayQT(0), // Qtot normalized versus local X
276 fProfileArrayQM2D(0), // Qmax normalized versus local X and phi
277 fProfileArrayQT2D(0), // Qtot normalized versus local X and phi
281 fSimpleFitter(0), // simple fitter for short pads
282 fSqrtFitter(0), // sqrt fitter for medium pads
283 fLogFitter(0), // log fitter for long pads
284 fFitter0M(0), // fitting of the atenuation, angular correction, and mean chamber gain
285 fFitter1M(0), // fitting of the atenuation, angular correction, and mean chamber gain
286 fFitter2M(0), // fitting of the atenuation, angular correction, and mean chamber gain
287 fFitter0T(0), // fitting of the atenuation, angular correction, and mean chamber gain
288 fFitter1T(0), // fitting of the atenuation, angular correction, and mean chamber gain
289 fFitter2T(0), // fitting of the atenuation, angular correction, and mean chamber gain
290 fSingleSectorFitter(0), // just for debugging
294 fTotalTracks(0), // just for debugging
295 fAcceptedTracks(0), // just for debugging
296 fDebugCalPadRaw(0), // just for debugging
297 fDebugCalPadCorr(0), // just for debugging
298 fPrevIter(0) // the calibration object in its previous iteration (will not be owned by the new object, don't forget to delete it!)
304 G__SetCatchException(0);
305 this->SetNameTitle(name, title);
307 fPrevIter = prevIter;
309 // Fitter initialization
311 fSimpleFitter = new AliTPCFitPad(8, "hyp7", "");
312 fSqrtFitter = new AliTPCFitPad(8, "hyp7", "");
313 fLogFitter = new AliTPCFitPad(8, "hyp7", "");
314 fSingleSectorFitter = new AliTPCFitPad(8, "hyp7", "");
316 fFitter0M = new TLinearFitter(45,"hyp44");
317 fFitter1M = new TLinearFitter(45,"hyp44");
318 fFitter2M = new TLinearFitter(45,"hyp44");
319 fFitter0T = new TLinearFitter(45,"hyp44");
320 fFitter1T = new TLinearFitter(45,"hyp44");
321 fFitter2T = new TLinearFitter(45,"hyp44");
324 // Add profile histograms -JUST for visualization - Not used for real calibration
327 fArrayQM=new TObjArray(73); // Qmax normalized
328 fArrayQT=new TObjArray(73); // Qtot normalized
329 fProfileArrayQM = new TObjArray(37); // Qmax normalized versus local X
330 fProfileArrayQT = new TObjArray(37); // Qtot normalized versus local X
331 fProfileArrayQM2D = new TObjArray(37); // Qmax normalized versus local X and phi
332 fProfileArrayQT2D = new TObjArray(37); // Qtot normalized versus local X and phi
334 for (Int_t i=0; i<73; i++){
335 sprintf(hname,"QM_%d",i);
336 fArrayQM->AddAt(new TH1F(hname,hname,200,0,1000),i);
337 sprintf(hname,"QT_%d",i);
338 fArrayQT->AddAt(new TH1F(hname,hname,200,0,1000),i);
341 for (Int_t i=0; i<37;i++){
342 sprintf(hname,"QMvsx_%d",i);
343 fProfileArrayQM->AddAt(new TProfile(hname,hname,50,89,250),i);
344 sprintf(hname,"QTvsx_%d",i);
345 fProfileArrayQT->AddAt(new TProfile(hname,hname,50,89,250),i);
346 sprintf(hname,"QM2D_%d",i);
347 fProfileArrayQM2D->AddAt(new TProfile2D(hname,hname,50,89,250,10,-0.15,0.15),i);
348 sprintf(hname,"QT2D_%d",i);
349 fProfileArrayQT2D->AddAt(new TProfile2D(hname,hname,50,89,250,10,-0.15,0.15),i);
352 // just for debugging -counters
356 fDebugCalPadRaw = new AliTPCCalPad("DebugCalPadRaw", "All clusters simply added up before correction");
357 fDebugCalPadCorr = new AliTPCCalPad("DebugCalPadCorr", "All clusters simply added up after correction");
358 // this will be gone for the a new ROOT version > v5-17-05
359 for (UInt_t i = 0; i < 36; i++) {
360 fNShortClusters[i] = 0;
361 fNMediumClusters[i] = 0;
362 fNLongClusters[i] = 0;
366 AliTPCcalibTracksGain::~AliTPCcalibTracksGain() {
371 Info("Destructor","");
372 if (fSimpleFitter) delete fSimpleFitter;
373 if (fSqrtFitter) delete fSqrtFitter;
374 if (fLogFitter) delete fLogFitter;
375 if (fSingleSectorFitter) delete fSingleSectorFitter;
377 if (fDebugCalPadRaw) delete fDebugCalPadRaw;
378 if (fDebugCalPadCorr) delete fDebugCalPadCorr;
381 void AliTPCcalibTracksGain::Terminate(){
383 // Evaluate fitters and close the debug stream.
384 // Also move or copy the debug stream, if a debugStreamPrefix is provided.
388 AliTPCcalibBase::Terminate();
393 void AliTPCcalibTracksGain::Process(AliTPCseed* seed) {
395 // Main method to be called when a new seed is supposed to be processed
396 // and be used for gain calibration. Its quality is checked before it
401 if (!fCuts->AcceptTrack(seed)) return;
406 Long64_t AliTPCcalibTracksGain::Merge(TCollection *list) {
408 // Merge() merges the results of all AliTPCcalibTracksGain objects contained in
409 // list, thus allowing a distributed computation of several files, e.g. on PROOF.
410 // The merged results are merged with the data members of the AliTPCcalibTracksGain
411 // object used for calling the Merge method.
412 // The return value is 0 /*the total number of tracks used for calibration*/ if the merge
413 // is successful, otherwise it is -1.
416 if (!list || list->IsEmpty()) return -1;
418 if (!fSimpleFitter) fSimpleFitter = new AliTPCFitPad(8, "hyp7", "");
419 if (!fSqrtFitter) fSqrtFitter = new AliTPCFitPad(8, "hyp7", "");
420 if (!fLogFitter) fLogFitter = new AliTPCFitPad(8, "hyp7", "");
421 if (!fSingleSectorFitter) fSingleSectorFitter = new AliTPCFitPad(8, "hyp7", "");
424 // just for debugging
425 if (!fDebugCalPadRaw) fDebugCalPadRaw = new AliTPCCalPad("DebugCalPadRaw", "All clusters simply added up before correction");
426 if (!fDebugCalPadCorr) fDebugCalPadCorr = new AliTPCCalPad("DebugCalPadCorr", "All clusters simply added up after correction");
428 TIterator* iter = list->MakeIterator();
429 AliTPCcalibTracksGain* cal = 0;
431 while ((cal = (AliTPCcalibTracksGain*)iter->Next())) {
432 if (!cal->InheritsFrom(AliTPCcalibTracksGain::Class())) {
433 Error("Merge","Attempt to add object of class %s to a %s", cal->ClassName(), this->ClassName());
442 void AliTPCcalibTracksGain::Add(AliTPCcalibTracksGain* cal) {
444 // Adds another AliTPCcalibTracksGain object to this object.
447 fSimpleFitter->Add(cal->fSimpleFitter);
448 fSqrtFitter->Add(cal->fSqrtFitter);
449 fLogFitter->Add(cal->fLogFitter);
450 fSingleSectorFitter->Add(cal->fSingleSectorFitter);
454 fFitter0M->Add(cal->fFitter0M);
455 fFitter1M->Add(cal->fFitter1M);
456 fFitter2M->Add(cal->fFitter2M);
457 fFitter0T->Add(cal->fFitter0T);
458 fFitter1T->Add(cal->fFitter1T);
459 fFitter2T->Add(cal->fFitter2T);
464 for (Int_t i=0; i<73; i++){
466 his = (TH1F*)fArrayQM->At(i);
467 hism = (TH1F*)cal->fArrayQM->At(i);
468 if (his && hism) his->Add(hism);
469 his = (TH1F*)fArrayQT->At(i);
470 hism = (TH1F*)cal->fArrayQT->At(i);
471 if (his && hism) his->Add(hism);
475 for (Int_t i=0; i<37; i++){
477 his = (TProfile*)fProfileArrayQM->At(i);
478 hism = (TProfile*)cal->fProfileArrayQM->At(i);
479 if (his && hism) his->Add(hism);
480 his = (TProfile*)fProfileArrayQT->At(i);
481 hism = (TProfile*)cal->fProfileArrayQT->At(i);
482 if (his && hism) his->Add(hism);
486 for (Int_t i=0; i<37; i++){
487 TProfile2D *his,*hism;
488 his = (TProfile2D*)fProfileArrayQM2D->At(i);
489 hism = (TProfile2D*)cal->fProfileArrayQM2D->At(i);
490 if (his && hism) his->Add(hism);
491 his = (TProfile2D*)fProfileArrayQT2D->At(i);
492 hism = (TProfile2D*)cal->fProfileArrayQT2D->At(i);
493 if (his && hism) his->Add(hism);
496 // this will be gone for the a new ROOT version > v5-17-05
497 for (UInt_t iSegment = 0; iSegment < 36; iSegment++) {
498 fNShortClusters[iSegment] += cal->fNShortClusters[iSegment];
499 fNMediumClusters[iSegment] += cal->fNMediumClusters[iSegment];
500 fNLongClusters[iSegment] += cal->fNLongClusters[iSegment];
503 // just for debugging, remove me
504 fTotalTracks += cal->fTotalTracks;
505 fAcceptedTracks += cal->fAcceptedTracks;
506 fDebugCalPadRaw->Add(cal->fDebugCalPadRaw);
507 fDebugCalPadCorr->Add(cal->fDebugCalPadCorr);
511 void AliTPCcalibTracksGain::AddTrack(AliTPCseed* seed) {
513 // The clusters making up the track (seed) are added to various fit functions.
514 // See AddCluster(...) for more detail.
519 // simple histograming part
520 for (Int_t i=0; i<159; i++){
521 AliTPCclusterMI* cluster = seed->GetClusterPointer(i);
522 if (cluster) AddCluster(cluster);
526 void AliTPCcalibTracksGain::AddCluster(AliTPCclusterMI* cluster){
528 // Adding cluster information to the simple histograms
529 // No correction, fittings are applied
531 Float_t kThreshold=5;
532 if (cluster->GetX()<=0) return;
533 if (cluster->GetQ()<=kThreshold) return;
537 Int_t sector = cluster->GetDetector();
540 if (his) his->Fill(cluster->GetQ());
542 if (his) his->Fill(cluster->GetQ());
544 if (his) his->Fill(cluster->GetMax());
546 if (his) his->Fill(cluster->GetMax());
550 prof = GetProfileQT(sector);
551 if (prof) prof->Fill(cluster->GetX(),cluster->GetQ());
552 prof = GetProfileQT(-1);
553 if (prof) prof->Fill(cluster->GetX(),cluster->GetQ());
554 prof = GetProfileQM(sector);
555 if (prof) prof->Fill(cluster->GetX(),cluster->GetMax());
556 prof = GetProfileQM(-1);
557 if (prof) prof->Fill(cluster->GetX(),cluster->GetMax());
559 Float_t phi = cluster->GetY()/cluster->GetX();
561 prof2 = GetProfileQT2D(sector);
562 if (prof2) prof2->Fill(cluster->GetX(),phi,cluster->GetQ());
563 prof2 = GetProfileQT2D(-1);
564 if (prof2) prof2->Fill(cluster->GetX(),phi,cluster->GetQ());
565 prof2 = GetProfileQM2D(sector);
566 if (prof2) prof2->Fill(cluster->GetX(),phi,cluster->GetMax());
567 prof2 = GetProfileQM2D(-1);
568 if (prof2) prof2->Fill(cluster->GetX(),phi,cluster->GetMax());
575 void AliTPCcalibTracksGain::AddCluster(AliTPCclusterMI* cluster, Float_t /*momenta*/, Float_t/* mdedx*/, Int_t padType,
576 Float_t xcenter, TVectorD& dedxQ, TVectorD& /*dedxM*/, Float_t /*fraction*/, Float_t fraction2, Float_t dedge,
577 TVectorD& /*parY*/, TVectorD& /*parZ*/, TVectorD& meanPos) {
579 // Adds cluster to the appropriate fitter for later analysis.
580 // The charge used for the fit is the maximum charge for this specific cluster or the
581 // accumulated charge per cluster, depending on the value of fgkUseTotalCharge.
582 // Depending on the pad size where the cluster is registered, the value will be put in
583 // the appropriate fitter. Furthermore, for each pad size three different types of fitters
584 // are used. The fit functions are the same for all fitters (parabolic functions), but the value
585 // added to each fitter is different. The simple fitter gets the charge plugged in as is, the sqrt fitter
586 // gets the square root of the charge, and the log fitter gets fgkM*(1+q/fgkM), where q is the original charge
591 Error("AddCluster", "Cluster not valid.");
595 if (dedge < 3.) return;
596 if (fraction2 > 0.7) return;
598 //Int_t padType = GetPadType(cluster->GetX());
600 //Double_t centerPad[2] = {0};
601 //AliTPCFitPad::GetPadRegionCenterLocal(padType, centerPad);
602 //xx[0] = cluster->GetX() - centerPad[0];
603 //xx[1] = cluster->GetY() - centerPad[1];
604 xx[0] = cluster->GetX() - xcenter;
605 xx[1] = cluster->GetY();
606 xx[2] = xx[0] * xx[0];
607 xx[3] = xx[1] * xx[1];
608 xx[4] = xx[0] * xx[1];
609 xx[5] = TMath::Abs(cluster->GetZ()) - TMath::Abs(meanPos[4]);
610 xx[6] = xx[5] * xx[5];
612 // Update profile histograms
618 Int_t segment = cluster->GetDetector() % 36;
619 Double_t q = fgkUseTotalCharge ? ((Double_t)(cluster->GetQ())) : ((Double_t)(cluster->GetMax())); // note: no normalization to pad size!
621 // just for debugging
624 GetRowPad(cluster->GetX(), cluster->GetY(), row, pad);
625 fDebugCalPadRaw->GetCalROC(cluster->GetDetector())->SetValue(row, pad, q + fDebugCalPadRaw->GetCalROC(cluster->GetDetector())->GetValue(row, pad));
627 // correct charge by normalising to mean charge per track
630 // just for debugging
631 fDebugCalPadCorr->GetCalROC(cluster->GetDetector())->SetValue(row, pad, q + fDebugCalPadCorr->GetCalROC(cluster->GetDetector())->GetValue(row, pad));
633 Double_t sqrtQ = TMath::Sqrt(q);
634 Double_t logQ = fgkM * TMath::Log(1 + q / fgkM);
635 fSimpleFitter->GetFitter(segment, padType)->AddPoint(xx, q);
636 fSqrtFitter->GetFitter(segment, padType)->AddPoint(xx, sqrtQ);
637 fLogFitter->GetFitter(segment, padType)->AddPoint(xx, logQ);
638 fSingleSectorFitter->GetFitter(0, padType)->AddPoint(xx, q);
640 // this will be gone for the a new ROOT version > v5-17-05
641 if (padType == kShortPads)
642 fNShortClusters[segment]++;
643 if (padType == kMediumPads)
644 fNMediumClusters[segment]++;
645 if (padType == kLongPads)
646 fNLongClusters[segment]++;
649 void AliTPCcalibTracksGain::Evaluate(Bool_t robust, Double_t frac) {
651 // Evaluates all fitters contained in this object.
652 // If the robust option is set to kTRUE a robust fit is performed with frac as
653 // the minimal fraction of good points (see TLinearFitter::EvalRobust for details).
654 // Beware: Robust fitting is much slower!
657 fSimpleFitter->Evaluate(robust, frac);
658 fSqrtFitter->Evaluate(robust, frac);
659 fLogFitter->Evaluate(robust, frac);
660 fSingleSectorFitter->Evaluate(robust, frac);
669 AliTPCCalPad* AliTPCcalibTracksGain::CreateFitCalPad(UInt_t fitType, Bool_t undoTransformation, Bool_t normalizeToPadSize) {
671 // Creates the calibration object AliTPCcalPad using fitted parameterization
674 for (UInt_t iSector = 0; iSector < 72; iSector++)
675 tpc.Add(CreateFitCalROC(iSector, fitType, undoTransformation, normalizeToPadSize));
676 return new AliTPCCalPad(&tpc);
679 AliTPCCalROC* AliTPCcalibTracksGain::CreateFitCalROC(UInt_t sector, UInt_t fitType, Bool_t undoTransformation, Bool_t normalizeToPadSize) {
681 // Create the AliTPCCalROC with the values per pad
682 // sector - sector of interest
688 GetParameters(sector % 36, 0, fitType, par);
689 return CreateFitCalROC(sector, 0, par, fitType, undoTransformation, normalizeToPadSize);
692 GetParameters(sector % 36, 1, fitType, par);
693 AliTPCCalROC* roc1 = CreateFitCalROC(sector, 1, par, fitType, undoTransformation, normalizeToPadSize);
694 GetParameters(sector % 36, 2, fitType, par);
695 AliTPCCalROC* roc2 = CreateFitCalROC(sector, 2, par, fitType, undoTransformation, normalizeToPadSize);
696 AliTPCCalROC* roc3 = CreateCombinedCalROC(roc1, roc2);
703 AliTPCCalROC* AliTPCcalibTracksGain::CreateFitCalROC(UInt_t sector, UInt_t padType, TVectorD &fitParam, UInt_t fitType, Bool_t undoTransformation, Bool_t normalizeToPadSize) {
705 // This function is essentially a copy of AliTPCCalROC::CreateGlobalFitCalROC(...), with the
706 // modifications, that the center of the region of same pad size is used as the origin
707 // of the fit function instead of the center of the ROC.
708 // The possibility of a linear fit is removed as well because it is not needed.
709 // Only values for pads with the given pad size are calculated, the rest is 0.
710 // Set undoTransformation for undoing the transformation that was applied to the
711 // charge values before they were put into the fitter (thus allowing comparison to the original
712 // charge values). For fitType use 0 for the simple fitter, 1 for the sqrt fitter, 2 for the log fitter.
713 // If normalizeToPadSize is true, the values are normalized to the pad size.
714 // Please be aware, that you even need to specify the fitType if you want to normalize to the pad size without
715 // undoing the transformation (because normalizing involves undoing the trafo first, then normalizing, then
716 // applying the trafo again).
717 // Please note: The normalization to the pad size is a simple linear scaling with the pad length, which
718 // actually doesn't describe reality!
722 Double_t centerPad[2] = {0};
723 Float_t localXY[3] = {0};
724 AliTPCROC* tpcROC = AliTPCROC::Instance();
725 if ((padType == 0 && sector >= tpcROC->GetNInnerSector()) || (padType > 0 && sector < tpcROC->GetNInnerSector()) || sector >= tpcROC->GetNSector())
727 AliTPCCalROC* lROCfitted = new AliTPCCalROC(sector);
728 //tpcROC->GetPositionLocal(sector, lROCfitted->GetNrows()/2, lROCfitted->GetNPads(lROCfitted->GetNrows()/2)/2, centerPad); // use this instead of the switch statement if you want to calculate the center of the ROC and not the center of the regions with the same pad size
734 endRow = lROCfitted->GetNrows();
742 endRow = lROCfitted->GetNrows();
746 AliTPCFitPad::GetPadRegionCenterLocal(padType, centerPad);
748 for (UInt_t irow = startRow; irow < endRow; irow++) {
749 for (UInt_t ipad = 0; ipad < lROCfitted->GetNPads(irow); ipad++) {
750 tpcROC->GetPositionLocal(sector, irow, ipad, localXY); // calculate position localXY by pad and row number
751 dlx = localXY[0] - centerPad[0];
752 dly = localXY[1] - centerPad[1];
753 value = fitParam[0] + fitParam[1]*dlx + fitParam[2]*dly + fitParam[3]*dlx*dlx + fitParam[4]*dly*dly + fitParam[5]*dlx*dly;
755 // Let q' = value be the transformed value without any pad size corrections,
756 // let T be the transformation and let l be the pad size
757 // 1) don't undo transformation, don't normalize: return q'
758 // 2) undo transformation, don't normalize: return T^{-1} q'
759 // 3) undo transformation, normalize: return (T^{-1} q') / l
760 // 4) don't undo transformation, normalize: return T((T^{-1} q') / l)
761 if (!undoTransformation && !normalizeToPadSize) {/* value remains unchanged */} // (1)
762 else { // (2), (3), (4)
765 case 0: /* value remains unchanged */ break;
766 case 1: value = value * value; break;
767 case 2: value = (TMath::Exp(value / fgkM) - 1) * fgkM; break;
768 default: Error("CreateFitCalROC", "Wrong fit type."); break;
770 if (normalizeToPadSize) value /= GetPadLength(localXY[0]); // (3)
772 if (!undoTransformation && normalizeToPadSize) { // (4)
775 case 0: /* value remains unchanged */ break;
776 case 1: value = TMath::Sqrt(value); break;
777 case 2: value = fgkM * TMath::Log(1 + value / fgkM); break;
778 default: Error("CreateFitCalROC", "Wrong fit type."); break;
781 lROCfitted->SetValue(irow, ipad, value);
787 AliTPCCalROC* AliTPCcalibTracksGain::CreateCombinedCalROC(const AliTPCCalROC* roc1, const AliTPCCalROC* roc2) {
789 // Combines the medium pad size values of roc1 with the long pad size values of roc2 into a new
790 // AliTPCCalROC. Returns a null pointer if any one of the ROCs is an IROC; issues a warning message
791 // if the sectors of roc1 and roc2 don't match, but still continue and use the sector of roc1 as the
792 // sector of the new ROC.
795 if (!roc1 || !roc2) return 0;
796 if ((Int_t)(roc1->GetSector()) < fgTPCparam->GetNInnerSector()) return 0;
797 if ((Int_t)(roc2->GetSector()) < fgTPCparam->GetNInnerSector()) return 0;
798 if (roc1->GetSector() != roc2->GetSector()) Warning("CreateCombinedCalROC", "Sector number mismatch.");
799 AliTPCCalROC* roc = new AliTPCCalROC(roc1->GetSector());
801 for (UInt_t iRow = 0; iRow < 64; iRow++) {
802 for (UInt_t iPad = 0; iPad < roc->GetNPads(iRow); iPad++)
803 roc->SetValue(iRow, iPad, roc1->GetValue(iRow, iPad));
805 for (UInt_t iRow = 64; iRow < roc->GetNrows(); iRow++) {
806 for (UInt_t iPad = 0; iPad < roc->GetNPads(iRow); iPad++)
807 roc->SetValue(iRow, iPad, roc2->GetValue(iRow, iPad));
812 void AliTPCcalibTracksGain::GetParameters(UInt_t segment, UInt_t padType, UInt_t fitType, TVectorD &fitParam) {
814 // Puts the fit parameters for the specified segment (IROC & OROC), padType and fitType
815 // into the fitParam TVectorD (which should contain 8 elements).
816 // padType is one of kShortPads, kMediumPads, kLongPads. fitType is one of kSimpleFitter, kSqrtFitter, kLogFitter.
817 // Note: The fitter has to be evaluated first!
820 GetFitter(segment, padType, fitType)->GetParameters(fitParam);
823 void AliTPCcalibTracksGain::GetErrors(UInt_t segment, UInt_t padType, UInt_t fitType, TVectorD &fitError) {
825 // Puts the fit parameter errors for the specified segment (IROC & OROC), padType and fitType
826 // into the fitError TVectorD (which should contain 8 elements).
827 // padType is one of kShortPads, kMediumPads, kLongPads. fitType is one of kSimpleFitter, kSqrtFitter, kLogFitter.
828 // Note: The fitter has to be evaluated first!
831 GetFitter(segment, padType, fitType)->GetErrors(fitError);
832 fitError *= TMath::Sqrt(GetRedChi2(segment, padType, fitType));
835 Double_t AliTPCcalibTracksGain::GetRedChi2(UInt_t segment, UInt_t padType, UInt_t fitType) {
837 // Returns the reduced chi^2 value for the specified segment, padType and fitType.
838 // padType is one of kShortPads, kMediumPads, kLongPads. fitType is one of kSimpleFitter, kSqrtFitter, kLogFitter.
839 // Note: The fitter has to be evaluated first!
842 // this will be gone for the a new ROOT version > v5-17-05
843 Int_t lNClusters = 0;
846 lNClusters = fNShortClusters[segment];
849 lNClusters = fNMediumClusters[segment];
852 lNClusters = fNLongClusters[segment];
855 return GetFitter(segment, padType, fitType)->GetChisquare()/(lNClusters - 8);
858 void AliTPCcalibTracksGain::GetCovarianceMatrix(UInt_t segment, UInt_t padType, UInt_t fitType, TMatrixD& covMatrix) {
860 // Returns the covariance matrix for the specified segment, padType, fitType.
861 // padType is one of kShortPads, kMediumPads, kLongPads. fitType is one of kSimpleFitter, kSqrtFitter, kLogFitter.
864 GetFitter(segment, padType, fitType)->GetCovarianceMatrix(covMatrix);
867 TLinearFitter* AliTPCcalibTracksGain::GetFitter(UInt_t segment, UInt_t padType, UInt_t fitType) {
869 // Returns the TLinearFitter object for the specified segment, padType, fitType.
870 // padType is one of kShortPads, kMediumPads, kLongPads. fitType is one of kSimpleFitter, kSqrtFitter, kLogFitter.
875 return fSimpleFitter->GetFitter(segment, padType);
877 return fSqrtFitter->GetFitter(segment, padType);
879 return fLogFitter->GetFitter(segment, padType);
881 return fSingleSectorFitter->GetFitter(0, padType);
886 Double_t AliTPCcalibTracksGain::GetPadLength(Double_t lx) {
888 // The function returns 0.75 for an IROC, 1. for an OROC at medium pad size position,
889 // 1.5 for an OROC at long pad size position, -1 if out of bounds.
892 Double_t irocLow = fgTPCparam->GetPadRowRadiiLow(0) - fgTPCparam->GetInnerPadPitchLength()/2;
893 Double_t irocUp = fgTPCparam->GetPadRowRadiiLow(fgTPCparam->GetNRowLow()-1) + fgTPCparam->GetInnerPadPitchLength()/2;
894 Double_t orocLow1 = fgTPCparam->GetPadRowRadiiUp(0) - fgTPCparam->GetOuter1PadPitchLength()/2;
895 Double_t orocUp1 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp1()-1) + fgTPCparam->GetOuter1PadPitchLength()/2;
896 Double_t orocLow2 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp1()) - fgTPCparam->GetOuter2PadPitchLength()/2;
897 Double_t orocUp2 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp()-1) + fgTPCparam->GetOuter2PadPitchLength()/2;
900 if (lx >= irocLow && lx <= irocUp) return 0.75;
901 // if OROC medium pads
902 if (lx >= orocLow1 && lx <= orocUp1) return 1.;
904 if (lx >= orocLow2 && lx <= orocUp2) return 1.5;
909 Int_t AliTPCcalibTracksGain::GetPadType(Double_t lx) {
911 // The function returns 0 for an IROC, 1 for an OROC at medium pad size position,
912 // 2 for an OROC at long pad size position, -1 if out of bounds.
915 if (GetPadLength(lx) == 0.75) return 0;
916 else if (GetPadLength(lx) == 1.) return 1;
917 else if (GetPadLength(lx) == 1.5) return 2;
921 // ONLY FOR DEBUGGING PURPOSES - REMOVE ME WHEN NOT NEEDED ANYMORE
922 Bool_t AliTPCcalibTracksGain::GetRowPad(Double_t lx, Double_t ly, Int_t& row, Int_t& pad) {
924 // Calculate the row and pad number when the local coordinates are given.
925 // Returns kFALSE if the position is out of range, otherwise return kTRUE.
926 // WARNING: This function is preliminary and probably isn't very accurate!!
929 Double_t irocLow = fgTPCparam->GetPadRowRadiiLow(0) - fgTPCparam->GetInnerPadPitchLength()/2;
930 //Double_t irocUp = fgTPCparam->GetPadRowRadiiLow(fgTPCparam->GetNRowLow()-1) + fgTPCparam->GetInnerPadPitchLength()/2;
931 Double_t orocLow1 = fgTPCparam->GetPadRowRadiiUp(0) - fgTPCparam->GetOuter1PadPitchLength()/2;
932 //Double_t orocUp1 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp1()-1) + fgTPCparam->GetOuter1PadPitchLength()/2;
933 Double_t orocLow2 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp1()) - fgTPCparam->GetOuter2PadPitchLength()/2;
934 //Double_t orocUp2 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp()-1) + fgTPCparam->GetOuter2PadPitchLength()/2;
936 if (GetPadType(lx) == 0) {
937 row = (Int_t)((lx - irocLow) / fgTPCparam->GetInnerPadPitchLength());
938 pad = (Int_t)((ly + fgTPCparam->GetYInner(row)) / fgTPCparam->GetInnerPadPitchWidth());
939 } else if (GetPadType(lx) == 1) {
940 row = (Int_t)((lx - orocLow1) / fgTPCparam->GetOuter1PadPitchLength());
941 pad = (Int_t)((ly + fgTPCparam->GetYOuter(row)) / fgTPCparam->GetOuterPadPitchWidth());
942 } else if (GetPadType(lx) == 2) {
943 row = fgTPCparam->GetNRowUp1() + (Int_t)((lx - orocLow2) / fgTPCparam->GetOuter2PadPitchLength());
944 pad = (Int_t)((ly + fgTPCparam->GetYOuter(row)) / fgTPCparam->GetOuterPadPitchWidth());
950 void AliTPCcalibTracksGain::DumpTrack(AliTPCseed* track) {
952 // Dump track information to the debug stream
965 for (Int_t ipad = 0; ipad < 3; ipad++) {
966 dedxM[ipad].ResizeTo(5);
967 dedxQ[ipad].ResizeTo(5);
968 parY[ipad].ResizeTo(3);
969 parZ[ipad].ResizeTo(3);
970 meanPos[ipad].ResizeTo(6);
971 Bool_t isOK = GetDedx(track, ipad, rows, sector[ipad], npoints[ipad], dedxM[ipad], dedxQ[ipad], parY[ipad], parZ[ipad], meanPos[ipad]);
973 AddTracklet(sector[ipad],ipad, dedxQ[ipad], dedxM[ipad], parY[ipad], parZ[ipad], meanPos[ipad] );
977 TTreeSRedirector * cstream = GetDebugStreamer();
979 (*cstream) << "Track" <<
980 "Track.=" << track << // track information
985 if ( GetStreamLevel()>1 && count>1){
986 (*cstream) << "TrackG" <<
987 "Track.=" << track << // track information
989 // info for pad type 0
990 "sector0="<<sector[0]<<
991 "npoints0="<<npoints[0]<<
992 "dedxM0.="<<&dedxM[0]<<
993 "dedxQ0.="<<&dedxQ[0]<<
994 "parY0.="<<&parY[0]<<
995 "parZ0.="<<&parZ[0]<<
996 "meanPos0.="<<&meanPos[0]<<
998 // info for pad type 1
999 "sector1="<<sector[1]<<
1000 "npoints1="<<npoints[1]<<
1001 "dedxM1.="<<&dedxM[1]<<
1002 "dedxQ1.="<<&dedxQ[1]<<
1003 "parY1.="<<&parY[1]<<
1004 "parZ1.="<<&parZ[1]<<
1005 "meanPos1.="<<&meanPos[1]<<
1007 // info for pad type 2
1008 "sector2="<<sector[2]<<
1009 "npoints2="<<npoints[2]<<
1010 "dedxM2.="<<&dedxM[2]<<
1011 "dedxQ2.="<<&dedxQ[2]<<
1012 "parY2.="<<&parY[2]<<
1013 "parZ2.="<<&parZ[2]<<
1014 "meanPos2.="<<&meanPos[2]<<
1021 Bool_t AliTPCcalibTracksGain::GetDedx(AliTPCseed* track, Int_t padType, Int_t* /*rows*/,
1022 Int_t §or, Int_t& npoints,
1023 TVectorD &dedxM, TVectorD &dedxQ,
1024 TVectorD &parY, TVectorD &parZ, TVectorD&meanPos)
1027 // GetDedx for given sector for given track
1028 // padType - type of pads
1031 static TLinearFitter fitY(2, "pol1");
1032 static TLinearFitter fitZ(2, "pol1");
1035 Int_t firstRow = 0, lastRow = 0;
1037 Float_t xcenter = 0;
1038 const Float_t ktany = TMath::Tan(TMath::DegToRad() * 10);
1039 const Float_t kedgey = 4.;
1042 lastRow = fgTPCparam->GetNRowLow();
1046 firstRow = fgTPCparam->GetNRowLow();
1047 lastRow = fgTPCparam->GetNRowLow() + fgTPCparam->GetNRowUp1();
1051 firstRow = fgTPCparam->GetNRowLow() + fgTPCparam->GetNRowUp1();
1052 lastRow = fgTPCparam->GetNRowLow() + fgTPCparam->GetNRowUp();
1055 minRow = (lastRow - firstRow) / 2;
1058 Int_t nclusters = 0;
1059 Int_t nclustersNE = 0; // number of not edge clusters
1060 Int_t lastSector = -1;
1061 Float_t amplitudeQ[100];
1062 Float_t amplitudeM[100];
1070 for (Int_t iCluster = firstRow; iCluster < lastRow; iCluster++) {
1071 AliTPCclusterMI* cluster = track->GetClusterPointer(iCluster);
1073 Int_t detector = cluster->GetDetector() ;
1074 if (lastSector == -1) lastSector = detector;
1075 if (lastSector != detector) continue;
1076 amplitudeQ[nclusters] = cluster->GetQ();
1077 amplitudeM[nclusters] = cluster->GetMax();
1078 rowIn[nclusters] = iCluster;
1080 Double_t dx = cluster->GetX() - xcenter;
1081 Double_t y = cluster->GetY();
1082 Double_t z = cluster->GetZ();
1083 fitY.AddPoint(&dx, y);
1084 fitZ.AddPoint(&dx, z);
1091 if (TMath::Abs(cluster->GetY()) < cluster->GetX()*ktany - kedgey) nclustersNE++;
1095 if (nclusters < minRow / 2) return kFALSE;
1096 if (nclustersNE < minRow / 2) return kFALSE;
1097 for (Int_t i = 0; i < 6; i++) meanPos[i] /= Double_t(nclusters);
1100 fitY.GetParameters(parY);
1101 fitZ.GetParameters(parZ);
1103 // calculate truncated mean
1105 TMath::Sort(nclusters, amplitudeQ, index, kFALSE);
1110 for (Int_t i = 0; i < 5; i++) {
1119 for (Int_t i = 0; i < nclusters; i++) {
1120 Int_t rowSorted = rowIn[index[i]];
1121 AliTPCclusterMI* cluster = track->GetClusterPointer(rowSorted);
1123 if (TMath::Abs(cluster->GetY()) > cluster->GetX()*ktany - kedgey) continue; //don't take edge clusters
1125 if (inonEdge < nclustersNE * 0.5) {
1127 dedxQ[0] += amplitudeQ[index[i]];
1128 dedxM[0] += amplitudeM[index[i]];
1130 if (inonEdge < nclustersNE * 0.6) {
1132 dedxQ[1] += amplitudeQ[index[i]];
1133 dedxM[1] += amplitudeM[index[i]];
1135 if (inonEdge < nclustersNE * 0.7) {
1137 dedxQ[2] += amplitudeQ[index[i]];
1138 dedxM[2] += amplitudeM[index[i]];
1140 if (inonEdge < nclustersNE * 0.8) {
1142 dedxQ[3] += amplitudeQ[index[i]];
1143 dedxM[3] += amplitudeM[index[i]];
1145 if (inonEdge < nclustersNE * 0.9) {
1147 dedxQ[4] += amplitudeQ[index[i]];
1148 dedxM[4] += amplitudeM[index[i]];
1151 for (Int_t i = 0; i < 5; i++) {
1152 dedxQ[i] /= ndedx[i];
1153 dedxM[i] /= ndedx[i];
1155 TTreeSRedirector * cstream = GetDebugStreamer();
1157 Float_t momenta = track->GetP();
1158 Float_t mdedx = track->GetdEdx();
1159 for (Int_t i = 0; i < nclusters; i++) {
1160 Int_t rowSorted = rowIn[index[i]];
1161 AliTPCclusterMI* cluster = track->GetClusterPointer(rowSorted);
1163 printf("Problem\n");
1166 if (TMath::Abs(cluster->GetY()) < cluster->GetX()*ktany - kedgey) inonEdge++;
1167 Float_t dedge = cluster->GetX()*ktany - TMath::Abs(cluster->GetY());
1168 Float_t fraction = Float_t(i) / Float_t(nclusters);
1169 Float_t fraction2 = Float_t(inonEdge) / Float_t(nclustersNE);
1171 AddCluster(cluster, momenta, mdedx, padType, xcenter, dedxQ, dedxM, fraction, fraction2, dedge, parY, parZ, meanPos);
1173 if (cstream) (*cstream) << "dEdx" <<
1174 "Cl.=" << cluster << // cluster of interest
1175 "P=" << momenta << // track momenta
1176 "dedx=" << mdedx << // mean dedx - corrected for angle
1177 "IPad=" << padType << // pad type 0..2
1178 "xc=" << xcenter << // x center of chamber
1179 "dedxQ.=" << &dedxQ << // dedxQ - total charge
1180 "dedxM.=" << &dedxM << // dedxM - maximal charge
1181 "fraction=" << fraction << // fraction - order in statistic (0,1)
1182 "fraction2=" << fraction2 << // fraction - order in statistic (0,1)
1183 "dedge=" << dedge << // distance to the edge
1184 "parY.=" << &parY << // line fit
1185 "parZ.=" << &parZ << // line fit
1186 "meanPos.=" << &meanPos << // mean position (dx, dx^2, y,y^2, z, z^2)
1190 if (cstream) (*cstream) << "dEdxT" <<
1191 "P=" << momenta << // track momenta
1192 "npoints="<<inonEdge<< // number of points
1193 "sector="<<lastSector<< // sector number
1194 "dedx=" << mdedx << // mean dedx - corrected for angle
1195 "IPad=" << padType << // pad type 0..2
1196 "xc=" << xcenter << // x center of chamber
1197 "dedxQ.=" << &dedxQ << // dedxQ - total charge
1198 "dedxM.=" << &dedxM << // dedxM - maximal charge
1199 "parY.=" << &parY << // line fit
1200 "parZ.=" << &parZ << // line fit
1201 "meanPos.=" << &meanPos << // mean position (dx, dx^2, y,y^2, z, z^2)
1204 sector = lastSector;
1209 void AliTPCcalibTracksGain::AddTracklet(UInt_t sector, UInt_t padType,TVectorD &dedxQ, TVectorD &dedxM,TVectorD& parY, TVectorD& parZ, TVectorD& meanPos){
1211 // Add measured point - dedx to the fitter
1214 //chain->SetAlias("dr","(250-abs(meanPos.fElements[4]))/250");
1215 //chain->SetAlias("tz","(0+abs(parZ.fElements[1]))");
1216 //chain->SetAlias("ty","(0+abs(parY.fElements[1]))");
1217 //chain->SetAlias("corrg","sqrt((1+ty^2)*(1+tz^2))");
1218 //expession fast - TString *strq0 = toolkit.FitPlane(chain,"dedxQ.fElements[2]","dr++ty++tz++dr*ty++dr*tz++ty*tz++ty^2++tz^2","IPad==0",chi2,npoints,param,covar,0,100000);
1222 // z and angular part
1225 xxx[0] = (250.-TMath::Abs(meanPos[4]))/250.;
1226 xxx[1] = TMath::Abs(parY[1]);
1227 xxx[2] = TMath::Abs(parZ[1]);
1228 xxx[3] = xxx[0]*xxx[1];
1229 xxx[4] = xxx[0]*xxx[2];
1230 xxx[5] = xxx[1]*xxx[2];
1231 xxx[6] = xxx[0]*xxx[0];
1232 xxx[7] = xxx[1]*xxx[1];
1233 xxx[8] = xxx[2]*xxx[2];
1237 Int_t tsector = sector%36;
1238 for (Int_t i=0;i<35;i++){
1239 xxx[9+i]=(i==tsector)?1:0;
1241 TLinearFitter *fitterM = fFitter0M;
1242 if (padType==1) fitterM=fFitter1M;
1243 if (padType==2) fitterM=fFitter2M;
1244 fitterM->AddPoint(xxx,dedxM[1]);
1246 TLinearFitter *fitterT = fFitter0T;
1247 if (padType==1) fitterT = fFitter1T;
1248 if (padType==2) fitterT = fFitter2T;
1249 fitterT->AddPoint(xxx,dedxQ[1]);
1253 TGraph *AliTPCcalibTracksGain::CreateAmpGraph(Int_t ipad, Bool_t qmax){
1255 // create the amplitude graph
1256 // The normalized amplitudes are extrapolated to the 0 angle (y,z) and 0 drift length
1261 if (ipad==0) fFitter0M->GetParameters(vec);
1262 if (ipad==1) fFitter1M->GetParameters(vec);
1263 if (ipad==2) fFitter2M->GetParameters(vec);
1265 if (ipad==0) fFitter0T->GetParameters(vec);
1266 if (ipad==1) fFitter1T->GetParameters(vec);
1267 if (ipad==2) fFitter2T->GetParameters(vec);
1272 for (Int_t i=0;i<35;i++){
1274 amp[i]=vec[10+i]+vec[0];
1277 Float_t mean = TMath::Mean(36,amp);
1278 for (Int_t i=0;i<36;i++){
1280 amp[i]=(amp[i]-mean)/mean;
1282 TGraph *gr = new TGraph(36,sec,amp);
1287 void AliTPCcalibTracksGain::UpdateClusterParam(AliTPCClusterParam* clparam){
1289 // SetQ normalization parameters
1291 // void SetQnorm(Int_t ipad, Int_t itype, TVectorD * norm);
1295 fFitter0T->GetParameters(vec);
1296 clparam->SetQnorm(0,0,&vec);
1297 fFitter1T->GetParameters(vec);
1298 clparam->SetQnorm(1,0,&vec);
1299 fFitter2T->GetParameters(vec);
1300 clparam->SetQnorm(2,0,&vec);
1302 fFitter0M->GetParameters(vec);
1303 clparam->SetQnorm(0,1,&vec);
1304 fFitter1M->GetParameters(vec);
1305 clparam->SetQnorm(1,1,&vec);
1306 fFitter2M->GetParameters(vec);
1307 clparam->SetQnorm(2,1,&vec);
1313 void AliTPCcalibTracksGain::Analyze(){