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 fDebugStream(0), //! debug stream for debugging
170 fCuts(0), // cuts that are used for sieving the tracks used for calibration
172 // Simple Array of histograms
174 fArrayQM(0), // Qmax normalized
175 fArrayQT(0), // Qtot normalized
176 fProfileArrayQM(0), // Qmax normalized versus local X
177 fProfileArrayQT(0), // Qtot normalized versus local X
178 fProfileArrayQM2D(0), // Qmax normalized versus local X and phi
179 fProfileArrayQT2D(0), // Qtot normalized versus local X and phi
183 fSimpleFitter(0), // simple fitter for short pads
184 fSqrtFitter(0), // sqrt fitter for medium pads
185 fLogFitter(0), // log fitter for long pads
186 fFitter0M(0), // fitting of the atenuation, angular correction, and mean chamber gain
187 fFitter1M(0), // fitting of the atenuation, angular correction, and mean chamber gain
188 fFitter2M(0), // fitting of the atenuation, angular correction, and mean chamber gain
189 fFitter0T(0), // fitting of the atenuation, angular correction, and mean chamber gain
190 fFitter1T(0), // fitting of the atenuation, angular correction, and mean chamber gain
191 fFitter2T(0), // fitting of the atenuation, angular correction, and mean chamber gain
192 fSingleSectorFitter(0), // just for debugging
196 fTotalTracks(0), // just for debugging
197 fAcceptedTracks(0), // just for debugging
198 fDebugCalPadRaw(0), // just for debugging
199 fDebugCalPadCorr(0), // just for debugging
200 fPrevIter(0) // the calibration object in its previous iteration (will not be owned by the new object, don't forget to delete it!)
204 // Default constructor.
208 AliTPCcalibTracksGain::AliTPCcalibTracksGain(const AliTPCcalibTracksGain& obj) :
210 fDebugStream(0), //! debug stream for debugging
211 fCuts(obj.fCuts), // cuts that are used for sieving the tracks used for calibration
212 fArrayQM(0), // Qmax normalized
213 fArrayQT(0), // Qtot normalized
217 fProfileArrayQM(obj.fProfileArrayQM), // Qmax normalized versus local X
218 fProfileArrayQT(obj.fProfileArrayQT), // Qtot normalized versus local X
219 fProfileArrayQM2D(obj.fProfileArrayQM2D), // Qmax normalized versus local X and phi
220 fProfileArrayQT2D(obj.fProfileArrayQT2D), // Qtot normalized versus local X and phi
224 fSimpleFitter(obj.fSimpleFitter), // simple fitter for short pads
225 fSqrtFitter(obj.fSqrtFitter), // sqrt fitter for medium pads
226 fLogFitter(obj.fLogFitter), // log fitter for long pads
227 fFitter0M(obj.fFitter0M),
228 fFitter1M(obj.fFitter1M),
229 fFitter2M(obj.fFitter2M),
230 fFitter0T(obj.fFitter0T),
231 fFitter1T(obj.fFitter1T),
232 fFitter2T(obj.fFitter2T),
233 fSingleSectorFitter(obj.fSingleSectorFitter), // just for debugging
237 fTotalTracks(obj.fTotalTracks), // just for debugging
238 fAcceptedTracks(obj.fAcceptedTracks), // just for debugging
239 fDebugCalPadRaw(obj.fDebugCalPadRaw), // just for debugging
240 fDebugCalPadCorr(obj.fDebugCalPadCorr), // just for debugging
241 fPrevIter(obj.fPrevIter) // the calibration object in its previous iteration (will not be owned by the new object, don't forget to delete it!)
249 AliTPCcalibTracksGain& AliTPCcalibTracksGain::operator=(const AliTPCcalibTracksGain& rhs) {
251 // Assignment operator.
255 TNamed::operator=(rhs);
256 fDebugCalPadRaw = new AliTPCCalPad(*(rhs.fDebugCalPadRaw));
257 fDebugCalPadCorr = new AliTPCCalPad(*(rhs.fDebugCalPadCorr));
258 fSimpleFitter = new AliTPCFitPad(*(rhs.fSimpleFitter));
259 fSqrtFitter = new AliTPCFitPad(*(rhs.fSqrtFitter));
260 fLogFitter = new AliTPCFitPad(*(rhs.fLogFitter));
261 fSingleSectorFitter = new AliTPCFitPad(*(rhs.fSingleSectorFitter));
262 fPrevIter = new AliTPCcalibTracksGain(*(rhs.fPrevIter));
263 fCuts = new AliTPCcalibTracksCuts(*(rhs.fCuts));
268 AliTPCcalibTracksGain::AliTPCcalibTracksGain(const char* name, const char* title, AliTPCcalibTracksCuts* cuts, TNamed* /*debugStreamPrefix*/, AliTPCcalibTracksGain* prevIter) :
270 fDebugStream(0), //! debug stream for debugging
271 fCuts(0), // cuts that are used for sieving the tracks used for calibration
272 fArrayQM(0), // Qmax normalized
273 fArrayQT(0), // Qtot normalized
277 fProfileArrayQM(0), // Qmax normalized versus local X
278 fProfileArrayQT(0), // Qtot normalized versus local X
279 fProfileArrayQM2D(0), // Qmax normalized versus local X and phi
280 fProfileArrayQT2D(0), // Qtot normalized versus local X and phi
284 fSimpleFitter(0), // simple fitter for short pads
285 fSqrtFitter(0), // sqrt fitter for medium pads
286 fLogFitter(0), // log fitter for long pads
287 fFitter0M(0), // fitting of the atenuation, angular correction, and mean chamber gain
288 fFitter1M(0), // fitting of the atenuation, angular correction, and mean chamber gain
289 fFitter2M(0), // fitting of the atenuation, angular correction, and mean chamber gain
290 fFitter0T(0), // fitting of the atenuation, angular correction, and mean chamber gain
291 fFitter1T(0), // fitting of the atenuation, angular correction, and mean chamber gain
292 fFitter2T(0), // fitting of the atenuation, angular correction, and mean chamber gain
293 fSingleSectorFitter(0), // just for debugging
297 fTotalTracks(0), // just for debugging
298 fAcceptedTracks(0), // just for debugging
299 fDebugCalPadRaw(0), // just for debugging
300 fDebugCalPadCorr(0), // just for debugging
301 fPrevIter(0) // the calibration object in its previous iteration (will not be owned by the new object, don't forget to delete it!)
307 G__SetCatchException(0);
309 fPrevIter = prevIter;
311 // Fitter initialization
313 fSimpleFitter = new AliTPCFitPad(8, "hyp7", "");
314 fSqrtFitter = new AliTPCFitPad(8, "hyp7", "");
315 fLogFitter = new AliTPCFitPad(8, "hyp7", "");
316 fSingleSectorFitter = new AliTPCFitPad(8, "hyp7", "");
318 fFitter0M = new TLinearFitter(45,"hyp44");
319 fFitter1M = new TLinearFitter(45,"hyp44");
320 fFitter2M = new TLinearFitter(45,"hyp44");
321 fFitter0T = new TLinearFitter(45,"hyp44");
322 fFitter1T = new TLinearFitter(45,"hyp44");
323 fFitter2T = new TLinearFitter(45,"hyp44");
326 // Add profile histograms -JUST for visualization - Not used for real calibration
329 fArrayQM=new TObjArray(73); // Qmax normalized
330 fArrayQT=new TObjArray(73); // Qtot normalized
331 fProfileArrayQM = new TObjArray(37); // Qmax normalized versus local X
332 fProfileArrayQT = new TObjArray(37); // Qtot normalized versus local X
333 fProfileArrayQM2D = new TObjArray(37); // Qmax normalized versus local X and phi
334 fProfileArrayQT2D = new TObjArray(37); // Qtot normalized versus local X and phi
336 for (Int_t i=0; i<73; i++){
337 sprintf(hname,"QM_%d",i);
338 fArrayQM->AddAt(new TH1F(hname,hname,200,0,1000),i);
339 sprintf(hname,"QT_%d",i);
340 fArrayQT->AddAt(new TH1F(hname,hname,200,0,1000),i);
343 for (Int_t i=0; i<37;i++){
344 sprintf(hname,"QMvsx_%d",i);
345 fProfileArrayQM->AddAt(new TProfile(hname,hname,50,89,250),i);
346 sprintf(hname,"QTvsx_%d",i);
347 fProfileArrayQT->AddAt(new TProfile(hname,hname,50,89,250),i);
348 sprintf(hname,"QM2D_%d",i);
349 fProfileArrayQM2D->AddAt(new TProfile2D(hname,hname,50,89,250,10,-0.15,0.15),i);
350 sprintf(hname,"QT2D_%d",i);
351 fProfileArrayQT2D->AddAt(new TProfile2D(hname,hname,50,89,250,10,-0.15,0.15),i);
354 // just for debugging -counters
358 fDebugCalPadRaw = new AliTPCCalPad("DebugCalPadRaw", "All clusters simply added up before correction");
359 fDebugCalPadCorr = new AliTPCCalPad("DebugCalPadCorr", "All clusters simply added up after correction");
360 // this will be gone for the a new ROOT version > v5-17-05
361 for (UInt_t i = 0; i < 36; i++) {
362 fNShortClusters[i] = 0;
363 fNMediumClusters[i] = 0;
364 fNLongClusters[i] = 0;
368 AliTPCcalibTracksGain::~AliTPCcalibTracksGain() {
373 Info("Destructor","");
374 if (fSimpleFitter) delete fSimpleFitter;
375 if (fSqrtFitter) delete fSqrtFitter;
376 if (fLogFitter) delete fLogFitter;
377 if (fSingleSectorFitter) delete fSingleSectorFitter;
381 //fDebugStream->GetFile()->Close();
382 printf("Deleting debug stream object\n");
387 if (fDebugCalPadRaw) delete fDebugCalPadRaw;
388 if (fDebugCalPadCorr) delete fDebugCalPadCorr;
391 void AliTPCcalibTracksGain::Terminate(){
393 // Evaluate fitters and close the debug stream.
394 // Also move or copy the debug stream, if a debugStreamPrefix is provided.
404 void AliTPCcalibTracksGain::AddInfo(TChain* chain, char* debugStreamPrefix, char* prevIterFileName) {
406 // Add some parameters to the chain.
407 // debugStreamPrefix: If specified, contains the location (either normal or xrootd directory)
408 // where the debug stream is moved (normal directory) or copied to (xrootd).
409 // prevIterFileName: If specified, contains an AliTPCcalibTracksGain object from a previous run
410 // for doing an iterative calibration procedure (right now unused).
411 // Note: The parameters are *not* added to this class, you need to do it later by retrieving
412 // the parameters from the chain and passing them to the constructor!
415 if (debugStreamPrefix) {
416 TNamed* objDebugStreamPrefix = new TNamed("debugStreamPrefix", debugStreamPrefix);
417 chain->GetUserInfo()->AddLast((TObject*)objDebugStreamPrefix);
420 if (prevIterFileName) {
421 TFile paramFile(prevIterFileName);
422 if (paramFile.IsZombie()) {
423 printf("File %s not found. Continuing without previous iteration.\n", prevIterFileName);
427 AliTPCcalibTracksGain *prevIter = (AliTPCcalibTracksGain*)paramFile.Get("calibTracksGain");
429 chain->GetUserInfo()->AddLast((TObject*)prevIter);
431 printf("No calibTracksGain object found. Continuing without previous iteration.\n");
435 Bool_t AliTPCcalibTracksGain::AcceptTrack(AliTPCseed* track) {
437 // Decides whether to accept a track or not depending on track parameters and cuts
438 // contained as AliTPCcalibTracksCuts object fCuts.
439 // Tracks are discarded if the number of clusters is too low or the transverse
440 // momentum is too low.
441 // The corresponding cut values are specified in the fCuts member.
444 if (track->GetNumberOfClusters() < fCuts->GetMinClusters()) return kFALSE;
445 //if ((TMath::Abs(track->GetY() / track->GetX()) > fCuts->GetEdgeYXCutNoise())
446 // && (TMath::Abs(track->GetTgl()) < fCuts->GetEdgeThetaCutNoise())) return kFALSE;
447 //if (track->GetNumberOfClusters() / (track->GetNFoundable()+1.) < fCuts->GetMinRatio()) return kFALSE;
448 if (TMath::Abs(track->GetSigned1Pt()) > fCuts->GetMax1pt()) return kFALSE;
450 //if (track->GetPt() < 50.) return kFALSE;
454 void AliTPCcalibTracksGain::Process(AliTPCseed* seed) {
456 // Main method to be called when a new seed is supposed to be processed
457 // and be used for gain calibration. Its quality is checked before it
462 if (!AcceptTrack(seed)) return;
467 Long64_t AliTPCcalibTracksGain::Merge(TCollection *list) {
469 // Merge() merges the results of all AliTPCcalibTracksGain objects contained in
470 // list, thus allowing a distributed computation of several files, e.g. on PROOF.
471 // The merged results are merged with the data members of the AliTPCcalibTracksGain
472 // object used for calling the Merge method.
473 // The return value is 0 /*the total number of tracks used for calibration*/ if the merge
474 // is successful, otherwise it is -1.
477 if (!list || list->IsEmpty()) return -1;
479 if (!fSimpleFitter) fSimpleFitter = new AliTPCFitPad(8, "hyp7", "");
480 if (!fSqrtFitter) fSqrtFitter = new AliTPCFitPad(8, "hyp7", "");
481 if (!fLogFitter) fLogFitter = new AliTPCFitPad(8, "hyp7", "");
482 if (!fSingleSectorFitter) fSingleSectorFitter = new AliTPCFitPad(8, "hyp7", "");
485 // just for debugging
486 if (!fDebugCalPadRaw) fDebugCalPadRaw = new AliTPCCalPad("DebugCalPadRaw", "All clusters simply added up before correction");
487 if (!fDebugCalPadCorr) fDebugCalPadCorr = new AliTPCCalPad("DebugCalPadCorr", "All clusters simply added up after correction");
489 TIterator* iter = list->MakeIterator();
490 AliTPCcalibTracksGain* cal = 0;
492 while ((cal = (AliTPCcalibTracksGain*)iter->Next())) {
493 if (!cal->InheritsFrom(AliTPCcalibTracksGain::Class())) {
494 Error("Merge","Attempt to add object of class %s to a %s", cal->ClassName(), this->ClassName());
503 void AliTPCcalibTracksGain::Add(AliTPCcalibTracksGain* cal) {
505 // Adds another AliTPCcalibTracksGain object to this object.
508 fSimpleFitter->Add(cal->fSimpleFitter);
509 fSqrtFitter->Add(cal->fSqrtFitter);
510 fLogFitter->Add(cal->fLogFitter);
511 fSingleSectorFitter->Add(cal->fSingleSectorFitter);
515 fFitter0M->Add(cal->fFitter0M);
516 fFitter1M->Add(cal->fFitter1M);
517 fFitter2M->Add(cal->fFitter2M);
518 fFitter0T->Add(cal->fFitter0T);
519 fFitter1T->Add(cal->fFitter1T);
520 fFitter2T->Add(cal->fFitter2T);
525 for (Int_t i=0; i<73; i++){
527 his = (TH1F*)fArrayQM->At(i);
528 hism = (TH1F*)cal->fArrayQM->At(i);
529 if (his && hism) his->Add(hism);
530 his = (TH1F*)fArrayQT->At(i);
531 hism = (TH1F*)cal->fArrayQT->At(i);
532 if (his && hism) his->Add(hism);
536 for (Int_t i=0; i<37; i++){
538 his = (TProfile*)fProfileArrayQM->At(i);
539 hism = (TProfile*)cal->fProfileArrayQM->At(i);
540 if (his && hism) his->Add(hism);
541 his = (TProfile*)fProfileArrayQT->At(i);
542 hism = (TProfile*)cal->fProfileArrayQT->At(i);
543 if (his && hism) his->Add(hism);
547 for (Int_t i=0; i<37; i++){
548 TProfile2D *his,*hism;
549 his = (TProfile2D*)fProfileArrayQM2D->At(i);
550 hism = (TProfile2D*)cal->fProfileArrayQM2D->At(i);
551 if (his && hism) his->Add(hism);
552 his = (TProfile2D*)fProfileArrayQT2D->At(i);
553 hism = (TProfile2D*)cal->fProfileArrayQT2D->At(i);
554 if (his && hism) his->Add(hism);
557 // this will be gone for the a new ROOT version > v5-17-05
558 for (UInt_t iSegment = 0; iSegment < 36; iSegment++) {
559 fNShortClusters[iSegment] += cal->fNShortClusters[iSegment];
560 fNMediumClusters[iSegment] += cal->fNMediumClusters[iSegment];
561 fNLongClusters[iSegment] += cal->fNLongClusters[iSegment];
564 // just for debugging, remove me
565 fTotalTracks += cal->fTotalTracks;
566 fAcceptedTracks += cal->fAcceptedTracks;
567 fDebugCalPadRaw->Add(cal->fDebugCalPadRaw);
568 fDebugCalPadCorr->Add(cal->fDebugCalPadCorr);
572 void AliTPCcalibTracksGain::AddTrack(AliTPCseed* seed) {
574 // The clusters making up the track (seed) are added to various fit functions.
575 // See AddCluster(...) for more detail.
578 if (!fDebugStream) fDebugStream = new TTreeSRedirector(fgkDebugStreamFileName);
581 // simple histograming part
582 for (Int_t i=0; i<159; i++){
583 AliTPCclusterMI* cluster = seed->GetClusterPointer(i);
584 if (cluster) AddCluster(cluster);
588 void AliTPCcalibTracksGain::AddCluster(AliTPCclusterMI* cluster){
590 // Adding cluster information to the simple histograms
591 // No correction, fittings are applied
593 Float_t kThreshold=5;
594 if (cluster->GetX()<=0) return;
595 if (cluster->GetQ()<=kThreshold) return;
599 Int_t sector = cluster->GetDetector();
602 if (his) his->Fill(cluster->GetQ());
604 if (his) his->Fill(cluster->GetQ());
606 if (his) his->Fill(cluster->GetMax());
608 if (his) his->Fill(cluster->GetMax());
612 prof = GetProfileQT(sector);
613 if (prof) prof->Fill(cluster->GetX(),cluster->GetQ());
614 prof = GetProfileQT(-1);
615 if (prof) prof->Fill(cluster->GetX(),cluster->GetQ());
616 prof = GetProfileQM(sector);
617 if (prof) prof->Fill(cluster->GetX(),cluster->GetMax());
618 prof = GetProfileQM(-1);
619 if (prof) prof->Fill(cluster->GetX(),cluster->GetMax());
621 Float_t phi = cluster->GetY()/cluster->GetX();
623 prof2 = GetProfileQT2D(sector);
624 if (prof2) prof2->Fill(cluster->GetX(),phi,cluster->GetQ());
625 prof2 = GetProfileQT2D(-1);
626 if (prof2) prof2->Fill(cluster->GetX(),phi,cluster->GetQ());
627 prof2 = GetProfileQM2D(sector);
628 if (prof2) prof2->Fill(cluster->GetX(),phi,cluster->GetMax());
629 prof2 = GetProfileQM2D(-1);
630 if (prof2) prof2->Fill(cluster->GetX(),phi,cluster->GetMax());
637 void AliTPCcalibTracksGain::AddCluster(AliTPCclusterMI* cluster, Float_t /*momenta*/, Float_t/* mdedx*/, Int_t padType,
638 Float_t xcenter, TVectorD& dedxQ, TVectorD& /*dedxM*/, Float_t /*fraction*/, Float_t fraction2, Float_t dedge,
639 TVectorD& /*parY*/, TVectorD& /*parZ*/, TVectorD& meanPos) {
641 // Adds cluster to the appropriate fitter for later analysis.
642 // The charge used for the fit is the maximum charge for this specific cluster or the
643 // accumulated charge per cluster, depending on the value of fgkUseTotalCharge.
644 // Depending on the pad size where the cluster is registered, the value will be put in
645 // the appropriate fitter. Furthermore, for each pad size three different types of fitters
646 // are used. The fit functions are the same for all fitters (parabolic functions), but the value
647 // added to each fitter is different. The simple fitter gets the charge plugged in as is, the sqrt fitter
648 // gets the square root of the charge, and the log fitter gets fgkM*(1+q/fgkM), where q is the original charge
653 Error("AddCluster", "Cluster not valid.");
657 if (dedge < 3.) return;
658 if (fraction2 > 0.7) return;
660 //Int_t padType = GetPadType(cluster->GetX());
662 //Double_t centerPad[2] = {0};
663 //AliTPCFitPad::GetPadRegionCenterLocal(padType, centerPad);
664 //xx[0] = cluster->GetX() - centerPad[0];
665 //xx[1] = cluster->GetY() - centerPad[1];
666 xx[0] = cluster->GetX() - xcenter;
667 xx[1] = cluster->GetY();
668 xx[2] = xx[0] * xx[0];
669 xx[3] = xx[1] * xx[1];
670 xx[4] = xx[0] * xx[1];
671 xx[5] = TMath::Abs(cluster->GetZ()) - TMath::Abs(meanPos[4]);
672 xx[6] = xx[5] * xx[5];
674 // Update profile histograms
680 Int_t segment = cluster->GetDetector() % 36;
681 Double_t q = fgkUseTotalCharge ? ((Double_t)(cluster->GetQ())) : ((Double_t)(cluster->GetMax())); // note: no normalization to pad size!
683 // just for debugging
686 GetRowPad(cluster->GetX(), cluster->GetY(), row, pad);
687 fDebugCalPadRaw->GetCalROC(cluster->GetDetector())->SetValue(row, pad, q + fDebugCalPadRaw->GetCalROC(cluster->GetDetector())->GetValue(row, pad));
689 // correct charge by normalising to mean charge per track
692 // just for debugging
693 fDebugCalPadCorr->GetCalROC(cluster->GetDetector())->SetValue(row, pad, q + fDebugCalPadCorr->GetCalROC(cluster->GetDetector())->GetValue(row, pad));
695 Double_t sqrtQ = TMath::Sqrt(q);
696 Double_t logQ = fgkM * TMath::Log(1 + q / fgkM);
697 fSimpleFitter->GetFitter(segment, padType)->AddPoint(xx, q);
698 fSqrtFitter->GetFitter(segment, padType)->AddPoint(xx, sqrtQ);
699 fLogFitter->GetFitter(segment, padType)->AddPoint(xx, logQ);
700 fSingleSectorFitter->GetFitter(0, padType)->AddPoint(xx, q);
702 // this will be gone for the a new ROOT version > v5-17-05
703 if (padType == kShortPads)
704 fNShortClusters[segment]++;
705 if (padType == kMediumPads)
706 fNMediumClusters[segment]++;
707 if (padType == kLongPads)
708 fNLongClusters[segment]++;
711 void AliTPCcalibTracksGain::Evaluate(Bool_t robust, Double_t frac) {
713 // Evaluates all fitters contained in this object.
714 // If the robust option is set to kTRUE a robust fit is performed with frac as
715 // the minimal fraction of good points (see TLinearFitter::EvalRobust for details).
716 // Beware: Robust fitting is much slower!
719 fSimpleFitter->Evaluate(robust, frac);
720 fSqrtFitter->Evaluate(robust, frac);
721 fLogFitter->Evaluate(robust, frac);
722 fSingleSectorFitter->Evaluate(robust, frac);
731 AliTPCCalPad* AliTPCcalibTracksGain::CreateFitCalPad(UInt_t fitType, Bool_t undoTransformation, Bool_t normalizeToPadSize) {
733 // Creates the calibration object AliTPCcalPad using fitted parameterization
736 for (UInt_t iSector = 0; iSector < 72; iSector++)
737 tpc.Add(CreateFitCalROC(iSector, fitType, undoTransformation, normalizeToPadSize));
738 return new AliTPCCalPad(&tpc);
741 AliTPCCalROC* AliTPCcalibTracksGain::CreateFitCalROC(UInt_t sector, UInt_t fitType, Bool_t undoTransformation, Bool_t normalizeToPadSize) {
743 // Create the AliTPCCalROC with the values per pad
744 // sector - sector of interest
750 GetParameters(sector % 36, 0, fitType, par);
751 return CreateFitCalROC(sector, 0, par, fitType, undoTransformation, normalizeToPadSize);
754 GetParameters(sector % 36, 1, fitType, par);
755 AliTPCCalROC* roc1 = CreateFitCalROC(sector, 1, par, fitType, undoTransformation, normalizeToPadSize);
756 GetParameters(sector % 36, 2, fitType, par);
757 AliTPCCalROC* roc2 = CreateFitCalROC(sector, 2, par, fitType, undoTransformation, normalizeToPadSize);
758 AliTPCCalROC* roc3 = CreateCombinedCalROC(roc1, roc2);
765 AliTPCCalROC* AliTPCcalibTracksGain::CreateFitCalROC(UInt_t sector, UInt_t padType, TVectorD &fitParam, UInt_t fitType, Bool_t undoTransformation, Bool_t normalizeToPadSize) {
767 // This function is essentially a copy of AliTPCCalROC::CreateGlobalFitCalROC(...), with the
768 // modifications, that the center of the region of same pad size is used as the origin
769 // of the fit function instead of the center of the ROC.
770 // The possibility of a linear fit is removed as well because it is not needed.
771 // Only values for pads with the given pad size are calculated, the rest is 0.
772 // Set undoTransformation for undoing the transformation that was applied to the
773 // charge values before they were put into the fitter (thus allowing comparison to the original
774 // charge values). For fitType use 0 for the simple fitter, 1 for the sqrt fitter, 2 for the log fitter.
775 // If normalizeToPadSize is true, the values are normalized to the pad size.
776 // Please be aware, that you even need to specify the fitType if you want to normalize to the pad size without
777 // undoing the transformation (because normalizing involves undoing the trafo first, then normalizing, then
778 // applying the trafo again).
779 // Please note: The normalization to the pad size is a simple linear scaling with the pad length, which
780 // actually doesn't describe reality!
784 Double_t centerPad[2] = {0};
785 Float_t localXY[3] = {0};
786 AliTPCROC* tpcROC = AliTPCROC::Instance();
787 if ((padType == 0 && sector >= tpcROC->GetNInnerSector()) || (padType > 0 && sector < tpcROC->GetNInnerSector()) || sector >= tpcROC->GetNSector())
789 AliTPCCalROC* lROCfitted = new AliTPCCalROC(sector);
790 //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
796 endRow = lROCfitted->GetNrows();
804 endRow = lROCfitted->GetNrows();
808 AliTPCFitPad::GetPadRegionCenterLocal(padType, centerPad);
810 for (UInt_t irow = startRow; irow < endRow; irow++) {
811 for (UInt_t ipad = 0; ipad < lROCfitted->GetNPads(irow); ipad++) {
812 tpcROC->GetPositionLocal(sector, irow, ipad, localXY); // calculate position localXY by pad and row number
813 dlx = localXY[0] - centerPad[0];
814 dly = localXY[1] - centerPad[1];
815 value = fitParam[0] + fitParam[1]*dlx + fitParam[2]*dly + fitParam[3]*dlx*dlx + fitParam[4]*dly*dly + fitParam[5]*dlx*dly;
817 // Let q' = value be the transformed value without any pad size corrections,
818 // let T be the transformation and let l be the pad size
819 // 1) don't undo transformation, don't normalize: return q'
820 // 2) undo transformation, don't normalize: return T^{-1} q'
821 // 3) undo transformation, normalize: return (T^{-1} q') / l
822 // 4) don't undo transformation, normalize: return T((T^{-1} q') / l)
823 if (!undoTransformation && !normalizeToPadSize) {/* value remains unchanged */} // (1)
824 else { // (2), (3), (4)
827 case 0: /* value remains unchanged */ break;
828 case 1: value = value * value; break;
829 case 2: value = (TMath::Exp(value / fgkM) - 1) * fgkM; break;
830 default: Error("CreateFitCalROC", "Wrong fit type."); break;
832 if (normalizeToPadSize) value /= GetPadLength(localXY[0]); // (3)
834 if (!undoTransformation && normalizeToPadSize) { // (4)
837 case 0: /* value remains unchanged */ break;
838 case 1: value = TMath::Sqrt(value); break;
839 case 2: value = fgkM * TMath::Log(1 + value / fgkM); break;
840 default: Error("CreateFitCalROC", "Wrong fit type."); break;
843 lROCfitted->SetValue(irow, ipad, value);
849 AliTPCCalROC* AliTPCcalibTracksGain::CreateCombinedCalROC(const AliTPCCalROC* roc1, const AliTPCCalROC* roc2) {
851 // Combines the medium pad size values of roc1 with the long pad size values of roc2 into a new
852 // AliTPCCalROC. Returns a null pointer if any one of the ROCs is an IROC; issues a warning message
853 // if the sectors of roc1 and roc2 don't match, but still continue and use the sector of roc1 as the
854 // sector of the new ROC.
857 if (!roc1 || !roc2) return 0;
858 if ((Int_t)(roc1->GetSector()) < fgTPCparam->GetNInnerSector()) return 0;
859 if ((Int_t)(roc2->GetSector()) < fgTPCparam->GetNInnerSector()) return 0;
860 if (roc1->GetSector() != roc2->GetSector()) Warning("CreateCombinedCalROC", "Sector number mismatch.");
861 AliTPCCalROC* roc = new AliTPCCalROC(roc1->GetSector());
863 for (UInt_t iRow = 0; iRow < 64; iRow++) {
864 for (UInt_t iPad = 0; iPad < roc->GetNPads(iRow); iPad++)
865 roc->SetValue(iRow, iPad, roc1->GetValue(iRow, iPad));
867 for (UInt_t iRow = 64; iRow < roc->GetNrows(); iRow++) {
868 for (UInt_t iPad = 0; iPad < roc->GetNPads(iRow); iPad++)
869 roc->SetValue(iRow, iPad, roc2->GetValue(iRow, iPad));
874 void AliTPCcalibTracksGain::GetParameters(UInt_t segment, UInt_t padType, UInt_t fitType, TVectorD &fitParam) {
876 // Puts the fit parameters for the specified segment (IROC & OROC), padType and fitType
877 // into the fitParam TVectorD (which should contain 8 elements).
878 // padType is one of kShortPads, kMediumPads, kLongPads. fitType is one of kSimpleFitter, kSqrtFitter, kLogFitter.
879 // Note: The fitter has to be evaluated first!
882 GetFitter(segment, padType, fitType)->GetParameters(fitParam);
885 void AliTPCcalibTracksGain::GetErrors(UInt_t segment, UInt_t padType, UInt_t fitType, TVectorD &fitError) {
887 // Puts the fit parameter errors for the specified segment (IROC & OROC), padType and fitType
888 // into the fitError TVectorD (which should contain 8 elements).
889 // padType is one of kShortPads, kMediumPads, kLongPads. fitType is one of kSimpleFitter, kSqrtFitter, kLogFitter.
890 // Note: The fitter has to be evaluated first!
893 GetFitter(segment, padType, fitType)->GetErrors(fitError);
894 fitError *= TMath::Sqrt(GetRedChi2(segment, padType, fitType));
897 Double_t AliTPCcalibTracksGain::GetRedChi2(UInt_t segment, UInt_t padType, UInt_t fitType) {
899 // Returns the reduced chi^2 value for the specified segment, padType and fitType.
900 // padType is one of kShortPads, kMediumPads, kLongPads. fitType is one of kSimpleFitter, kSqrtFitter, kLogFitter.
901 // Note: The fitter has to be evaluated first!
904 // this will be gone for the a new ROOT version > v5-17-05
905 Int_t lNClusters = 0;
908 lNClusters = fNShortClusters[segment];
911 lNClusters = fNMediumClusters[segment];
914 lNClusters = fNLongClusters[segment];
917 return GetFitter(segment, padType, fitType)->GetChisquare()/(lNClusters - 8);
920 void AliTPCcalibTracksGain::GetCovarianceMatrix(UInt_t segment, UInt_t padType, UInt_t fitType, TMatrixD& covMatrix) {
922 // Returns the covariance matrix for the specified segment, padType, fitType.
923 // padType is one of kShortPads, kMediumPads, kLongPads. fitType is one of kSimpleFitter, kSqrtFitter, kLogFitter.
926 GetFitter(segment, padType, fitType)->GetCovarianceMatrix(covMatrix);
929 TLinearFitter* AliTPCcalibTracksGain::GetFitter(UInt_t segment, UInt_t padType, UInt_t fitType) {
931 // Returns the TLinearFitter object for the specified segment, padType, fitType.
932 // padType is one of kShortPads, kMediumPads, kLongPads. fitType is one of kSimpleFitter, kSqrtFitter, kLogFitter.
937 return fSimpleFitter->GetFitter(segment, padType);
939 return fSqrtFitter->GetFitter(segment, padType);
941 return fLogFitter->GetFitter(segment, padType);
943 return fSingleSectorFitter->GetFitter(0, padType);
948 Double_t AliTPCcalibTracksGain::GetPadLength(Double_t lx) {
950 // The function returns 0.75 for an IROC, 1. for an OROC at medium pad size position,
951 // 1.5 for an OROC at long pad size position, -1 if out of bounds.
954 Double_t irocLow = fgTPCparam->GetPadRowRadiiLow(0) - fgTPCparam->GetInnerPadPitchLength()/2;
955 Double_t irocUp = fgTPCparam->GetPadRowRadiiLow(fgTPCparam->GetNRowLow()-1) + fgTPCparam->GetInnerPadPitchLength()/2;
956 Double_t orocLow1 = fgTPCparam->GetPadRowRadiiUp(0) - fgTPCparam->GetOuter1PadPitchLength()/2;
957 Double_t orocUp1 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp1()-1) + fgTPCparam->GetOuter1PadPitchLength()/2;
958 Double_t orocLow2 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp1()) - fgTPCparam->GetOuter2PadPitchLength()/2;
959 Double_t orocUp2 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp()-1) + fgTPCparam->GetOuter2PadPitchLength()/2;
962 if (lx >= irocLow && lx <= irocUp) return 0.75;
963 // if OROC medium pads
964 if (lx >= orocLow1 && lx <= orocUp1) return 1.;
966 if (lx >= orocLow2 && lx <= orocUp2) return 1.5;
971 Int_t AliTPCcalibTracksGain::GetPadType(Double_t lx) {
973 // The function returns 0 for an IROC, 1 for an OROC at medium pad size position,
974 // 2 for an OROC at long pad size position, -1 if out of bounds.
977 if (GetPadLength(lx) == 0.75) return 0;
978 else if (GetPadLength(lx) == 1.) return 1;
979 else if (GetPadLength(lx) == 1.5) return 2;
983 // ONLY FOR DEBUGGING PURPOSES - REMOVE ME WHEN NOT NEEDED ANYMORE
984 Bool_t AliTPCcalibTracksGain::GetRowPad(Double_t lx, Double_t ly, Int_t& row, Int_t& pad) {
986 // Calculate the row and pad number when the local coordinates are given.
987 // Returns kFALSE if the position is out of range, otherwise return kTRUE.
988 // WARNING: This function is preliminary and probably isn't very accurate!!
991 Double_t irocLow = fgTPCparam->GetPadRowRadiiLow(0) - fgTPCparam->GetInnerPadPitchLength()/2;
992 //Double_t irocUp = fgTPCparam->GetPadRowRadiiLow(fgTPCparam->GetNRowLow()-1) + fgTPCparam->GetInnerPadPitchLength()/2;
993 Double_t orocLow1 = fgTPCparam->GetPadRowRadiiUp(0) - fgTPCparam->GetOuter1PadPitchLength()/2;
994 //Double_t orocUp1 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp1()-1) + fgTPCparam->GetOuter1PadPitchLength()/2;
995 Double_t orocLow2 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp1()) - fgTPCparam->GetOuter2PadPitchLength()/2;
996 //Double_t orocUp2 = fgTPCparam->GetPadRowRadiiUp(fgTPCparam->GetNRowUp()-1) + fgTPCparam->GetOuter2PadPitchLength()/2;
998 if (GetPadType(lx) == 0) {
999 row = (Int_t)((lx - irocLow) / fgTPCparam->GetInnerPadPitchLength());
1000 pad = (Int_t)((ly + fgTPCparam->GetYInner(row)) / fgTPCparam->GetInnerPadPitchWidth());
1001 } else if (GetPadType(lx) == 1) {
1002 row = (Int_t)((lx - orocLow1) / fgTPCparam->GetOuter1PadPitchLength());
1003 pad = (Int_t)((ly + fgTPCparam->GetYOuter(row)) / fgTPCparam->GetOuterPadPitchWidth());
1004 } else if (GetPadType(lx) == 2) {
1005 row = fgTPCparam->GetNRowUp1() + (Int_t)((lx - orocLow2) / fgTPCparam->GetOuter2PadPitchLength());
1006 pad = (Int_t)((ly + fgTPCparam->GetYOuter(row)) / fgTPCparam->GetOuterPadPitchWidth());
1012 void AliTPCcalibTracksGain::DumpTrack(AliTPCseed* track) {
1014 // Dump track information to the debug stream
1024 TVectorD meanPos[3];
1027 for (Int_t ipad = 0; ipad < 3; ipad++) {
1028 dedxM[ipad].ResizeTo(5);
1029 dedxQ[ipad].ResizeTo(5);
1030 parY[ipad].ResizeTo(3);
1031 parZ[ipad].ResizeTo(3);
1032 meanPos[ipad].ResizeTo(6);
1033 Bool_t isOK = GetDedx(track, ipad, rows, sector[ipad], npoints[ipad], dedxM[ipad], dedxQ[ipad], parY[ipad], parZ[ipad], meanPos[ipad]);
1035 AddTracklet(sector[ipad],ipad, dedxQ[ipad], dedxM[ipad], parY[ipad], parZ[ipad], meanPos[ipad] );
1039 (*fDebugStream) << "Track" <<
1040 "Track.=" << track << // track information
1046 (*fDebugStream) << "TrackG" <<
1047 "Track.=" << track << // track information
1049 // info for pad type 0
1050 "sector0="<<sector[0]<<
1051 "npoints0="<<npoints[0]<<
1052 "dedxM0.="<<&dedxM[0]<<
1053 "dedxQ0.="<<&dedxQ[0]<<
1054 "parY0.="<<&parY[0]<<
1055 "parZ0.="<<&parZ[0]<<
1056 "meanPos0.="<<&meanPos[0]<<
1058 // info for pad type 1
1059 "sector1="<<sector[1]<<
1060 "npoints1="<<npoints[1]<<
1061 "dedxM1.="<<&dedxM[1]<<
1062 "dedxQ1.="<<&dedxQ[1]<<
1063 "parY1.="<<&parY[1]<<
1064 "parZ1.="<<&parZ[1]<<
1065 "meanPos1.="<<&meanPos[1]<<
1067 // info for pad type 2
1068 "sector2="<<sector[2]<<
1069 "npoints2="<<npoints[2]<<
1070 "dedxM2.="<<&dedxM[2]<<
1071 "dedxQ2.="<<&dedxQ[2]<<
1072 "parY2.="<<&parY[2]<<
1073 "parZ2.="<<&parZ[2]<<
1074 "meanPos2.="<<&meanPos[2]<<
1081 Bool_t AliTPCcalibTracksGain::GetDedx(AliTPCseed* track, Int_t padType, Int_t* /*rows*/,
1082 Int_t §or, Int_t& npoints,
1083 TVectorD &dedxM, TVectorD &dedxQ,
1084 TVectorD &parY, TVectorD &parZ, TVectorD&meanPos)
1087 // GetDedx for given sector for given track
1088 // padType - type of pads
1091 static TLinearFitter fitY(2, "pol1");
1092 static TLinearFitter fitZ(2, "pol1");
1095 Int_t firstRow = 0, lastRow = 0;
1097 Float_t xcenter = 0;
1098 const Float_t ktany = TMath::Tan(TMath::DegToRad() * 10);
1099 const Float_t kedgey = 4.;
1102 lastRow = fgTPCparam->GetNRowLow();
1106 firstRow = fgTPCparam->GetNRowLow();
1107 lastRow = fgTPCparam->GetNRowLow() + fgTPCparam->GetNRowUp1();
1111 firstRow = fgTPCparam->GetNRowLow() + fgTPCparam->GetNRowUp1();
1112 lastRow = fgTPCparam->GetNRowLow() + fgTPCparam->GetNRowUp();
1115 minRow = (lastRow - firstRow) / 2;
1118 Int_t nclusters = 0;
1119 Int_t nclustersNE = 0; // number of not edge clusters
1120 Int_t lastSector = -1;
1121 Float_t amplitudeQ[100];
1122 Float_t amplitudeM[100];
1130 for (Int_t iCluster = firstRow; iCluster < lastRow; iCluster++) {
1131 AliTPCclusterMI* cluster = track->GetClusterPointer(iCluster);
1133 Int_t detector = cluster->GetDetector() ;
1134 if (lastSector == -1) lastSector = detector;
1135 if (lastSector != detector) continue;
1136 amplitudeQ[nclusters] = cluster->GetQ();
1137 amplitudeM[nclusters] = cluster->GetMax();
1138 rowIn[nclusters] = iCluster;
1140 Double_t dx = cluster->GetX() - xcenter;
1141 Double_t y = cluster->GetY();
1142 Double_t z = cluster->GetZ();
1143 fitY.AddPoint(&dx, y);
1144 fitZ.AddPoint(&dx, z);
1151 if (TMath::Abs(cluster->GetY()) < cluster->GetX()*ktany - kedgey) nclustersNE++;
1155 if (nclusters < minRow / 2) return kFALSE;
1156 if (nclustersNE < minRow / 2) return kFALSE;
1157 for (Int_t i = 0; i < 6; i++) meanPos[i] /= Double_t(nclusters);
1160 fitY.GetParameters(parY);
1161 fitZ.GetParameters(parZ);
1163 // calculate truncated mean
1165 TMath::Sort(nclusters, amplitudeQ, index, kFALSE);
1170 for (Int_t i = 0; i < 5; i++) {
1179 for (Int_t i = 0; i < nclusters; i++) {
1180 Int_t rowSorted = rowIn[index[i]];
1181 AliTPCclusterMI* cluster = track->GetClusterPointer(rowSorted);
1183 if (TMath::Abs(cluster->GetY()) > cluster->GetX()*ktany - kedgey) continue; //don't take edge clusters
1185 if (inonEdge < nclustersNE * 0.5) {
1187 dedxQ[0] += amplitudeQ[index[i]];
1188 dedxM[0] += amplitudeM[index[i]];
1190 if (inonEdge < nclustersNE * 0.6) {
1192 dedxQ[1] += amplitudeQ[index[i]];
1193 dedxM[1] += amplitudeM[index[i]];
1195 if (inonEdge < nclustersNE * 0.7) {
1197 dedxQ[2] += amplitudeQ[index[i]];
1198 dedxM[2] += amplitudeM[index[i]];
1200 if (inonEdge < nclustersNE * 0.8) {
1202 dedxQ[3] += amplitudeQ[index[i]];
1203 dedxM[3] += amplitudeM[index[i]];
1205 if (inonEdge < nclustersNE * 0.9) {
1207 dedxQ[4] += amplitudeQ[index[i]];
1208 dedxM[4] += amplitudeM[index[i]];
1211 for (Int_t i = 0; i < 5; i++) {
1212 dedxQ[i] /= ndedx[i];
1213 dedxM[i] /= ndedx[i];
1217 Float_t momenta = track->GetP();
1218 Float_t mdedx = track->GetdEdx();
1219 for (Int_t i = 0; i < nclusters; i++) {
1220 Int_t rowSorted = rowIn[index[i]];
1221 AliTPCclusterMI* cluster = track->GetClusterPointer(rowSorted);
1223 printf("Problem\n");
1226 if (TMath::Abs(cluster->GetY()) < cluster->GetX()*ktany - kedgey) inonEdge++;
1227 Float_t dedge = cluster->GetX()*ktany - TMath::Abs(cluster->GetY());
1228 Float_t fraction = Float_t(i) / Float_t(nclusters);
1229 Float_t fraction2 = Float_t(inonEdge) / Float_t(nclustersNE);
1231 AddCluster(cluster, momenta, mdedx, padType, xcenter, dedxQ, dedxM, fraction, fraction2, dedge, parY, parZ, meanPos);
1233 (*fDebugStream) << "dEdx" <<
1234 "Cl.=" << cluster << // cluster of interest
1235 "P=" << momenta << // track momenta
1236 "dedx=" << mdedx << // mean dedx - corrected for angle
1237 "IPad=" << padType << // pad type 0..2
1238 "xc=" << xcenter << // x center of chamber
1239 "dedxQ.=" << &dedxQ << // dedxQ - total charge
1240 "dedxM.=" << &dedxM << // dedxM - maximal charge
1241 "fraction=" << fraction << // fraction - order in statistic (0,1)
1242 "fraction2=" << fraction2 << // fraction - order in statistic (0,1)
1243 "dedge=" << dedge << // distance to the edge
1244 "parY.=" << &parY << // line fit
1245 "parZ.=" << &parZ << // line fit
1246 "meanPos.=" << &meanPos << // mean position (dx, dx^2, y,y^2, z, z^2)
1250 (*fDebugStream) << "dEdxT" <<
1251 "P=" << momenta << // track momenta
1252 "npoints="<<inonEdge<< // number of points
1253 "sector="<<lastSector<< // sector number
1254 "dedx=" << mdedx << // mean dedx - corrected for angle
1255 "IPad=" << padType << // pad type 0..2
1256 "xc=" << xcenter << // x center of chamber
1257 "dedxQ.=" << &dedxQ << // dedxQ - total charge
1258 "dedxM.=" << &dedxM << // dedxM - maximal charge
1259 "parY.=" << &parY << // line fit
1260 "parZ.=" << &parZ << // line fit
1261 "meanPos.=" << &meanPos << // mean position (dx, dx^2, y,y^2, z, z^2)
1264 sector = lastSector;
1269 void AliTPCcalibTracksGain::AddTracklet(UInt_t sector, UInt_t padType,TVectorD &dedxQ, TVectorD &dedxM,TVectorD& parY, TVectorD& parZ, TVectorD& meanPos){
1271 // Add measured point - dedx to the fitter
1274 //chain->SetAlias("dr","(250-abs(meanPos.fElements[4]))/250");
1275 //chain->SetAlias("tz","(0+abs(parZ.fElements[1]))");
1276 //chain->SetAlias("ty","(0+abs(parY.fElements[1]))");
1277 //chain->SetAlias("corrg","sqrt((1+ty^2)*(1+tz^2))");
1278 //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);
1282 // z and angular part
1285 xxx[0] = (250.-TMath::Abs(meanPos[4]))/250.;
1286 xxx[1] = TMath::Abs(parY[1]);
1287 xxx[2] = TMath::Abs(parZ[1]);
1288 xxx[3] = xxx[0]*xxx[1];
1289 xxx[4] = xxx[0]*xxx[2];
1290 xxx[5] = xxx[1]*xxx[2];
1291 xxx[6] = xxx[0]*xxx[0];
1292 xxx[7] = xxx[1]*xxx[1];
1293 xxx[8] = xxx[2]*xxx[2];
1297 Int_t tsector = sector%36;
1298 for (Int_t i=0;i<35;i++){
1299 xxx[9+i]=(i==tsector)?1:0;
1301 TLinearFitter *fitterM = fFitter0M;
1302 if (padType==1) fitterM=fFitter1M;
1303 if (padType==2) fitterM=fFitter2M;
1304 fitterM->AddPoint(xxx,dedxM[1]);
1306 TLinearFitter *fitterT = fFitter0T;
1307 if (padType==1) fitterT = fFitter1T;
1308 if (padType==2) fitterT = fFitter2T;
1309 fitterT->AddPoint(xxx,dedxQ[1]);
1313 TGraph *AliTPCcalibTracksGain::CreateAmpGraph(Int_t ipad, Bool_t qmax){
1315 // create the amplitude graph
1316 // The normalized amplitudes are extrapolated to the 0 angle (y,z) and 0 drift length
1321 if (ipad==0) fFitter0M->GetParameters(vec);
1322 if (ipad==1) fFitter1M->GetParameters(vec);
1323 if (ipad==2) fFitter2M->GetParameters(vec);
1325 if (ipad==0) fFitter0T->GetParameters(vec);
1326 if (ipad==1) fFitter1T->GetParameters(vec);
1327 if (ipad==2) fFitter2T->GetParameters(vec);
1332 for (Int_t i=0;i<35;i++){
1334 amp[i]=vec[10+i]+vec[0];
1337 Float_t mean = TMath::Mean(36,amp);
1338 for (Int_t i=0;i<36;i++){
1340 amp[i]=(amp[i]-mean)/mean;
1342 TGraph *gr = new TGraph(36,sec,amp);
1347 void AliTPCcalibTracksGain::UpdateClusterParam(AliTPCClusterParam* clparam){
1349 // SetQ normalization parameters
1351 // void SetQnorm(Int_t ipad, Int_t itype, TVectorD * norm);
1355 fFitter0T->GetParameters(vec);
1356 clparam->SetQnorm(0,0,&vec);
1357 fFitter1T->GetParameters(vec);
1358 clparam->SetQnorm(1,0,&vec);
1359 fFitter2T->GetParameters(vec);
1360 clparam->SetQnorm(2,0,&vec);
1362 fFitter0M->GetParameters(vec);
1363 clparam->SetQnorm(0,1,&vec);
1364 fFitter1M->GetParameters(vec);
1365 clparam->SetQnorm(1,1,&vec);
1366 fFitter2M->GetParameters(vec);
1367 clparam->SetQnorm(2,1,&vec);