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)
100 // In order to debug some numerical algorithm all data data which are used for
101 // fitters can be stored in the debug streamers. In case of fitting roblems the
102 // errors and tendencies can be checked.
110 ////////////////////////////////////////////////////////////////////////////
114 gSystem->Load("libANALYSIS");
115 gSystem->Load("libSTAT");
116 gSystem->Load("libTPCcalib");
118 TFile fcalib("CalibObjects.root");
119 TObjArray * array = (TObjArray*)fcalib.Get("TPCCalib");
120 AliTPCcalibTracksGain * gain = ( AliTPCcalibTracksGain *)array->FindObject("calibTracksGain");
123 // Angular and drift correction
125 AliTPCClusterParam *param = new AliTPCClusterParam;param->SetInstance(param);
126 gain->UpdateClusterParam(param);
127 TF2 fdrty("fdrty","AliTPCClusterParam::SQnorm(0,0,x,y,0)",0,1,0,1)
130 // Make visual Tree - compare with Kr calibration
132 AliTPCCalPad * gain010 = gain->CreateFitCalPad(0,kTRUE,0); gain010->SetName("CGain010");
133 AliTPCCalPad * gain110 = gain->CreateFitCalPad(1,kTRUE,0); gain110->SetName("CGain110");
134 AliTPCCalPad * gain210 = gain->CreateFitCalPad(2,kTRUE,0); gain210->SetName("CGain210");
135 TFile fkr("/u/miranov/GainMap.root");
136 AliTPCCalPad *gainKr = fkr.Get("GainMap"); fkr->SetName("KrGain");
138 AliTPCPreprocessorOnline * preprocesor = new AliTPCPreprocessorOnline;
139 preprocesor->AddComponent(gain010);
140 preprocesor->AddComponent(gain110);
141 preprocesor->AddComponent(gain210);
142 preprocesor->AddComponent(gainKr);
143 preprocesor->DumpToFile("cosmicGain.root");
147 // Simple session using the debug streamers
150 gSystem->AddIncludePath("-I$ALICE_ROOT/TPC/macros");
151 gROOT->LoadMacro("$ALICE_ROOT/TPC/macros/AliXRDPROOFtoolkit.cxx+")
152 AliXRDPROOFtoolkit tool;
154 TChain * chain0 = tool.MakeChain("gain.txt","dEdx",0,1000000);
155 TChain * chain1 = tool.MakeChain("gain.txt","Track",0,1000000);
156 TChain * chain2 = tool.MakeChain("gain.txt","TrackG",0,1000000);
161 chain2->SetAlias("k1","1/0.855");
162 chain2->SetAlias("k0","1/0.9928");
163 chain2->SetAlias("k2","1/1.152");
169 #include "AliTPCcalibTracksGain.h"
172 #include <TPDGCode.h>
175 #include "TMatrixD.h"
176 #include "TTreeStream.h"
178 #include "AliTPCParamSR.h"
179 #include "AliTPCClusterParam.h"
180 #include "AliTrackPointArray.h"
184 #include <TLinearFitter.h>
185 #include <TTreeStream.h>
187 #include <TCollection.h>
188 #include <TIterator.h>
189 #include <TProfile.h>
190 #include <TProfile2D.h>
192 #include <TStatToolkit.h>
198 #include "AliMathBase.h"
200 #include "AliTPCROC.h"
201 #include "AliTPCParamSR.h"
202 #include "AliTPCCalROC.h"
203 #include "AliTPCCalPad.h"
204 #include "AliTPCClusterParam.h"
205 #include "AliTPCcalibDB.h"
207 #include "AliTracker.h"
209 #include "AliESDtrack.h"
210 #include "AliESDfriend.h"
211 #include "AliESDfriendTrack.h"
212 #include "AliTPCseed.h"
213 #include "AliTPCclusterMI.h"
214 #include "AliTPCcalibTracksCuts.h"
215 #include "AliTPCFitPad.h"
216 #include "TStatToolkit.h"
222 #include "AliESDEvent.h"
226 TFile f("TPCCalibTracksGain.root")
228 gSystem->Load("libPWGPP.so")
234 TString * str = comp.FitPlane("Cl.fQ/dedxQ.fElements[0]","Cl.fY++Cl.fX","Cl.fDetector<36",chi2,vec,mat)
238 ClassImp(AliTPCcalibTracksGain)
240 const Bool_t AliTPCcalibTracksGain::fgkUseTotalCharge = kTRUE;
241 const Double_t AliTPCcalibTracksGain::fgkM = 25.;
242 const char* AliTPCcalibTracksGain::fgkDebugStreamFileName = "TPCCalibTracksGain.root";
243 AliTPCParamSR* AliTPCcalibTracksGain::fgTPCparam = new AliTPCParamSR();
245 AliTPCcalibTracksGain::AliTPCcalibTracksGain() :
247 fCuts(0), // cuts that are used for sieving the tracks used for calibration
251 fSimpleFitter(0), // simple fitter for short pads
252 fSqrtFitter(0), // sqrt fitter for medium pads
253 fLogFitter(0), // log fitter for long pads
255 fFitter0M(0), // fitting of the atenuation, angular correction, and mean chamber gain
256 fFitter1M(0), // fitting of the atenuation, angular correction, and mean chamber gain
257 fFitter2M(0), // fitting of the atenuation, angular correction, and mean chamber gain
258 fFitter0T(0), // fitting of the atenuation, angular correction, and mean chamber gain
259 fFitter1T(0), // fitting of the atenuation, angular correction, and mean chamber gain
260 fFitter2T(0), // fitting of the atenuation, angular correction, and mean chamber gain
262 fDFitter0M(0), // fitting of the atenuation, angular correction
263 fDFitter1M(0), // fitting of the atenuation, angular correction
264 fDFitter2M(0), // fitting of the atenuation, angular correction
265 fDFitter0T(0), // fitting of the atenuation, angular correction
266 fDFitter1T(0), // fitting of the atenuation, angular correction
267 fDFitter2T(0), // fitting of the atenuation, angular correction
269 fSingleSectorFitter(0), // just for debugging
273 fTotalTracks(0), // just for debugging
274 fAcceptedTracks(0) // just for debugging
278 // Default constructor.
282 AliTPCcalibTracksGain::AliTPCcalibTracksGain(const AliTPCcalibTracksGain& obj) :
283 AliTPCcalibBase(obj),
284 fCuts(obj.fCuts), // cuts that are used for sieving the tracks used for calibration
288 fSimpleFitter(obj.fSimpleFitter), // simple fitter for short pads
289 fSqrtFitter(obj.fSqrtFitter), // sqrt fitter for medium pads
290 fLogFitter(obj.fLogFitter), // log fitter for long pads
291 fFitter0M(obj.fFitter0M),
292 fFitter1M(obj.fFitter1M),
293 fFitter2M(obj.fFitter2M),
294 fFitter0T(obj.fFitter0T),
295 fFitter1T(obj.fFitter1T),
296 fFitter2T(obj.fFitter2T),
298 fDFitter0M(obj.fDFitter0M),
299 fDFitter1M(obj.fDFitter1M),
300 fDFitter2M(obj.fDFitter2M),
301 fDFitter0T(obj.fDFitter0T),
302 fDFitter1T(obj.fDFitter1T),
303 fDFitter2T(obj.fDFitter2T),
304 fSingleSectorFitter(obj.fSingleSectorFitter), // just for debugging
308 fTotalTracks(obj.fTotalTracks), // just for debugging
309 fAcceptedTracks(obj.fAcceptedTracks) // just for debugging
317 AliTPCcalibTracksGain& AliTPCcalibTracksGain::operator=(const AliTPCcalibTracksGain& rhs) {
319 // Assignment operator.
323 TNamed::operator=(rhs);
324 fSimpleFitter = new AliTPCFitPad(*(rhs.fSimpleFitter));
325 fSqrtFitter = new AliTPCFitPad(*(rhs.fSqrtFitter));
326 fLogFitter = new AliTPCFitPad(*(rhs.fLogFitter));
327 fSingleSectorFitter = new AliTPCFitPad(*(rhs.fSingleSectorFitter));
328 fCuts = new AliTPCcalibTracksCuts(*(rhs.fCuts));
333 AliTPCcalibTracksGain::AliTPCcalibTracksGain(const char* name, const char* title, AliTPCcalibTracksCuts* cuts) :
335 fCuts(0), // cuts that are used for sieving the tracks used for calibration
339 fSimpleFitter(0), // simple fitter for short pads
340 fSqrtFitter(0), // sqrt fitter for medium pads
341 fLogFitter(0), // log fitter for long pads
342 fFitter0M(0), // fitting of the atenuation, angular correction, and mean chamber gain
343 fFitter1M(0), // fitting of the atenuation, angular correction, and mean chamber gain
344 fFitter2M(0), // fitting of the atenuation, angular correction, and mean chamber gain
345 fFitter0T(0), // fitting of the atenuation, angular correction, and mean chamber gain
346 fFitter1T(0), // fitting of the atenuation, angular correction, and mean chamber gain
347 fFitter2T(0), // fitting of the atenuation, angular correction, and mean chamber gain
349 fDFitter0M(0), // fitting of the atenuation, angular correction
350 fDFitter1M(0), // fitting of the atenuation, angular correction
351 fDFitter2M(0), // fitting of the atenuation, angular correction
352 fDFitter0T(0), // fitting of the atenuation, angular correction
353 fDFitter1T(0), // fitting of the atenuation, angular correction
354 fDFitter2T(0), // fitting of the atenuation, angular correction
355 fSingleSectorFitter(0), // just for debugging
359 fTotalTracks(0), // just for debugging
360 fAcceptedTracks(0) // just for debugging
366 this->SetNameTitle(name, title);
369 // Fitter initialization
371 fSimpleFitter = new AliTPCFitPad(8, "hyp7", "");
372 fSqrtFitter = new AliTPCFitPad(8, "hyp7", "");
373 fLogFitter = new AliTPCFitPad(8, "hyp7", "");
374 fSingleSectorFitter = new AliTPCFitPad(8, "hyp7", "");
376 fFitter0M = new TLinearFitter(45,"hyp44");
377 fFitter1M = new TLinearFitter(45,"hyp44");
378 fFitter2M = new TLinearFitter(45,"hyp44");
379 fFitter0T = new TLinearFitter(45,"hyp44");
380 fFitter1T = new TLinearFitter(45,"hyp44");
381 fFitter2T = new TLinearFitter(45,"hyp44");
383 fDFitter0M = new TLinearFitter(10,"hyp9");
384 fDFitter1M = new TLinearFitter(10,"hyp9");
385 fDFitter2M = new TLinearFitter(10,"hyp9");
386 fDFitter0T = new TLinearFitter(10,"hyp9");
387 fDFitter1T = new TLinearFitter(10,"hyp9");
388 fDFitter2T = new TLinearFitter(10,"hyp9");
391 fFitter0M->StoreData(kFALSE);
392 fFitter1M->StoreData(kFALSE);
393 fFitter2M->StoreData(kFALSE);
394 fFitter0T->StoreData(kFALSE);
395 fFitter1T->StoreData(kFALSE);
396 fFitter2T->StoreData(kFALSE);
398 fDFitter0M->StoreData(kFALSE);
399 fDFitter1M->StoreData(kFALSE);
400 fDFitter2M->StoreData(kFALSE);
401 fDFitter0T->StoreData(kFALSE);
402 fDFitter1T->StoreData(kFALSE);
403 fDFitter2T->StoreData(kFALSE);
406 // just for debugging -counters
412 AliTPCcalibTracksGain::~AliTPCcalibTracksGain() {
417 Info("Destructor",":");
418 if (fSimpleFitter) delete fSimpleFitter;
419 if (fSqrtFitter) delete fSqrtFitter;
420 if (fLogFitter) delete fLogFitter;
421 if (fSingleSectorFitter) delete fSingleSectorFitter;
428 void AliTPCcalibTracksGain::Terminate(){
430 // Evaluate fitters and close the debug stream.
431 // Also move or copy the debug stream, if a debugStreamPrefix is provided.
435 AliTPCcalibBase::Terminate();
440 void AliTPCcalibTracksGain::Process(AliTPCseed* seed) {
442 // Main method to be called when a new seed is supposed to be processed
443 // and be used for gain calibration. Its quality is checked before it
449 if (!fCuts->AcceptTrack(seed)) return;
453 static Bool_t doinit= kTRUE;
455 fSimpleFitter = new AliTPCFitPad(8, "hyp7", "");
456 fSqrtFitter = new AliTPCFitPad(8, "hyp7", "");
457 fLogFitter = new AliTPCFitPad(8, "hyp7", "");
458 fSingleSectorFitter = new AliTPCFitPad(8, "hyp7", "");
460 fFitter0M = new TLinearFitter(45,"hyp44");
461 fFitter1M = new TLinearFitter(45,"hyp44");
462 fFitter2M = new TLinearFitter(45,"hyp44");
463 fFitter0T = new TLinearFitter(45,"hyp44");
464 fFitter1T = new TLinearFitter(45,"hyp44");
465 fFitter2T = new TLinearFitter(45,"hyp44");
467 fDFitter0M = new TLinearFitter(10,"hyp9");
468 fDFitter1M = new TLinearFitter(10,"hyp9");
469 fDFitter2M = new TLinearFitter(10,"hyp9");
470 fDFitter0T = new TLinearFitter(10,"hyp9");
471 fDFitter1T = new TLinearFitter(10,"hyp9");
472 fDFitter2T = new TLinearFitter(10,"hyp9");
481 Long64_t AliTPCcalibTracksGain::Merge(TCollection *list) {
483 // Merge() merges the results of all AliTPCcalibTracksGain objects contained in
484 // list, thus allowing a distributed computation of several files, e.g. on PROOF.
485 // The merged results are merged with the data members of the AliTPCcalibTracksGain
486 // object used for calling the Merge method.
487 // The return value is 0 /*the total number of tracks used for calibration*/ if the merge
488 // is successful, otherwise it is -1.
491 if (!list || list->IsEmpty()) return -1;
493 if (!fSimpleFitter) fSimpleFitter = new AliTPCFitPad(8, "hyp7", "");
494 if (!fSqrtFitter) fSqrtFitter = new AliTPCFitPad(8, "hyp7", "");
495 if (!fLogFitter) fLogFitter = new AliTPCFitPad(8, "hyp7", "");
496 if (!fSingleSectorFitter) fSingleSectorFitter = new AliTPCFitPad(8, "hyp7", "");
500 TIterator* iter = list->MakeIterator();
501 AliTPCcalibTracksGain* cal = 0;
503 while ((cal = (AliTPCcalibTracksGain*)iter->Next())) {
504 if (!cal->InheritsFrom(AliTPCcalibTracksGain::Class())) {
505 //Error("Merge","Attempt to add object of class %s to a %s", cal->ClassName(), this->ClassName());
514 Float_t AliTPCcalibTracksGain::GetGain(AliTPCclusterMI *cluster){
519 AliTPCCalPad * gainMap = AliTPCcalibDB::Instance()->GetDedxGainFactor();
521 AliTPCCalROC * roc = gainMap->GetCalROC(cluster->GetDetector());
522 gainPad = roc->GetValue(cluster->GetRow(), TMath::Nint(cluster->GetPad()));
527 Float_t AliTPCcalibTracksGain::GetMaxNorm(AliTPCclusterMI * cluster, Float_t ky, Float_t kz){
529 // Get normalized amplituded if the gain map provided
531 AliTPCClusterParam * parcl = AliTPCcalibDB::Instance()->GetClusterParam();
533 parcl->QmaxCorrection(cluster->GetDetector(), cluster->GetRow(),cluster->GetPad(),
534 cluster->GetTimeBin(),ky,kz,0.5,0.5,1.6);
536 return GetGain(cluster)*maxNorm;
540 Float_t AliTPCcalibTracksGain::GetQNorm(AliTPCclusterMI * cluster, Float_t ky, Float_t kz){
542 // Get normalized amplituded if the gain map provided
544 AliTPCClusterParam * parcl = AliTPCcalibDB::Instance()->GetClusterParam();
545 Float_t totNorm = parcl->QtotCorrection(cluster->GetDetector(), cluster->GetRow(),cluster->GetPad(), cluster->GetTimeBin(),ky,kz,0.5,0.5,cluster->GetQ(),2.5,1.6);
546 return GetGain(cluster)*totNorm;
551 void AliTPCcalibTracksGain::Add(AliTPCcalibTracksGain* cal) {
553 // Adds another AliTPCcalibTracksGain object to this object.
556 fSimpleFitter->Add(cal->fSimpleFitter);
557 fSqrtFitter->Add(cal->fSqrtFitter);
558 fLogFitter->Add(cal->fLogFitter);
559 fSingleSectorFitter->Add(cal->fSingleSectorFitter);
563 if (cal->fFitter0M->GetNpoints()>0) fFitter0M->Add(cal->fFitter0M);
564 if (cal->fFitter1M->GetNpoints()>0) fFitter1M->Add(cal->fFitter1M);
565 if (cal->fFitter2M->GetNpoints()>0) fFitter2M->Add(cal->fFitter2M);
566 if (cal->fFitter0T->GetNpoints()>0) fFitter0T->Add(cal->fFitter0T);
567 if (cal->fFitter1T->GetNpoints()>0) fFitter1T->Add(cal->fFitter1T);
568 if (cal->fFitter2T->GetNpoints()>0) fFitter2T->Add(cal->fFitter2T);
570 if (cal->fDFitter0M->GetNpoints()>0) fDFitter0M->Add(cal->fDFitter0M);
571 if (cal->fDFitter1M->GetNpoints()>0) fDFitter1M->Add(cal->fDFitter1M);
572 if (cal->fDFitter2M->GetNpoints()>0) fDFitter2M->Add(cal->fDFitter2M);
573 if (cal->fDFitter0T->GetNpoints()>0) fDFitter0T->Add(cal->fDFitter0T);
574 if (cal->fDFitter1T->GetNpoints()>0) fDFitter1T->Add(cal->fDFitter1T);
575 if (cal->fDFitter2T->GetNpoints()>0) fDFitter2T->Add(cal->fDFitter2T);
578 // just for debugging, remove me
579 fTotalTracks += cal->fTotalTracks;
580 fAcceptedTracks += cal->fAcceptedTracks;
584 void AliTPCcalibTracksGain::AddTrack(AliTPCseed* seed) {
586 // The clusters making up the track (seed) are added to various fit functions.
587 // See AddCluster(...) for more detail.
596 void AliTPCcalibTracksGain::AddCluster(AliTPCclusterMI* cluster, Float_t /*momenta*/, Float_t/* mdedx*/, Int_t padType,
597 Float_t xcenter, TVectorD& dedxQ, TVectorD& /*dedxM*/, Float_t /*fraction*/, Float_t fraction2, Float_t dedge,
598 TVectorD& parY, TVectorD& parZ, TVectorD& meanPos) {
600 // Adds cluster to the appropriate fitter for later analysis.
601 // The charge used for the fit is the maximum charge for this specific cluster or the
602 // accumulated charge per cluster, depending on the value of fgkUseTotalCharge.
603 // Depending on the pad size where the cluster is registered, the value will be put in
604 // the appropriate fitter. Furthermore, for each pad size three different types of fitters
605 // are used. The fit functions are the same for all fitters (parabolic functions), but the value
606 // added to each fitter is different. The simple fitter gets the charge plugged in as is, the sqrt fitter
607 // gets the square root of the charge, and the log fitter gets fgkM*(1+q/fgkM), where q is the original charge
611 Float_t kfraction = 0.7;
615 // Where to put selection on threshold?
616 // Defined by the Q/dEdxT variable - see debug streamer:
618 // Debug stream variables: (Where tu cut ?)
619 // chain0->Draw("Cl.fQ/dedxQ.fElements[1]>>his(100,0,3)","fraction2<0.6&&dedge>3","",1000000);
621 // chain0->Draw("Cl.fMax/dedxM.fElements[1]>>his(100,0,3)","fraction2<0.6&&dedge>3","",1000000)
623 // chain0->Draw("Cl.fQ/dedxQ.fElements[2]>>his(100,0,3)","fraction2<0.7&&dedge>3","",1000000)
625 // chain0->Draw("Cl.fMax/dedxM.fElements[2]>>his(100,0,3)","fraction2<0.7&&dedge>3","",1000000)
627 // chain0->Draw("Cl.fQ/dedxQ.fElements[3]>>his(100,0,3)","fraction2<0.8&&dedge>3","",1000000)
630 // chain0->Draw("Cl.fQ/dedxQ.fElements[4]>>his(100,0,3)","fraction2<0.9&&dedge>3","",1000000)
633 // Fraction choosen 0.7
636 Error("AddCluster", "Cluster not valid.");
640 if (dedge < kedge) return;
641 if (fraction2 > kfraction) return;
643 //Int_t padType = GetPadType(cluster->GetX());
645 //Double_t centerPad[2] = {0};
646 //AliTPCFitPad::GetPadRegionCenterLocal(padType, centerPad);
647 //xx[0] = cluster->GetX() - centerPad[0];
648 //xx[1] = cluster->GetY() - centerPad[1];
649 xx[0] = cluster->GetX() - xcenter;
650 xx[1] = cluster->GetY();
651 xx[2] = xx[0] * xx[0];
652 xx[3] = xx[1] * xx[1];
653 xx[4] = xx[0] * xx[1];
654 xx[5] = TMath::Abs(cluster->GetZ()) - TMath::Abs(meanPos[4]);
655 xx[6] = xx[5] * xx[5];
660 Int_t segment = cluster->GetDetector() % 36;
661 Double_t q = fgkUseTotalCharge ?
662 ((Double_t)(cluster->GetQ()/GetQNorm(cluster,parY[1], parZ[1]))) : ((Double_t)(cluster->GetMax()/GetMaxNorm(cluster,parY[1], parZ[1])));
664 // correct charge by normalising to mean charge per track
667 // just for debugging
669 Double_t sqrtQ = TMath::Sqrt(q);
670 Double_t logQ = fgkM * TMath::Log(1 + q / fgkM);
671 TLinearFitter * fitter =0;
673 fitter = fSimpleFitter->GetFitter(segment, padType);
674 fitter->AddPoint(xx, q);
676 fitter = fSqrtFitter->GetFitter(segment, padType);
677 fitter->AddPoint(xx, sqrtQ);
679 fitter = fLogFitter->GetFitter(segment, padType);
680 fitter->AddPoint(xx, logQ);
682 fitter=fSingleSectorFitter->GetFitter(0, padType);
683 fitter->AddPoint(xx, q);
687 void AliTPCcalibTracksGain::Evaluate(Bool_t robust, Double_t frac) {
689 // Evaluates all fitters contained in this object.
690 // If the robust option is set to kTRUE a robust fit is performed with frac as
691 // the minimal fraction of good points (see TLinearFitter::EvalRobust for details).
692 // Beware: Robust fitting is much slower!
695 fSimpleFitter->Evaluate(robust, frac);
696 fSqrtFitter->Evaluate(robust, frac);
697 fLogFitter->Evaluate(robust, frac);
698 fSingleSectorFitter->Evaluate(robust, frac);
714 AliTPCCalPad* AliTPCcalibTracksGain::CreateFitCalPad(UInt_t fitType, Bool_t undoTransformation, Bool_t normalizeToPadSize) {
716 // Creates the calibration object AliTPCcalPad using fitted parameterization
719 for (UInt_t iSector = 0; iSector < 72; iSector++)
720 tpc.Add(CreateFitCalROC(iSector, fitType, undoTransformation, normalizeToPadSize));
721 return new AliTPCCalPad(&tpc);
724 AliTPCCalROC* AliTPCcalibTracksGain::CreateFitCalROC(UInt_t sector, UInt_t fitType, Bool_t undoTransformation, Bool_t normalizeToPadSize) {
726 // Create the AliTPCCalROC with the values per pad
727 // sector - sector of interest
733 GetParameters(sector % 36, 0, fitType, par);
734 return CreateFitCalROC(sector, 0, par, fitType, undoTransformation, normalizeToPadSize);
737 GetParameters(sector % 36, 1, fitType, par);
738 AliTPCCalROC* roc1 = CreateFitCalROC(sector, 1, par, fitType, undoTransformation, normalizeToPadSize);
739 GetParameters(sector % 36, 2, fitType, par);
740 AliTPCCalROC* roc2 = CreateFitCalROC(sector, 2, par, fitType, undoTransformation, normalizeToPadSize);
741 AliTPCCalROC* roc3 = CreateCombinedCalROC(roc1, roc2);
748 AliTPCCalROC* AliTPCcalibTracksGain::CreateFitCalROC(UInt_t sector, UInt_t padType, TVectorD &fitParam, UInt_t fitType, Bool_t undoTransformation, Bool_t normalizeToPadSize) {
750 // This function is essentially a copy of AliTPCCalROC::CreateGlobalFitCalROC(...), with the
751 // modifications, that the center of the region of same pad size is used as the origin
752 // of the fit function instead of the center of the ROC.
753 // The possibility of a linear fit is removed as well because it is not needed.
754 // Only values for pads with the given pad size are calculated, the rest is 0.
755 // Set undoTransformation for undoing the transformation that was applied to the
756 // charge values before they were put into the fitter (thus allowing comparison to the original
757 // charge values). For fitType use 0 for the simple fitter, 1 for the sqrt fitter, 2 for the log fitter.
758 // If normalizeToPadSize is true, the values are normalized to the pad size.
759 // Please be aware, that you even need to specify the fitType if you want to normalize to the pad size without
760 // undoing the transformation (because normalizing involves undoing the trafo first, then normalizing, then
761 // applying the trafo again).
762 // Please note: The normalization to the pad size is a simple linear scaling with the pad length, which
763 // actually doesn't describe reality!
767 Double_t centerPad[2] = {0};
768 Float_t localXY[3] = {0};
769 AliTPCROC* tpcROC = AliTPCROC::Instance();
770 if ((padType == 0 && sector >= tpcROC->GetNInnerSector()) || (padType > 0 && sector < tpcROC->GetNInnerSector()) || sector >= tpcROC->GetNSector())
772 AliTPCCalROC* lROCfitted = new AliTPCCalROC(sector);
773 //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
779 endRow = lROCfitted->GetNrows();
787 endRow = lROCfitted->GetNrows();
791 AliTPCFitPad::GetPadRegionCenterLocal(padType, centerPad);
793 for (UInt_t irow = startRow; irow < endRow; irow++) {
794 for (UInt_t ipad = 0; ipad < lROCfitted->GetNPads(irow); ipad++) {
795 tpcROC->GetPositionLocal(sector, irow, ipad, localXY); // calculate position localXY by pad and row number
796 dlx = localXY[0] - centerPad[0];
797 dly = localXY[1] - centerPad[1];
798 value = fitParam[0] + fitParam[1]*dlx + fitParam[2]*dly + fitParam[3]*dlx*dlx + fitParam[4]*dly*dly + fitParam[5]*dlx*dly;
800 // Let q' = value be the transformed value without any pad size corrections,
801 // let T be the transformation and let l be the pad size
802 // 1) don't undo transformation, don't normalize: return q'
803 // 2) undo transformation, don't normalize: return T^{-1} q'
804 // 3) undo transformation, normalize: return (T^{-1} q') / l
805 // 4) don't undo transformation, normalize: return T((T^{-1} q') / l)
806 if (!undoTransformation && !normalizeToPadSize) {/* value remains unchanged */} // (1)
807 else { // (2), (3), (4)
810 case 0: /* value remains unchanged */ break;
811 case 1: value = value * value; break;
812 case 2: value = (TMath::Exp(value / fgkM) - 1) * fgkM; break;
813 default: Error("CreateFitCalROC", "Wrong fit type."); break;
815 if (normalizeToPadSize) value /= GetPadLength(localXY[0]); // (3)
817 if (!undoTransformation && normalizeToPadSize) { // (4)
820 case 0: /* value remains unchanged */ break;
821 case 1: value = TMath::Sqrt(value); break;
822 case 2: value = fgkM * TMath::Log(1 + value / fgkM); break;
823 default: Error("CreateFitCalROC", "Wrong fit type."); break;
826 lROCfitted->SetValue(irow, ipad, value);
832 AliTPCCalROC* AliTPCcalibTracksGain::CreateCombinedCalROC(const AliTPCCalROC* roc1, const AliTPCCalROC* roc2) {
834 // Combines the medium pad size values of roc1 with the long pad size values of roc2 into a new
835 // AliTPCCalROC. Returns a null pointer if any one of the ROCs is an IROC; issues a warning message
836 // if the sectors of roc1 and roc2 don't match, but still continue and use the sector of roc1 as the
837 // sector of the new ROC.
840 if (!roc1 || !roc2) return 0;
841 if ((Int_t)(roc1->GetSector()) < fgTPCparam->GetNInnerSector()) return 0;
842 if ((Int_t)(roc2->GetSector()) < fgTPCparam->GetNInnerSector()) return 0;
843 if (roc1->GetSector() != roc2->GetSector()) Warning("CreateCombinedCalROC", "Sector number mismatch.");
844 AliTPCCalROC* roc = new AliTPCCalROC(roc1->GetSector());
846 for (UInt_t iRow = 0; iRow < 64; iRow++) {
847 for (UInt_t iPad = 0; iPad < roc->GetNPads(iRow); iPad++)
848 roc->SetValue(iRow, iPad, roc1->GetValue(iRow, iPad));
850 for (UInt_t iRow = 64; iRow < roc->GetNrows(); iRow++) {
851 for (UInt_t iPad = 0; iPad < roc->GetNPads(iRow); iPad++)
852 roc->SetValue(iRow, iPad, roc2->GetValue(iRow, iPad));
857 Bool_t AliTPCcalibTracksGain::GetParameters(UInt_t segment, UInt_t padType, UInt_t fitType, TVectorD &fitParam) {
859 // Puts the fit parameters for the specified segment (IROC & OROC), padType and fitType
860 // into the fitParam TVectorD (which should contain 8 elements).
861 // padType is one of kShortPads, kMediumPads, kLongPads. fitType is one of kSimpleFitter, kSqrtFitter, kLogFitter.
862 // Note: The fitter has to be evaluated first!
864 TLinearFitter * fitter = GetFitter(segment, padType, fitType);
867 fitter->GetParameters(fitParam);
870 Error("AliTPCcalibTracksGain::GetParameters","Fitter%d_%d_%d not available", segment, padType, fitType);
876 void AliTPCcalibTracksGain::GetErrors(UInt_t segment, UInt_t padType, UInt_t fitType, TVectorD &fitError) {
878 // Puts the fit parameter errors for the specified segment (IROC & OROC), padType and fitType
879 // into the fitError TVectorD (which should contain 8 elements).
880 // padType is one of kShortPads, kMediumPads, kLongPads. fitType is one of kSimpleFitter, kSqrtFitter, kLogFitter.
881 // Note: The fitter has to be evaluated first!
884 GetFitter(segment, padType, fitType)->GetErrors(fitError);
885 //fitError *= TMath::Sqrt(GetRedChi2(segment, padType, fitType));
889 void AliTPCcalibTracksGain::GetCovarianceMatrix(UInt_t segment, UInt_t padType, UInt_t fitType, TMatrixD& covMatrix) {
891 // Returns the covariance matrix for the specified segment, padType, fitType.
892 // padType is one of kShortPads, kMediumPads, kLongPads. fitType is one of kSimpleFitter, kSqrtFitter, kLogFitter.
895 GetFitter(segment, padType, fitType)->GetCovarianceMatrix(covMatrix);
898 TLinearFitter* AliTPCcalibTracksGain::GetFitter(UInt_t segment, UInt_t padType, UInt_t fitType) {
900 // Returns the TLinearFitter object for the specified segment, padType, fitType.
901 // padType is one of kShortPads, kMediumPads, kLongPads. fitType is one of kSimpleFitter, kSqrtFitter, kLogFitter.
906 return fSimpleFitter->GetFitter(segment, padType);
908 return fSqrtFitter->GetFitter(segment, padType);
910 return fLogFitter->GetFitter(segment, padType);
912 return fSingleSectorFitter->GetFitter(0, padType);
917 Double_t AliTPCcalibTracksGain::GetPadLength(Double_t lx) {
919 // The function returns 0.75 for an IROC, 1. for an OROC at medium pad size position,
920 // 1.5 for an OROC at long pad size position, -1 if out of bounds.
923 Double_t irocLow = fgTPCparam->GetPadRowRadiiLow(0) - fgTPCparam->GetInnerPadPitchLength()/2;
924 Double_t irocUp = fgTPCparam->GetPadRowRadiiLow(fgTPCparam->GetNRowLow()-1) + fgTPCparam->GetInnerPadPitchLength()/2;
925 Double_t orocLow1 = fgTPCparam->GetPadRowRadiiUp(0) - fgTPCparam->GetOuter1PadPitchLength()/2;
926 Double_t orocUp1 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp1()-1) + fgTPCparam->GetOuter1PadPitchLength()/2;
927 Double_t orocLow2 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp1()) - fgTPCparam->GetOuter2PadPitchLength()/2;
928 Double_t orocUp2 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp()-1) + fgTPCparam->GetOuter2PadPitchLength()/2;
931 if (lx >= irocLow && lx <= irocUp) return 0.75;
932 // if OROC medium pads
933 if (lx >= orocLow1 && lx <= orocUp1) return 1.;
935 if (lx >= orocLow2 && lx <= orocUp2) return 1.5;
940 Int_t AliTPCcalibTracksGain::GetPadType(Double_t lx) {
942 // The function returns 0 for an IROC, 1 for an OROC at medium pad size position,
943 // 2 for an OROC at long pad size position, -1 if out of bounds.
946 if (GetPadLength(lx) == 0.75) return 0;
947 else if (GetPadLength(lx) == 1.) return 1;
948 else if (GetPadLength(lx) == 1.5) return 2;
952 void AliTPCcalibTracksGain::DumpTrack(AliTPCseed* track) {
954 // Dump track information to the debug stream
967 for (Int_t ipad = 0; ipad < 3; ipad++) {
968 dedxM[ipad].ResizeTo(5);
969 dedxQ[ipad].ResizeTo(5);
970 parY[ipad].ResizeTo(3);
971 parZ[ipad].ResizeTo(3);
972 meanPos[ipad].ResizeTo(6);
973 Bool_t isOK = GetDedx(track, ipad, rows, sector[ipad], npoints[ipad], dedxM[ipad], dedxQ[ipad], parY[ipad], parZ[ipad], meanPos[ipad]);
975 AddTracklet(sector[ipad],ipad, dedxQ[ipad], dedxM[ipad], parY[ipad], parZ[ipad], meanPos[ipad] );
979 TTreeSRedirector * cstream = GetDebugStreamer();
981 (*cstream) << "Track" <<
982 "run="<<fRun<< // run number
983 "event="<<fEvent<< // event number
984 "time="<<fTime<< // time stamp of event
985 "trigger="<<fTrigger<< // trigger
986 "mag="<<fMagF<< // magnetic field
987 "Track.=" << track << // track information
992 if ( GetStreamLevel()>1 && count>1){
993 (*cstream) << "TrackG" <<
994 "run="<<fRun<< // run number
995 "event="<<fEvent<< // event number
996 "time="<<fTime<< // time stamp of event
997 "trigger="<<fTrigger<< // trigger
998 "mag="<<fMagF<< // magnetic field
999 "Track.=" << track << // track information
1001 // info for pad type 0
1002 "sector0="<<sector[0]<<
1003 "npoints0="<<npoints[0]<<
1004 "dedxM0.="<<&dedxM[0]<<
1005 "dedxQ0.="<<&dedxQ[0]<<
1006 "parY0.="<<&parY[0]<<
1007 "parZ0.="<<&parZ[0]<<
1008 "meanPos0.="<<&meanPos[0]<<
1010 // info for pad type 1
1011 "sector1="<<sector[1]<<
1012 "npoints1="<<npoints[1]<<
1013 "dedxM1.="<<&dedxM[1]<<
1014 "dedxQ1.="<<&dedxQ[1]<<
1015 "parY1.="<<&parY[1]<<
1016 "parZ1.="<<&parZ[1]<<
1017 "meanPos1.="<<&meanPos[1]<<
1019 // info for pad type 2
1020 "sector2="<<sector[2]<<
1021 "npoints2="<<npoints[2]<<
1022 "dedxM2.="<<&dedxM[2]<<
1023 "dedxQ2.="<<&dedxQ[2]<<
1024 "parY2.="<<&parY[2]<<
1025 "parZ2.="<<&parZ[2]<<
1026 "meanPos2.="<<&meanPos[2]<<
1033 Bool_t AliTPCcalibTracksGain::GetDedx(AliTPCseed* track, Int_t padType, Int_t* /*rows*/,
1034 Int_t §or, Int_t& npoints,
1035 TVectorD &dedxM, TVectorD &dedxQ,
1036 TVectorD &parY, TVectorD &parZ, TVectorD&meanPos)
1039 // GetDedx for given sector for given track
1040 // padType - type of pads
1043 static TLinearFitter fitY(2, "pol1");
1044 static TLinearFitter fitZ(2, "pol1");
1045 fitY.StoreData(kFALSE);
1046 fitZ.StoreData(kFALSE);
1049 Int_t firstRow = 0, lastRow = 0;
1051 Float_t xcenter = 0;
1052 const Float_t ktany = TMath::Tan(TMath::DegToRad() * 10);
1053 const Float_t kedgey = 4.;
1056 lastRow = fgTPCparam->GetNRowLow();
1060 firstRow = fgTPCparam->GetNRowLow();
1061 lastRow = fgTPCparam->GetNRowLow() + fgTPCparam->GetNRowUp1();
1065 firstRow = fgTPCparam->GetNRowLow() + fgTPCparam->GetNRowUp1();
1066 lastRow = fgTPCparam->GetNRowLow() + fgTPCparam->GetNRowUp();
1069 minRow = (lastRow - firstRow) / 2;
1072 Int_t nclusters = 0;
1073 Int_t nclustersNE = 0; // number of not edge clusters
1074 Int_t lastSector = -1;
1075 Float_t amplitudeQ[100];
1076 Float_t amplitudeM[100];
1084 for (Int_t iCluster = firstRow; iCluster < lastRow; iCluster++) {
1085 AliTPCclusterMI* cluster = track->GetClusterPointer(iCluster);
1087 Int_t detector = cluster->GetDetector() ;
1088 if (lastSector == -1) lastSector = detector;
1089 if (lastSector != detector) continue;
1090 amplitudeQ[nclusters] = cluster->GetQ()/GetQNorm(cluster,parY[1], parZ[1]);
1091 amplitudeM[nclusters] = cluster->GetMax()/GetMaxNorm(cluster,parY[1], parZ[1]);
1092 rowIn[nclusters] = iCluster;
1094 Double_t dx = cluster->GetX() - xcenter;
1095 Double_t y = cluster->GetY();
1096 Double_t z = cluster->GetZ();
1097 fitY.AddPoint(&dx, y);
1098 fitZ.AddPoint(&dx, z);
1105 if (TMath::Abs(cluster->GetY()) < cluster->GetX()*ktany - kedgey) nclustersNE++;
1109 if (nclusters < minRow / 2) return kFALSE;
1110 if (nclustersNE < minRow / 2) return kFALSE;
1111 for (Int_t i = 0; i < 6; i++) meanPos[i] /= Double_t(nclusters);
1114 fitY.GetParameters(parY);
1115 fitZ.GetParameters(parZ);
1117 // calculate truncated mean
1119 TMath::Sort(nclusters, amplitudeQ, index, kFALSE);
1124 for (Int_t i = 0; i < 5; i++) {
1133 for (Int_t i = 0; i < nclusters; i++) {
1134 Int_t rowSorted = rowIn[index[i]];
1135 AliTPCclusterMI* cluster = track->GetClusterPointer(rowSorted);
1137 if (TMath::Abs(cluster->GetY()) > cluster->GetX()*ktany - kedgey) continue; //don't take edge clusters
1139 if (inonEdge < nclustersNE * 0.5) {
1141 dedxQ[0] += amplitudeQ[index[i]];
1142 dedxM[0] += amplitudeM[index[i]];
1144 if (inonEdge < nclustersNE * 0.6) {
1146 dedxQ[1] += amplitudeQ[index[i]];
1147 dedxM[1] += amplitudeM[index[i]];
1149 if (inonEdge < nclustersNE * 0.7) {
1151 dedxQ[2] += amplitudeQ[index[i]];
1152 dedxM[2] += amplitudeM[index[i]];
1154 if (inonEdge < nclustersNE * 0.8) {
1156 dedxQ[3] += amplitudeQ[index[i]];
1157 dedxM[3] += amplitudeM[index[i]];
1159 if (inonEdge < nclustersNE * 0.9) {
1161 dedxQ[4] += amplitudeQ[index[i]];
1162 dedxM[4] += amplitudeM[index[i]];
1165 for (Int_t i = 0; i < 5; i++) {
1166 dedxQ[i] /= ndedx[i];
1167 dedxM[i] /= ndedx[i];
1169 TTreeSRedirector * cstream = GetDebugStreamer();
1171 Float_t momenta = track->GetP();
1172 Float_t mdedx = track->GetdEdx();
1173 for (Int_t i = 0; i < nclusters; i++) {
1174 Int_t rowSorted = rowIn[index[i]];
1175 AliTPCclusterMI* cluster = track->GetClusterPointer(rowSorted);
1177 printf("Problem\n");
1180 if (TMath::Abs(cluster->GetY()) < cluster->GetX()*ktany - kedgey) inonEdge++;
1181 Float_t dedge = cluster->GetX()*ktany - TMath::Abs(cluster->GetY());
1182 Float_t fraction = Float_t(i) / Float_t(nclusters);
1183 Float_t fraction2 = Float_t(inonEdge) / Float_t(nclustersNE);
1185 AddCluster(cluster, momenta, mdedx, padType, xcenter, dedxQ, dedxM, fraction, fraction2, dedge, parY, parZ, meanPos);
1187 Double_t qNorm = GetQNorm(cluster,parY[1], parZ[1]);
1188 Double_t mNorm = GetMaxNorm(cluster,parY[1], parZ[1]);
1191 Float_t gain = GetGain(cluster);
1192 if (cstream) (*cstream) << "dEdx" <<
1193 "run="<<fRun<< // run number
1194 "event="<<fEvent<< // event number
1195 "time="<<fTime<< // time stamp of event
1196 "trigger="<<fTrigger<< // trigger
1197 "mag="<<fMagF<< // magnetic field
1199 "Cl.=" << cluster << // cluster of interest
1200 "gain="<<gain<< // gain at cluster position
1201 "mNorm="<<mNorm<< // Q max normalization
1202 "qNorm="<<qNorm<< // Q tot normalization
1203 "P=" << momenta << // track momenta
1204 "dedx=" << mdedx << // mean dedx - corrected for angle
1205 "IPad=" << padType << // pad type 0..2
1206 "xc=" << xcenter << // x center of chamber
1207 "dedxQ.=" << &dedxQ << // dedxQ - total charge
1208 "dedxM.=" << &dedxM << // dedxM - maximal charge
1209 "fraction=" << fraction << // fraction - order in statistic (0,1)
1210 "fraction2=" << fraction2 << // fraction - order in statistic (0,1)
1211 "dedge=" << dedge << // distance to the edge
1212 "parY.=" << &parY << // line fit
1213 "parZ.=" << &parZ << // line fit
1214 "meanPos.=" << &meanPos << // mean position (dx, dx^2, y,y^2, z, z^2)
1218 if (cstream) (*cstream) << "dEdxT" <<
1219 "run="<<fRun<< // run number
1220 "event="<<fEvent<< // event number
1221 "time="<<fTime<< // time stamp of event
1222 "trigger="<<fTrigger<< // trigger
1223 "mag="<<fMagF<< // magnetic field
1224 "P=" << momenta << // track momenta
1225 "npoints="<<inonEdge<< // number of points
1226 "sector="<<lastSector<< // sector number
1227 "dedx=" << mdedx << // mean dedx - corrected for angle
1228 "IPad=" << padType << // pad type 0..2
1229 "xc=" << xcenter << // x center of chamber
1230 "dedxQ.=" << &dedxQ << // dedxQ - total charge
1231 "dedxM.=" << &dedxM << // dedxM - maximal charge
1232 "parY.=" << &parY << // line fit
1233 "parZ.=" << &parZ << // line fit
1234 "meanPos.=" << &meanPos << // mean position (dx, dx^2, y,y^2, z, z^2)
1237 sector = lastSector;
1242 void AliTPCcalibTracksGain::AddTracklet(UInt_t sector, UInt_t padType,TVectorD &dedxQ, TVectorD &dedxM,TVectorD& parY, TVectorD& parZ, TVectorD& meanPos){
1244 // Add measured point - dedx to the fitter
1247 //chain->SetAlias("dr","(250-abs(meanPos.fElements[4]))/250");
1248 //chain->SetAlias("tz","(0+abs(parZ.fElements[1]))");
1249 //chain->SetAlias("ty","(0+abs(parY.fElements[1]))");
1250 //chain->SetAlias("corrg","sqrt((1+ty^2)*(1+tz^2))");
1251 //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);
1255 // z and angular part
1258 xxx[0] = (250.-TMath::Abs(meanPos[4]))/250.;
1259 xxx[1] = TMath::Abs(parY[1]);
1260 xxx[2] = TMath::Abs(parZ[1]);
1261 xxx[3] = xxx[0]*xxx[1];
1262 xxx[4] = xxx[0]*xxx[2];
1263 xxx[5] = xxx[1]*xxx[2];
1264 xxx[6] = xxx[0]*xxx[0];
1265 xxx[7] = xxx[1]*xxx[1];
1266 xxx[8] = xxx[2]*xxx[2];
1270 Int_t tsector = sector%36;
1271 for (Int_t i=0;i<35;i++){
1272 xxx[9+i]=(i==tsector)?1:0;
1274 TLinearFitter *fitterM = fFitter0M;
1275 if (padType==1) fitterM=fFitter1M;
1276 if (padType==2) fitterM=fFitter2M;
1277 fitterM->AddPoint(xxx,dedxM[1]);
1279 TLinearFitter *fitterT = fFitter0T;
1280 if (padType==1) fitterT = fFitter1T;
1281 if (padType==2) fitterT = fFitter2T;
1282 fitterT->AddPoint(xxx,dedxQ[1]);
1284 TLinearFitter *dfitterM = fDFitter0M;
1285 if (padType==1) dfitterM=fDFitter1M;
1286 if (padType==2) dfitterM=fDFitter2M;
1287 dfitterM->AddPoint(xxx,dedxM[1]);
1289 TLinearFitter *dfitterT = fDFitter0T;
1290 if (padType==1) dfitterT = fDFitter1T;
1291 if (padType==2) dfitterT = fDFitter2T;
1292 dfitterT->AddPoint(xxx,dedxQ[1]);
1296 TGraph *AliTPCcalibTracksGain::CreateAmpGraph(Int_t ipad, Bool_t qmax){
1298 // create the amplitude graph
1299 // The normalized amplitudes are extrapolated to the 0 angle (y,z) and 0 drift length
1304 if (ipad==0) fFitter0M->GetParameters(vec);
1305 if (ipad==1) fFitter1M->GetParameters(vec);
1306 if (ipad==2) fFitter2M->GetParameters(vec);
1308 if (ipad==0) fFitter0T->GetParameters(vec);
1309 if (ipad==1) fFitter1T->GetParameters(vec);
1310 if (ipad==2) fFitter2T->GetParameters(vec);
1315 for (Int_t i=0;i<35;i++){
1317 amp[i]=vec[10+i]+vec[0];
1320 Float_t mean = TMath::Mean(36,amp);
1321 for (Int_t i=0;i<36;i++){
1323 amp[i]=(amp[i]-mean)/mean;
1325 TGraph *gr = new TGraph(36,sec,amp);
1330 void AliTPCcalibTracksGain::UpdateClusterParam(AliTPCClusterParam* clparam){
1332 // SetQ normalization parameters
1334 // void SetQnorm(Int_t ipad, Int_t itype, TVectorD * norm);
1345 fDFitter0T->GetParameters(vec);
1346 clparam->SetQnorm(0,0,&vec);
1347 fDFitter1T->GetParameters(vec);
1348 clparam->SetQnorm(1,0,&vec);
1349 fDFitter2T->GetParameters(vec);
1350 clparam->SetQnorm(2,0,&vec);
1352 fDFitter0M->GetParameters(vec);
1353 clparam->SetQnorm(0,1,&vec);
1354 fDFitter1M->GetParameters(vec);
1355 clparam->SetQnorm(1,1,&vec);
1356 fDFitter2M->GetParameters(vec);
1357 clparam->SetQnorm(2,1,&vec);
1363 void AliTPCcalibTracksGain::Analyze(){