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 **************************************************************************/
17 ///////////////////////////////////////////////////////////////////////////////
19 // Class to analyse tracks for calibration //
20 // to be used as a component in AliTPCSelectorTracks //
21 // In the constructor you have to specify name and title //
22 // to get the Object out of a file. //
23 // The parameter 'clusterParam', a AliTPCClusterParam object //
24 // (needed for TPC cluster error and shape parameterization) //
25 // Normally you get this object out of the file 'TPCClusterParam.root' //
26 // In the parameter 'cuts' the cuts are specified, that decide //
27 // weather a track will be accepted for calibration or not. //
33 Raw Data -> Local Reconstruction -> Tracking -> Calibration -> RefData (component itself)
34 Offline/HLT Offline/HLT OCDB entries (AliTPCClusterParam)
38 ///////////////////////////////////////////////////////////////////////////////
52 //#include <TPDGCode.h>
54 #include "TLinearFitter.h"
55 //#include "TMatrixD.h"
56 #include "TTreeStream.h"
59 #include <TGraph2DErrors.h>
60 #include "TPostScript.h"
66 #include <TCollection.h>
68 #include <TLinearFitter.h>
74 #include "AliTracker.h"
76 #include "AliESDtrack.h"
77 #include "AliESDfriend.h"
78 #include "AliESDfriendTrack.h"
79 #include "AliTPCseed.h"
80 #include "AliTPCclusterMI.h"
81 #include "AliTPCROC.h"
83 #include "AliTPCParamSR.h"
84 #include "AliTrackPointArray.h"
85 #include "AliTPCcalibTracks.h"
86 #include "AliTPCClusterParam.h"
87 #include "AliTPCcalibTracksCuts.h"
88 #include "AliTPCCalPadRegion.h"
89 #include "AliTPCCalPad.h"
90 #include "AliTPCCalROC.h"
92 #include "TPaveText.h"
96 //#include "TThread.h"
98 //#include "TLockFile.h"
101 ClassImp(AliTPCcalibTracks)
104 AliTPCcalibTracks::AliTPCcalibTracks():
115 fArrayChargeVsDriftlength(0),
116 fcalPadRegionChargeVsDriftlength(0),
125 fRejectedTracksHisto(0),
126 fHclusterPerPadrow(0),
127 fHclusterPerPadrowRaw(0),
129 fCalPadClusterPerPad(0),
130 fCalPadClusterPerPadRaw(0),
140 // AliTPCcalibTracks default constructor
142 if (fDebugLevel > 0) cout << "AliTPCcalibTracks' default constructor called" << endl;
147 AliTPCcalibTracks::AliTPCcalibTracks(const AliTPCcalibTracks& calibTracks):
158 fArrayChargeVsDriftlength(0),
159 fcalPadRegionChargeVsDriftlength(0),
168 fRejectedTracksHisto(0),
169 fHclusterPerPadrow(0),
170 fHclusterPerPadrowRaw(0),
172 fCalPadClusterPerPad(0),
173 fCalPadClusterPerPadRaw(0),
183 // AliTPCcalibTracks copy constructor
185 if (fDebugLevel > 0) cout << " ***** this is AliTPCcalibTracks' copy constructor ***** " << endl;
187 Bool_t dirStatus = TH1::AddDirectoryStatus();
188 TH1::AddDirectory(kFALSE);
191 // backward compatibility: if the data member doesn't yet exist, it will not be merged
192 (calibTracks.fArrayAmpRow) ? length = calibTracks.fArrayAmpRow->GetEntriesFast() : length = -1;
193 fArrayAmpRow = new TObjArray(length);
194 fArrayAmp = new TObjArray(length);
195 for (Int_t i = 0; i < length; i++) {
196 fArrayAmpRow->AddAt( (TProfile*)calibTracks.fArrayAmpRow->At(i)->Clone(), i);
197 fArrayAmp->AddAt( ((TProfile*)calibTracks.fArrayAmp->At(i)->Clone()), i);
200 (calibTracks.fArrayQDY) ? length = calibTracks.fArrayQDY->GetEntriesFast() : length = -1;
201 fArrayQDY= new TObjArray(length);
202 fArrayQDZ= new TObjArray(length);
203 fArrayQRMSY= new TObjArray(length);
204 fArrayQRMSZ= new TObjArray(length);
205 for (Int_t i = 0; i < length; i++) {
206 fArrayQDY->AddAt( ((TH1F*)calibTracks.fArrayQDY->At(i)->Clone()), i);
207 fArrayQDZ->AddAt( ((TH1F*)calibTracks.fArrayQDZ->At(i)->Clone()), i);
208 fArrayQRMSY->AddAt( ((TH1F*)calibTracks.fArrayQRMSY->At(i)->Clone()), i);
209 fArrayQRMSZ->AddAt( ((TH1F*)calibTracks.fArrayQRMSZ->At(i)->Clone()), i);
212 (calibTracks.fResolY) ? length = calibTracks.fResolY->GetEntriesFast() : length = -1;
213 fResolY = new TObjArray(length);
214 fResolZ = new TObjArray(length);
215 fRMSY = new TObjArray(length);
216 fRMSZ = new TObjArray(length);
217 for (Int_t i = 0; i < length; i++) {
218 fResolY->AddAt( ((TH1F*)calibTracks.fResolY->At(i)->Clone()), i);
219 fResolZ->AddAt( ((TH1F*)calibTracks.fResolZ->At(i)->Clone()), i);
220 fRMSY->AddAt( ((TH1F*)calibTracks.fRMSY->At(i)->Clone()), i);
221 fRMSZ->AddAt( ((TH1F*)calibTracks.fRMSZ->At(i)->Clone()), i);
224 (calibTracks.fArrayChargeVsDriftlength) ? length = calibTracks.fArrayChargeVsDriftlength->GetEntriesFast() : length = -1;
225 (calibTracks.fArrayChargeVsDriftlength) ? fArrayChargeVsDriftlength = new TObjArray(length) : fArrayChargeVsDriftlength = 0;
226 for (Int_t i = 0; i < length; i++) {
227 fArrayChargeVsDriftlength->AddAt( ((TProfile*)calibTracks.fArrayChargeVsDriftlength->At(i)->Clone()), i);
230 fDeltaY = (TH1F*)calibTracks.fDeltaY->Clone();
231 fDeltaZ = (TH1F*)calibTracks.fDeltaZ->Clone();
232 fHclus = (TH1I*)calibTracks.fHclus->Clone();
233 fClusterCutHisto = (TH2I*)calibTracks.fClusterCutHisto->Clone();
234 fRejectedTracksHisto = (TH1I*)calibTracks.fRejectedTracksHisto->Clone();
235 fHclusterPerPadrow = (TH1I*)calibTracks.fHclusterPerPadrow->Clone();
236 fHclusterPerPadrowRaw = (TH1I*)calibTracks.fHclusterPerPadrowRaw->Clone();
237 fcalPadRegionChargeVsDriftlength = (AliTPCCalPadRegion*)calibTracks.fcalPadRegionChargeVsDriftlength->Clone();
238 fCalPadClusterPerPad = (AliTPCCalPad*)calibTracks.fCalPadClusterPerPad->Clone();
239 fCalPadClusterPerPadRaw = (AliTPCCalPad*)calibTracks.fCalPadClusterPerPadRaw->Clone();
241 fCuts = new AliTPCcalibTracksCuts(calibTracks.fCuts->GetMinClusters(), calibTracks.fCuts->GetMinRatio(),
242 calibTracks.fCuts->GetMax1pt(), calibTracks.fCuts->GetEdgeYXCutNoise(), calibTracks.fCuts->GetEdgeThetaCutNoise());
243 fDebugLevel = calibTracks.GetLogLevel();
244 SetNameTitle(calibTracks.GetName(), calibTracks.GetTitle());
245 TH1::AddDirectory(dirStatus); // set status back to original status
246 // cout << "+++++ end of copy constructor +++++" << endl; // TO BE REMOVED
250 AliTPCcalibTracks & AliTPCcalibTracks::operator=(const AliTPCcalibTracks& calibTracks){
252 // assgnment operator
254 if (this != &calibTracks) {
255 new (this) AliTPCcalibTracks(calibTracks);
262 AliTPCcalibTracks::AliTPCcalibTracks(const Text_t *name, const Text_t *title, AliTPCClusterParam *clusterParam, AliTPCcalibTracksCuts* cuts, Int_t logLevel) :
273 fArrayChargeVsDriftlength(0),
274 fcalPadRegionChargeVsDriftlength(0),
283 fRejectedTracksHisto(0),
284 fHclusterPerPadrow(0),
285 fHclusterPerPadrowRaw(0),
287 fCalPadClusterPerPad(0),
288 fCalPadClusterPerPadRaw(0),
298 // AliTPCcalibTracks constructor
299 // specify 'name' and 'title' of your object
300 // specify 'clusterParam', (needed for TPC cluster error and shape parameterization)
301 // In the parameter 'cuts' the cuts are specified, that decide
302 // weather a track will be accepted for calibration or not.
303 // log level - debug output: -1: silence, 0: default, 1: things like constructor called, 5: write fDebugStream, 6: waste your screen
305 // All histograms are instatiated in this constructor.
307 if (fDebugLevel > 0) cout << " ***** this is AliTPCcalibTracks' main constructor ***** " << endl;
308 G__SetCatchException(0);
310 fClusterParam = clusterParam;
312 fClusterParam->SetInstance(fClusterParam);
315 Error("AliTPCcalibTracks","No cluster parametrization found! A valid clusterParam object is needed in the constructor. (To be found in 'TPCClusterParam.root'.)");
318 fDebugLevel = logLevel;
319 if (fDebugLevel > 4) fDebugStream = new TTreeSRedirector("TPCSelectorDebug.root"); // needs investigation !!!!!
321 TH1::AddDirectory(kFALSE);
326 fHclus = new TH1I("hclus","Number of clusters per track",160, 0, 160); // valgrind 3
327 fRejectedTracksHisto = new TH1I("RejectedTracksHisto", "Rejected tracks, sorted by failed cut", 10, 1, 10);
328 fHclusterPerPadrow = new TH1I("fHclusterPerPadrow", " clusters per padRow, used for the resolution tree", 160, 0, 160);
329 fHclusterPerPadrowRaw = new TH1I("fHclusterPerPadrowRaw", " clusters per padRow, before cutting clusters", 160, 0, 160);
330 fCalPadClusterPerPad = new AliTPCCalPad("fCalPadClusterPerPad", "clusters per pad");
331 fCalPadClusterPerPadRaw = new AliTPCCalPad("fCalPadClusterPerPadRaw", "clusters per pad, before cutting clusters");
332 fClusterCutHisto = new TH2I("fClusterCutHisto", "Cutted cluster over padRow; Cut Criterium; PadRow", 5,1,5, 160,0,159);
334 // Amplitude - sector - row histograms
335 fArrayAmpRow = new TObjArray(72);
336 fArrayAmp = new TObjArray(72);
337 fArrayChargeVsDriftlength = new TObjArray(72);
339 for (Int_t i = 0; i < 36; i++){
340 sprintf(chname,"Amp_row_Sector%d",i);
341 prof1 = new TProfile(chname,chname,63,0,64); // valgrind 3 193,536 bytes in 354 blocks are still reachable
342 prof1->SetXTitle("Pad row");
343 prof1->SetYTitle("Mean Max amplitude");
344 fArrayAmpRow->AddAt(prof1,i);
345 sprintf(chname,"Amp_row_Sector%d",i+36);
346 prof1 = new TProfile(chname,chname,96,0,97); // valgrind 3 3,912 bytes in 6 blocks are possibly lost
347 prof1->SetXTitle("Pad row");
348 prof1->SetYTitle("Mean Max amplitude");
349 fArrayAmpRow->AddAt(prof1,i+36);
352 sprintf(chname,"Amp_Sector%d",i);
353 his1 = new TH1F(chname,chname,250,0,500); // valgrind
354 his1->SetXTitle("Max Amplitude (ADC)");
355 fArrayAmp->AddAt(his1,i);
356 sprintf(chname,"Amp_Sector%d",i+36);
357 his1 = new TH1F(chname,chname,200,0,600); // valgrind 3 13,408,208 bytes in 229 blocks are still reachable
358 his1->SetXTitle("Max Amplitude (ADC)");
359 fArrayAmp->AddAt(his1,i+36);
362 sprintf(chname, "driftlengt vs. charge, ROC %i", i);
363 prof1 = new TProfile(chname, chname, 500, 0, 250);
364 prof1->SetYTitle("Charge");
365 prof1->SetXTitle("Driftlength");
366 fArrayChargeVsDriftlength->AddAt(prof1,i);
367 sprintf(chname, "driftlengt vs. charge, ROC %i", i+36);
368 prof1 = new TProfile(chname, chname, 500, 0, 250);
369 prof1->SetYTitle("Charge");
370 prof1->SetXTitle("Driftlength");
371 fArrayChargeVsDriftlength->AddAt(prof1,i+36);
374 TH1::AddDirectory(kFALSE);
376 fDeltaY = new TH1F("DeltaY","DeltaY",100,-1,1);
377 fDeltaZ = new TH1F("DeltaZ","DeltaZ",100,-1,1);
379 fResolY = new TObjArray(3);
380 fResolZ = new TObjArray(3);
381 fRMSY = new TObjArray(3);
382 fRMSZ = new TObjArray(3);
385 his3D = new TH3F("Resol Y0","Resol Y0", 5,20,250, 4, 0,1., 50, -1,1);
386 fResolY->AddAt(his3D,0);
387 his3D = new TH3F("Resol Y1","Resol Y1", 5,20,250, 4, 0,1., 50, -1,1);
388 fResolY->AddAt(his3D,1);
389 his3D = new TH3F("Resol Y2","Resol Y2", 5,20,250, 4, 0,0.8, 50, -1,1);
390 fResolY->AddAt(his3D,2);
392 his3D = new TH3F("Resol Z0","Resol Z0", 5,20,250, 4, 0,1, 50, -1,1);
393 fResolZ->AddAt(his3D,0);
394 his3D = new TH3F("Resol Z1","Resol Z1", 5,20,250, 4, 0,1, 50, -1,1);
395 fResolZ->AddAt(his3D,1);
396 his3D = new TH3F("Resol Z2","Resol Z2", 5,20,250, 4, 0,1, 50, -1,1);
397 fResolZ->AddAt(his3D,2);
399 his3D = new TH3F("RMS Y0","RMS Y0", 5,20,250, 4, 0,1., 50, 0,0.8);
400 fRMSY->AddAt(his3D,0);
401 his3D = new TH3F("RMS Y1","RMS Y1", 5,20,250, 4, 0,1., 50, 0,0.8);
402 fRMSY->AddAt(his3D,1);
403 his3D = new TH3F("RMS Y2","RMS Y2", 5,20,250, 4, 0,0.8, 50, 0,0.8);
404 fRMSY->AddAt(his3D,2);
406 his3D = new TH3F("RMS Z0","RMS Z0", 5,20,250, 4, 0,1, 50, 0,0.8);
407 fRMSZ->AddAt(his3D,0);
408 his3D = new TH3F("RMS Z1","RMS Z1", 5,20,250, 4, 0,1, 50, 0,0.8);
409 fRMSZ->AddAt(his3D,1);
410 his3D = new TH3F("RMS Z2","RMS Z2", 5,20,250, 4, 0,1, 50, 0,0.8);
411 fRMSZ->AddAt(his3D,2);
414 TH1::AddDirectory(kFALSE);
416 fArrayQDY = new TObjArray(300);
417 fArrayQDZ = new TObjArray(300);
418 fArrayQRMSY = new TObjArray(300);
419 fArrayQRMSZ = new TObjArray(300);
420 for (Int_t iq = 0; iq <= 10; iq++){
421 for (Int_t ipad = 0; ipad < 3; ipad++){
422 Int_t bin = GetBin(iq, ipad);
423 Float_t qmean = GetQ(bin);
425 sprintf(name,"ResolY Pad%d Qmiddle%f",ipad, qmean);
426 his3D = new TH3F(name, name, 20,10,250, 20, 0,1.5, 50, -1,1);
427 fArrayQDY->AddAt(his3D, bin);
428 sprintf(name,"ResolZ Pad%d Qmiddle%f",ipad, qmean);
429 his3D = new TH3F(name, name, 20,10,250, 20, 0,1.5, 50, -1,1);
430 fArrayQDZ->AddAt(his3D, bin);
431 sprintf(name,"RMSY Pad%d Qmiddle%f",ipad, qmean);
432 his3D = new TH3F(name, name, 20,10,250, 20, 0,1.5, 50, 0,1);
433 fArrayQRMSY->AddAt(his3D, bin);
434 sprintf(name,"RMSZ Pad%d Qmiddle%f",ipad, qmean);
435 his3D = new TH3F(name, name, 20,10,250, 20, 0,1.5, 50, 0,1);
436 fArrayQRMSZ->AddAt(his3D, bin);
440 fcalPadRegionChargeVsDriftlength = new AliTPCCalPadRegion("fcalPadRegionChargeVsDriftlength", "TProfiles with charge vs driftlength for each pad region");
442 for (UInt_t padSize = 0; padSize < 3; padSize++) {
443 for (UInt_t isector = 0; isector < 36; isector++) {
444 if (padSize == 0) sprintf(chname, "driftlengt vs. charge, sector %i, short pads", isector);
445 if (padSize == 1) sprintf(chname, "driftlengt vs. charge, sector %i, medium pads", isector);
446 if (padSize == 2) sprintf(chname, "driftlengt vs. charge, sector %i, long pads", isector);
447 tempProf = new TProfile(chname, chname, 500, 0, 250);
448 tempProf->SetYTitle("Charge");
449 tempProf->SetXTitle("Driftlength");
450 fcalPadRegionChargeVsDriftlength->SetObject(tempProf, isector, padSize);
454 fFitterLinY1 = new TLinearFitter (2,"pol1");
455 fFitterLinZ1 = new TLinearFitter (2,"pol1");
456 fFitterLinY2 = new TLinearFitter (2,"pol1");
457 fFitterLinZ2 = new TLinearFitter (2,"pol1");
458 fFitterParY = new TLinearFitter (3,"pol2");
459 fFitterParZ = new TLinearFitter (3,"pol2");
461 if (fDebugLevel > 1) cout << "AliTPCcalibTracks object sucessfully constructed: " << GetName() << endl;
462 cout << "end of main constructor" << endl; // TO BE REMOVED
466 AliTPCcalibTracks::~AliTPCcalibTracks() {
468 // AliTPCcalibTracks destructor
471 if (fDebugLevel > 0) cout << "AliTPCcalibTracks' destuctor called." << endl;
473 if (fArrayAmpRow) length = fArrayAmpRow->GetEntriesFast();
474 for (Int_t i = 0; i < length; i++){
475 delete fArrayAmpRow->At(i);
476 delete fArrayAmp->At(i);
484 if (fResolY) length = fResolY->GetEntriesFast();
485 for (Int_t i = 0; i < length; i++){
486 delete fResolY->At(i);
487 delete fResolZ->At(i);
496 if (fArrayQDY) length = fArrayQDY->GetEntriesFast();
497 for (Int_t i = 0; i < length; i++){
498 delete fArrayQDY->At(i);
499 delete fArrayQDZ->At(i);
500 delete fArrayQRMSY->At(i);
501 delete fArrayQRMSZ->At(i);
504 if (fArrayChargeVsDriftlength) length = fArrayChargeVsDriftlength->GetEntriesFast();
505 for (Int_t i = 0; i < length; i++){
506 delete fArrayChargeVsDriftlength->At(i);
520 delete fArrayChargeVsDriftlength;
523 delete fRejectedTracksHisto;
524 delete fClusterCutHisto;
525 delete fHclusterPerPadrow;
526 delete fHclusterPerPadrowRaw;
527 if (fCalPadClusterPerPad) delete fCalPadClusterPerPad;
528 if (fCalPadClusterPerPadRaw) delete fCalPadClusterPerPadRaw;
529 fcalPadRegionChargeVsDriftlength->Delete();
530 delete fcalPadRegionChargeVsDriftlength;
531 if (fDebugLevel > 4) delete fDebugStream;
535 void AliTPCcalibTracks::AddInfo(TChain * chain, char* fileName){
537 // Add the neccessary information for processing to the chain
538 // (cluster parametrization)
540 TFile clusterParamFile(fileName);
541 AliTPCClusterParam *clusterParam = (AliTPCClusterParam *) clusterParamFile.Get("Param");
542 chain->GetUserInfo()->AddLast((TObject*)clusterParam);
543 cout << "Clusterparametrization added to the chain." << endl;
547 void AliTPCcalibTracks::Process(AliTPCseed *track, AliESDtrack */*esd*/){
549 // To be called in the selector
550 // first AcceptTrack is evaluated, then calls all the following analyse functions:
551 // FillResolutionHistoLocal(track)
552 // AlignUpDown(track, esd)
554 if (fDebugLevel > 5) Info("Process","Starting to process the track...");
555 Int_t accpetStatus = AcceptTrack(track);
556 if (accpetStatus == 0) {
557 FillResolutionHistoLocal(track);
558 // AlignUpDown(track, esd);
560 else fRejectedTracksHisto->Fill(accpetStatus);
565 Int_t AliTPCcalibTracks::GetBin(Float_t q, Int_t pad){
567 // calculate bins for given q and pad type
570 Int_t res = TMath::Max( TMath::Nint((TMath::Sqrt(q) - 3.)), 0 );
577 Int_t AliTPCcalibTracks::GetBin(Int_t iq, Int_t pad){
579 // calculate bins for given iq and pad type
582 return iq * 3 + pad;;
586 Float_t AliTPCcalibTracks::GetQ(Int_t bin){
588 // returns to bin belonging charge
591 Int_t bin0 = bin / 3;
597 Float_t AliTPCcalibTracks::GetPad(Int_t bin){
599 // returns to bin belonging pad
607 Int_t AliTPCcalibTracks::AcceptTrack(AliTPCseed * track){
609 // Function, that decides wheather a given track is accepted for
610 // the analysis or not.
611 // The cuts are specified in the AliTPCcalibTracksCuts object 'fCuts'
612 // Returns 0 if a track is accepted or an integer different from 0
613 // to indicate the failed cut
615 const Int_t kMinClusters = fCuts->GetMinClusters();
616 const Float_t kMinRatio = fCuts->GetMinRatio();
617 const Float_t kMax1pt = fCuts->GetMax1pt();
618 const Float_t kEdgeYXCutNoise = fCuts->GetEdgeYXCutNoise();
619 const Float_t kEdgeThetaCutNoise = fCuts->GetEdgeThetaCutNoise();
622 // edge induced noise tracks - NEXT RELEASE will be removed during tracking
623 if ( TMath::Abs(track->GetY() / track->GetX()) > kEdgeYXCutNoise )
624 if ( TMath::Abs(track->GetTgl()) < kEdgeThetaCutNoise ) return 1;
625 if (track->GetNumberOfClusters() < kMinClusters) return 2;
626 Float_t ratio = track->GetNumberOfClusters() / (track->GetNFoundable() + 1.);
627 if (ratio < kMinRatio) return 3;
628 // Float_t mpt = track->Get1Pt(); // Get1Pt() doesn't exist any more
629 Float_t mpt = track->GetSigned1Pt();
630 if (TMath::Abs(mpt) > kMax1pt) return 4;
631 //if (TMath::Abs(track->GetZ())>240.) return kFALSE;
632 //if (TMath::Abs(track->GetZ())<10.) return kFALSE;
633 //if (TMath::Abs(track->GetTgl())>0.03) return kFALSE;
635 if (fDebugLevel > 5) Info("AcceptTrack","Track has been accepted.");
640 void AliTPCcalibTracks::FillResolutionHistoLocal(AliTPCseed * track){
642 // fill resolution histograms - localy - tracklet in the neighborhood
643 // write debug information to 'TPCSelectorDebug.root'
645 // _ the main function, called during track analysis _
647 // loop over all padrows along the track
648 // fit tracklets (length: 13 clusters) calculate mean chi^2 for this track-fit in Y and Z direction
650 // loop again over all padrows along the track
651 // fit tracklet (clusters in given padrow +- kDelta padrows)
652 // with polynom of 2nd order and two polynoms of 1st order
653 // take both polynoms of 1st order, calculate difference of their parameters
654 // add covariance matrixes and calculate chi2 of this difference
655 // if this chi2 is bigger than a given threshold, assume that the current cluster is
656 // a kink an goto next padrow
658 // fill fArrayAmpRow, array with amplitudes vs. row for given sector
659 // fill fArrayAmp, array with amplitude histograms for give sector
660 // fill fRMSY, fRMSZ, fArrayQRMSY and fArrayQRMSZ, fDeltaY, fDeltaZ, fResolY, fResolZ, fArrayQDY, fArrayQDY
662 // write debug information to 'TPCSelectorDebug.root'
663 // only for every kDeltaWriteDebugStream'th padrow to reduce data volume
664 // and to avoid redundant data
667 if (fDebugLevel > 5) Info("FillResolutionHistoLocal"," ***** Start of FillResolutionHistoLocal *****");
668 const Int_t kDelta = 10; // delta rows to fit
669 const Float_t kMinRatio = 0.75; // minimal ratio
670 const Float_t kCutChi2 = 6.; // cut chi2 - left right - kink removal
671 const Float_t kErrorFraction = 0.5; // use only clusters with small interpolation error - for error param
672 const Int_t kFirstLargePad = 127; // medium pads -> long pads
673 const Float_t kLargePadSize = 1.5; // factor between medium and long pads' area
674 const Int_t kDeltaWriteDebugStream = 5; // only for every kDeltaWriteDebugStream'th padrow debug information is calulated and written to debugstream
675 // TLinearFitter fFitterLinY1 = fFitterLinY1;
676 // TLinearFitter fFitterLinZ1 = ffFitterLinZ1;
677 // TLinearFitter fFitterLinY2 = ffFitterLinY2;
678 // TLinearFitter fFitterLinZ2 = ffFitterLinZ2;
679 // TLinearFitter fFitterParY = ffFitterParY;
680 // TLinearFitter fFitterParZ = ffFitterParZ;
687 TMatrixD matrixY0(2,2);
688 TMatrixD matrixZ0(2,2);
689 TMatrixD matrixY1(2,2);
690 TMatrixD matrixZ1(2,2);
692 // estimate mean error
693 Int_t nTrackletsAll = 0; // number of tracklets for given track
694 Float_t csigmaY = 0; // mean sigma for tracklet refit in Y direction
695 Float_t csigmaZ = 0; // mean sigma for tracklet refit in Z direction
696 Int_t nClusters = 0; // working variable, number of clusters per tracklet
697 Int_t sectorG = -1; // working variable, sector of tracklet, has to stay constant for one tracklet
699 fHclus->Fill(track->GetNumberOfClusters()); // for statistics overview
700 // ---------------------------------------------------------------------
701 for (Int_t irow = 0; irow < 159; irow++){
702 // loop over all rows along the track
703 // fit tracklets (length: 13 rows) with pol2 in Y and Z direction
704 // calculate mean chi^2 for this track-fit in Y and Z direction
705 AliTPCclusterMI * cluster0 = track->GetClusterPointer(irow);
706 if (!cluster0) continue; // no cluster found
707 Int_t sector = cluster0->GetDetector();
708 fHclusterPerPadrowRaw->Fill(irow);
710 Int_t ipad = TMath::Nint(cluster0->GetPad());
711 Float_t value = fCalPadClusterPerPadRaw->GetCalROC(sector)->GetValue((sector<36)?irow:irow-64, TMath::Nint(cluster0->GetPad()));
712 fCalPadClusterPerPadRaw->GetCalROC(sector)->SetValue((sector<36)?irow:irow-64, ipad, value + 1 );
714 if (sector != sectorG){
715 // track leaves sector before it crossed enough rows to fit / initialization
717 fFitterParY->ClearPoints();
718 fFitterParZ->ClearPoints();
723 Double_t x = cluster0->GetX();
724 fFitterParY->AddPoint(&x, cluster0->GetY(), 1);
725 fFitterParZ->AddPoint(&x, cluster0->GetZ(), 1);
727 if ( nClusters >= kDelta + 3 ){
728 // if more than 13 (kDelta+3) clusters were added to the fitters
729 // fit the tracklet, increase trackletCounter
733 csigmaY += fFitterParY->GetChisquare() / (nClusters - 3.);
734 csigmaZ += fFitterParZ->GetChisquare() / (nClusters - 3.);
736 fFitterParY->ClearPoints();
737 fFitterParZ->ClearPoints();
740 } // for (Int_t irow = 0; irow < 159; irow++)
741 // mean chi^2 for all tracklet fits in Y and in Z direction:
742 csigmaY = TMath::Sqrt(csigmaY / nTrackletsAll);
743 csigmaZ = TMath::Sqrt(csigmaZ / nTrackletsAll);
744 // ---------------------------------------------------------------------
746 for (Int_t irow = 0; irow < 159; irow++){
747 // loop again over all rows along the track
750 Int_t nclFound = 0; // number of clusters in the neighborhood
751 Int_t ncl0 = 0; // number of clusters in rows < rowOfCenterCluster
752 Int_t ncl1 = 0; // number of clusters in rows > rowOfCenterCluster
753 AliTPCclusterMI * cluster0 = track->GetClusterPointer(irow);
754 if (!cluster0) continue;
755 Int_t sector = cluster0->GetDetector();
756 Float_t xref = cluster0->GetX();
759 fFitterParY->ClearPoints();
760 fFitterParZ->ClearPoints();
761 fFitterLinY1->ClearPoints();
762 fFitterLinZ1->ClearPoints();
763 fFitterLinY2->ClearPoints();
764 fFitterLinZ2->ClearPoints();
766 // fit tracklet (clusters in given padrow +- kDelta padrows)
767 // with polynom of 2nd order and two polynoms of 1st order
768 // take both polynoms of 1st order, calculate difference of their parameters
769 // add covariance matrixes and calculate chi2 of this difference
770 // if this chi2 is bigger than a given threshold, assume that the current cluster is
771 // a kink an goto next padrow
773 for (Int_t idelta = -kDelta; idelta <= kDelta; idelta++){
774 // loop over irow +- kDelta rows (neighboured rows)
777 if (idelta == 0) continue; // don't use center cluster
778 if (idelta + irow < 0 || idelta + irow > 159) continue; // don't go out of ROC
779 AliTPCclusterMI * currentCluster = track->GetClusterPointer(irow + idelta);
780 if (!currentCluster) continue;
781 if (currentCluster->GetType() < 0) continue;
782 if (currentCluster->GetDetector() != sector) continue;
783 Double_t x = currentCluster->GetX() - xref; // x = differece: current cluster - cluster @ irow
787 fFitterLinY1->AddPoint(&x, currentCluster->GetY(), csigmaY);
788 fFitterLinZ1->AddPoint(&x, currentCluster->GetZ(), csigmaZ);
792 fFitterLinY2->AddPoint(&x, currentCluster->GetY(), csigmaY);
793 fFitterLinZ2->AddPoint(&x, currentCluster->GetZ(), csigmaZ);
795 fFitterParY->AddPoint(&x, currentCluster->GetY(), csigmaY);
796 fFitterParZ->AddPoint(&x, currentCluster->GetZ(), csigmaZ);
797 } // loop over neighbourhood for fitter filling
799 if (nclFound < kDelta * kMinRatio) fRejectedTracksHisto->Fill(10);
800 if (nclFound < kDelta * kMinRatio) fClusterCutHisto->Fill(1, irow);
801 if (nclFound < kDelta * kMinRatio) continue; // if not enough clusters (7.5) found in neighbourhood goto next padrow
804 Double_t chi2 = (fFitterParY->GetChisquare() + fFitterParZ->GetChisquare()) / (2. * nclFound - 6.);
805 if (chi2 > kCutChi2) fRejectedTracksHisto->Fill(9);
806 if (chi2 > kCutChi2) fClusterCutHisto->Fill(2, irow);
807 if (chi2 > kCutChi2) continue; // if chi^2 is too big goto next padrow
810 // only when there are enough clusters (4) in each direction
812 fFitterLinY1->Eval();
813 fFitterLinZ1->Eval();
816 fFitterLinY2->Eval();
817 fFitterLinZ2->Eval();
820 if (ncl0 > 4 && ncl1 > 4){
821 fFitterLinY1->GetCovarianceMatrix(matrixY0);
822 fFitterLinY2->GetCovarianceMatrix(matrixY1);
823 fFitterLinZ1->GetCovarianceMatrix(matrixZ0);
824 fFitterLinZ2->GetCovarianceMatrix(matrixZ1);
825 fFitterLinY2->GetParameters(paramY1);
826 fFitterLinZ2->GetParameters(paramZ1);
827 fFitterLinY1->GetParameters(paramY0);
828 fFitterLinZ1->GetParameters(paramZ0);
831 matrixY0 += matrixY1;
832 matrixZ0 += matrixZ1;
835 TMatrixD difY(2, 1, paramY0.GetMatrixArray());
836 TMatrixD difYT(1, 2, paramY0.GetMatrixArray());
838 TMatrixD mulY(matrixY0, TMatrixD::kMult, difY);
839 TMatrixD chi2Y(difYT, TMatrixD::kMult, mulY);
842 TMatrixD difZ(2, 1, paramZ0.GetMatrixArray());
843 TMatrixD difZT(1, 2, paramZ0.GetMatrixArray());
845 TMatrixD mulZ(matrixZ0, TMatrixD::kMult, difZ);
846 TMatrixD chi2Z(difZT, TMatrixD::kMult, mulZ);
850 if (chi2 * 0.25 > kCutChi2) fRejectedTracksHisto->Fill(8);
851 if (chi2 * 0.25 > kCutChi2) fClusterCutHisto->Fill(3, irow);
852 if (chi2 * 0.25 > kCutChi2) continue; // if chi2 is too big goto next padrow
853 // fit tracklet with polynom of 2nd order and two polynoms of 1st order
854 // take both polynoms of 1st order, calculate difference of their parameters
855 // add covariance matrixes and calculate chi2 of this difference
856 // if this chi2 is bigger than a given threshold, assume that the current cluster is
857 // a kink an goto next padrow
860 // current padrow has no kink
862 // get fit parameters from pol2 fit:
863 Double_t paramY[4], paramZ[4];
864 paramY[0] = fFitterParY->GetParameter(0);
865 paramY[1] = fFitterParY->GetParameter(1);
866 paramY[2] = fFitterParY->GetParameter(2);
867 paramZ[0] = fFitterParZ->GetParameter(0);
868 paramZ[1] = fFitterParZ->GetParameter(1);
869 paramZ[2] = fFitterParZ->GetParameter(2);
871 Double_t tracky = paramY[0];
872 Double_t trackz = paramZ[0];
873 Float_t deltay = tracky - cluster0->GetY();
874 Float_t deltaz = trackz - cluster0->GetZ();
875 Float_t angley = paramY[1] - paramY[0] / xref;
876 Float_t anglez = paramZ[1];
878 Float_t max = cluster0->GetMax();
879 UInt_t isegment = cluster0->GetDetector() % 36;
880 Int_t padSize = 0; // short pads
881 if (cluster0->GetDetector() >= 36) {
882 padSize = 1; // medium pads
883 if (cluster0->GetRow() > 63) padSize = 2; // long pads
886 // =========================================
887 // wirte collected information to histograms
888 // =========================================
890 TProfile *profAmpRow = (TProfile*)fArrayAmpRow->At(sector);
891 if ( irow >= kFirstLargePad) max /= kLargePadSize;
892 profAmpRow->Fill( (Double_t)cluster0->GetRow(), max );
893 TH1F *hisAmp = (TH1F*)fArrayAmp->At(sector);
896 // remove the following two lines one day:
897 TProfile *profDriftLength = (TProfile*)fArrayChargeVsDriftlength->At(sector);
898 profDriftLength->Fill( 250.-(Double_t)TMath::Abs(cluster0->GetZ()), max );
900 TProfile *profDriftLengthTmp = (TProfile*)(fcalPadRegionChargeVsDriftlength->GetObject(isegment, padSize));
901 profDriftLengthTmp->Fill( 250.-(Double_t)TMath::Abs(cluster0->GetZ()), max );
903 fHclusterPerPadrow->Fill(irow); // fill histogram showing clusters per padrow
904 Int_t ipad = TMath::Nint(cluster0->GetPad());
905 Float_t value = fCalPadClusterPerPad->GetCalROC(sector)->GetValue((sector<36)?irow:irow-64, TMath::Nint(cluster0->GetPad()));
906 fCalPadClusterPerPad->GetCalROC(sector)->SetValue((sector<36)?irow:irow-64, ipad, value + 1 );
910 his3 = (TH3F*)fRMSY->At(padSize);
911 if (his3) his3->Fill(250 - TMath::Abs(cluster0->GetZ()), TMath::Abs(angley), TMath::Sqrt(cluster0->GetSigmaY2()) );
912 his3 = (TH3F*)fRMSZ->At(padSize);
913 if (his3) his3->Fill( 250 - TMath::Abs(cluster0->GetZ()), TMath::Abs(anglez), TMath::Sqrt(cluster0->GetSigmaZ2()) );
915 his3 = (TH3F*)fArrayQRMSY->At(GetBin(cluster0->GetMax(), padSize));
916 if (his3) his3->Fill( 250 - TMath::Abs(cluster0->GetZ()), TMath::Abs(angley), TMath::Sqrt(cluster0->GetSigmaY2()) );
917 his3 = (TH3F*)fArrayQRMSZ->At(GetBin(cluster0->GetMax(), padSize));
918 if (his3) his3->Fill( 250 - TMath::Abs(cluster0->GetZ()), TMath::Abs(anglez), TMath::Sqrt(cluster0->GetSigmaZ2()) );
921 // Fill resolution histograms
922 Bool_t useForResol = kTRUE;
923 if (fFitterParY->GetParError(0) > kErrorFraction * csigmaY) useForResol = kFALSE;
926 fDeltaY->Fill(deltay);
927 fDeltaZ->Fill(deltaz);
928 his3 = (TH3F*)fResolY->At(padSize);
929 if (his3) his3->Fill( 250 - TMath::Abs(cluster0->GetZ()), TMath::Abs(angley), deltay );
930 his3 = (TH3F*)fResolZ->At(padSize);
931 if (his3) his3->Fill( 250 - TMath::Abs(cluster0->GetZ()), TMath::Abs(anglez), deltaz );
932 his3 = (TH3F*)fArrayQDY->At(GetBin(cluster0->GetMax(), padSize));
933 if (his3) his3->Fill( 250 - TMath::Abs(cluster0->GetZ()),TMath::Abs(angley), deltay );
934 his3 = (TH3F*)fArrayQDZ->At(GetBin(cluster0->GetMax(), padSize));
935 if (his3) his3->Fill( 250 - TMath::Abs(cluster0->GetZ()),TMath::Abs(anglez), deltaz );
938 //=============================================================================================
940 if (useForResol && nclFound > 2 * kMinRatio * kDelta
941 && irow % kDeltaWriteDebugStream == 0 && fDebugLevel > 4){
942 if (fDebugLevel > 5) Info("FillResolutionHistoLocal","Filling 'TPCSelectorDebug.root', irow = %i", irow);
943 FillResolutionHistoLocalDebugPart(track, cluster0, irow, angley, anglez, nclFound, kDelta);
944 } // if (useForResol && nclFound > 2 * kMinRatio * kDelta)
946 } // loop over all padrows along the track: for (Int_t irow = 0; irow < 159; irow++)
947 } // FillResolutionHistoLocal(...)
951 void AliTPCcalibTracks::FillResolutionHistoLocalDebugPart(AliTPCseed *track, AliTPCclusterMI *cluster0, Int_t irow, Float_t angley, Float_t anglez, Int_t nclFound, Int_t kDelta) {
953 // - debug part of FillResolutionHistoLocal -
954 // called only for every kDeltaWriteDebugStream'th padrow, to avoid to much redundant data
955 // called only for fDebugLevel > 4
956 // fill resolution trees
959 Int_t sector = cluster0->GetDetector();
960 Float_t xref = cluster0->GetX();
961 Int_t padSize = 0; // short pads
962 if (cluster0->GetDetector() >= 36) {
963 padSize = 1; // medium pads
964 if (cluster0->GetRow() > 63) padSize = 2; // long pads
967 static TLinearFitter fitY0(3, "pol2");
968 static TLinearFitter fitZ0(3, "pol2");
969 static TLinearFitter fitY2(5, "hyp4");
970 static TLinearFitter fitZ2(5, "hyp4");
971 static TLinearFitter fitY2Q(5, "hyp4");
972 static TLinearFitter fitZ2Q(5, "hyp4");
973 static TLinearFitter fitY2S(5, "hyp4");
974 static TLinearFitter fitZ2S(5, "hyp4");
979 fitY2Q.ClearPoints();
980 fitZ2Q.ClearPoints();
981 fitY2S.ClearPoints();
982 fitZ2S.ClearPoints();
984 for (Int_t idelta = -kDelta; idelta <= kDelta; idelta++){
985 // loop over irow +- kDelta rows (neighboured rows)
988 if (idelta == 0) continue;
989 if (idelta + irow < 0 || idelta + irow > 159) continue; // don't go out of ROC
990 AliTPCclusterMI * cluster = track->GetClusterPointer(irow + idelta);
991 if (!cluster) continue;
992 if (cluster->GetType() < 0) continue;
993 if (cluster->GetDetector() != sector) continue;
994 Double_t x = cluster->GetX() - xref;
995 Double_t sigmaY0 = fClusterParam->GetError0Par( 0, padSize, (250.0 - TMath::Abs(cluster->GetZ())), TMath::Abs(angley) );
996 Double_t sigmaZ0 = fClusterParam->GetError0Par( 1, padSize, (250.0 - TMath::Abs(cluster->GetZ())), TMath::Abs(anglez) );
998 Double_t sigmaYQ = fClusterParam->GetErrorQPar( 0, padSize, (250.0 - TMath::Abs(cluster->GetZ())), TMath::Abs(angley), TMath::Abs(cluster->GetMax()) );
999 Double_t sigmaZQ = fClusterParam->GetErrorQPar( 1, padSize, (250.0 - TMath::Abs(cluster->GetZ())), TMath::Abs(anglez), TMath::Abs(cluster->GetMax()) );
1000 Double_t sigmaYS = fClusterParam->GetErrorQParScaled( 0, padSize, (250.0 - TMath::Abs(cluster->GetZ())),
1001 TMath::Abs(angley), TMath::Abs(cluster->GetMax()) );
1002 Double_t sigmaZS = fClusterParam->GetErrorQParScaled( 1, padSize, (250.0 - TMath::Abs(cluster->GetZ())),
1003 TMath::Abs(anglez), TMath::Abs(cluster->GetMax()) );
1004 Float_t rmsYFactor = fClusterParam->GetShapeFactor( 0, padSize,(250.0 - TMath::Abs(cluster->GetZ())),
1005 TMath::Abs(anglez), TMath::Abs(cluster->GetMax()),
1006 TMath::Sqrt(cluster0->GetSigmaY2()), 0 );
1007 Float_t rmsZFactor = fClusterParam->GetShapeFactor(0, padSize,(250.0 - TMath::Abs(cluster->GetZ())),
1008 TMath::Abs(anglez), TMath::Abs(cluster->GetMax()),
1009 TMath::Sqrt(cluster0->GetSigmaZ2()),0 );
1010 sigmaYS = TMath::Sqrt(sigmaYS * sigmaYS + rmsYFactor * rmsYFactor / 12.);
1011 sigmaZS = TMath::Sqrt(sigmaZS * sigmaZS + rmsZFactor * rmsZFactor / 12. + rmsYFactor * rmsYFactor / 24.);
1014 fitY0.AddPoint(&x, cluster->GetY(), sigmaY0);
1015 fitZ0.AddPoint(&x, cluster->GetZ(), sigmaZ0);
1018 xxx[0] = ( (idelta+irow) % 2 == 0 ) ? 1 : 0;
1020 xxx[2] = ( (idelta+irow) % 2 == 0 ) ? x : 0;
1022 fitY2.AddPoint(xxx, cluster->GetY(), sigmaY0);
1023 fitY2Q.AddPoint(xxx, cluster->GetY(), sigmaYQ);
1024 fitY2S.AddPoint(xxx, cluster->GetY(), sigmaYS);
1025 fitZ2.AddPoint(xxx, cluster->GetZ(), sigmaZ0);
1026 fitZ2Q.AddPoint(xxx, cluster->GetZ(), sigmaZQ);
1027 fitZ2S.AddPoint(xxx, cluster->GetZ(), sigmaZS);
1029 } // neigbouhood-loop
1039 Float_t chi2Y0 = fitY0.GetChisquare() / (nclFound-3.);
1040 Float_t chi2Z0 = fitZ0.GetChisquare() / (nclFound-3.);
1041 Float_t chi2Y2 = fitY2.GetChisquare() / (nclFound-5.);
1042 Float_t chi2Z2 = fitZ2.GetChisquare() / (nclFound-5.);
1043 Float_t chi2Y2Q = fitY2Q.GetChisquare() / (nclFound-5.);
1044 Float_t chi2Z2Q = fitZ2Q.GetChisquare() / (nclFound-5.);
1045 Float_t chi2Y2S = fitY2S.GetChisquare() / (nclFound-5.);
1046 Float_t chi2Z2S = fitZ2S.GetChisquare() / (nclFound-5.);
1048 static TVectorD parY0(3);
1049 static TMatrixD matY0(3, 3);
1050 static TVectorD parZ0(3);
1051 static TMatrixD matZ0(3, 3);
1052 fitY0.GetParameters(parY0);
1053 fitY0.GetCovarianceMatrix(matY0);
1054 fitZ0.GetParameters(parZ0);
1055 fitZ0.GetCovarianceMatrix(matZ0);
1057 static TVectorD parY2(5);
1058 static TMatrixD matY2(5,5);
1059 static TVectorD parZ2(5);
1060 static TMatrixD matZ2(5,5);
1061 fitY2.GetParameters(parY2);
1062 fitY2.GetCovarianceMatrix(matY2);
1063 fitZ2.GetParameters(parZ2);
1064 fitZ2.GetCovarianceMatrix(matZ2);
1066 static TVectorD parY2Q(5);
1067 static TMatrixD matY2Q(5,5);
1068 static TVectorD parZ2Q(5);
1069 static TMatrixD matZ2Q(5,5);
1070 fitY2Q.GetParameters(parY2Q);
1071 fitY2Q.GetCovarianceMatrix(matY2Q);
1072 fitZ2Q.GetParameters(parZ2Q);
1073 fitZ2Q.GetCovarianceMatrix(matZ2Q);
1074 static TVectorD parY2S(5);
1075 static TMatrixD matY2S(5,5);
1076 static TVectorD parZ2S(5);
1077 static TMatrixD matZ2S(5,5);
1078 fitY2S.GetParameters(parY2S);
1079 fitY2S.GetCovarianceMatrix(matY2S);
1080 fitZ2S.GetParameters(parZ2S);
1081 fitZ2S.GetCovarianceMatrix(matZ2S);
1082 Float_t sigmaY0 = TMath::Sqrt(matY0(0,0));
1083 Float_t sigmaZ0 = TMath::Sqrt(matZ0(0,0));
1084 Float_t sigmaDY0 = TMath::Sqrt(matY0(1,1));
1085 Float_t sigmaDZ0 = TMath::Sqrt(matZ0(1,1));
1086 Float_t sigmaY2 = TMath::Sqrt(matY2(1,1));
1087 Float_t sigmaZ2 = TMath::Sqrt(matZ2(1,1));
1088 Float_t sigmaDY2 = TMath::Sqrt(matY2(3,3));
1089 Float_t sigmaDZ2 = TMath::Sqrt(matZ2(3,3));
1090 Float_t sigmaY2Q = TMath::Sqrt(matY2Q(1,1));
1091 Float_t sigmaZ2Q = TMath::Sqrt(matZ2Q(1,1));
1092 Float_t sigmaDY2Q = TMath::Sqrt(matY2Q(3,3));
1093 Float_t sigmaDZ2Q = TMath::Sqrt(matZ2Q(3,3));
1094 Float_t sigmaY2S = TMath::Sqrt(matY2S(1,1));
1095 Float_t sigmaZ2S = TMath::Sqrt(matZ2S(1,1));
1096 Float_t sigmaDY2S = TMath::Sqrt(matY2S(3,3));
1097 Float_t sigmaDZ2S = TMath::Sqrt(matZ2S(3,3));
1100 Float_t csigmaY0 = fClusterParam->GetError0Par(0,padSize,(250.0-TMath::Abs(cluster0->GetZ())),TMath::Abs(angley));
1101 Float_t csigmaZ0 = fClusterParam->GetError0Par(1,padSize,(250.0-TMath::Abs(cluster0->GetZ())),TMath::Abs(anglez));
1103 Float_t csigmaYQ = fClusterParam->GetErrorQPar(0,padSize,(250.0-TMath::Abs(cluster0->GetZ())),
1104 TMath::Abs(angley), TMath::Abs(cluster0->GetMax()));
1105 Float_t csigmaZQ = fClusterParam->GetErrorQPar(1,padSize,(250.0-TMath::Abs(cluster0->GetZ())),
1106 TMath::Abs(anglez),TMath::Abs(cluster0->GetMax()));
1107 Float_t csigmaYS = fClusterParam->GetErrorQParScaled(0,padSize,(250.0-TMath::Abs(cluster0->GetZ())),
1108 TMath::Abs(angley), TMath::Abs(cluster0->GetMax()));
1109 Float_t csigmaZS = fClusterParam->GetErrorQParScaled(1,padSize,(250.0-TMath::Abs(cluster0->GetZ())),
1110 TMath::Abs(anglez),TMath::Abs(cluster0->GetMax()));
1111 ///////////////////////////////////////////////////////////////////////////////
1113 // Class to analyse tracks for calibration //
1114 // to be used as a component in AliTPCSelectorTracks //
1115 // In the constructor you have to specify name and title //
1116 // to get the Object out of a file. //
1117 // The parameter 'clusterParam', a AliTPCClusterParam object //
1118 // (needed for TPC cluster error and shape parameterization) //
1119 // Normally you get this object out of the file 'TPCClusterParam.root' //
1120 // In the parameter 'cuts' the cuts are specified, that decide //
1121 // weather a track will be accepted for calibration or not. //
1124 ///////////////////////////////////////////////////////////////////////////////
1127 Float_t meanRMSY = 0;
1128 Float_t meanRMSZ = 0;
1130 for (Int_t idelta = -2; idelta <= 2; idelta++){
1131 // loop over neighbourhood
1132 if (idelta+irow < 0 || idelta+irow > 159) continue;
1133 // if (idelta+irow>159) continue;
1134 AliTPCclusterMI * cluster = track->GetClusterPointer(irow+idelta);
1135 if (!cluster) continue;
1136 meanRMSY += TMath::Sqrt(cluster->GetSigmaY2());
1137 meanRMSZ += TMath::Sqrt(cluster->GetSigmaZ2());
1143 Float_t rmsY = TMath::Sqrt(cluster0->GetSigmaY2());
1144 Float_t rmsZ = TMath::Sqrt(cluster0->GetSigmaZ2());
1145 Float_t rmsYT = fClusterParam->GetRMSQ(0,padSize,(250.0-TMath::Abs(cluster0->GetZ())),
1146 TMath::Abs(angley), TMath::Abs(cluster0->GetMax()));
1147 Float_t rmsZT = fClusterParam->GetRMSQ(1,padSize,(250.0-TMath::Abs(cluster0->GetZ())),
1148 TMath::Abs(anglez), TMath::Abs(cluster0->GetMax()));
1149 Float_t rmsYT0 = fClusterParam->GetRMS0(0,padSize,(250.0-TMath::Abs(cluster0->GetZ())),
1150 TMath::Abs(angley));
1151 Float_t rmsZT0 = fClusterParam->GetRMS0(1,padSize,(250.0-TMath::Abs(cluster0->GetZ())),
1152 TMath::Abs(anglez));
1153 Float_t rmsYSigma = fClusterParam->GetRMSSigma(0,padSize,(250.0-TMath::Abs(cluster0->GetZ())),
1154 TMath::Abs(anglez), TMath::Abs(cluster0->GetMax()));
1155 Float_t rmsZSigma = fClusterParam->GetRMSSigma(0,padSize,(250.0-TMath::Abs(cluster0->GetZ())),
1156 TMath::Abs(anglez), TMath::Abs(cluster0->GetMax()));
1157 Float_t rmsYFactor = fClusterParam->GetShapeFactor(0,padSize,(250.0-TMath::Abs(cluster0->GetZ())),
1158 TMath::Abs(anglez), TMath::Abs(cluster0->GetMax()),
1160 Float_t rmsZFactor = fClusterParam->GetShapeFactor(0,padSize,(250.0-TMath::Abs(cluster0->GetZ())),
1161 TMath::Abs(anglez), TMath::Abs(cluster0->GetMax()),
1165 (*fDebugStream)<<"ResolCl"<< // valgrind 3 40,000 bytes in 1 blocks are possibly
1168 "CSigmaY0="<<csigmaY0<< // cluster errorY
1169 "CSigmaYQ="<<csigmaYQ<< // cluster errorY - q scaled
1170 "CSigmaYS="<<csigmaYS<< // cluster errorY - q scaled
1171 "CSigmaZ0="<<csigmaZ0<< //
1172 "CSigmaZQ="<<csigmaZQ<<
1173 "CSigmaZS="<<csigmaZS<<
1174 "shapeYF="<<rmsYFactor<<
1175 "shapeZF="<<rmsZFactor<<
1178 "rmsYM="<<meanRMSY<<
1179 "rmsZM="<<meanRMSZ<<
1184 "rmsYS="<<rmsYSigma<<
1185 "rmsZS="<<rmsZSigma<<
1186 "padSize="<<padSize<<
1190 "SigmaY0="<<sigmaY0<<
1191 "SigmaZ0="<<sigmaZ0<<
1197 (*fDebugStream)<<"ResolTr"<<
1198 "padSize="<<padSize<<
1206 "chi2Y2Q="<<chi2Y2Q<<
1207 "chi2Z2Q="<<chi2Z2Q<<
1208 "chi2Y2S="<<chi2Y2S<<
1209 "chi2Z2S="<<chi2Z2S<<
1218 "SigmaY0="<<sigmaY0<<
1219 "SigmaZ0="<<sigmaZ0<<
1220 "SigmaDY0="<<sigmaDY0<<
1221 "SigmaDZ0="<<sigmaDZ0<<
1222 "SigmaY2="<<sigmaY2<<
1223 "SigmaZ2="<<sigmaZ2<<
1224 "SigmaDY2="<<sigmaDY2<<
1225 "SigmaDZ2="<<sigmaDZ2<<
1226 "SigmaY2Q="<<sigmaY2Q<<
1227 "SigmaZ2Q="<<sigmaZ2Q<<
1228 "SigmaDY2Q="<<sigmaDY2Q<<
1229 "SigmaDZ2Q="<<sigmaDZ2Q<<
1230 "SigmaY2S="<<sigmaY2S<<
1231 "SigmaZ2S="<<sigmaZ2S<<
1232 "SigmaDY2S="<<sigmaDY2S<<
1233 "SigmaDZ2S="<<sigmaDZ2S<<
1245 TH2D * AliTPCcalibTracks::MakeDiff(TH2D * hfit, TF2 * func){
1247 // creates a new histogram which contains the difference between
1248 // the histogram hfit and the function func
1250 TH2D * result = (TH2D*)hfit->Clone(); // valgrind 3 40,139 bytes in 11 blocks are still reachable
1251 result->SetTitle(Form("%s fit residuals",result->GetTitle()));
1252 result->SetName(Form("%s fit residuals",result->GetName()));
1253 TAxis *xaxis = hfit->GetXaxis();
1254 TAxis *yaxis = hfit->GetYaxis();
1256 for (Int_t biny = 0; biny <= yaxis->GetNbins(); biny++) {
1257 x[1] = yaxis->GetBinCenter(biny);
1258 for (Int_t binx = 0; binx <= xaxis->GetNbins(); binx++) {
1259 x[0] = xaxis->GetBinCenter(binx);
1260 Int_t bin = hfit->GetBin(binx, biny);
1261 Double_t val = hfit->GetBinContent(bin);
1262 // result->SetBinContent( bin, (val - func->Eval(x[0], x[1])) / func->Eval(x[0], x[1]) );
1263 result->SetBinContent( bin, (val / func->Eval(x[0], x[1])) - 1 );
1270 void AliTPCcalibTracks::SetStyle() const {
1272 // set style, can be called by all draw functions
1274 gROOT->SetStyle("Plain");
1275 gStyle->SetFillColor(10);
1276 gStyle->SetPadColor(10);
1277 gStyle->SetCanvasColor(10);
1278 gStyle->SetStatColor(10);
1279 gStyle->SetPalette(1,0);
1280 gStyle->SetNumberContours(60);
1284 void AliTPCcalibTracks::Draw(Option_t* opt){
1286 // draw-function of AliTPCcalibTracks
1287 // will draws some exemplaric pictures
1290 if (fDebugLevel > 6) Info("Draw", "Drawing an exemplaric picture.");
1294 TCanvas *c1 = new TCanvas();
1296 TVirtualPad *upperThird = c1->GetPad(1);
1297 TVirtualPad *middleThird = c1->GetPad(2);
1298 TVirtualPad *lowerThird = c1->GetPad(3);
1299 upperThird->Divide(2,0);
1300 TVirtualPad *upleft = upperThird->GetPad(1);
1301 TVirtualPad *upright = upperThird->GetPad(2);
1302 middleThird->Divide(2,0);
1303 TVirtualPad *middleLeft = middleThird->GetPad(1);
1304 TVirtualPad *middleRight = middleThird->GetPad(2);
1305 lowerThird->Divide(2,0);
1306 TVirtualPad *downLeft = lowerThird->GetPad(1);
1307 TVirtualPad *downRight = lowerThird->GetPad(2);
1311 min = fDeltaY->GetBinCenter(fDeltaY->GetMaximumBin())-20;
1312 max = fDeltaY->GetBinCenter(fDeltaY->GetMaximumBin())+20;
1313 fDeltaY->SetAxisRange(min, max);
1314 fDeltaY->Fit("gaus","q","",min, max); // valgrind 3 7 block possibly lost 2,400 bytes in 1 blocks are still reachable
1318 max = fDeltaZ->GetBinCenter(fDeltaZ->GetMaximumBin())+20;
1319 min = fDeltaZ->GetBinCenter(fDeltaZ->GetMaximumBin())-20;
1320 fDeltaZ->SetAxisRange(min, max);
1321 fDeltaZ->Fit("gaus","q","",min, max);
1328 fRejectedTracksHisto->Draw(opt);
1329 TPaveText *pt = new TPaveText(0.6,0.6, 0.8,0.8, "NDC");
1330 TText *t1 = pt->AddText("1: kEdgeThetaCutNoise");
1331 TText *t2 = pt->AddText("2: kMinClusters");
1332 TText *t3 = pt->AddText("3: kMinRatio");
1333 TText *t4 = pt->AddText("4: kMax1pt");
1334 t1 = t1; t2 = t2; t3 = t3; t4 = t4; // avoid compiler warnings
1335 pt->SetToolTipText("Legend for failed cuts");
1339 fHclusterPerPadrowRaw->Draw(opt);
1342 fHclusterPerPadrow->Draw(opt);
1346 void AliTPCcalibTracks::MakeReport(Int_t stat, char* pathName){
1348 // all functions are called, that produce pictures
1349 // the histograms are written to the directory 'pathName'
1350 // 'stat' is a threshhold: only histograms with more than 'stat' entries are wirtten to file
1351 // 'stat' is also the number of minEntries for MakeResPlotsQTree
1354 if (fDebugLevel > 0) Info("MakeReport","Writing plots and trees to '%s'.", pathName);
1355 MakeAmpPlots(stat, pathName);
1356 MakeDeltaPlots(pathName);
1357 FitResolutionNew(pathName);
1358 FitRMSNew(pathName);
1359 MakeChargeVsDriftLengthPlots(pathName);
1360 // MakeResPlotsQ(1, 1);
1361 MakeResPlotsQTree(stat, pathName);
1365 void AliTPCcalibTracks::MakeAmpPlots(Int_t stat, char* pathName){
1367 // creates several plots:
1368 // fArrayAmp.ps, fArrayAmpRow.ps and DeltaYZ.ps
1369 // fArrayAmp.ps: one histogram per sector, the histogram shows the charge per cluster
1370 // fArrayAmpRow.ps: one histogram per sector, mean max. amplitude vs. pad row with landau fit
1371 // DeltaYZ.ps: DeltaY and DeltaZ histogram with gaus fit
1372 // Empty histograms (sectors without data) are not written to file
1373 // the ps-files are written to the directory 'pathName', that is created if it does not exist
1374 // 'stat': only histograms with more than 'stat' entries are written to file.
1378 gSystem->MakeDirectory(pathName);
1379 gSystem->ChangeDirectory(pathName);
1381 TCanvas* c1 = new TCanvas(); // valgrind 3 ??? 634 bytes in 28 blocks are still reachable
1383 // histograms with accumulated amplitude for all IROCs and OROCs
1384 TH1F *allAmpHisIROC = ((TH1F*)(fArrayAmp->At(0))->Clone());
1385 allAmpHisIROC->SetName("Amp all IROCs");
1386 allAmpHisIROC->SetTitle("Amp all IROCs");
1387 TH1F *allAmpHisOROC = ((TH1F*)(fArrayAmp->At(36))->Clone());
1388 allAmpHisOROC->SetName("Amp all OROCs");
1389 allAmpHisOROC->SetTitle("Amp all OROCs");
1391 ps = new TPostScript("fArrayAmp.ps", 112);
1392 if (fDebugLevel > -1) cout << "creating fArrayAmp.ps..." << endl;
1393 for (Int_t i = 0; i < fArrayAmp->GetEntriesFast(); i++){
1394 if ( ((TH1F*)fArrayAmp->At(i))->GetEntries() < stat ) continue;
1396 ((TH1F*)fArrayAmp->At(i))->Draw();
1397 c1->Update(); // valgrind 3
1398 if (i > 0 && i < 36) {
1399 allAmpHisIROC->Add(((TH1F*)fArrayAmp->At(i)));
1400 allAmpHisOROC->Add(((TH1F*)fArrayAmp->At(i+36)));
1404 allAmpHisIROC->Draw();
1405 c1->Update(); // valgrind
1407 allAmpHisOROC->Draw();
1415 ps = new TPostScript("fArrayAmpRow.ps", 112);
1416 if (fDebugLevel > -1) cout << "creating fArrayAmpRow.ps..." << endl;
1417 for (Int_t i = 0; i < fArrayAmpRow->GetEntriesFast(); i++){
1418 his = (TH1F*)fArrayAmpRow->At(i);
1419 if (his->GetEntries() < stat) continue;
1421 min = TMath::Max( his->GetBinCenter(his->GetMaximumBin() )-100., 0.);
1422 max = his->GetBinCenter(5*his->GetMaximumBin()) + 100;
1423 his->SetAxisRange(min, max);
1424 his->Fit("pol3", "q", "", min, max);
1425 // his->Draw("error"); // don't use this line when you don't want to have empty pages in the ps-file
1431 gSystem->ChangeDirectory("..");
1435 void AliTPCcalibTracks::MakeDeltaPlots(char* pathName){
1437 // creates several plots:
1438 // DeltaYZ.ps: DeltaY and DeltaZ histogram with gaus fit
1439 // the ps-files are written to the directory 'pathName', that is created if it does not exist
1443 gSystem->MakeDirectory(pathName);
1444 gSystem->ChangeDirectory(pathName);
1446 TCanvas* c1 = new TCanvas(); // valgrind 3 ??? 634 bytes in 28 blocks are still reachable
1451 ps = new TPostScript("DeltaYZ.ps", 112);
1452 if (fDebugLevel > -1) cout << "creating DeltaYZ.ps..." << endl;
1453 min = fDeltaY->GetBinCenter(fDeltaY->GetMaximumBin())-20;
1454 max = fDeltaY->GetBinCenter(fDeltaY->GetMaximumBin())+20;
1455 fDeltaY->SetAxisRange(min, max);
1457 fDeltaY->Fit("gaus","q","",min, max); // valgrind 3 7 block possibly lost 2,400 bytes in 1 blocks are still reachable
1460 max = fDeltaZ->GetBinCenter(fDeltaZ->GetMaximumBin())+20;
1461 min = fDeltaZ->GetBinCenter(fDeltaZ->GetMaximumBin())-20;
1462 fDeltaZ->SetAxisRange(min, max);
1463 fDeltaZ->Fit("gaus","q","",min, max);
1468 gSystem->ChangeDirectory("..");
1472 void AliTPCcalibTracks::MakeChargeVsDriftLengthPlotsOld(char* pathName){
1474 // creates charge vs. driftlength plots, one TProfile for each ROC
1475 // is not correct like this, should be one TProfile for each sector and padsize
1479 gSystem->MakeDirectory(pathName);
1480 gSystem->ChangeDirectory(pathName);
1482 TCanvas* c1 = new TCanvas(); // valgrind 3 ??? 634 bytes in 28 blocks are still reachable
1484 ps = new TPostScript("chargeVsDriftlengthOld.ps", 112);
1485 if (fDebugLevel > -1) cout << "creating chargeVsDriftlength.ps..." << endl;
1486 TProfile *chargeVsDriftlengthAllIROCs = ((TProfile*)fArrayChargeVsDriftlength->At(0)->Clone());
1487 TProfile *chargeVsDriftlengthAllOROCs = ((TProfile*)fArrayChargeVsDriftlength->At(36)->Clone());
1488 chargeVsDriftlengthAllIROCs->SetName("allAmpHisIROC");
1489 chargeVsDriftlengthAllIROCs->SetTitle("charge vs. driftlength, all IROCs");
1490 chargeVsDriftlengthAllOROCs->SetName("allAmpHisOROC");
1491 chargeVsDriftlengthAllOROCs->SetTitle("charge vs. driftlength, all OROCs");
1493 for (Int_t i = 0; i < fArrayChargeVsDriftlength->GetEntriesFast(); i++) {
1494 ((TProfile*)fArrayChargeVsDriftlength->At(i))->Draw();
1496 if (i > 0 && i < 36) {
1497 chargeVsDriftlengthAllIROCs->Add(((TProfile*)fArrayChargeVsDriftlength->At(i)));
1498 chargeVsDriftlengthAllOROCs->Add(((TProfile*)fArrayChargeVsDriftlength->At(i+36)));
1502 chargeVsDriftlengthAllIROCs->Draw();
1503 c1->Update(); // valgrind
1505 chargeVsDriftlengthAllOROCs->Draw();
1510 gSystem->ChangeDirectory("..");
1514 void AliTPCcalibTracks::MakeChargeVsDriftLengthPlots(char* pathName){
1516 // creates charge vs. driftlength plots, one TProfile for each ROC
1517 // under development....
1521 gSystem->MakeDirectory(pathName);
1522 gSystem->ChangeDirectory(pathName);
1524 TCanvas* c1 = new TCanvas("c1", "c1", 700,(Int_t)(TMath::Sqrt(2)*700)); // valgrind 3 ??? 634 bytes in 28 blocks are still reachable
1525 // TCanvas c1("c1", "c1", 500,(sqrt(2)*500))
1528 ps = new TPostScript("chargeVsDriftlength.ps", 111);
1529 if (fDebugLevel > -1) cout << "creating chargeVsDriftlengthNew.ps..." << endl;
1531 TProfile *chargeVsDriftlengthAllShortPads = ((TProfile*)fcalPadRegionChargeVsDriftlength->GetObject(0,0)->Clone());
1532 TProfile *chargeVsDriftlengthAllMediumPads = ((TProfile*)fcalPadRegionChargeVsDriftlength->GetObject(0,1)->Clone());
1533 TProfile *chargeVsDriftlengthAllLongPads = ((TProfile*)fcalPadRegionChargeVsDriftlength->GetObject(0,2)->Clone());
1534 chargeVsDriftlengthAllShortPads->SetName("allAmpHisShortPads");
1535 chargeVsDriftlengthAllShortPads->SetTitle("charge vs. driftlength, all sectors, short pads");
1536 chargeVsDriftlengthAllMediumPads->SetName("allAmpHisMediumPads");
1537 chargeVsDriftlengthAllMediumPads->SetTitle("charge vs. driftlength, all sectors, medium pads");
1538 chargeVsDriftlengthAllLongPads->SetName("allAmpHisLongPads");
1539 chargeVsDriftlengthAllLongPads->SetTitle("charge vs. driftlength, all sectors, long pads");
1541 for (Int_t i = 0; i < 36; i++) {
1542 c1->cd(1)->SetGridx();
1543 c1->cd(1)->SetGridy();
1544 ((TProfile*)fcalPadRegionChargeVsDriftlength->GetObject(i,0))->Draw();
1545 c1->cd(2)->SetGridx();
1546 c1->cd(2)->SetGridy();
1547 ((TProfile*)fcalPadRegionChargeVsDriftlength->GetObject(i,1))->Draw();
1548 c1->cd(3)->SetGridx();
1549 c1->cd(3)->SetGridy();
1550 ((TProfile*)fcalPadRegionChargeVsDriftlength->GetObject(i,2))->Draw();
1552 chargeVsDriftlengthAllShortPads->Add( (TProfile*)fcalPadRegionChargeVsDriftlength->GetObject(0,0));
1553 chargeVsDriftlengthAllMediumPads->Add((TProfile*)fcalPadRegionChargeVsDriftlength->GetObject(0,1));
1554 chargeVsDriftlengthAllLongPads->Add( (TProfile*)fcalPadRegionChargeVsDriftlength->GetObject(0,2));
1557 c1->cd(1)->SetGridx();
1558 c1->cd(1)->SetGridy();
1559 chargeVsDriftlengthAllShortPads->Draw();
1560 c1->cd(2)->SetGridx();
1561 c1->cd(2)->SetGridy();
1562 chargeVsDriftlengthAllMediumPads->Draw();
1563 c1->cd(3)->SetGridx();
1564 c1->cd(3)->SetGridy();
1565 chargeVsDriftlengthAllLongPads->Draw();
1566 c1->Update(); // valgrind
1571 gSystem->ChangeDirectory("..");
1576 void AliTPCcalibTracks::FitResolutionNew(char* pathName){
1578 // calculates different resulution fits in Y and Z direction
1579 // the histograms are written to 'ResolutionYZ.ps'
1580 // writes calculated resolution to 'resol.txt'
1581 // all files are stored in the directory pathName
1585 gSystem->MakeDirectory(pathName);
1586 gSystem->ChangeDirectory(pathName);
1590 if (fDebugLevel > -1) cout << "creating ResolutionYZ.ps..." << endl;
1591 TPostScript *ps = new TPostScript("ResolutionYZ.ps", 112);
1592 TF2 *fres = new TF2("fres","TMath::Sqrt([0]*[0]+[1]*[1]*x+[2]*[2]*y*y)",0,250,0,1);
1593 fres->SetParameter(0,0.02);
1594 fres->SetParameter(1,0.0054);
1595 fres->SetParameter(2,0.13);
1597 TH1::AddDirectory(kTRUE); // TH3F::FitSlicesZ() writes histograms into the current directory
1599 // create histogramw for Y-resolution
1600 TH3F * hisResY0 = (TH3F*)fResolY->At(0);
1601 hisResY0->FitSlicesZ();
1602 TH2D * hisResY02 = (TH2D*)gDirectory->Get("Resol Y0_2");
1603 TH3F * hisResY1 = (TH3F*)fResolY->At(1);
1604 hisResY1->FitSlicesZ();
1605 TH2D * hisResY12 = (TH2D*)gDirectory->Get("Resol Y1_2");
1606 TH3F * hisResY2 = (TH3F*)fResolY->At(2);
1607 hisResY2->FitSlicesZ();
1608 TH2D * hisResY22 = (TH2D*)gDirectory->Get("Resol Y2_2");
1612 hisResY02->Fit(fres, "q"); // valgrind 132,072 bytes in 6 blocks are indirectly lost
1613 hisResY02->Draw("surf1");
1615 MakeDiff(hisResY02,fres)->Draw("surf1");
1617 // c.SaveAs("ResolutionYPad0.eps");
1620 hisResY12->Fit(fres, "q");
1621 hisResY12->Draw("surf1");
1623 MakeDiff(hisResY12,fres)->Draw("surf1");
1625 // c.SaveAs("ResolutionYPad1.eps");
1628 hisResY22->Fit(fres, "q");
1629 hisResY22->Draw("surf1");
1631 MakeDiff(hisResY22,fres)->Draw("surf1");
1633 // c.SaveAs("ResolutionYPad2.eps");
1635 // create histogramw for Z-resolution
1636 TH3F * hisResZ0 = (TH3F*)fResolZ->At(0);
1637 hisResZ0->FitSlicesZ();
1638 TH2D * hisResZ02 = (TH2D*)gDirectory->Get("Resol Z0_2");
1639 TH3F * hisResZ1 = (TH3F*)fResolZ->At(1);
1640 hisResZ1->FitSlicesZ();
1641 TH2D * hisResZ12 = (TH2D*)gDirectory->Get("Resol Z1_2");
1642 TH3F * hisResZ2 = (TH3F*)fResolZ->At(2);
1643 hisResZ2->FitSlicesZ();
1644 TH2D * hisResZ22 = (TH2D*)gDirectory->Get("Resol Z2_2");
1648 hisResZ02->Fit(fres, "q");
1649 hisResZ02->Draw("surf1");
1651 MakeDiff(hisResZ02,fres)->Draw("surf1");
1653 // c.SaveAs("ResolutionZPad0.eps");
1656 hisResZ12->Fit(fres, "q");
1657 hisResZ12->Draw("surf1");
1659 MakeDiff(hisResZ12,fres)->Draw("surf1");
1661 // c.SaveAs("ResolutionZPad1.eps");
1664 hisResZ22->Fit(fres, "q");
1665 hisResZ22->Draw("surf1");
1667 MakeDiff(hisResZ22,fres)->Draw("surf1");
1669 // c.SaveAs("ResolutionZPad2.eps");
1673 // write calculated resoltuions to 'resol.txt'
1674 ofstream fresol("resol.txt");
1675 fresol<<"Pad 0.75 cm"<<"\n";
1676 hisResY02->Fit(fres, "q"); // valgrind
1677 fresol<<"Y\t"<<fres->GetParameter(0)<<"\t"<<fres->GetParameter(1)<<"\t"<<fres->GetParameter(2)<<"\n";
1678 hisResZ02->Fit(fres, "q");
1679 fresol<<"Z\t"<<fres->GetParameter(0)<<"\t"<<fres->GetParameter(1)<<"\t"<<fres->GetParameter(2)<<"\n";
1681 fresol<<"Pad 1.00 cm"<<1<<"\n";
1682 hisResY12->Fit(fres, "q"); // valgrind
1683 fresol<<"Y\t"<<fres->GetParameter(0)<<"\t"<<fres->GetParameter(1)<<"\t"<<fres->GetParameter(2)<<"\n";
1684 hisResZ12->Fit(fres, "q");
1685 fresol<<"Z\t"<<fres->GetParameter(0)<<"\t"<<fres->GetParameter(1)<<"\t"<<fres->GetParameter(2)<<"\n";
1687 fresol<<"Pad 1.50 cm"<<0<<"\n";
1688 hisResY22->Fit(fres, "q");
1689 fresol<<"Y\t"<<fres->GetParameter(0)<<"\t"<<fres->GetParameter(1)<<"\t"<<fres->GetParameter(2)<<"\n";
1690 hisResZ22->Fit(fres, "q");
1691 fresol<<"Z\t"<<fres->GetParameter(0)<<"\t"<<fres->GetParameter(1)<<"\t"<<fres->GetParameter(2)<<"\n";
1693 TH1::AddDirectory(kFALSE);
1694 gSystem->ChangeDirectory("..");
1699 void AliTPCcalibTracks::FitRMSNew(char* pathName){
1701 // calculates different resulution-rms fits in Y and Z direction
1702 // the histograms are written to 'RMS_YZ.ps'
1703 // writes calculated resolution rms to 'rms.txt'
1704 // all files are stored in the directory pathName
1708 gSystem->MakeDirectory(pathName);
1709 gSystem->ChangeDirectory(pathName);
1711 TCanvas c; // valgrind 3 42,120 bytes in 405 blocks are still reachable 23,816 bytes in 229 blocks are still reachable
1713 if (fDebugLevel > -1) cout << "creating RMS_YZ.ps..." << endl;
1714 TPostScript *ps = new TPostScript("RMS_YZ.ps", 112);
1715 TF2 *frms = new TF2("fres","TMath::Sqrt([0]*[0]+[1]*[1]*x+[2]*[2]*y*y)",0,250,0,1);
1716 frms->SetParameter(0,0.02);
1717 frms->SetParameter(1,0.0054);
1718 frms->SetParameter(2,0.13);
1720 TH1::AddDirectory(kTRUE); // TH3F::FitSlicesZ() writes histograms into the current directory
1722 // create histogramw for Y-RMS
1723 TH3F * hisResY0 = (TH3F*)fRMSY->At(0);
1724 hisResY0->FitSlicesZ();
1725 TH2D * hisResY02 = (TH2D*)gDirectory->Get("RMS Y0_1");
1726 TH3F * hisResY1 = (TH3F*)fRMSY->At(1);
1727 hisResY1->FitSlicesZ();
1728 TH2D * hisResY12 = (TH2D*)gDirectory->Get("RMS Y1_1");
1729 TH3F * hisResY2 = (TH3F*)fRMSY->At(2);
1730 hisResY2->FitSlicesZ();
1731 TH2D * hisResY22 = (TH2D*)gDirectory->Get("RMS Y2_1");
1735 hisResY02->Fit(frms, "qn0");
1736 hisResY02->Draw("surf1");
1738 MakeDiff(hisResY02,frms)->Draw("surf1");
1740 // c.SaveAs("RMSYPad0.eps");
1743 hisResY12->Fit(frms, "qn0"); // valgrind several blocks possibly lost
1744 hisResY12->Draw("surf1");
1746 MakeDiff(hisResY12,frms)->Draw("surf1");
1748 // c.SaveAs("RMSYPad1.eps");
1751 hisResY22->Fit(frms, "qn0");
1752 hisResY22->Draw("surf1");
1754 MakeDiff(hisResY22,frms)->Draw("surf1");
1756 // c.SaveAs("RMSYPad2.eps");
1758 // create histogramw for Z-RMS
1759 TH3F * hisResZ0 = (TH3F*)fRMSZ->At(0);
1760 hisResZ0->FitSlicesZ();
1761 TH2D * hisResZ02 = (TH2D*)gDirectory->Get("RMS Z0_1");
1762 TH3F * hisResZ1 = (TH3F*)fRMSZ->At(1);
1763 hisResZ1->FitSlicesZ();
1764 TH2D * hisResZ12 = (TH2D*)gDirectory->Get("RMS Z1_1");
1765 TH3F * hisResZ2 = (TH3F*)fRMSZ->At(2);
1766 hisResZ2->FitSlicesZ();
1767 TH2D * hisResZ22 = (TH2D*)gDirectory->Get("RMS Z2_1");
1771 hisResZ02->Fit(frms, "qn0"); // valgrind
1772 hisResZ02->Draw("surf1");
1774 MakeDiff(hisResZ02,frms)->Draw("surf1");
1776 // c.SaveAs("RMSZPad0.eps");
1779 hisResZ12->Fit(frms, "qn0");
1780 hisResZ12->Draw("surf1");
1782 MakeDiff(hisResZ12,frms)->Draw("surf1");
1784 // c.SaveAs("RMSZPad1.eps");
1787 hisResZ22->Fit(frms, "qn0"); // valgrind 1 block possibly lost
1788 hisResZ22->Draw("surf1");
1790 MakeDiff(hisResZ22,frms)->Draw("surf1");
1792 // c.SaveAs("RMSZPad2.eps");
1794 // write calculated resoltuion rms to 'rms.txt'
1795 ofstream filerms("rms.txt");
1796 filerms<<"Pad 0.75 cm"<<"\n";
1797 hisResY02->Fit(frms, "qn0"); // valgrind 23 blocks indirectly lost
1798 filerms<<"Y\t"<<frms->GetParameter(0)<<"\t"<<frms->GetParameter(1)<<"\t"<<frms->GetParameter(2)<<"\n";
1799 hisResZ02->Fit(frms, "qn0"); // valgrind 23 blocks indirectly lost
1800 filerms<<"Z\t"<<frms->GetParameter(0)<<"\t"<<frms->GetParameter(1)<<"\t"<<frms->GetParameter(2)<<"\n";
1802 filerms<<"Pad 1.00 cm"<<1<<"\n";
1803 hisResY12->Fit(frms, "qn0"); // valgrind 3,256 bytes in 22 blocks are indirectly lost
1804 filerms<<"Y\t"<<frms->GetParameter(0)<<"\t"<<frms->GetParameter(1)<<"\t"<<frms->GetParameter(2)<<"\n";
1805 hisResZ12->Fit(frms, "qn0"); // valgrind 66,036 bytes in 3 blocks are still reachable
1806 filerms<<"Z\t"<<frms->GetParameter(0)<<"\t"<<frms->GetParameter(1)<<"\t"<<frms->GetParameter(2)<<"\n";
1808 filerms<<"Pad 1.50 cm"<<0<<"\n";
1809 hisResY22->Fit(frms, "qn0"); // valgrind 40,139 bytes in 11 blocks are still reachable 330,180 bytes in 15 blocks are possibly lost
1810 filerms<<"Y\t"<<frms->GetParameter(0)<<"\t"<<frms->GetParameter(1)<<"\t"<<frms->GetParameter(2)<<"\n";
1811 hisResZ22->Fit(frms, "qn0");
1812 filerms<<"Z\t"<<frms->GetParameter(0)<<"\t"<<frms->GetParameter(1)<<"\t"<<frms->GetParameter(2)<<"\n";
1814 TH1::AddDirectory(kFALSE);
1815 gSystem->ChangeDirectory("..");
1822 void AliTPCcalibTracks::MakeResPlotsQTree(Int_t minEntries, char* pathName){
1824 // Make tree with resolution parameters
1825 // the result is written to 'resol.root' in directory 'pathname'
1826 // file information are available in fileInfo
1827 // available variables in the tree 'Resol':
1828 // Entries: number of entries for this resolution point
1829 // nbins: number of bins that were accumulated
1830 // Dim: direction, Dim==0: y-direction, Dim==1: z-direction
1831 // Pad: padSize; short, medium and long
1832 // Length: pad length, 0.75, 1, 1.5
1833 // QMean: mean charge of current charge bin and its neighbours, Qmean<0: integrated spectra
1834 // Zc: center of middle bin in drift direction
1835 // Zm: mean dirftlength for accumulated Delta-Histograms
1836 // Zs: width of driftlength bin
1837 // AngleC: center of middle bin in Angle-Direction
1838 // AngleM: mean angle for accumulated Delta-Histograms
1839 // AngleS: width of Angle-bin
1840 // Resol: sigma for gaus fit through Delta-Histograms
1841 // Sigma: error of sigma for gaus fit through Delta Histograms
1842 // MeanR: mean of the Delta-Histogram
1843 // SigmaR: rms of the Delta-Histogram
1844 // RMSm: mean of the gaus fit through RMS-Histogram
1845 // RMS: sigma of the gaus fit through RMS-Histogram
1846 // RMSe0: error of mean of gaus fit in RMS-Histogram
1847 // RMSe1: error of sigma of gaus fit in RMS-Histogram
1850 if (fDebugLevel > -1) cout << " ***** this is MakeResPlotsQTree *****" << endl;
1851 if (fDebugLevel > -1) cout << " relax, the calculation will take a while..." << endl;
1853 gSystem->MakeDirectory(pathName);
1854 gSystem->ChangeDirectory(pathName);
1855 TString kFileName = "resol.root";
1856 TTreeSRedirector fTreeResol(kFileName.Data());
1858 TH3F *resArray[2][3][11];
1859 TH3F *rmsArray[2][3][11];
1861 // load histograms from fArrayQDY and fArrayQDZ
1862 // into resArray and rmsArray
1863 // that is all we need here
1864 for (Int_t idim = 0; idim < 2; idim++){
1865 for (Int_t ipad = 0; ipad < 3; ipad++){
1866 for (Int_t iq = 0; iq <= 10; iq++){
1867 rmsArray[idim][ipad][iq]=0;
1868 resArray[idim][ipad][iq]=0;
1869 Int_t bin = GetBin(iq,ipad);
1871 if (idim == 0) hresl = (TH3F*)fArrayQDY->At(bin);
1872 if (idim == 1) hresl = (TH3F*)fArrayQDZ->At(bin);
1873 if (!hresl) continue;
1874 resArray[idim][ipad][iq] = (TH3F*) hresl->Clone();
1875 resArray[idim][ipad][iq]->SetDirectory(0);
1876 TH3F * hreslRMS = 0;
1877 if (idim == 0) hreslRMS = (TH3F*)fArrayQRMSY->At(bin);
1878 if (idim == 1) hreslRMS = (TH3F*)fArrayQRMSZ->At(bin);
1879 if (!hreslRMS) continue;
1880 rmsArray[idim][ipad][iq] = (TH3F*) hreslRMS->Clone();
1881 rmsArray[idim][ipad][iq]->SetDirectory(0);
1885 if (fDebugLevel > -1) cout << "Histograms loaded, starting to proces..." << endl;
1887 //--------------------------------------------------------------------------------------------
1891 Double_t zMean, angleMean, zCenter, angleCenter;
1892 Double_t zSigma, angleSigma;
1893 TH1D *projectionRes = new TH1D("projectionRes", "projectionRes", 50, -1, 1);
1894 TH1D *projectionRms = new TH1D("projectionRms", "projectionRms", 50, -1, 1);
1895 TF1 *fitFunction = new TF1("fitFunction", "gaus");
1896 Float_t entriesQ = 0;
1897 Int_t loopCounter = 1;
1899 for (Int_t idim = 0; idim < 2; idim++){
1900 // Loop y-z corrdinate
1901 for (Int_t ipad = 0; ipad < 3; ipad++){
1903 for (Int_t iq = -1; iq < 10; iq++){
1905 if (fDebugLevel > -1)
1906 cout << "Loop-counter, this is loop " << loopCounter << " of 66, ("
1907 << (Int_t)((loopCounter)/66.*100) << "% done), "
1908 << "idim = " << idim << ", ipad = " << ipad << ", iq = " << iq << " \r" << std::flush;
1917 // integrated spectra
1918 for (Int_t iql = 0; iql < 10; iql++){
1919 Int_t bin = GetBin(iql,ipad);
1920 TH3F *hresl = resArray[idim][ipad][iql];
1921 TH3F *hrmsl = rmsArray[idim][ipad][iql];
1922 if (!hresl) continue;
1923 if (!hrmsl) continue;
1924 entriesQ += hresl->GetEntries();
1925 qMean += hresl->GetEntries() * GetQ(bin);
1927 hres = (TH3F*)hresl->Clone();
1928 hrms = (TH3F*)hrmsl->Clone();
1936 qMean *= -1.; // integral mean charge
1939 // loop over neighboured Q-bins
1940 // accumulate entries from neighboured Q-bins
1941 for (Int_t iql = iq - 1; iql <= iq + 1; iql++){
1942 if (iql < 0) continue;
1943 Int_t bin = GetBin(iql,ipad);
1944 TH3F * hresl = resArray[idim][ipad][iql];
1945 TH3F * hrmsl = rmsArray[idim][ipad][iql];
1946 if (!hresl) continue;
1947 if (!hrmsl) continue;
1948 entriesQ += hresl->GetEntries();
1949 qMean += hresl->GetEntries() * GetQ(bin);
1951 hres = (TH3F*) hresl->Clone();
1952 hrms = (TH3F*) hrmsl->Clone();
1962 TAxis *xAxisDriftLength = hres->GetXaxis(); // driftlength / z - axis
1963 TAxis *yAxisAngle = hres->GetYaxis(); // angle axis
1964 TAxis *zAxisDelta = hres->GetZaxis(); // delta axis
1965 TAxis *zAxisRms = hrms->GetZaxis(); // rms axis
1967 // loop over all angle bins
1968 for (Int_t ibinyAngle = 1; ibinyAngle <= yAxisAngle->GetNbins(); ibinyAngle++) {
1969 angleCenter = yAxisAngle->GetBinCenter(ibinyAngle);
1970 // loop over all driftlength bins
1971 for (Int_t ibinxDL = 1; ibinxDL <= xAxisDriftLength->GetNbins(); ibinxDL++) {
1972 zCenter = xAxisDriftLength->GetBinCenter(ibinxDL);
1973 zSigma = xAxisDriftLength->GetBinWidth(ibinxDL);
1974 angleSigma = yAxisAngle->GetBinWidth(ibinyAngle);
1975 zMean = zCenter; // changens, when more statistic is accumulated
1976 angleMean = angleCenter; // changens, when more statistic is accumulated
1978 // create 2 1D-Histograms, projectionRes and projectionRms
1979 // these histograms are delta histograms for given direction, padSize, chargeBin,
1980 // angleBin and driftLengthBin
1981 // later on they will be fitted with a gausian, its sigma is the resoltuion...
1982 sprintf(name,"%s, zCenter: %f, angleCenter: %f", hres->GetName(), zCenter, angleCenter);
1983 // TH1D * projectionRes = new TH1D(name, name, zAxisDelta->GetNbins(), zAxisDelta->GetXmin(), zAxisDelta->GetXmax());
1984 projectionRes->SetNameTitle(name, name);
1985 sprintf(name,"%s, zCenter: %f, angleCenter: %f", hrms->GetName(),zCenter,angleCenter);
1986 // TH1D * projectionRms = new TH1D(name, name, zAxisDelta->GetNbins(), zAxisRms->GetXmin(), zAxisRms->GetXmax());
1987 projectionRms->SetNameTitle(name, name);
1989 projectionRes->Reset();
1990 projectionRes->SetBins(zAxisDelta->GetNbins(), zAxisDelta->GetXmin(), zAxisDelta->GetXmax());
1991 projectionRms->Reset();
1992 projectionRms->SetBins(zAxisRms->GetNbins(), zAxisRms->GetXmin(), zAxisRms->GetXmax());
1993 projectionRes->SetDirectory(0);
1994 projectionRms->SetDirectory(0);
1996 Double_t entries = 0;
1997 Int_t nbins = 0; // counts, how many bins were accumulated
2002 // fill projectionRes and projectionRms for given dim, ipad and iq,
2003 // as well as for given angleBin and driftlengthBin
2004 // if this gives not enough statistic, include neighbourhood
2005 // (angle and driftlength) successifely
2006 for (Int_t dbin = 0; dbin <= 8; dbin++){ // delta-bins around centered angleBin and driftlengthBin
2007 for (Int_t dbiny2 = -1; dbiny2 <= 1; dbiny2++) { // delta-bins in angle direction
2008 for (Int_t dbinx2 = -3; dbinx2 <= 3; dbinx2++){ // delta-bins in driftlength direction
2009 if (TMath::Abs(dbinx2) + TMath::Abs(dbiny2) != dbin) continue; // add each bin only one time !
2010 Int_t binx2 = ibinxDL + dbinx2; // position variable in x (driftlength) direction
2011 Int_t biny2 = ibinyAngle + dbiny2; // position variable in y (angle) direction
2012 if (binx2 < 1 || biny2 < 1) continue; // don't go out of the histogram!
2013 if (binx2 >= xAxisDriftLength->GetNbins()) continue; // don't go out of the histogram!
2014 if (biny2 >= yAxisAngle->GetNbins()) continue; // don't go out of the histogram!
2015 nbins++; // count the number of accumulated bins
2016 // Fill resolution histo
2017 for (Int_t ibin3 = 1; ibin3 < zAxisDelta->GetNbins(); ibin3++) {
2018 // Int_t content = (Int_t)hres->GetBinContent(binx2, biny2, ibin3); // unused variable
2019 projectionRes->Fill(zAxisDelta->GetBinCenter(ibin3), hres->GetBinContent(binx2, biny2, ibin3));
2020 entries += hres->GetBinContent(binx2, biny2, ibin3);
2021 zMean += hres->GetBinContent(binx2, biny2, ibin3) * xAxisDriftLength->GetBinCenter(binx2);
2022 angleMean += hres->GetBinContent(binx2, biny2, ibin3) * yAxisAngle->GetBinCenter(biny2);
2025 for (Int_t ibin3 = 1; ibin3 < zAxisRms->GetNbins(); ibin3++) {
2026 projectionRms->Fill(zAxisRms->GetBinCenter(ibin3), hrms->GetBinContent(binx2, biny2, ibin3));
2029 if (entries > minEntries) break; // enough statistic accumulated
2031 if (entries > minEntries) break; // enough statistic accumulated
2033 if ( entries< minEntries) continue; // when it was absolutly impossible to get enough statistic, don't write this point into the resolution tree
2035 angleMean /= entries;
2037 if (entries > minEntries) {
2038 // when enough statistic is accumulated
2039 // fit Delta histograms with a gausian
2040 // of the gausian is the resolution (resol), its fit error is sigma
2041 // store also mean and RMS of the histogram
2042 Float_t xmin = projectionRes->GetMean() - 2. * projectionRes->GetRMS() - 0.2;
2043 Float_t xmax = projectionRes->GetMean() + 2. * projectionRes->GetRMS() + 0.2;
2045 // projectionRes->Fit("gaus", "q0", "", xmin, xmax);
2046 // Float_t resol = projectionRes->GetFunction("gaus")->GetParameter(2);
2047 // Float_t sigma = projectionRes->GetFunction("gaus")->GetParError(2);
2048 fitFunction->SetMaximum(xmax);
2049 fitFunction->SetMinimum(xmin);
2050 projectionRes->Fit("fitFunction", "qN0", "", xmin, xmax);
2051 Float_t resol = fitFunction->GetParameter(2);
2052 Float_t sigma = fitFunction->GetParError(2);
2054 Float_t meanR = projectionRes->GetMean();
2055 Float_t sigmaR = projectionRes->GetRMS();
2056 // fit also RMS histograms with a gausian
2057 // store mean and sigma of the gausian in rmsMean and rmsSigma
2058 // store also the fit errors in errorRMS and errorSigma
2059 xmin = projectionRms->GetMean() - 2. * projectionRes->GetRMS() - 0.2;
2060 xmax = projectionRms->GetMean() + 2. * projectionRes->GetRMS() + 0.2;
2062 // projectionRms->Fit("gaus","q0","",xmin,xmax);
2063 // Float_t rmsMean = projectionRms->GetFunction("gaus")->GetParameter(1);
2064 // Float_t rmsSigma = projectionRms->GetFunction("gaus")->GetParameter(2);
2065 // Float_t errorRMS = projectionRms->GetFunction("gaus")->GetParError(1);
2066 // Float_t errorSigma = projectionRms->GetFunction("gaus")->GetParError(2);
2067 projectionRms->Fit("fitFunction", "qN0", "", xmin, xmax);
2068 Float_t rmsMean = fitFunction->GetParameter(1);
2069 Float_t rmsSigma = fitFunction->GetParameter(2);
2070 Float_t errorRMS = fitFunction->GetParError(1);
2071 Float_t errorSigma = fitFunction->GetParError(2);
2073 Float_t length = 0.75;
2074 if (ipad == 1) length = 1;
2075 if (ipad == 2) length = 1.5;
2077 fTreeResol<<"Resol"<<
2078 "Entries="<<entries<< // number of entries for this resolution point
2079 "nbins="<<nbins<< // number of bins that were accumulated
2080 "Dim="<<idim<< // direction, Dim==0: y-direction, Dim==1: z-direction
2081 "Pad="<<ipad<< // padSize; short, medium and long
2082 "Length="<<length<< // pad length, 0.75, 1, 1.5
2083 "QMean="<<qMean<< // mean charge of current charge bin and its neighbours, Qmean<0: integrated spectra
2084 "Zc="<<zCenter<< // center of middle bin in drift direction
2085 "Zm="<<zMean<< // mean dirftlength for accumulated Delta-Histograms
2086 "Zs="<<zSigma<< // width of driftlength bin
2087 "AngleC="<<angleCenter<< // center of middle bin in Angle-Direction
2088 "AngleM="<<angleMean<< // mean angle for accumulated Delta-Histograms
2089 "AngleS="<<angleSigma<< // width of Angle-bin
2090 "Resol="<<resol<< // sigma for gaus fit through Delta-Histograms
2091 "Sigma="<<sigma<< // error of sigma for gaus fit through Delta Histograms
2092 "MeanR="<<meanR<< // mean of the Delta-Histogram
2093 "SigmaR="<<sigmaR<< // rms of the Delta-Histogram
2094 "RMSm="<<rmsMean<< // mean of the gaus fit through RMS-Histogram
2095 "RMSs="<<rmsSigma<< // sigma of the gaus fit through RMS-Histogram
2096 "RMSe0="<<errorRMS<< // error of mean of gaus fit in RMS-Histogram
2097 "RMSe1="<<errorSigma<< // error of sigma of gaus fit in RMS-Histogram
2099 if (fDebugLevel > 5) {
2100 projectionRes->SetDirectory(fTreeResol.GetFile());
2101 projectionRes->Write(projectionRes->GetName());
2102 projectionRes->SetDirectory(0);
2103 projectionRms->SetDirectory(fTreeResol.GetFile());
2104 projectionRms->Write(projectionRms->GetName());
2105 projectionRes->SetDirectory(0);
2107 } // if (projectionRes->GetSum() > minEntries)
2108 } // for (Int_t ibinxDL = 1; ibinxDL <= xAxisDriftLength->GetNbins(); ibinxDL++)
2109 } // for (Int_t ibinyAngle = 1; ibinyAngle <= yAxisAngle->GetNbins(); ibinyAngle++)
2114 delete projectionRes;
2115 delete projectionRms;
2117 // TFile resolFile(fTreeResol.GetFile());
2118 TObjString fileInfo(Form("Resolution tree, minEntries = %i", minEntries));
2119 fileInfo.Write("fileInfo");
2120 // resolFile.Close();
2121 // fTreeResol.GetFile()->Close();
2122 if (fDebugLevel > -1) cout << endl;
2123 if (fDebugLevel > -1) cout << "MakeResPlotsQTree done, results are in '"<< kFileName.Data() <<"'." << endl;
2124 gSystem->ChangeDirectory("..");
2132 Int_t AliTPCcalibTracks::fgLoopCounter = 0;
2133 void AliTPCcalibTracks::MakeResPlotsQTreeThread(Int_t minEntries, char* pathName){
2137 if (fDebugLevel > -1) cout << " ***** this is MakeResPlotsQTreeThread *****" << endl;
2138 if (fDebugLevel > -1) cout << " relax, the calculation will take a while..." << endl;
2139 if (fDebugLevel > -1) cout << " it will be done using 6 TThreads." << endl;
2141 gSystem->MakeDirectory(pathName);
2142 gSystem->ChangeDirectory(pathName);
2143 TString kFileName = "resol.root";
2144 // TTreeSRedirector *fTreeResol = new TTreeSRedirector(kFileName.Data());
2145 TTreeSRedirector fTreeResol(kFileName.Data());
2147 TH3F *resArray[2][3][11];
2148 TH3F *rmsArray[2][3][11];
2150 // load histograms from fArrayQDY and fArrayQDZ
2151 // into resArray and rmsArray
2152 // that is all we need here
2153 for (Int_t idim = 0; idim < 2; idim++){
2154 for (Int_t ipad = 0; ipad < 3; ipad++){
2155 for (Int_t iq = 0; iq <= 10; iq++){
2156 rmsArray[idim][ipad][iq]=0;
2157 resArray[idim][ipad][iq]=0;
2158 Int_t bin = GetBin(iq,ipad);
2160 if (idim == 0) hresl = (TH3F*)fArrayQDY->At(bin);
2161 if (idim == 1) hresl = (TH3F*)fArrayQDZ->At(bin);
2162 if (!hresl) continue;
2163 resArray[idim][ipad][iq] = (TH3F*) hresl->Clone();
2164 resArray[idim][ipad][iq]->SetDirectory(0);
2165 TH3F * hreslRMS = 0;
2166 if (idim == 0) hreslRMS = (TH3F*)fArrayQRMSY->At(bin);
2167 if (idim == 1) hreslRMS = (TH3F*)fArrayQRMSZ->At(bin);
2168 if (!hreslRMS) continue;
2169 rmsArray[idim][ipad][iq] = (TH3F*) hreslRMS->Clone();
2170 rmsArray[idim][ipad][iq]->SetDirectory(0);
2174 if (fDebugLevel > 4) cout << "Histograms loaded, starting to proces..." << endl;
2176 //--------------------------------------------------------------------------------------------
2178 Int_t threadCounter = 0;
2179 TObjArray *listOfThreads = new TObjArray();
2182 for (Int_t idim = 0; idim < 2; idim++){
2183 // Loop y-z corrdinate
2184 for (Int_t ipad = 0; ipad < 3; ipad++){
2187 // make list of variables for threads
2192 TthreadParameterStruct *structOfParameters = new TthreadParameterStruct();
2193 structOfParameters->logLevel = fDebugLevel;
2194 structOfParameters->minEntries = minEntries;
2195 structOfParameters->dim = idim;
2196 structOfParameters->pad = ipad;
2197 structOfParameters->resArray = &resArray;
2198 structOfParameters->rmsArray = &rmsArray;
2199 structOfParameters->fileName = &kFileName;
2200 structOfParameters->fTreeResol = &fTreeResol;
2201 TThread *thread = new TThread(Form("thread%i", threadCounter), (void(*) (void *))&MakeResPlotsQTreeThreadFunction, (void*)structOfParameters);
2202 listOfThreads->AddAt(thread, threadCounter);
2204 // gSystem->Sleep(500); // so that the threads do not run synchron
2206 // typedef TH3F test;
2208 // TH3F* (*testArray)[2][3][11];
2209 // testArray = &resArray;
2211 int (*ptr)[2][3][4];
2213 int (*ptr2)[2][3][4] = ptr;
2214 int j = (*ptr2)[1][1][1];
2221 // wait untill all threads are finished
2222 Bool_t allFinished = kFALSE;
2223 Int_t numberOfRunningThreads = 0;
2224 char c[4] = {'-', '\\', '|', '/'};
2226 while (!allFinished) {
2227 allFinished = kTRUE;
2228 numberOfRunningThreads = 0;
2229 for (Int_t i = 0; i < listOfThreads->GetEntriesFast(); i++) {
2230 if (listOfThreads->At(i) != 0x0 && ((TThread*)listOfThreads->At(i))->GetState() == TThread::kRunningState) {
2231 allFinished = kFALSE;
2232 numberOfRunningThreads++;
2235 cout << "Loop-counter, loop " << fgLoopCounter << " of 66 has just started, ("
2236 << (Int_t)((fgLoopCounter)/66.*100) << "% done), " << "number of running TThreads: "
2237 << numberOfRunningThreads << " \t" << c[iTime%4] << " \r" << std::flush;
2239 gSystem->Sleep(500);
2244 // Real time 0:01:31, CP time 44.690
2246 // version without sleep:
2247 // Real time 0:02:18, CP time 106.280
2249 // version with sleep, listOfThreads-Bug corrected:
2250 // Real time 0:01:35, CP time 0.800
2252 TObjString fileInfo(Form("Resolution tree, minEntries = %i", minEntries));
2253 fileInfo.Write("fileInfo");
2254 if (fDebugLevel > -1) cout << endl;
2255 if (fDebugLevel > -1) cout << "MakeResPlotsQTree done, results are in '"<< kFileName.Data() <<"'." << endl;
2256 gSystem->ChangeDirectory("..");
2260 TMutex* AliTPCcalibTracks::fgWriteMutex = new TMutex();
2261 TMutex* AliTPCcalibTracks::fgFitResMutex = new TMutex();
2262 TMutex* AliTPCcalibTracks::fgFitRmsMutex = new TMutex();
2263 void* AliTPCcalibTracks::MakeResPlotsQTreeThreadFunction(void* arg){
2268 TthreadParameterStruct *structOfParameters = (TthreadParameterStruct*)arg;
2269 Int_t fDebugLevel = structOfParameters->logLevel;
2270 Int_t minEntries = structOfParameters->minEntries;
2271 Int_t idim = structOfParameters->dim;
2272 Int_t ipad = structOfParameters->pad;
2274 TH3F* (*resArray)[2][3][11] = structOfParameters->resArray;
2275 TH3F* (*rmsArray)[2][3][11] = structOfParameters->rmsArray;
2277 TString *kFileName = structOfParameters->fileName;
2278 TTreeSRedirector *fTreeResol = structOfParameters->fTreeResol;
2280 if (fDebugLevel > 4) TThread::Printf("Thread started, dim = %i, pad = %i...", idim, ipad);
2284 sprintf(name, "dim%ipad%i", idim, ipad);
2285 TH1D *projectionRes = new TH1D(Form("projectionRes%s", name), "projectionRes", 50, -1, 1);
2286 TH1D *projectionRms = new TH1D(Form("projectionRms%s", name), "projectionRms", 50, -1, 1);
2287 char fitFuncName[200];
2288 sprintf(name, "fitFunctionDim%iPad%i", idim, ipad);
2289 TF1 *fitFunction = new TF1(fitFuncName, "gaus");
2292 Double_t zMean, angleMean, zCenter, angleCenter;
2293 Double_t zSigma, angleSigma;
2295 for (Int_t iq = -1; iq < 10; iq++){
2301 Float_t entriesQ = 0;
2303 if (fDebugLevel > 4) TThread::Printf(" start of iq-loop, dim = %i, pad = %i, iq = %i...", idim, ipad, iq);
2306 // integrated spectra
2307 for (Int_t iql = 0; iql < 10; iql++){
2308 Int_t bin = GetBin(iql,ipad);
2309 TH3F *hresl = (*resArray)[idim][ipad][iql];
2310 TH3F *hrmsl = (*rmsArray)[idim][ipad][iql];
2311 if (!hresl) continue;
2312 if (!hrmsl) continue;
2313 entriesQ += hresl->GetEntries();
2314 qMean += hresl->GetEntries() * GetQ(bin);
2317 hres = (TH3F*)hresl->Clone();
2318 hrms = (TH3F*)hrmsl->Clone();
2327 qMean *= -1.; // integral mean charge
2330 // loop over neighboured Q-bins
2331 // accumulate entries from neighboured Q-bins
2332 for (Int_t iql = iq - 1; iql <= iq + 1; iql++){
2333 if (iql < 0) continue;
2334 Int_t bin = GetBin(iql,ipad);
2335 TH3F * hresl = (*resArray)[idim][ipad][iql];
2336 TH3F * hrmsl = (*rmsArray)[idim][ipad][iql];
2337 if (!hresl) continue;
2338 if (!hrmsl) continue;
2339 entriesQ += hresl->GetEntries();
2340 qMean += hresl->GetEntries() * GetQ(bin);
2343 hres = (TH3F*) hresl->Clone();
2344 hrms = (TH3F*) hrmsl->Clone();
2354 TAxis *xAxisDriftLength = hres->GetXaxis(); // driftlength / z - axis
2355 TAxis *yAxisAngle = hres->GetYaxis(); // angle axis
2356 TAxis *zAxisDelta = hres->GetZaxis(); // delta axis
2357 TAxis *zAxisRms = hrms->GetZaxis(); // rms axis
2359 // loop over all angle bins
2360 for (Int_t ibinyAngle = 1; ibinyAngle <= yAxisAngle->GetNbins(); ibinyAngle++) {
2361 angleCenter = yAxisAngle->GetBinCenter(ibinyAngle);
2362 // loop over all driftlength bins
2363 for (Int_t ibinxDL = 1; ibinxDL <= xAxisDriftLength->GetNbins(); ibinxDL++) {
2364 zCenter = xAxisDriftLength->GetBinCenter(ibinxDL);
2365 zSigma = xAxisDriftLength->GetBinWidth(ibinxDL);
2366 angleSigma = yAxisAngle->GetBinWidth(ibinyAngle);
2367 zMean = zCenter; // changens, when more statistic is accumulated
2368 angleMean = angleCenter; // changens, when more statistic is accumulated
2370 // create 2 1D-Histograms, projectionRes and projectionRms
2371 // these histograms are delta histograms for given direction, padSize, chargeBin,
2372 // angleBin and driftLengthBin
2373 // later on they will be fitted with a gausian, its sigma is the resoltuion...
2374 sprintf(name,"%s, zCenter: %f, angleCenter: %f", hres->GetName(), zCenter, angleCenter);
2375 projectionRes->SetNameTitle(name, name);
2376 sprintf(name,"%s, zCenter: %f, angleCenter: %f", hrms->GetName(),zCenter,angleCenter);
2377 projectionRms->SetNameTitle(name, name);
2379 projectionRes->Reset();
2380 projectionRes->SetBins(zAxisDelta->GetNbins(), zAxisDelta->GetXmin(), zAxisDelta->GetXmax());
2381 projectionRms->Reset();
2382 projectionRms->SetBins(zAxisRms->GetNbins(), zAxisRms->GetXmin(), zAxisRms->GetXmax());
2383 projectionRes->SetDirectory(0);
2384 projectionRms->SetDirectory(0);
2386 Double_t entries = 0;
2387 Int_t nbins = 0; // counts, how many bins were accumulated
2392 // fill projectionRes and projectionRms for given dim, ipad and iq,
2393 // as well as for given angleBin and driftlengthBin
2394 // if this gives not enough statistic, include neighbourhood
2395 // (angle and driftlength) successifely
2396 for (Int_t dbin = 0; dbin <= 8; dbin++){ // delta-bins around centered angleBin and driftlengthBin
2397 for (Int_t dbiny2 = -1; dbiny2 <= 1; dbiny2++) { // delta-bins in angle direction
2398 for (Int_t dbinx2 = -3; dbinx2 <= 3; dbinx2++){ // delta-bins in driftlength direction
2399 if (TMath::Abs(dbinx2) + TMath::Abs(dbiny2) != dbin) continue; // add each bin only one time !
2400 Int_t binx2 = ibinxDL + dbinx2; // position variable in x (driftlength) direction
2401 Int_t biny2 = ibinyAngle + dbiny2; // position variable in y (angle) direction
2402 if (binx2 < 1 || biny2 < 1) continue; // don't go out of the histogram!
2403 if (binx2 >= xAxisDriftLength->GetNbins()) continue; // don't go out of the histogram!
2404 if (biny2 >= yAxisAngle->GetNbins()) continue; // don't go out of the histogram!
2405 nbins++; // count the number of accumulated bins
2406 // Fill resolution histo
2407 for (Int_t ibin3 = 1; ibin3 < zAxisDelta->GetNbins(); ibin3++) {
2408 // Int_t content = (Int_t)hres->GetBinContent(binx2, biny2, ibin3); // unused variable
2409 projectionRes->Fill(zAxisDelta->GetBinCenter(ibin3), hres->GetBinContent(binx2, biny2, ibin3));
2410 entries += hres->GetBinContent(binx2, biny2, ibin3);
2411 zMean += hres->GetBinContent(binx2, biny2, ibin3) * xAxisDriftLength->GetBinCenter(binx2);
2412 angleMean += hres->GetBinContent(binx2, biny2, ibin3) * yAxisAngle->GetBinCenter(biny2);
2415 for (Int_t ibin3 = 1; ibin3 < zAxisRms->GetNbins(); ibin3++) {
2416 projectionRms->Fill(zAxisRms->GetBinCenter(ibin3), hrms->GetBinContent(binx2, biny2, ibin3));
2419 if (entries > minEntries) break; // enough statistic accumulated
2421 if (entries > minEntries) break; // enough statistic accumulated
2423 if ( entries< minEntries) continue; // when it was absolutly impossible to get enough statistic, don't write this point into the resolution tree
2425 angleMean /= entries;
2427 if (entries > minEntries) {
2428 // when enough statistic is accumulated
2429 // fit Delta histograms with a gausian
2430 // of the gausian is the resolution (resol), its fit error is sigma
2431 // store also mean and RMS of the histogram
2432 Float_t xmin = projectionRes->GetMean() - 2. * projectionRes->GetRMS() - 0.2;
2433 Float_t xmax = projectionRes->GetMean() + 2. * projectionRes->GetRMS() + 0.2;
2434 fitFunction->SetMaximum(xmax);
2435 fitFunction->SetMinimum(xmin);
2437 // fgFitResMutex->Lock();
2438 projectionRes->Fit(fitFuncName, "qN0", "", xmin, xmax);
2439 // fgFitResMutex->UnLock();
2441 Float_t resol = fitFunction->GetParameter(2);
2442 Float_t sigma = fitFunction->GetParError(2);
2443 Float_t meanR = projectionRes->GetMean();
2444 Float_t sigmaR = projectionRes->GetRMS();
2445 // fit also RMS histograms with a gausian
2446 // store mean and sigma of the gausian in rmsMean and rmsSigma
2447 // store also the fit errors in errorRMS and errorSigma
2448 xmin = projectionRms->GetMean() - 2. * projectionRes->GetRMS() - 0.2;
2449 xmax = projectionRms->GetMean() + 2. * projectionRes->GetRMS() + 0.2;
2450 fitFunction->SetMaximum(xmax);
2451 fitFunction->SetMinimum(xmin);
2453 projectionRms->Fit(fitFuncName, "qN0", "", xmin, xmax);
2455 Float_t rmsMean = fitFunction->GetParameter(1);
2456 Float_t rmsSigma = fitFunction->GetParameter(2);
2457 Float_t errorRMS = fitFunction->GetParError(1);
2458 Float_t errorSigma = fitFunction->GetParError(2);
2459 Float_t length = 0.75;
2460 if (ipad == 1) length = 1;
2461 if (ipad == 2) length = 1.5;
2463 fgWriteMutex->Lock();
2464 (*fTreeResol)<<"Resol"<<
2465 "Entries="<<entries<< // number of entries for this resolution point
2466 "nbins="<<nbins<< // number of bins that were accumulated
2467 "Dim="<<idim<< // direction, Dim==0: y-direction, Dim==1: z-direction
2468 "Pad="<<ipad<< // padSize; short, medium and long
2469 "Length="<<length<< // pad length, 0.75, 1, 1.5
2470 "QMean="<<qMean<< // mean charge of current charge bin and its neighbours, Qmean<0: integrated spectra
2471 "Zc="<<zCenter<< // center of middle bin in drift direction
2472 "Zm="<<zMean<< // mean dirftlength for accumulated Delta-Histograms
2473 "Zs="<<zSigma<< // width of driftlength bin
2474 "AngleC="<<angleCenter<< // center of middle bin in Angle-Direction
2475 "AngleM="<<angleMean<< // mean angle for accumulated Delta-Histograms
2476 "AngleS="<<angleSigma<< // width of Angle-bin
2477 "Resol="<<resol<< // sigma for gaus fit through Delta-Histograms
2478 "Sigma="<<sigma<< // error of sigma for gaus fit through Delta Histograms
2479 "MeanR="<<meanR<< // mean of the Delta-Histogram
2480 "SigmaR="<<sigmaR<< // rms of the Delta-Histogram
2481 "RMSm="<<rmsMean<< // mean of the gaus fit through RMS-Histogram
2482 "RMSs="<<rmsSigma<< // sigma of the gaus fit through RMS-Histogram
2483 "RMSe0="<<errorRMS<< // error of mean of gaus fit in RMS-Histogram
2484 "RMSe1="<<errorSigma<< // error of sigma of gaus fit in RMS-Histogram
2486 if (fDebugLevel > 5) {
2487 projectionRes->SetDirectory(fTreeResol->GetFile());
2488 projectionRes->Write(projectionRes->GetName());
2489 projectionRes->SetDirectory(0);
2490 projectionRms->SetDirectory(fTreeResol->GetFile());
2491 projectionRms->Write(projectionRms->GetName());
2492 projectionRes->SetDirectory(0);
2494 fgWriteMutex->UnLock();
2495 } // if (projectionRes->GetSum() > minEntries)
2496 } // for (Int_t ibinxDL = 1; ibinxDL <= xAxisDriftLength->GetNbins(); ibinxDL++)
2497 } // for (Int_t ibinyAngle = 1; ibinyAngle <= yAxisAngle->GetNbins(); ibinyAngle++)
2500 delete projectionRes;
2501 delete projectionRms;
2502 if (fDebugLevel > 4) TThread::Printf("Ende, dim = %i, pad = %i", idim, ipad);
2509 Long64_t AliTPCcalibTracks::Merge(TCollection *collectionList) {
2511 // function to merge several AliTPCcalibTracks objects after PROOF calculation
2512 // The object's histograms are merged via their merge functions
2513 // Be carefull: histograms are linked to a file, switch this off by TH1::AddDirectory(kFALSE) !!!
2516 if (fDebugLevel > 0) cout << " ***** this is AliTPCcalibTracks::Merge(TCollection *collectionList) *****"<< endl;
2517 if (!collectionList) return 0;
2518 if (collectionList->IsEmpty()) return -1;
2520 if (fDebugLevel > 1) cout << "the collectionList contains " << collectionList->GetEntries() << " entries." << endl; // REMOVE THIS LINE!!!!!!!!!!!!!!!!!1
2521 if (fDebugLevel > 5) cout << " the list in the merge-function looks as follows: " << endl;
2522 collectionList->Print();
2524 // create a list for each data member
2525 TList* deltaYList = new TList;
2526 TList* deltaZList = new TList;
2527 TList* arrayAmpRowList = new TList;
2528 TList* rejectedTracksList = new TList;
2529 TList* hclusList = new TList;
2530 TList* clusterCutHistoList = new TList;
2531 TList* arrayAmpList = new TList;
2532 TList* arrayQDYList = new TList;
2533 TList* arrayQDZList = new TList;
2534 TList* arrayQRMSYList = new TList;
2535 TList* arrayQRMSZList = new TList;
2536 TList* arrayChargeVsDriftlengthList = new TList;
2537 TList* calPadRegionChargeVsDriftlengthList = new TList;
2538 TList* hclusterPerPadrowList = new TList;
2539 TList* hclusterPerPadrowRawList = new TList;
2540 TList* resolYList = new TList;
2541 TList* resolZList = new TList;
2542 TList* rMSYList = new TList;
2543 TList* rMSZList = new TList;
2545 // TList* nRowsList = new TList;
2546 // TList* nSectList = new TList;
2547 // TList* fileNoList = new TList;
2549 TIterator *listIterator = collectionList->MakeIterator();
2550 AliTPCcalibTracks *calibTracks = 0;
2551 if (fDebugLevel > 1) cout << "start to iterate, filling lists" << endl;
2553 while ( (calibTracks = (AliTPCcalibTracks*)listIterator->Next()) ){
2554 // loop over all entries in the collectionList and get dataMembers into lists
2555 if (!calibTracks) continue;
2557 deltaYList->Add( calibTracks->GetfDeltaY() );
2558 deltaZList->Add( calibTracks->GetfDeltaZ() );
2559 arrayAmpRowList->Add(calibTracks->GetfArrayAmpRow());
2560 arrayAmpList->Add(calibTracks->GetfArrayAmp());
2561 arrayQDYList->Add(calibTracks->GetfArrayQDY());
2562 arrayQDZList->Add(calibTracks->GetfArrayQDZ());
2563 arrayQRMSYList->Add(calibTracks->GetfArrayQRMSY());
2564 arrayQRMSZList->Add(calibTracks->GetfArrayQRMSZ());
2565 resolYList->Add(calibTracks->GetfResolY());
2566 resolZList->Add(calibTracks->GetfResolZ());
2567 rMSYList->Add(calibTracks->GetfRMSY());
2568 rMSZList->Add(calibTracks->GetfRMSZ());
2569 arrayChargeVsDriftlengthList->Add(calibTracks->GetfArrayChargeVsDriftlength());
2570 calPadRegionChargeVsDriftlengthList->Add(calibTracks->GetCalPadRegionchargeVsDriftlength());
2571 hclusList->Add(calibTracks->GetfHclus());
2572 rejectedTracksList->Add(calibTracks->GetfRejectedTracksHisto());
2573 clusterCutHistoList->Add(calibTracks->GetfClusterCutHisto());
2574 hclusterPerPadrowList->Add(calibTracks->GetfHclusterPerPadrow());
2575 hclusterPerPadrowRawList->Add(calibTracks->GetfHclusterPerPadrowRaw());
2576 fCalPadClusterPerPad->Add(calibTracks->GetfCalPadClusterPerPad());
2577 fCalPadClusterPerPadRaw->Add(calibTracks->GetfCalPadClusterPerPadRaw());
2579 if (fDebugLevel > 5) cout << "filling lists, object " << counter << " added." << endl;
2583 // merge data members
2584 if (fDebugLevel > 0) cout << "histogram's merge-functins are called... " << endl;
2585 fDeltaY->Merge(deltaYList);
2586 fDeltaZ->Merge(deltaZList);
2587 fHclus->Merge(hclusList);
2588 fClusterCutHisto->Merge(clusterCutHistoList);
2589 fRejectedTracksHisto->Merge(rejectedTracksList);
2590 fHclusterPerPadrow->Merge(hclusterPerPadrowList);
2591 fHclusterPerPadrowRaw->Merge(hclusterPerPadrowRawList);
2593 TObjArray* objarray = 0;
2595 TList* histList = 0;
2596 TIterator *objListIterator = 0;
2598 if (fDebugLevel > 0) cout << "merging fArrayAmpRows..." << endl;
2599 // merge fArrayAmpRows
2600 for (Int_t i = 0; i < fArrayAmpRow->GetEntriesFast(); i++ ) { // loop over data member, i<72
2601 objListIterator = arrayAmpRowList->MakeIterator();
2602 histList = new TList;
2603 while (( objarray = (TObjArray*)objListIterator->Next() )) {
2604 // loop over arrayAmpRowList, get TObjArray, get object at position i, cast it into TProfile
2605 if (!objarray) continue;
2606 hist = (TProfile*)(objarray->At(i));
2607 histList->Add(hist);
2609 ((TProfile*)(fArrayAmpRow->At(i)))->Merge(histList);
2611 delete objListIterator;
2614 if (fDebugLevel > 0) cout << "merging fArrayAmps..." << endl;
2616 for (Int_t i = 0; i < fArrayAmp->GetEntriesFast(); i++ ) { // loop over data member, i<72
2617 TIterator *objListIterator = arrayAmpList->MakeIterator();
2618 histList = new TList;
2619 while (( objarray = (TObjArray*)objListIterator->Next() )) {
2620 // loop over arrayAmpList, get TObjArray, get object at position i, cast it into TH1F
2621 if (!objarray) continue;
2622 hist = (TH1F*)(objarray->At(i));
2623 histList->Add(hist);
2625 ((TH1F*)(fArrayAmp->At(i)))->Merge(histList);
2627 delete objListIterator;
2630 if (fDebugLevel > 0) cout << "merging fArrayQDY..." << endl;
2632 for (Int_t i = 0; i < fArrayQDY->GetEntriesFast(); i++) { // loop over data member, i < 300
2633 objListIterator = arrayQDYList->MakeIterator();
2634 histList = new TList;
2635 while (( objarray = (TObjArray*)objListIterator->Next() )) {
2636 // loop over arrayQDYList, get TObjArray, get object at position i, cast it into TH3F
2637 if (!objarray) continue;
2638 hist = (TH3F*)(objarray->At(i));
2639 histList->Add(hist);
2641 ((TH3F*)(fArrayQDY->At(i)))->Merge(histList);
2643 delete objListIterator;
2646 if (fDebugLevel > 0) cout << "merging fArrayQDZ..." << endl;
2648 for (Int_t i = 0; i < fArrayQDZ->GetEntriesFast(); i++) { // loop over data member, i < 300
2649 objListIterator = arrayQDZList->MakeIterator();
2650 histList = new TList;
2651 while (( objarray = (TObjArray*)objListIterator->Next() )) {
2652 // loop over arrayQDZList, get TObjArray, get object at position i, cast it into TH3F
2653 if (!objarray) continue;
2654 hist = (TH3F*)(objarray->At(i));
2655 histList->Add(hist);
2657 ((TH3F*)(fArrayQDZ->At(i)))->Merge(histList);
2659 delete objListIterator;
2662 if (fDebugLevel > 0) cout << "merging fArrayQRMSY..." << endl;
2663 // merge fArrayQRMSY
2664 for (Int_t i = 0; i < fArrayQRMSY->GetEntriesFast(); i++) { // loop over data member, i < 300
2665 objListIterator = arrayQRMSYList->MakeIterator();
2666 histList = new TList;
2667 while (( objarray = (TObjArray*)objListIterator->Next() )) {
2668 // loop over arrayQDZList, get TObjArray, get object at position i, cast it into TH3F
2669 if (!objarray) continue;
2670 hist = (TH3F*)(objarray->At(i));
2671 histList->Add(hist);
2673 ((TH3F*)(fArrayQRMSY->At(i)))->Merge(histList);
2675 delete objListIterator;
2678 if (fDebugLevel > 0) cout << "merging fArrayQRMSZ..." << endl;
2679 // merge fArrayQRMSZ
2680 for (Int_t i = 0; i < fArrayQRMSZ->GetEntriesFast(); i++) { // loop over data member, i < 300
2681 objListIterator = arrayQRMSZList->MakeIterator();
2682 histList = new TList;
2683 while (( objarray = (TObjArray*)objListIterator->Next() )) {
2684 // loop over arrayQDZList, get TObjArray, get object at position i, cast it into TH3F
2685 if (!objarray) continue;
2686 hist = (TH3F*)(objarray->At(i));
2687 histList->Add(hist);
2689 ((TH3F*)(fArrayQRMSZ->At(i)))->Merge(histList);
2691 delete objListIterator;
2694 if (fDebugLevel > 0) cout << "merging fArrayChargeVsDriftlength..." << endl;
2695 // merge fArrayChargeVsDriftlength
2696 for (Int_t i = 0; i < fArrayChargeVsDriftlength->GetEntriesFast(); i++) { // loop over data member, i < 300
2697 objListIterator = arrayChargeVsDriftlengthList->MakeIterator();
2698 histList = new TList;
2699 while (( objarray = (TObjArray*)objListIterator->Next() )) {
2700 // loop over arrayQDZList, get TObjArray, get object at position i, cast it into TProfile
2701 if (!objarray) continue;
2702 hist = (TProfile*)(objarray->At(i));
2703 histList->Add(hist);
2705 ((TProfile*)(fArrayChargeVsDriftlength->At(i)))->Merge(histList);
2707 delete objListIterator;
2710 if (fDebugLevel > 0) cout << "merging fcalPadRegionChargeVsDriftlength..." << endl;
2711 // merge fcalPadRegionChargeVsDriftlength
2712 AliTPCCalPadRegion *cpr = 0x0;
2715 TIterator *regionIterator = fcalPadRegionChargeVsDriftlength->MakeIterator();
2716 while (hist = (TProfile*)regionIterator->Next()) {
2717 // loop over all calPadRegion's in destination calibTracks object
2718 objListIterator = calPadRegionChargeVsDriftlengthList->MakeIterator();
2719 while (( cpr = (AliTPCCalPadRegion*)objListIterator->Next() )) {
2726 for (UInt_t isec = 0; isec < 36; isec++) {
2727 for (UInt_t padSize = 0; padSize < 3; padSize++){
2728 objListIterator = calPadRegionChargeVsDriftlengthList->MakeIterator();
2729 histList = new TList;
2730 while (( cpr = (AliTPCCalPadRegion*)objListIterator->Next() )) {
2731 // loop over calPadRegionChargeVsDriftlengthList, get AliTPCCalPadRegion, get object
2733 hist = (TProfile*)cpr->GetObject(isec, padSize);
2734 histList->Add(hist);
2736 ((TProfile*)(fcalPadRegionChargeVsDriftlength->GetObject(isec, padSize)))->Merge(histList);
2738 delete objListIterator;
2745 if (fDebugLevel > 0) cout << "starting to merge the rest: fResolY, fResolZ , fRMSY, fRMSZ..." << endl;
2747 for (Int_t i = 0; i < fResolY->GetEntriesFast(); i++) { // loop over data member, i < 3
2748 objListIterator = resolYList->MakeIterator();
2749 histList = new TList;
2750 while (( objarray = (TObjArray*)objListIterator->Next() )) {
2751 // loop over arrayQDZList, get TObjArray, get object at position i, cast it into TH3F
2752 if (!objarray) continue;
2753 hist = (TH3F*)(objarray->At(i));
2754 histList->Add(hist);
2756 ((TH3F*)(fResolY->At(i)))->Merge(histList);
2758 delete objListIterator;
2762 for (Int_t i = 0; i < fResolZ->GetEntriesFast(); i++) { // loop over data member, i < 3
2763 objListIterator = resolZList->MakeIterator();
2764 histList = new TList;
2765 while (( objarray = (TObjArray*)objListIterator->Next() )) {
2766 // loop over arrayQDZList, get TObjArray, get object at position i, cast it into TH3F
2767 if (!objarray) continue;
2768 hist = (TH3F*)(objarray->At(i));
2769 histList->Add(hist);
2771 ((TH3F*)(fResolZ->At(i)))->Merge(histList);
2773 delete objListIterator;
2777 for (Int_t i = 0; i < fRMSY->GetEntriesFast(); i++) { // loop over data member, i < 3
2778 objListIterator = rMSYList->MakeIterator();
2779 histList = new TList;
2780 while (( objarray = (TObjArray*)objListIterator->Next() )) {
2781 // loop over arrayQDZList, get TObjArray, get object at position i, cast it into TH3F
2782 if (!objarray) continue;
2783 hist = (TH3F*)(objarray->At(i));
2784 histList->Add(hist);
2786 ((TH3F*)(fRMSY->At(i)))->Merge(histList);
2788 delete objListIterator;
2792 for (Int_t i = 0; i < fRMSZ->GetEntriesFast(); i++) { // loop over data member, i < 3
2793 objListIterator = rMSZList->MakeIterator();
2794 histList = new TList;
2795 while (( objarray = (TObjArray*)objListIterator->Next() )) {
2796 // loop over arrayQDZList, get TObjArray, get object at position i, cast it into TH3F
2797 if (!objarray) continue;
2798 hist = (TH3F*)(objarray->At(i));
2799 histList->Add(hist);
2801 ((TH3F*)(fRMSZ->At(i)))->Merge(histList);
2803 delete objListIterator;
2808 delete arrayAmpRowList;
2809 delete arrayAmpList;
2810 delete arrayQDYList;
2811 delete arrayQDZList;
2812 delete arrayQRMSYList;
2813 delete arrayQRMSZList;
2818 // delete nRowsList;
2819 // delete nSectList;
2820 // delete fileNoList;
2821 delete listIterator;
2823 if (fDebugLevel > 0) cout << "merging done!" << endl;
2829 AliTPCcalibTracks* AliTPCcalibTracks::TestMerge(AliTPCcalibTracks *ct, AliTPCClusterParam *clusterParam, Int_t nCalTracks){
2831 // function to test AliTPCcalibTrack::Merge:
2832 // in the file 'f' is a AliTPCcalibTrack object with name "calibTracks"
2833 // this object is appended 'nCalTracks' times to a TList
2834 // A new AliTPCcalibTrack object is created which merges the list
2835 // this object is returned
2838 // .L AliTPCcalibTracks.cxx+g
2840 TFile f("Output.root");
2841 AliTPCcalibTracks* calTracks = (AliTPCcalibTracks*)f.Get("calibTracks");
2843 TFile clusterParamFile("/u/lbozyk/calibration/workdir/calibTracks/TPCClusterParam.root");
2844 AliTPCClusterParam *clusterParam = (AliTPCClusterParam *) clusterParamFile.Get("Param");
2845 clusterParamFile.Close();
2847 AliTPCcalibTracks::TestMerge(calTracks, clusterParam);
2849 TList *list = new TList();
2850 if (ct == 0 || clusterParam == 0) return 0;
2851 cout << "making list with " << nCalTracks << " AliTPCcalibTrack objects" << endl;
2852 for (Int_t i = 0; i < nCalTracks; i++) {
2853 if (i%10==0) cout << "Adding element " << i << " of " << nCalTracks << endl;
2854 list->Add(new AliTPCcalibTracks(*ct));
2857 // only for check at the end
2858 AliTPCcalibTracks* cal1 = new AliTPCcalibTracks(*ct);
2859 Double_t cal1Entries = ((TH1F*)cal1->GetfArrayAmpRow()->At(5))->GetEntries();
2860 // Double_t cal1Entries = 5; //((TH1F*)ct->GetfArrayAmpRow()->At(5))->GetEntries();
2862 cout << "The list contains " << list->GetEntries() << " entries. " << endl;
2865 AliTPCcalibTracksCuts *cuts = new AliTPCcalibTracksCuts(20, 0.4, 0.5, 0.13, 0.018);
2866 AliTPCcalibTracks* cal = new AliTPCcalibTracks("calTracksMerged", "calTracksMerged", clusterParam, cuts, 5);
2869 cout << "cal->GetfArrayAmpRow()->At(5)->Print():" << endl;
2870 cal->GetfArrayAmpRow()->At(5)->Print();
2871 Double_t calEntries = ((TH1F*)cal->GetfArrayAmpRow()->At(5))->GetEntries();
2873 cout << "cal1->GetfArrayAmpRow()->At(5))->GetEntries() = " << cal1Entries << endl;
2874 cout << " cal->GetfArrayAmpRow()->At(5))->GetEntries() = " << calEntries << endl;
2875 printf("That means there were %f / %f = %f AliTPCcalibTracks-Objects merged. \n",
2876 calEntries, cal1Entries, ((Double_t)calEntries/cal1Entries));