From cc80f89ead2e03e663aa5c2e2330945097ba3ffd Mon Sep 17 00:00:00 2001 From: kowal2 Date: Mon, 17 Apr 2000 09:42:27 +0000 Subject: [PATCH] removed obsolete AliTPCDigitsDisplay.C --- TPC/AliArrayI.cxx | 71 ++ TPC/AliArrayI.h | 23 + TPC/AliArrayS.cxx | 75 ++ TPC/AliArrayS.h | 22 + TPC/AliCluster.cxx | 61 ++ TPC/AliCluster.h | 53 ++ TPC/AliClusterFinder.cxx | 899 +++++++++++++++++++ TPC/AliClusterFinder.h | 314 +++++++ TPC/AliClusters.cxx | 173 ++++ TPC/AliClusters.h | 37 + TPC/AliClustersArray.cxx | 101 +++ TPC/AliClustersArray.h | 31 + TPC/AliDetectorParam.cxx | 73 ++ TPC/AliDetectorParam.h | 49 + TPC/AliDigits.cxx | 413 +++++++++ TPC/AliDigits.h | 98 ++ TPC/AliDigitsArray.cxx | 71 ++ TPC/AliDigitsArray.h | 25 + TPC/AliH2F.cxx | 387 ++++++++ TPC/AliH2F.h | 63 ++ TPC/AliSegmentArray.cxx | 342 +++++++ TPC/AliSegmentArray.h | 78 ++ TPC/AliSegmentID.cxx | 38 + TPC/AliSegmentID.h | 27 + TPC/AliSimDigits.cxx | 394 ++++++++ TPC/AliSimDigits.h | 75 ++ TPC/AliTPC.cxx | 1680 ++++++++++++++--------------------- TPC/AliTPC.h | 115 +-- TPC/AliTPCCluster.cxx | 175 ++++ TPC/AliTPCCluster.h | 60 ++ TPC/AliTPCClustersArray.cxx | 178 ++++ TPC/AliTPCClustersArray.h | 49 + TPC/AliTPCClustersRow.cxx | 54 ++ TPC/AliTPCClustersRow.h | 32 + TPC/AliTPCD.cxx | 158 ---- TPC/AliTPCD.h | 74 -- TPC/AliTPCDigitDisplay.C | 64 ++ TPC/AliTPCDigitsArray.cxx | 169 ++++ TPC/AliTPCDigitsArray.h | 51 ++ TPC/AliTPCDigitsDisplay.C | 53 -- TPC/AliTPCDigitsH.cxx | 644 ++++++++++++++ TPC/AliTPCDigitsH.h | 114 +++ TPC/AliTPCHits2Digits.C | 35 +- TPC/AliTPCPRF2D.cxx | 361 +++++--- TPC/AliTPCPRF2D.h | 88 +- TPC/AliTPCParam.cxx | 894 +++++++++++-------- TPC/AliTPCParam.h | 750 ++++++++++++---- TPC/AliTPCParamCR.cxx | 251 ++++++ TPC/AliTPCParamCR.h | 51 ++ TPC/AliTPCParamSR.cxx | 399 +++++++++ TPC/AliTPCParamSR.h | 73 ++ TPC/AliTPCRF1D.cxx | 66 +- TPC/AliTPCRF1D.h | 4 +- TPC/AliTPCSecGeo.h | 44 - TPC/AliTPCTestClustering.C | 13 +- TPC/AliTPCTestTracking.C | 387 ++++---- TPC/AliTPCprf2d.root | Bin 4206 -> 0 bytes TPC/AliTPCv0.cxx | 37 +- TPC/AliTPCv0.h | 1 + TPC/AliTPCv1.cxx | 85 +- TPC/AliTPCv1.h | 1 + TPC/AliTPCv2.cxx | 75 +- TPC/AliTPCv2.h | 1 + TPC/AliTPCv3.cxx | 46 +- TPC/AliTPCv3.h | 1 + TPC/CLFinderDemo.C | 41 + TPC/ClassTree.C | 204 +++++ TPC/Makefile | 33 +- TPC/ParamTest.C | 15 + TPC/TPCAnal.C | 542 +++++++++++ TPC/TPCConfig.C | 80 ++ TPC/TPCDigits2Clusters.C | 220 +++++ TPC/TPCHits2ExactClusters.C | 73 ++ TPC/TPCLinkDef.h | 27 +- TPC/TPCtest.C | 27 + TPC/TestAliTPCDigitsArray.C | 74 ++ TPC/TestSimDigits.C | 34 + TPC/diganal.C | 664 ++++++++++++++ TPC/template.C | 48 + TPC/template.cxx | 126 +++ 80 files changed, 11129 insertions(+), 2405 deletions(-) create mode 100644 TPC/AliArrayI.cxx create mode 100644 TPC/AliArrayI.h create mode 100644 TPC/AliArrayS.cxx create mode 100644 TPC/AliArrayS.h create mode 100644 TPC/AliCluster.cxx create mode 100644 TPC/AliCluster.h create mode 100644 TPC/AliClusterFinder.cxx create mode 100644 TPC/AliClusterFinder.h create mode 100644 TPC/AliClusters.cxx create mode 100644 TPC/AliClusters.h create mode 100644 TPC/AliClustersArray.cxx create mode 100644 TPC/AliClustersArray.h create mode 100644 TPC/AliDetectorParam.cxx create mode 100644 TPC/AliDetectorParam.h create mode 100644 TPC/AliDigits.cxx create mode 100644 TPC/AliDigits.h create mode 100644 TPC/AliDigitsArray.cxx create mode 100644 TPC/AliDigitsArray.h create mode 100644 TPC/AliH2F.cxx create mode 100644 TPC/AliH2F.h create mode 100644 TPC/AliSegmentArray.cxx create mode 100644 TPC/AliSegmentArray.h create mode 100644 TPC/AliSegmentID.cxx create mode 100644 TPC/AliSegmentID.h create mode 100644 TPC/AliSimDigits.cxx create mode 100644 TPC/AliSimDigits.h create mode 100644 TPC/AliTPCCluster.cxx create mode 100644 TPC/AliTPCCluster.h create mode 100644 TPC/AliTPCClustersArray.cxx create mode 100644 TPC/AliTPCClustersArray.h create mode 100644 TPC/AliTPCClustersRow.cxx create mode 100644 TPC/AliTPCClustersRow.h delete mode 100644 TPC/AliTPCD.cxx delete mode 100644 TPC/AliTPCD.h create mode 100644 TPC/AliTPCDigitDisplay.C create mode 100644 TPC/AliTPCDigitsArray.cxx create mode 100644 TPC/AliTPCDigitsArray.h delete mode 100644 TPC/AliTPCDigitsDisplay.C create mode 100644 TPC/AliTPCDigitsH.cxx create mode 100644 TPC/AliTPCDigitsH.h create mode 100644 TPC/AliTPCParamCR.cxx create mode 100644 TPC/AliTPCParamCR.h create mode 100644 TPC/AliTPCParamSR.cxx create mode 100644 TPC/AliTPCParamSR.h delete mode 100644 TPC/AliTPCSecGeo.h delete mode 100644 TPC/AliTPCprf2d.root create mode 100644 TPC/CLFinderDemo.C create mode 100644 TPC/ClassTree.C create mode 100644 TPC/ParamTest.C create mode 100644 TPC/TPCAnal.C create mode 100644 TPC/TPCConfig.C create mode 100644 TPC/TPCDigits2Clusters.C create mode 100644 TPC/TPCHits2ExactClusters.C create mode 100644 TPC/TPCtest.C create mode 100644 TPC/TestAliTPCDigitsArray.C create mode 100644 TPC/TestSimDigits.C create mode 100644 TPC/diganal.C create mode 100644 TPC/template.C create mode 100644 TPC/template.cxx diff --git a/TPC/AliArrayI.cxx b/TPC/AliArrayI.cxx new file mode 100644 index 00000000000..9d0ec86a570 --- /dev/null +++ b/TPC/AliArrayI.cxx @@ -0,0 +1,71 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:32:37 kowal2 + +"ROOT"-based class with some extra functionality + +*/ + +/////////////////////////////////////////////////////////////////////// +// Added additional functionality to original TArrayI // +// multiple inheritance from TObject to be possible use automatic // +// branch mechanism for tree +// function Expand to be possible expand array without deleting // +// array contents // +// // +// Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk // +// // +/////////////////////////////////////////////////////////////////////// +#include "AliArrayI.h" +ClassImp(AliArrayI) +void AliArrayI::Expand(Int_t n) +{ + // + // Set array size of TArrayI object to n integers and copy old array + // If n<0 leave array unchanged. + // user are responsible for appopiate size of array + // + if (n < 0) return; + fArray = (Int_t*) TStorage::ReAlloc(fArray, n * sizeof(Int_t),fN * sizeof(Int_t)); + if (fArray!=0) fN= n; +} + +void AliArrayI::Streamer(TBuffer &R__b) +{ + // Stream an object of class AliTPC. + + if (R__b.IsReading()) { + Version_t R__v = R__b.ReadVersion(); if (R__v) { } + TObject::Streamer(R__b); + //read pad parameters + R__b >> fN; + if (fArray!=0) { + delete [] fArray; + fArray = 0; + } + if (fN>0){ + fArray = new Int_t[fN]; + R__b.ReadFastArray(fArray,fN); + } + } else { + R__b.WriteVersion(AliArrayI::IsA()); + TObject::Streamer(R__b); + R__b << fN; + if (fN>0) R__b.WriteFastArray(fArray,fN); + } +} diff --git a/TPC/AliArrayI.h b/TPC/AliArrayI.h new file mode 100644 index 00000000000..d73c210524c --- /dev/null +++ b/TPC/AliArrayI.h @@ -0,0 +1,23 @@ +#ifndef AliArrayI_H +#define AliArrayI_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +//////////////////////////////////////////////// +// Manager class generaol Alice segment +// segment is for example one pad row in TPC // +//////////////////////////////////////////////// + +#include "TObject.h" +#include "TArrayI.h" + +class AliArrayI: public TObject ,public TArrayI { +public: + void Expand(Int_t n); + ClassDef(AliArrayI,1) +}; + +#endif //ALIARRAY_I + diff --git a/TPC/AliArrayS.cxx b/TPC/AliArrayS.cxx new file mode 100644 index 00000000000..0eb5a744767 --- /dev/null +++ b/TPC/AliArrayS.cxx @@ -0,0 +1,75 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:32:37 kowal2 + +"ROOT"-based class with some extra functionality + +*/ + +/////////////////////////////////////////////////////////////////////// +// Added additional functionality to original TArrayS // +// multiple inheritance from TObject to be possible use automatic // +// branch mechanism for tree +// function Expand to be possible expand array without deleting // +// array contents // // +// // +// Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk // +// // +/////////////////////////////////////////////////////////////////////// +#include "AliArrayS.h" +ClassImp(AliArrayS) +void AliArrayS::Expand(Int_t n) +{ + // + // Set array size of TArrayS object to n integers and copy old array + // If n<0 leave array unchanged. + // user are responsible for apropriate size of array + // + if (n < 0) return; + fArray = (Short_t*) TStorage::ReAlloc(fArray, n * sizeof(UShort_t),fN * sizeof(UShort_t)); + if (fArray!=0) fN= n; + else fN =0; +} + + + +void AliArrayS::Streamer(TBuffer &R__b) +{ + // Stream an object of class AliTPC. + + if (R__b.IsReading()) { + Version_t R__v = R__b.ReadVersion(); if (R__v) { } + TObject::Streamer(R__b); + //read pad parameters + R__b >> fN; + if (fArray!=0){ + delete [] fArray; + fArray =0; + } + if (fN>0){ + fArray = new Short_t[fN]; + R__b.ReadFastArray(fArray,fN); + } + } else { + R__b.WriteVersion(AliArrayS::IsA()); + TObject::Streamer(R__b); + R__b << fN; + if (fN>0) R__b.WriteFastArray(fArray,fN); + } +} + diff --git a/TPC/AliArrayS.h b/TPC/AliArrayS.h new file mode 100644 index 00000000000..023271a8b3c --- /dev/null +++ b/TPC/AliArrayS.h @@ -0,0 +1,22 @@ +#ifndef ALIARRAYS_H +#define ALIARRAYS_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +//////////////////////////////////////////////// +// Manager class generaol Alice segment digits +// segment is for example one pad row in TPC // +//////////////////////////////////////////////// + +#include "TObject.h" +#include "TArrayS.h" + + +class AliArrayS: public TObject,public TArrayS { +public: + void Expand(Int_t n); + ClassDef(AliArrayS,1) +}; +#endif //ALIARRAYS_H diff --git a/TPC/AliCluster.cxx b/TPC/AliCluster.cxx new file mode 100644 index 00000000000..f407673de68 --- /dev/null +++ b/TPC/AliCluster.cxx @@ -0,0 +1,61 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:34:02 kowal2 + +Clusters handling in a new data structure + +*/ + +/////////////////////////////////////////////////////////////////////////////// +// // +// Time Projection Chamber clusters objects // +// +// Origin: Marian Ivanov , GSI Darmstadt +// // +//Begin_Html +/* + +*/ +//End_Html +// // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include "AliCluster.h" + +ClassImp(AliCluster) +//_____________________________________________________________________________ +Int_t AliCluster::Compare(TObject * o) +{ + // + // compare two clusters according y coordinata + AliCluster *cl= (AliCluster *)o; + if (fYfY) return -1; + if (fY==cl->fY) return 0; + return 1; +} + +Bool_t AliCluster::IsSortable() const +{ + // + //make AliCluster sortabale + return kTRUE; +} + +ClassImp(AliDigitCluster) +ClassImp(AliDifCluster) diff --git a/TPC/AliCluster.h b/TPC/AliCluster.h new file mode 100644 index 00000000000..3226171aa67 --- /dev/null +++ b/TPC/AliCluster.h @@ -0,0 +1,53 @@ +#ifndef ALICLUSTER_H +#define ALICLUSTER_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +#include "TObject.h" + +class AliCluster : public TObject { +public: + Int_t fTracks[3];//labels of overlapped tracks + Float_t fX ; //Y of cluster + Float_t fY ; //Z of cluster + Float_t fQ ; //Q of cluster (in ADC counts) + Float_t fSigmaX2; //Sigma Y square of cluster + Float_t fSigmaY2; //Sigma Z square of cluster + Float_t fSigmaXY; // XY moment + Float_t fArea; //area of cluster + Float_t fMax; //amplitude at maximum +public: + AliCluster() { + fTracks[0]=fTracks[1]=fTracks[2]=0; + fX=fY=fQ=fSigmaX2=fSigmaY2=0.; + } + virtual ~AliCluster() {;} + Bool_t IsSortable() const; + Int_t Compare(TObject *o) ; + ClassDef(AliCluster,1) // Tclusters +}; + +class AliDigitCluster : public AliCluster { +public: + Int_t fNx; //number of accepted x bins + Int_t fNy; //number of accepted y bins + Float_t fMaxX; //maximum x bin + Float_t fMaxY; //maximum y bin +public: + ClassDef(AliDigitCluster,1) // Tclusters +}; + +class AliDifCluster : public AliDigitCluster { +public: + Float_t fDx; //delta x + Float_t fDy; //delta y + Float_t fAngleX;//x angle + Float_t fAngleY;//y angle + Float_t fOrigQ; //original charge + Int_t fGenerTrack; //track number of nearest track + ClassDef(AliDifCluster,1) // Tclusters +}; + +#endif //ALICLUSTER_H diff --git a/TPC/AliClusterFinder.cxx b/TPC/AliClusterFinder.cxx new file mode 100644 index 00000000000..f2fcd3d7dce --- /dev/null +++ b/TPC/AliClusterFinder.cxx @@ -0,0 +1,899 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:34:56 kowal2 + +Experimental cluster finder + +*/ + +//----------------------------------------------------------------------------- +// +// Implementation of class ALICLUSTERFINDER +// +//Class for cluster finding in two dimension. +//In the present there are implemented two algorithm +//primitive recursion algorithm. (FindPeaks) +//Algorithm is not working in case of overlaping clusters +//Maximum - minimum in direction algoritm (Find clusters) +//In this algoritm we suppose that each cluster has local +//maximum. From this local maximum I mus see each point +//of cluster. +//From maximum i can accept every point in radial +//direction which is before border in direction +//Border in direction occur if we have next in +//direction nder threshold or response begin +//to increase in given radial direction +//----------------------------------------------------------------------------- +#include "TMinuit.h" +#include "AliArrayI.h" +#include "TClonesArray.h" +#include "AliTPC.h" +#include "TRandom.h" +#include "AliH2F.h" +#include "TMarker.h" +#include "AliCluster.h" +#include "AliClusterFinder.h" + +#include "iostream.h" //I.Belikov + +//direction constants possible direction in 8 different sectors +// + + +const Int_t kClStackSize =1000; + + + + +static AliClusterFinder * gClusterFinder; //for fitting routine + +void gauss(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag) +{ + AliArrayI * points = gClusterFinder->GetStack(); + const Int_t nbins = gClusterFinder->GetStackIndex(); + Int_t i; + //calculate chisquare + Double_t chisq = 0; + Double_t delta; + for (i=0;iAt(i*3); + Float_t y = points->At(i*3+1); + Float_t z = points->At(i*3+2); + Float_t deltax2 = (x-par[1]); + deltax2*=deltax2; + deltax2*=par[3]; + Float_t deltay2 = (y-par[2]); + deltay2*=deltay2; + deltay2*=par[4]; + + delta = z-par[0]*TMath::Exp(-deltax2-deltay2); + chisq += delta*delta; + } + f = chisq; +} + + +ClassImp(AliClusterFinder) + +AliClusterFinder::AliClusterFinder() +{ + fDigits =0; + fDimX = 0; + fDimY = 0; + fOver = 0; + fNoiseTh = 3; + fMulSigma2 = 16; //4 sigma + fDirSigmaFac = 1.4; + fDirAmpFac =1.3; + fNType=8; + fThreshold = 2; + fStack = new AliArrayI; + fStack->Set(kClStackSize); + fClustersArray =0; + + fDetectorParam = 0; + ResetStatus(); + fBFit = kFALSE; + fMinuit= new TMinuit(5); + fMinuit->SetFCN(gauss); + gClusterFinder = this; + +} + + +AliClusterFinder::~AliClusterFinder() +{ + if (fDigits != 0) delete fDigits; +} + +void AliClusterFinder::GetHisto(TH2F * his2) +{ + + Int_t idim =his2->GetNbinsX(); + Int_t jdim =his2->GetNbinsY(); + fX1 = his2->GetXaxis()->GetXmin(); + fX2 = his2->GetXaxis()->GetXmax(); + fY1 = his2->GetYaxis()->GetXmin(); + fY2 = his2->GetYaxis()->GetXmax(); + + if ( (idim>0) && (jdim>0)) + { + rOK = kTRUE; + fDimX = idim; + fDimY = jdim; + //Int_t size =idim*jdim; + if (fDigits !=0) delete fDigits; + fDigits = (AliCell*) new AliCell[idim*jdim]; + } else + rOK=kFALSE; + for (Int_t i = 0; iGetBin(i+1,j+1); + AliCell * cell = GetCell(i,j); + if (cell!=0) cell->SetSignal(his2->GetBinContent(index)); + } + +} + + + + +void AliClusterFinder::FindMaxima() +{ + for (Int_t i=0; ifX=ItoX(c->fX); + c->fY=JtoY(c->fY); + c->fMaxX=ItoX(c->fMaxX); + c->fMaxY=JtoY(c->fMaxY); + + c->fSigmaX2=c->fSigmaX2*(fX2-fX1)*(fX2-fX1)/(fDimX*fDimX); + c->fSigmaY2=c->fSigmaY2*(fY2-fY1)*(fY2-fY1)/(fDimY*fDimY); + c->fArea =c->fArea*(fX2-fX1)*(fY2-fY1)/(fDimX*fDimY); +} +void AliClusterFinder::AddToStack(Int_t i, Int_t j, Int_t signal) +{ + // + //add digit to stack + // + if ( ((fStackIndex+2)>=kClStackSize) || (fStackIndex<0) ) return; + fStack->AddAt(i,fStackIndex); + fStack->AddAt(j,fStackIndex+1); + fStack->AddAt(signal,fStackIndex+2); + fStackIndex+=3; +} + +void AliClusterFinder::GetClusterStatistic(AliDigitCluster & cluster) +{ + // + //calculate statistic of cluster + // + Double_t sumxw,sumyw,sumx2w,sumy2w,sumxyw,sumw; + Int_t minx,maxx,miny,maxy,maxQ; + sumxw=sumyw=sumx2w=sumy2w=sumxyw=sumw=0; + minx=fDimX; + maxx=-fDimX; + miny=fDimY; + maxy=-fDimY; + Int_t x0=fStack->At(0); + Int_t y0=fStack->At(1); + maxQ=fStack->At(2); + for (Int_t i = 0; iAt(i); + Int_t y = fStack->At(i+1); + Int_t dx=x-x0; + Int_t dy=y-y0; + Int_t w = fStack->At(i+2); + if (xmaxx) maxx=x; + if (y>maxy) maxy=y; + sumxw+=dx*w; + sumyw+=dy*w; + sumx2w+=dx*dx*w; + sumy2w+=dy*dy*w; + sumxyw+=dx*dy*w; + sumw+=w; + } + cluster.fQ = sumw; + if (sumw>0){ + cluster.fX = sumxw/sumw; + cluster.fY = sumyw/sumw; + cluster.fQ = sumw; + cluster.fSigmaX2 = sumx2w/sumw-cluster.fX*cluster.fX; + cluster.fSigmaY2 = sumy2w/sumw-cluster.fY*cluster.fY; + cluster.fSigmaXY = sumxyw/sumw-cluster.fX*cluster.fY; + cluster.fMaxX = x0; + cluster.fMaxY = y0; + cluster.fMax = maxQ; + cluster.fArea = fStackIndex/3; + cluster.fNx = maxx-minx+1; + cluster.fNy = maxy-miny+1; + cluster.fX +=x0; + cluster.fY +=y0; + } +} +void AliClusterFinder::GetClusterFit(AliDigitCluster & cluster) +{ + // + //calculate statistic of cluster + // + Double_t arglist[10]; + Int_t ierflg = 0; + + arglist[0] = 1; + fMinuit->mnexcm("SET ERR", arglist ,1,ierflg); + + //fistly find starting parameters + Int_t minx,maxx,miny,maxy,maxQ,maxQx,maxQy; + Int_t over =0; + Float_t sumxw,sumyw,sumw; + sumxw=sumyw=sumw=0; + minx=fDimX; + maxx=-fDimX; + miny=fDimY; + maxy=-fDimY; + maxQx=fStack->At(0); + maxQy=fStack->At(1); + maxQ=fStack->At(2); + + for (Int_t i = 0; iAt(i); + Int_t y = fStack->At(i+1); + Int_t w = fStack->At(i+2); + if (w>fThreshold) { + over++; + sumw+=w; + sumxw+=x*w; + sumyw+=y*w; + if (xmaxx) maxx=x; + if (y>maxy) maxy=y; + if (w>maxQ) { + maxQ=w; + maxQx=x; + maxQy=y; + } + } + } + Int_t nx = maxx-minx+1; + Int_t ny = maxy-miny+1; + + SetSigma2(maxQx,maxQy,fCurrentSigmaX2,fCurrentSigmaY2); + Double_t vstart[5]={maxQ,sumxw/sumw,sumyw/sumw,1/(2*fCurrentSigmaX2),1/(2*fCurrentSigmaY2)}; + Double_t step[5]={1.,0.01,0.01,0.01,0.01}; + fMinuit->mnparm(0, "amp", vstart[0], step[0], 0,0,ierflg); + fMinuit->mnparm(1, "x0", vstart[1], step[1], 0,0,ierflg); + fMinuit->mnparm(2, "y0", vstart[2], step[2], 0,0,ierflg); + fMinuit->mnparm(3, "sx2", vstart[3], step[3], 0,0,ierflg); + fMinuit->mnparm(4, "sy2", vstart[4], step[4], 0,0,ierflg); + arglist[0] = 500; + arglist[1] = 1.; + + fMinuit->mnfree(0); //set unfixed all parameters + //if we have area less then + if (over<=21) { //if we dont't have more then 7 points + fMinuit->FixParameter(3); + fMinuit->FixParameter(4); + } + else { + if (nx<3) fMinuit->FixParameter(3); //fix sigma x if no data in x direction + if (ny<3) fMinuit->FixParameter(4); //fix sigma y if no data in y direction + } + fMinuit->mnexcm("MIGRAD", arglist ,2,ierflg); + + if (sumw>0){ + Double_t x[5]; + Double_t error[5]; + fMinuit->GetParameter(0,x[0],error[0]); + fMinuit->GetParameter(1,x[1],error[1]); + fMinuit->GetParameter(2,x[2],error[2]); + fMinuit->GetParameter(3,x[3],error[3]); + fMinuit->GetParameter(4,x[4],error[4]); + + cluster.fX = x[1]; + cluster.fY = x[2]; + cluster.fMaxX = maxQx; + cluster.fMaxY = maxQy; + + cluster.fQ = sumw; + cluster.fSigmaX2 = 1/TMath::Sqrt(2*x[3]); + cluster.fSigmaY2 = 1/TMath::Sqrt(2*x[4]); + cluster.fSigmaXY = 0; + cluster.fMax = x[0]; + cluster.fArea = over; + cluster.fNx = nx; + cluster.fNy = ny; + } +} + +Bool_t AliClusterFinder::CheckIfDirBorder(Float_t x, Float_t y, + Int_t i,Int_t j) +{ + // + //function which control if given cell with index i, j is the + //minimum in direction + // x and y are estimate of local maximum + //direction is given by the + Float_t virtualcell; + AliCell * cellor= GetCell(i,j); + + //control derivation in direction + //if function grows up in direction then there is border + Float_t dx = i-x; + Float_t dy = j-y; + Float_t dd = TMath::Sqrt(dx*dx+dy*dy); + Float_t ddx = TMath::Abs(dx); + ddx = (ddx>0.5) ? ddx-0.5: 0; + ddx*=ddx; + Float_t ddy = TMath::Abs(dy); + ddy = (ddy>0.5) ? ddy-0.5: 0; + ddy*=ddy; + Float_t d2 = ddx/(2*fDirSigmaFac*fCurrentSigmaX2)+ddy/(2*fDirSigmaFac*fCurrentSigmaY2); //safety factor + //I accept sigmax and sigma y bigge by factor sqrt(fDirsigmaFac) + Float_t amp = TMath::Exp(-d2)*fCurrentMaxAmp*fDirAmpFac; //safety factor fDirFac>1 + + if (cellor->GetSignal()>amp) return kTRUE; + if (dd==0) return kFALSE; + + dx/=dd; + dy/=dd; + virtualcell = GetVirtualSignal(i+dx,j+dy); + if (virtualcell <=fThreshold) return kFALSE; + if (virtualcell>cellor->GetSignal()) + if (virtualcell>(cellor->GetSignal()+fNoiseTh)) + {cellor->SetDirBorder(fIndex+1); return kTRUE;} + else + { + virtualcell = GetVirtualSignal(i+2*dx,j+2*dy); + if (virtualcell>cellor->GetSignal()) + { cellor->SetDirBorder(fIndex+1); return kTRUE;} + }; + return kFALSE; +} + + + +Bool_t AliClusterFinder::IsMaximum(Int_t i, Int_t j) +{ + //there is maximum if given digits is 1 sigma over all adjacent + //in 8 neighborow + //or ther exist virual maximum + //is maximum on 24 points neighboring + // Bool_t res = kFALSE; + Int_t over =0; + Int_t overth=0; + Int_t oversigma =0; + AliCell * cell = GetCell(i,j); + if (cell == 0) return kFALSE; + for ( Int_t di=-1;di<=1;di++) + for ( Int_t dj=-1;dj<=1;dj++){ + if ( (di!=0) || (dj!=0)) + { + AliCell * cell2=GetCell(i+di,j+dj); + if (cell2 == 0) { + over+=1; + oversigma+=1; + } + else + { + if (cell2->GetSignal()>cell->GetSignal()) return kFALSE; + if (cell2->GetSignal()>fThreshold) overth++; + if (cell2->GetSignal()==cell->GetSignal()) { + if (di<0) return kFALSE; + if ( (di+dj)<0) return kFALSE; + } + // if (cell->GetSignal()>=cell2->GetSignal()){ + over+=1; + if (cell->GetSignal()>fNoiseTh+cell2->GetSignal()) + oversigma+=1; + //} + } + } + } + //if I have only one neighborough over threshold + if (overth<2) return kFALSE; + if (over<8) return kFALSE; + if (oversigma==8) { + fCurrentMaxX = i; + fCurrentMaxY = j; + fCurrentMaxAmp =cell->GetSignal(); + SetMaximum(fIndex+1,i,j); + return kTRUE; + } + //check if there exist virtual maximum + for (Float_t dii=0;(dii<1);dii+=0.5) + for (Float_t dj=0;(dj<1);dj+=0.5) + if (IsVirtualMaximum(Float_t(i)+dii,Float_t(j)+dj)){ + fCurrentMaxX = i+dii; + fCurrentMaxY = j+dj; + fCurrentMaxAmp =cell->GetSignal(); + SetMaximum(fIndex+1,i,j); + return kTRUE; + } + return kFALSE; +} + +Bool_t AliClusterFinder::IsVirtualMaximum(Float_t x, Float_t y) +{ + //there is maximum if given digits is 1 sigma over all adjacent + //in 8 neighborow or + //is maximum on 24 points neighboring + Bool_t res = kFALSE; + Int_t over =0; + Int_t overth=0; + Int_t oversigma =0; + Float_t virtualcell = GetVirtualSignal(x,y); + if (virtualcell < 0) return kFALSE; + for ( Int_t di=-1;di<=1;di++) + for ( Int_t dj=-1;dj<=1;dj++) + if ( (di!=0) || (dj!=0)) + { + Float_t virtualcell2=GetVirtualSignal(x+di,y+dj); + if (virtualcell2 < 0) { + over+=1; + oversigma+=1; + } + else + { + if (virtualcell2>fThreshold) overth++; + if (virtualcell>=virtualcell2){ + over+=1; + if (virtualcell>fNoiseTh+virtualcell2) + oversigma+=1; + } + } + } + if (overth<2) return kFALSE; + //if there exist only one or less neighboring above threshold + if (oversigma==8) res = kTRUE; + else if ((over==8)&&(GetNType()==8)) res=kTRUE; + else if (over ==8 ) + for ( Int_t dia=-2;dia<=2;dia++) + for ( Int_t dj=-2;dj<=2;dj++) + if ( (dia==2)||(dia==-2) || (dj==2)|| (dj==-2) ) + { + Float_t virtualcell2=GetVirtualSignal(x+dia,y+dj); + if (virtualcell2 < 0) { + over+=1; + oversigma+=1; + } + else + { + if (virtualcell>=virtualcell2) over+=1; + } + } + if (over == 24) res=kTRUE; + return res; + +} + + +void AliClusterFinder::ResetSignal() +{ + //reset dignals to 0 + Int_t size = fDimX*fDimY; + AliCell *dig=fDigits; + if (rOK==kTRUE) for (Int_t i=0 ; i=0) && (i=0) && (ji)? 1:0; + Int_t ddj = (rj>j)? 1:0; + Float_t sum = 0; + Float_t sumw= 0; + for (Int_t di=0;di<=ddi;di++) + for (Int_t dj=0;dj<=ddj;dj++) + { + Float_t w = (ri-i-di)*(ri-i-di)+(rj-j-dj)*(rj-j-dj); + if (w>0) w=1/TMath::Sqrt(w); + else w=9999999; + AliCell * cel2 =GetCell(i+di,j+dj); + if (cel2!=0) { + sumw+=w; + sum+= cel2->GetSignal()*w; + } + } + if (sumw>0) return (sum/sumw); + else + return -1; +} + + + +void AliClusterFinder::Streamer(TBuffer & R__b) +{ + if (R__b.IsReading()) { + // Version_t R__v = R__b.ReadVersion(); + } else { + R__b.WriteVersion(AliClusterFinder::IsA()); + } +} + + +Bool_t AliClusterFinder::SetSigma2(Int_t i, Int_t j, Float_t & sigmax2, Float_t &sigmay2) +{ + // + //set sigmax2 and sigma y2 accordig i and j position of cell + // + if (fDetectorParam==0) { + sigmax2=1; + sigmay2=1; + return kFALSE; + } + Float_t x[3] = {ItoX(i),JtoY(j),0}; + Float_t sigma[2]; + fDetectorParam->GetClusterSize(x,fDetectorIndex,0,0,sigma); + sigmax2=sigma[0]*(fX2-fX1)*(fX2-fX1)/(fDimX*fDimX); + sigmay2=sigma[1]*(fY2-fY1)*(fY2-fY1)/(fDimY*fDimY); + return kTRUE; +} + +void AliClusterFinder::SetBlockIndex(Int_t * index) +{ + // + //calculate which indexes we must check for border + // + if (TMath::Abs(index[0])<2) index[2] = 0; + else { + index[2] = TMath::Abs(index[0])-1; + if (index[0]<0) index[2]*=-1; //first x block + } + if (TMath::Abs(index[1])<2) index[3] = 0; + else { + index[3] = TMath::Abs(index[1])-1; + if (index[1]<0) index[3]*=-1; //first y block + } + if (TMath::Abs(index[0])GetEntriesFast(); + ResetStatus(); + + for (Int_t i=0; iIsChecked())) Adjacent(i,j); + //if there exists more then 2 digits cluster + if (fStackIndex >2 ){ + if (fBFit==kFALSE) GetClusterStatistic(c); + else GetClusterFit(c); + //write some important chracteristic area of cluster + // + Transform(&c); + //write cluster information to array + TClonesArray &lclusters = *clusters; + new(lclusters[index++]) AliDigitCluster(c); + // cout<<"fx="<GetEntriesFast(); + + ResetStatus(); + + for (Int_t i=0; i2 ){ + if (fBFit==kFALSE) GetClusterStatistic(c); + else GetClusterFit(c); + //write some important chracteristic area of cluster + // + Transform(&c); + //write cluster information to array + TClonesArray &lclusters = *clusters; + new(lclusters[fIndex++]) AliDigitCluster(c); + // cout<<"fx="<GetEntriesFast(); + + ResetStatus(); + + Int_t dmax=5; + Int_t naccepted =1; + for (Int_t i=0; iGetSignal()); + + //loop over different distance + naccepted =1; + for ( Int_t dd =1;((dd<=dmax) && (naccepted>0));dd++){ + naccepted=0; + for (Int_t di = -dd;di<=dd;di++){ + Int_t ddj = dd-TMath::Abs(di); + Int_t sigstart = (ddj>0) ? -1 : 0; + for (Int_t sig = sigstart;sig<=1;sig+=2){ + Int_t dj= sig*ddj; + AliCell *cell= GetCell(i+di,j+dj); + if (cell==0) continue; + Int_t index[6]; + index[0]=di; + index[1]=dj; + if (dd>2) { + SetBlockIndex(index); //adjust index to control + if ( IsBorder(fIndex+1,i+index[2],j+index[3]) || + IsBorder(fIndex+1,i+index[4],j+index[5])) { + cell->SetBorder(fIndex+1); + continue; + } + } + if ( cell->GetSignal()<=fThreshold ){ + //if under threshold + cell->SetThBorder(fIndex+1); + if (fBFit==kTRUE) AddToStack(i+di,j+dj,cell->GetSignal()); + continue; + } + naccepted++; + if (CheckIfDirBorder(fCurrentMaxX,fCurrentMaxY,i+di,j+dj) == kTRUE) { + if (fBFit==kFALSE) AddToStack(i+di,j+dj,cell->GetSignal()/2); + continue; + } + AddToStack(i+di,j+dj,cell->GetSignal()); + + } //loop over sig dj + } //loop over di + + }//loop over dd + } //if there is maximum + //if there exists more then 2 digits cluster + if (fStackIndex >2 ){ + if (fBFit==kFALSE) GetClusterStatistic(c); + else GetClusterFit(c); + //write some important chracteristic area of cluster + // + Transform(&c); + //write cluster information to array + TClonesArray &lclusters = *clusters; + new(lclusters[fIndex++]) AliDigitCluster(c); + // cout<<"fx="< fMulSigma2) { + SetDirBorder(fIndex+1,i,j); + return; + } + } + AliCell *cell = GetCell(i,j); + Int_t q=cell->GetSignal(); + cell->SetChecked(fIndex+1); + if ( (q>fThreshold) || (fBFit==kTRUE)) AddToStack(i,j,q); + if ( q >fThreshold ) + { + + AliCell * newcel; + newcel = GetCell(i-1,j); + if (newcel !=0) if (!newcel->IsChecked(fIndex+1) ) Adjacent(i-1,j); + newcel = GetCell(i,j-1); + if (newcel !=0) if (!newcel->IsChecked(fIndex+1) ) Adjacent(i,j-1); + newcel = GetCell(i+1,j); + if (newcel !=0) if (!newcel->IsChecked(fIndex+1) ) Adjacent(i+1,j); + newcel = GetCell(i,j+1); + if (newcel !=0) if (!newcel->IsChecked(fIndex+1) ) Adjacent(i,j+1); + } + else cell->SetThBorder(fIndex+1); +} + + + +AliH2F * AliClusterFinder::Draw( const char *option, + Float_t x1, Float_t x2, Float_t y1, Float_t y2) +{ + // + //draw digits in given array + // + //make digits histo + char ch[30]; + sprintf(ch,"Cluster finder digits "); + if ( (fDimX<1)|| (fDimY<1)) { + return 0; + } + AliH2F * his = new AliH2F(ch,ch,fDimX,fX1,fX2,fDimY,fY1,fY2); + //set histogram values + for (Int_t i = 0; iFill(x,y,GetSignal(i,j)); + } + if (x1>=0) { + AliH2F *h2fsub = his->GetSubrange2d(x1,x2,y1,y2); + delete his; + his=h2fsub; + } + if (his==0) return 0; + if (option!=0) his->Draw(option); + else his->Draw(); + return his; +} + + +void AliClusterFinder::DrawCluster( + Int_t color, Int_t size, Int_t style) +{ + + if (fClustersArray==0) return; + //draw marker for each of cluster + Int_t ncl=fClustersArray->GetEntriesFast(); + for (Int_t i=0;iUncheckedAt(i); + TMarker * marker = new TMarker; + marker->SetX(cl->fX); + marker->SetY(cl->fY); + marker->SetMarkerSize(size); + marker->SetMarkerStyle(style); + marker->SetMarkerColor(color); + marker->Draw(); + } +} + + + +AliH2F * AliClusterFinder::DrawBorders( const char *option, AliH2F *h, Int_t type , + Float_t x1, Float_t x2, Float_t y1, Float_t y2) +{ + // + //draw digits in given array + // + //make digits histo + char ch[30]; + sprintf(ch,"Cluster finder digits borders"); + if ( (fDimX<1)|| (fDimY<1)) { + return 0; + } + AliH2F * his; + if (h!=0) his =h; + else his = new AliH2F(ch,ch,fDimX,fX1,fX2,fDimY,fY1,fY2); + //set histogram values + for (Int_t i = 0; iFill(x,y,16); + if (((type==3)||(type==0))&&(IsDirBorder(0,i,j))) his->Fill(x,y,8); + if (((type==4)||(type==0))&&(IsThBorder(0,i,j))) his->Fill(x,y,4); + if (((type==2)||(type==0))&&IsBorder(0,i,j)) his->Fill(x,y,1); + + } + + if (x1>=0) { + AliH2F *h2fsub = his->GetSubrange2d(x1,x2,y1,y2); + delete his; + his=h2fsub; + } + if (his==0) return 0; + if (option!=0) his->Draw(option); + else his->Draw(); + return his; +} diff --git a/TPC/AliClusterFinder.h b/TPC/AliClusterFinder.h new file mode 100644 index 00000000000..47a55dffc9c --- /dev/null +++ b/TPC/AliClusterFinder.h @@ -0,0 +1,314 @@ +#ifndef TCLUSTERFINDER_H +#define TCLUSTERFINDER_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +// include files and class forward declarations +#include "TObject.h" +#include "TH2.h" +class TClonesArray; +class AliCluster; +class AliCell; +class AliArrayI; +class AliDetectorParam; +class TMinuit; +class AliH2F; +class AliClusterFinder : public TObject { + +public: + AliClusterFinder(); + // constructor which create cluster finder object + ~AliClusterFinder(); + void GetHisto(TH2F * his2); + //reset object to include histograms values + TClonesArray * FindPeaks1( TClonesArray *arr=0); + TClonesArray * FindPeaks2( TClonesArray *arr=0); + TClonesArray * FindPeaks3( TClonesArray *arr=0); + + void FindMaxima(); + // if at point is local maximum return cell with maximum information (for testing only + Int_t & GetNType(){return fNType;} //return type of neighborow for max determinatio + void SetThreshold(Float_t threshold) { fThreshold = threshold;} + void SetNoise(Float_t noise) {fNoiseTh =noise;} + void SetDirSigmaFac(Float_t fac) {fDirSigmaFac = fac;} + void SetDirAmpFac(Float_t fac) {fDirAmpFac = fac;} + + void SetDetectorParam(AliDetectorParam*param) {fDetectorParam = param;} + //set Detector parameters -necesssary to estimate cluster size + void SetDetectorIndex(Int_t *index) {fDetectorIndex = index;} + //set index of described detector + Bool_t SetSigma2(Int_t i, Int_t j, Float_t & sigmax2, Float_t & sigmay2); + //set sigmax and sigma y accordig i and j position of cell + void SetMulSigma(Float_t sigma) {fMulSigma2= sigma*sigma;} + AliArrayI * GetStack(){return fStack;} + Int_t GetStackIndex(){return fStackIndex;} + void SetBFit(Bool_t fit) {fBFit = fit;} + TMinuit * GetMinuit() {return fMinuit;} + AliH2F * Draw( const char *option=0,Float_t x1=-1, Float_t x2=-1, Float_t y1=-1, Float_t y2=-1); + //draw digits + void DrawCluster(Int_t color=5, Int_t size=5, Int_t style=4); + AliH2F * DrawBorders( const char *option=0, AliH2F *his=0, Int_t type =0, Float_t x1=-1, Float_t x2=-1, Float_t y1=-1, Float_t y2=-1); + //draw digits +public: + Bool_t IsMaximum(Int_t i, Int_t j); + Bool_t IsVirtualMaximum(Float_t x, Float_t y); + + void ResetSignal(); //reset signals to 0 + void ResetStatus(); //reset status of signals to not used + + AliCell * GetCell(Int_t i, Int_t j); + //return reference to the cell with index i,j + void SetBlockIndex(Int_t *index); //calculate which indexes we must check for border +public: + void AddToStack(Int_t i, Int_t j, Int_t signal); + //add given cell to the stack of particles + void GetClusterStatistic(AliDigitCluster & cluster); + //go through the cluster and calculate statistic + void GetClusterFit(AliDigitCluster & cluster); + Bool_t CheckIfDirBorder(Float_t x, Float_t y, Int_t i,Int_t j); + //check if given cell is border + void Adjacent(Int_t i, Int_t j); + //recursion procedure + Float_t ItoX(Float_t i) {return (fX1)+(i+0.5)*(fX2-fX1)/fDimX;} + Float_t JtoY(Float_t j) {return (fY1)+(j+0.5)*(fY2-fY1)/fDimY;} + + inline Bool_t IsChecked(Int_t index, Int_t i, Int_t j); + inline Bool_t IsBorder(Int_t index, Int_t i, Int_t j); + inline Bool_t IsThBorder(Int_t index, Int_t i, Int_t j); + inline Bool_t IsDirBorder(Int_t index, Int_t i, Int_t j); + inline Bool_t IsMaximum(Int_t index, Int_t i, Int_t j); + inline void SetChecked(Int_t index, Int_t i, Int_t j); + inline void SetBorder(Int_t index, Int_t i, Int_t j); + inline void SetThBorder(Int_t index, Int_t i, Int_t j); + inline void SetDirBorder(Int_t index, Int_t i, Int_t j); + inline void SetMaximum(Int_t index, Int_t i, Int_t j); + + + + inline Int_t GetSignal(Int_t i, Int_t j); + Float_t GetVirtualSignal(Float_t ri, Float_t rj); + //create new virtual cell and interpolate signal at position ri,rj + + void Transform(AliDigitCluster *c); +private: + Int_t fNType; //type of neighborow for maximum determination + Float_t fCurrentMaxX; //!current cluster maximum X index + Float_t fCurrentMaxY; //!current cluster maximum X index + Float_t fCurrentSigmaX2; //!current sigmax2 according detector (updated by function ...) + Float_t fCurrentSigmaY2;//! + Float_t fCurrentMaxAmp;//!current cluster maximum amplitude + Bool_t fBDistType; // + Bool_t fBFit; // + Float_t fMulSigma2; // + Float_t fDirSigmaFac; //!for direction border calculation + Float_t fDirAmpFac; //!for direction border calculation + + Float_t fThreshold; //treshold; + Float_t fNoiseTh; //noise threshoshol to accept maximum + AliCell * fDigits; //field with all cell digits + + + Int_t fIndex; //!index of current cluster + AliArrayI * fStack; //!stack with digits index + Int_t fStackIndex; //!stack index + TMinuit *fMinuit; //!minuit object + AliDetectorParam * fDetectorParam; //pointer to detector param - finder is not owner + Int_t * fDetectorIndex; // detector index - + //original frame + Float_t fX1; + Float_t fY1; + Float_t fX2; + Float_t fY2; + Int_t fDimX; + Int_t fDimY; + Int_t fOver; + + // + TClonesArray * fClustersArray; //array with current clusters + Bool_t rOK; + //signalize that all fields were initialised + ClassDef(AliClusterFinder,2) +}; + + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//objec AliCell + +const Int_t krCheck = 1; +const Int_t krBorder = 2; +const Int_t krThBorder = 4; +const Int_t krDirBorder = 8; +const Int_t krMaximum = 16; +const Int_t krIndexNull =0x1F; + +class AliCell{ +public : + AliCell(Int_t signal =0, Int_t status = 0){fSignal =signal;fStatus = status;} + //at the begining set + void SetSignal(Int_t signal){fSignal = signal;} + void SetStatus(Int_t status){fStatus = status;} + void SetChecked(Int_t index) {fStatus &=krIndexNull; fStatus+=(index<<5); fStatus|=krCheck;} + void SetChecked() {fStatus|=krCheck;} + void SetBorder(Int_t index) {fStatus &=krIndexNull; fStatus |= krBorder;fStatus+=(index<<5);} + void SetThBorder(Int_t index) {fStatus &=krIndexNull;fStatus|=krBorder|krThBorder;fStatus+=(index<<5);} + void SetDirBorder(Int_t index) {fStatus &=krIndexNull;fStatus|=krBorder|krDirBorder;fStatus+=(index<<5);} + void SetMaximum(Int_t index) {fStatus &=krIndexNull;fStatus|=krMaximum;fStatus+=(index<<5);} + + + void SetUnChecked(){if (fStatus&krCheck) fStatus-=krCheck;} + void SetUnBorder(){if (fStatus&krBorder) fStatus-=krBorder;} + void SetThUnBorder(){SetUnBorder();if (fStatus&krBorder) fStatus-=krThBorder+krBorder;} + void SetDirUnBorder(){SetUnBorder();if (fStatus&krBorder) fStatus-=krDirBorder+krBorder;} + + Bool_t IsChecked() {return fStatus&&krBorder;} + Bool_t IsChecked(Int_t index) {return ((fStatus>>5)==index);} + + Bool_t IsBorder() {return ((fStatus&krBorder)!=0);} + Bool_t IsBorder(Int_t index) {return ( ((fStatus&krBorder)!=0) && ((fStatus>>5)==index));} + Bool_t IsDirBorder() {return ((fStatus&krDirBorder)!=0);} + Bool_t IsDirBorder(Int_t index) {return ( ((fStatus&krDirBorder)!=0) && ((fStatus>>5)==index));} + Bool_t IsThBorder() {return ((fStatus&krThBorder)!=0);} + Bool_t IsThBorder(Int_t index) {return ( ((fStatus&krThBorder)!=0) && ((fStatus>>5)==index));} + + Bool_t IsMaximum() {return ((fStatus&krMaximum)!=0);} + Bool_t IsMaximum(Int_t index) {return ( ((fStatus&krMaximum)!=0) && ((fStatus>>5)==index));} + + void Reset() { fStatus = 0; fSignal =0;} + Int_t GetSignal() {return fSignal;} + Int_t GetStatus() {return fStatus;} + + +private: + Int_t fSignal; + Int_t fStatus; +}; + + + +Int_t AliClusterFinder::GetSignal(Int_t i, Int_t j) +{ + AliCell *c = GetCell(i,j); + Int_t res; + if (c==0) res = -1; + else res = c->GetSignal(); + return res; +} + + + +Bool_t AliClusterFinder::IsBorder(Int_t index, Int_t i, Int_t j) +{ + AliCell *c = GetCell(i,j); + Bool_t res; + if (c==0) res = kFALSE; + else { + if (index == 0) res = c->IsBorder(); + else res = c->IsBorder(index); + } + return res; +} + + + +Bool_t AliClusterFinder::IsThBorder(Int_t index, Int_t i, Int_t j) +{ + AliCell *c = GetCell(i,j); + Bool_t res; + if (c==0) res = kFALSE; + else { + if (index == 0) res = c->IsThBorder(); + else res = c->IsThBorder(index); + } + return res; +} + +Bool_t AliClusterFinder::IsDirBorder(Int_t index, Int_t i, Int_t j) +{ + AliCell *c = GetCell(i,j); + Bool_t res; + if (c==0) res = kFALSE; + else { + if (index == 0) res = c->IsDirBorder(); + else res = c->IsDirBorder(index); + } + return res; +} + +Bool_t AliClusterFinder::IsChecked(Int_t index, Int_t i, Int_t j) +{ + AliCell *c = GetCell(i,j); + Bool_t res; + if (c==0) res = kTRUE; + else { + if (index == 0) res = c->IsChecked(); + else res = c->IsChecked(index); + } + return res; +} + +Bool_t AliClusterFinder::IsMaximum(Int_t index, Int_t i, Int_t j) +{ + AliCell *c = GetCell(i,j); + Bool_t res; + if (c==0) res = kTRUE; + else { + if (index == 0) res = c->IsMaximum(); + else res = c->IsMaximum(index); + } + return res; +} + + +void AliClusterFinder::SetChecked(Int_t index, Int_t i, Int_t j) +{ + AliCell *c = GetCell(i,j); + if (c!=0) { + if (index>0) c->SetChecked(index); + else c->SetChecked(); + } +} + +void AliClusterFinder::SetBorder(Int_t index, Int_t i, Int_t j) +{ + AliCell *c = GetCell(i,j); + if (c!=0) { + if (index>0) c->SetBorder(index); + // else c->SetBorder(); + } +} + + +void AliClusterFinder::SetThBorder(Int_t index, Int_t i, Int_t j) +{ + AliCell *c = GetCell(i,j); + if (c!=0) { + if (index>0) c->SetThBorder(index); + else c->SetThBorder(0); + } +} + + +void AliClusterFinder::SetDirBorder(Int_t index, Int_t i, Int_t j) +{ + AliCell *c = GetCell(i,j); + if (c!=0) { + if (index>0) c->SetDirBorder(index); + else c->SetDirBorder(0); + } +} + + +void AliClusterFinder::SetMaximum(Int_t index, Int_t i, Int_t j) +{ + AliCell *c = GetCell(i,j); + if (c!=0) { + if (index>0) c->SetMaximum(index); + else c->SetMaximum(0); + } +} + +#endif /* TCLUSTERFINDER_H */ diff --git a/TPC/AliClusters.cxx b/TPC/AliClusters.cxx new file mode 100644 index 00000000000..9c3d830c789 --- /dev/null +++ b/TPC/AliClusters.cxx @@ -0,0 +1,173 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:34:02 kowal2 + +Clusters handling in a new data structure + +*/ + +/////////////////////////////////////////////////////////////////////////////// +// // +// Time Projection Chamber clusters objects // +// +// Origin: Marian Ivanov , GSI Darmstadt +// // +// // +// // +/////////////////////////////////////////////////////////////////////////////// +#include "TError.h" +#include "TClass.h" +#include +#include "AliCluster.h" +#include "AliClusters.h" +#include "TClonesArray.h" +#include "TMarker.h" + + +const Int_t kDefSize = 1; //defalut size + + +ClassImp(AliClusters) + +//***************************************************************************** +// +//_____________________________________________________________________________ +AliClusters::AliClusters() +{ + // + //default constructor + fNclusters=0; + fClusters =0; + fClass =0; +} + +Bool_t AliClusters::SetClass(const Text_t *classname) +{ + // + //set class of stored object + if ( fClass !=0 ) { + delete fClass; + fClass = 0; + } + + if (!gROOT) + ::Fatal("AliClusters::SetClass", "ROOT system not initialized"); + + fClass = gROOT->GetClass(classname); + if (!fClass) { + Error("AliClusters", "%s is not a valid class name", classname); + return kFALSE; + } + if (!fClass->InheritsFrom(AliCluster::Class())) { + Error("AliClusters", "%s does not inherit from AliCluster", classname); + return kFALSE; + } + return kTRUE; +} + +//_____________________________________________________________________________ +void AliClusters::SetArray(Int_t length) +{ + // + // construct Clones array of object + // + if (fClusters!=0) delete fClusters; + if (fClass==0){ + Error("AliClusters", "cluster type not initialised \n SetClass before!"); + return; + } + fClusters = new TClonesArray(fClass->GetName(),length); +} + + + +//_____________________________________________________________________________ +const AliCluster* AliClusters::operator[](Int_t i) +{ + // + // return cluster at internal position i + // + if (fClusters==0) return 0; + void * cl = fClusters->UncheckedAt(i); + if (cl==0) return 0; + return (AliCluster*)cl; +} +//_____________________________________________________________________________ +void AliClusters::Sort() +{ + // sort cluster + if (fClusters!=0) fClusters->Sort(); +} + +//_____________________________________________________________________________ +AliCluster * AliClusters::InsertCluster( const AliCluster * c) +{ + // + // Add a simulated cluster copy to the list + // + if (fClass==0) { + Error("AliClusters", "class type not specified"); + return 0; + } + if(!fClusters) fClusters=new TClonesArray(fClass->GetName(),1000); + TClonesArray &lclusters = *fClusters; + return new(lclusters[fNclusters++]) AliCluster(*c); +} + +//_____________________________________________________________________________ +Int_t AliClusters::Find(Double_t y) const +{ + // + // return index of cluster nearest to given y position + // + AliCluster* cl; + cl=(AliCluster*)fClusters->UncheckedAt(0); + if (y <= cl->fY) return 0; + cl=(AliCluster*)fClusters->UncheckedAt(fNclusters-1); + if (y > cl->fY) return fNclusters; + Int_t b=0, e=fNclusters-1, m=(b+e)/2; + for (; bUncheckedAt(m); + if (y > cl->fY) b=m+1; + else e=m; + } + return m; +} + + +//_____________________________________________________________________________ + +void AliClusters::Draw(Float_t shiftx, Float_t shifty, + Int_t color, Int_t size, Int_t style) +{ + + if (fClusters==0) return; + //draw marker for each of cluster + Int_t ncl=fClusters->GetEntriesFast(); + for (Int_t i=0;iUncheckedAt(i); + TMarker * marker = new TMarker; + marker->SetX(cl->fX+shiftx); + marker->SetY(cl->fY+shifty); + marker->SetMarkerSize(size); + marker->SetMarkerStyle(style); + marker->SetMarkerColor(color); + marker->Draw(); + } +} + diff --git a/TPC/AliClusters.h b/TPC/AliClusters.h new file mode 100644 index 00000000000..c042fe58417 --- /dev/null +++ b/TPC/AliClusters.h @@ -0,0 +1,37 @@ +#ifndef ALICLUSTERS_H +#define ALICLUSTERS_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +//////////////////////////////////////////////// +// Manager class for TPC clusters // +//////////////////////////////////////////////// + + +#include "AliSegmentID.h" +class TClonesArray; +class TObjArray; + + +class AliClusters : public AliSegmentID{ +public: + AliClusters(); + virtual AliCluster* InsertCluster(const AliCluster* c ); //insert copy of cluster + const AliCluster* operator[](Int_t i); + virtual Int_t Find(Double_t y) const; //find nearest cluster in y direction + void Sort(); + TClonesArray * GetArray(){return fClusters;} + void SetArray(Int_t length); //construct clonnes array of objects of type fClass + void Draw(Float_t shiftx, Float_t shifty, Int_t color, Int_t size, Int_t style); + Bool_t SetClass(const Text_t *classname); +protected: + TClonesArray * fClusters; + Int_t fNclusters; + TClass * fClass; //!type of cluster class + ClassDef(AliClusters,1) +}; + + +#endif //ALICLUSTERS_H diff --git a/TPC/AliClustersArray.cxx b/TPC/AliClustersArray.cxx new file mode 100644 index 00000000000..1aa56f3fb19 --- /dev/null +++ b/TPC/AliClustersArray.cxx @@ -0,0 +1,101 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:34:02 kowal2 + +Clusters handling in a new data structure + +*/ + +/////////////////////////////////////////////////////////////////////////////// +// // +// AliClustersArray object // +// +// Origin: Marian Ivanov , GSI Darmstadt +// // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include "TObject.h" +#include "TClass.h" +#include +#include "AliSegmentID.h" +#include "TObjArray.h" +#include "AliSegmentArray.h" + +#include "AliCluster.h" +#include "AliClusters.h" +#include "AliClusterFinder.h" +#include "AliDetectorParam.h" +#include "AliClustersArray.h" + + + +ClassImp(AliClustersArray) +// + +AliClustersArray::AliClustersArray() +{ + // + //Default constructor + // + fParam = 0; + fClusterType = 0; +} + +Bool_t AliClustersArray::SetClusterType(Text_t * classname) +{ + // + //set type of Clusters + // + if ( fClusterType !=0 ) { + delete fClusterType; + fClusterType = 0; + } + + if (!gROOT) + ::Fatal("AliTPCClustersArray", "ROOT system not initialized"); + + fClusterType = gROOT->GetClass(classname); + if (!fClusterType) { + Error("AliTPCClustersArray", "%s is not a valid class name", classname); + return kFALSE; + } + if (!fClusterType->InheritsFrom(AliCluster::Class())) { + Error("AliTPCClustersArray", "%s does not inherit from AliCluster", classname); + return kFALSE; + } + return kTRUE; +} + +Bool_t AliClustersArray::Setup(AliDetectorParam *param) +{ + // + //make copy of param object + + return kTRUE; +} + +Bool_t AliClustersArray::SetParam(AliDetectorParam * param) +{ + return kTRUE; +} + +Bool_t AliClustersArray::SetFinder(AliClustersFinder * finder) +{ + return kTRUE; +} diff --git a/TPC/AliClustersArray.h b/TPC/AliClustersArray.h new file mode 100644 index 00000000000..b9c4ce780ac --- /dev/null +++ b/TPC/AliClustersArray.h @@ -0,0 +1,31 @@ +#ifndef ALICLUSTERSARRAY_H +#define ALICLUSTERSARRAY_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +//////////////////////////////////////////////// +// Manager class for AliClustersArray // +//////////////////////////////////////////////// +class AliDetectorParam; +class AliClustersFinder; + +class AliClustersArray : public AliSegmentArray { +public: + AliClustersArray(); + virtual Bool_t Setup(AliDetectorParam *param); + const AliDetectorParam * GetParam() {return fParam;} + AliClustersFinder * GetFinder() {return fClFinder;} + virtual Bool_t SetParam(AliDetectorParam * param); + virtual Bool_t SetFinder(AliClustersFinder * finder); + Bool_t SetClusterType(Text_t *classname ); + TClass * GetClusterType() {return fClusterType;} +protected: + AliDetectorParam * fParam; //pointer to detector parameters + AliClustersFinder * fClFinder; //!pointer to cluster finder object + TClass *fClusterType; //! + ClassDef(AliClustersArray,1) +}; + +#endif diff --git a/TPC/AliDetectorParam.cxx b/TPC/AliDetectorParam.cxx new file mode 100644 index 00000000000..a663b423751 --- /dev/null +++ b/TPC/AliDetectorParam.cxx @@ -0,0 +1,73 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:36:13 kowal2 + +New Detector parameters handling class + +*/ + +/////////////////////////////////////////////////////////////////////// +// Paramter class for AliDetector // +// // +// Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk // +// // +/////////////////////////////////////////////////////////////////////// + +#include "TObject.h" +#include "AliDetectorParam.h" + + + + +Float_t * AliDetectorParam::GetAnglesAccMomentum(Float_t *x, Int_t * index, Float_t *momentum, Float_t *angle) +{ + // + //calculates deflection angle of particle with longitudinal + //longitudinal momentum[0] and transversal momentum momentum[1] + //at position (x,y,z) = (x[0],x[1],x[2]) + //angle[0] - deep angle + //angle[1] - magnetic deflection angle + if (momentum==0) { + Float_t rtotal =TMath::Sqrt(x[0]*x[0]+x[1]*x[1]); + if (rtotal==0) angle[0]=0; + else + angle[0] = TMath::ATan(x[2]/rtotal); + angle[1]=0; + return angle; + } + Float_t mtotal =TMath::Sqrt(momentum[0]*momentum[0]+momentum[1]*momentum[1]); + if (mtotal==0) { + angle[0]= 0; + angle[1]=0; + return angle; + } + angle[0]= TMath::ATan(momentum[2]/mtotal); + Float_t radius1 = TMath::Sqrt(x[0]*x[0]+x[1]*x[1]); //axial symetry in z + Float_t radius2 = 1000*mtotal/(3*fBField); + if (radius1 +class AliDetectorParam : public TNamed { +public: + AliDetectorParam(){;} + virtual Int_t GetNSegmentsTotal(){return 0;} //get total nuber of segments + virtual Bool_t Get1DIndex(Int_t *index, const Int_t * arrindex) {return kFALSE;} + //transform multidimensional index to one dimesional + virtual Bool_t GetNDIndex(const Int_t * index1, Int_t * arrIndex) {return kFALSE;} + //trasnform one dimesional index to multidimesional + virtual Float_t GetPrimaryLoss(Float_t *x, Int_t *index, Float_t *angle){return 0;} + virtual Float_t GetTotalLoss(Float_t *x, Int_t *index, Float_t *angle){return 0;} + virtual void GetClusterSize(Float_t *x, Int_t *index, Float_t *angle, Int_t mode, Float_t *sigma){;} + virtual void GetSpaceResolution(Float_t *x, Int_t *index, Float_t *angle, Float_t amplitude, Int_t mode, + Float_t *sigma){;} + virtual Float_t * GetAnglesAccMomentum(Float_t *x, Int_t * index, Float_t* momentum, Float_t *angle); + + void SetBField(Float_t b){fBField=b;} //set magnetic field intensity + void SetNPrimLoss(Float_t loss) {fNPrimLoss = loss;} + void SetNTotalLoss(Float_t loss) {fNTotalLoss = loss;} + Float_t GetBFiled() {return fBField;} + Float_t GetNPrimLoss() {return fNPrimLoss;} + Float_t GetNTotalLoss() {return fNTotalLoss;} +protected: + Float_t fBField; //intensity of magnetic field + Float_t fNPrimLoss; //number of produced primary electrons per cm + Float_t fNTotalLoss; //total number of produced electrons per cm + + ClassDef(AliDetectorParam,1) //parameter object for set:TPC +}; + + + + +#endif //ALIDPARAM_H diff --git a/TPC/AliDigits.cxx b/TPC/AliDigits.cxx new file mode 100644 index 00000000000..d28a4a538a5 --- /dev/null +++ b/TPC/AliDigits.cxx @@ -0,0 +1,413 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:37:42 kowal2 + +Digits handling in a new data structure + +*/ + +/////////////////////////////////////////////////////////////////////////////// +// // +// Alice digits array object AliDigits // +// // +// // +// // +/////////////////////////////////////////////////////////////////////////////// + + +#include "TClass.h" +#include +#include "TError.h" +#include "AliSegmentID.h" +#include "AliH2F.h" +#include "AliArrayI.h" +#include "AliArrayS.h" +#include "AliDigits.h" + + + +//_____________________________________________________________________________ +//_____________________________________________________________________________ +//_____________________________________________________________________________ +ClassImp(AliDigits) + + +AliDigits::AliDigits() +{ + fIndex = 0; + fElements = 0; + fThreshold =0; + Invalidate(); +} + +AliDigits::~AliDigits() +{ + // + //defaulta destructor + if (fIndex !=0 ) fIndex->Delete();; + if (fElements != 0) fElements->Delete(); + +} + + +Bool_t AliDigits::OutOfBoundsError(const char *where, Int_t row, Int_t column) +{ + // Generate an out-of-bounds error. Always returns false. + ::Error(where, "row %d col %d out of bounds (size: %d x %d, this: 0x%08x)", + row, column, fNrows, fNcols, this); + return kFALSE; +} + + +void AliDigits::Invalidate() +{ + // + //set default (invalid parameters) + if (fIndex != 0) delete fIndex; + fIndex = new AliArrayI; + + if (fElements!= 0) delete fElements; + + fElements = new AliArrayS; + + fNrows = fNcols =fNelems= -1; + fElements->Set(0); + fIndex->Set(0); + fBufType = -1; +} + +void AliDigits::Allocate(Int_t rows, Int_t columns) +{ + // + //construct empty buffer fDigits with size rows x columns + Invalidate(); + if (rows <= 0) { + Error("Allocate", "no of rows has to be positive"); + return; + } + if (columns <= 0) { + Error("Allocate", "no of columns has to be positive"); + return; + } + fNrows = rows; + fNcols=columns; + fNelems = fNrows * fNcols; + fElements->Set(fNelems); + fIndex->Set(fNcols); + for (Int_t i =0,k=0; i0) ExpandBuffer(); + if (fBufType !=0) { + Error("CompressBuffer", "buffer doesn't exist"); + return; + } + fThreshold = threshold; + //compress buffer of type 1 + if ( bufferType == 1) CompresBuffer1();//end of compresing bufer of type 1 +} + +Bool_t AliDigits::First() +{ + //adjust first valid current digit + if (fBufType ==0) return First0(); + if (fBufType ==1) return First1(); + return kFALSE; +} + +Bool_t AliDigits::Next() +{ + //addjust next valid current digit + if (fBufType ==0) return Next0(); + if (fBufType ==1) return Next1(); + return kFALSE; +} + +void AliDigits::AcceptHisto(AliH2F * his) +{ + // + //make digits buffer with value according histograms values + //for testing purpose + Int_t idim =his->GetNbinsX(); + Int_t jdim =his->GetNbinsY(); + if ( (idim<1)|| (jdim<1)) { + return; + } + //allocate proper buffer size + Allocate(idim,jdim); + //set digits values + for (Int_t i = 0; iGetBin(i+1,j+1); + SetDigitFast((Short_t)his->GetBinContent(index),i,j); + } +} + +AliH2F * AliDigits::GenerHisto() +{ + // + //make digits histo + char ch[30]; + sprintf(ch,"Segment_%d ",GetID()); + if ( (fNrows<1)|| (fNcols<1)) { + return 0; + } + AliH2F * his = new AliH2F("Digit histo",ch,fNrows,0,fNrows,fNcols,0,fNcols); + ExpandBuffer(); + //set histogram values + for (Int_t i = 0; iFill(i,j,GetDigitFast(i,j)); + return his; +} + +AliH2F * AliDigits::Draw(const char *option,Float_t x1, Float_t x2, Float_t y1, Float_t y2) +{ + // + //draw digits in given array + // + AliH2F *h2f = GenerHisto(); + if (x1>=0) { + AliH2F *h2fsub = h2f->GetSubrange2d(x1,x2,y1,y2); + delete h2f; + h2f=h2fsub; + } + if (h2f==0) return 0; + if (option!=0) h2f->Draw(option); + else h2f->Draw(); + return h2f; +} + +void AliDigits::ExpandBuffer1() +{ + // + //expand buffer of type to twodimensional array + Int_t i,k; + fNelems = fNrows*fNcols; + Short_t * buf = new Short_t[fNelems]; + fIndex->Set(fNcols); + for (i =0,k=0 ;ifN; + for (i=0;iAt(i); + else { + buf[(*fIndex)[col]+row]=fElements->At(i); + row++; + } + if (row==fNrows) { + row=0; + col++; + }else + if (row>fNrows){ + Invalidate(); + return; + } + } + fElements->Adopt(fNelems,buf); +} +void AliDigits::CompresBuffer1() +{ + // + //compres buffer according algorithm 1 + // + AliArrayS buf; //lets have the nearly the "worst case" + buf.Set(fNelems); + AliArrayI index; + index.Set(fNcols); + Int_t icurrent=-1; + Int_t izero; + for (Int_t col = 0; col0) { + //if we have currently izero count under threshold + icurrent++; + if (icurrent>=buf.fN) buf.Expand(icurrent*2); + buf[icurrent]= -izero; //write how many under zero + izero = 0; + } //end of reseting izero + icurrent++; + if (icurrent>=buf.fN) buf.Expand(icurrent*2); + buf[icurrent] = GetDigitFast(row,col); + }//if signal bigger then threshold + } //end of loop over rows + if (izero>0) { + icurrent++; + if (icurrent>=buf.fN) buf.Expand(icurrent*2); + buf[icurrent]= -izero; //write how many under zero + } + }//end of lopping over digits + buf.Expand(icurrent+1); + (*fElements)=buf; + fNelems = fElements->fN; + fBufType = 1; + (*fIndex) =index; + //end of compresing bufer of type 1 +} + + + +Bool_t AliDigits::First0() +{ + // + //first for the buffer type 0 + fCurrentRow = -1; + fCurrentCol = -1; + fCurrentIndex = -1; + Int_t i; + for (i=0; (( iAt(i)<=fThreshold));i++) + if (i == fNelems) return kFALSE; + fCurrentCol =i/fNrows; + fCurrentRow =i%fNrows; + fCurrentIndex = i; + return kTRUE; +} + +Bool_t AliDigits::Next0() +{ + // + //next for the buffer type 0 + // + if (fCurrentIndex<0) return kFALSE; // if we didn't adjust first + Int_t i; + for (i=fCurrentIndex+1; ( (iAt(i)<=fThreshold) ) ;i++); + if (i >= fNelems) { + fCurrentIndex = -1; + return kFALSE; + } + fCurrentCol =i/fNrows; + fCurrentRow =i%fNrows; + fCurrentIndex = i; + return kTRUE; +} + +Bool_t AliDigits::First1() +{ + // + //first for the buffer type 1 + fCurrentRow = -1; + fCurrentCol = 0; + fCurrentIndex = -1; + Int_t i; + for (i=0; iAt(i) < 0) fCurrentRow-=fElements->At(i); + else + fCurrentRow++; + if (fCurrentRow>=fNrows) { + fCurrentCol++; + fCurrentRow-=fNrows; + } + if (fElements->At(i)>fThreshold) break; + } + fCurrentIndex = i; + if (fCurrentIndex>=0) return kTRUE; + fCurrentRow =-1; + fCurrentCol =-1; + return kFALSE; +} + +Bool_t AliDigits::Next1() +{ + // + //next for the buffer type 1 + if (fCurrentIndex<0) return kFALSE; // if we didn't adjust first + Int_t i; + for (i=fCurrentIndex+1; iAt(i) < 0) fCurrentRow-=fElements->At(i); + else + fCurrentRow++; + if (fCurrentRow>=fNrows) { + fCurrentCol++; + fCurrentRow-=fNrows; + } + if (fElements->At(i)>fThreshold) break; + } + fCurrentIndex = i; + if ( (i>=0) && (i=fNcols) n2 = fNelems; + else + n2 = fIndex->At(column+1); + Int_t irow = 0; //current row + + for (i=fIndex->At(column); ( (iAt(i) < 0) irow-=fElements->At(i); + else + irow++; + } + if ( irow == row ) return fElements->At(i); + return -1; +} + diff --git a/TPC/AliDigits.h b/TPC/AliDigits.h new file mode 100644 index 00000000000..201f8871f89 --- /dev/null +++ b/TPC/AliDigits.h @@ -0,0 +1,98 @@ +#ifndef ALIDIGITS_H +#define ALIDIGITS_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +//////////////////////////////////////////////// +// Manager class generaol Alice segment digits +// segment is for example one pad row in TPC // +//////////////////////////////////////////////// + +#include "AliArrayI.h" +#include "AliArrayS.h" +#include "AliSegmentID.h" +class AliH2F; + +class AliDigits: public AliSegmentID{ +public: + AliDigits(); + ~AliDigits(); + inline Short_t GetDigitFast(Int_t row, Int_t column); //return value at given row and collumn + inline void SetDigitFast(Short_t value,Int_t row, Int_t column); //set value at given row and collumn + inline Bool_t BoundsOK(const char *where, Int_t row, Int_t col) ; //Check If Bound Ok + Bool_t OutOfBoundsError(const char *where, Int_t row, Int_t column); + virtual void Allocate(Int_t rows, Int_t columns); //construct empty buffer fDigits with size rows x columns + virtual Short_t GetDigit(Int_t row, Int_t column); + virtual void ExpandBuffer(); //expand buffer to twodimensional array + virtual void CompresBuffer(Int_t bufferType,Int_t threshold); //compres buffer according buffertype algorithm + virtual Bool_t First(); //adjust first valid current digit + virtual Bool_t Next(); //addjust next valid current digit + void SetThreshold(Int_t th) {fThreshold = th;} + Int_t GetThreshold() {return fThreshold;} + Int_t CurrentRow(){ return fCurrentRow;} //return current row + Int_t CurrentColumn(){ return fCurrentCol;} //return current column + Int_t CurrentDigit() {return fElements->At(fCurrentIndex);} //return degit for current row and column + void AcceptHisto(AliH2F * his); //update buffer for - it will content histogram values + AliH2F * GenerHisto(); //generate 2 dimensional histogram with digits + AliH2F * Draw( const char *option=0,Float_t x1=-1, Float_t x2=-1, Float_t y1=-1, Float_t y2=-1); //draw digits + Int_t GetSize() {return fNelems;} //return main buffer size +protected: + virtual void Invalidate(); + void ExpandBuffer1(); //expand buffer of type to twodimensional array + void CompresBuffer1(); //compres buffer according algorithm 1 + Bool_t First0(); //first for the buffer type 0 + Bool_t Next0(); //next for the buffer type 0 + Bool_t First1(); //first for the buffer type 1 + Bool_t Next1();//next for the buffer type 1 + Short_t GetDigit1(Int_t row, Int_t column); //return digit for given row and column + + Int_t fNrows; //number of rows in Segment + Int_t fNcols; //number of collumns in Segment +private: + AliArrayS *fElements; //buffer of 2 bytes integers for digits + AliArrayI *fIndex; //index position of column + Int_t fBufType; //type of the buffer - define compression algorithm + Int_t fThreshold; //treshold for zero suppresion + Int_t fNelems; //total number of elements + Int_t fCurrentRow; //!current row iteration + Int_t fCurrentCol; //!current column iteration + Int_t fCurrentIndex; //!current index in field + + ClassDef(AliDigits,1) +}; + + + +inline Bool_t AliDigits::BoundsOK(const char *where, Int_t row, Int_t col) +{ + //Check If Bound Ok + if ( (col>=fNcols) || (col<0) ) return OutOfBoundsError(where,row,col); + Int_t index =(*fIndex).At(col)+row; + if ( (index<0) || (index>fNelems)) return OutOfBoundsError(where,row,col); + return kTRUE; +} + +Short_t AliDigits::GetDigitFast(Int_t row, Int_t column) +{ + // + //return digit from fDigits array + //if out of range return dummy value ( value at row = 0, collumn = 0) + // + return fElements->At(fIndex->At(column)+row); +} + +void AliDigits::SetDigitFast(Short_t value, Int_t row, Int_t column) +{ + // + //set digit + // + if ( (row<0) || (row>=fNrows) || (column<0) || (column>=fNrows) ) + ::Error("AliDigits::SetDigitFast", "row %d col %d out of bounds (size: %d x %d, this: 0x%08x)", + row, column, fNrows, fNcols, this); + (*fElements)[fIndex->At(column)+row]=value; +} + +#endif + diff --git a/TPC/AliDigitsArray.cxx b/TPC/AliDigitsArray.cxx new file mode 100644 index 00000000000..eeb6e39db9b --- /dev/null +++ b/TPC/AliDigitsArray.cxx @@ -0,0 +1,71 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:37:42 kowal2 + +Digits handling in a new data structure + +*/ + +/////////////////////////////////////////////////////////////////////////////// +// // +// AliDigitsArray object // +// +// Origin: Marian Ivanov , GSI Darmstadt +// // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include "TObject.h" +#include "AliSegmentID.h" +#include "TObjArray.h" +#include "AliSegmentArray.h" + +#include "TError.h" +#include "AliDigits.h" +#include "AliDetectorParam.h" +#include "AliDigitsArray.h" + + + +ClassImp(AliDigitsArray) +// + +AliDigitsArray::AliDigitsArray() +{ + fParam = 0; +} + +AliDigitsArray::~AliDigitsArray() +{ + if (fParam != 0) delete fParam; +} + +Bool_t AliDigitsArray::Setup(AliDetectorParam *param) +{ + // + //setup array according parameters + SetParam(param); + return kTRUE; +} + + +Bool_t AliDigitsArray::SetParam(AliDetectorParam * param) +{ + fParam = param; + return kTRUE; +} diff --git a/TPC/AliDigitsArray.h b/TPC/AliDigitsArray.h new file mode 100644 index 00000000000..9200457318d --- /dev/null +++ b/TPC/AliDigitsArray.h @@ -0,0 +1,25 @@ +#ifndef ALIDIGITSARRAY_H +#define ALIDIGITSARRAY_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +//////////////////////////////////////////////// +// Manager class for AliDigitsArray // +//////////////////////////////////////////////// +class AliDetectorParam; + +class AliDigitsArray : public AliSegmentArray { +public: + AliDigitsArray(); + ~AliDigitsArray(); + virtual Bool_t Setup(AliDetectorParam *param); //setup array according parameters + const AliDetectorParam * GetParam() {return fParam;} + virtual Bool_t SetParam(AliDetectorParam * param); +protected: + AliDetectorParam * fParam; //pointer to detector parameters + ClassDef(AliDigitsArray,1) +}; + +#endif //ALIDIGITSARRAY_H diff --git a/TPC/AliH2F.cxx b/TPC/AliH2F.cxx new file mode 100644 index 00000000000..da02e6e807f --- /dev/null +++ b/TPC/AliH2F.cxx @@ -0,0 +1,387 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:32:37 kowal2 + +"ROOT"-based class with some extra functionality + +*/ + +//---------------------------------------------------------------------------- +// Author: Marian Ivanov +// +// Implementation of class AliH2F +// +//----------------------------------------------------------------------------- + +#include "AliH2F.h" +#include "TClonesArray.h" +#include "AliTPC.h" +#include "TRandom.h" +#include "AliCluster.h" +#include "AliClusterFinder.h" +//*KEEP,TMath. + +// other include files follow here + + +ClassImp(AliH2F) +//*********************************************************************** +//*********************************************************************** +//*********************************************************************** +//*********************************************************************** +AliH2F::AliH2F():TH2F() +{ + fSigmaX2 = 1.; + fSigmaY2 = 1.; + fdx = 1; + fdy=1; + fFitMatrix.ResizeTo(5,1); +} +AliH2F::AliH2F(const Text_t *name,const Text_t *title, + Int_t nbinsx,Axis_t xlow,Axis_t xup + ,Int_t nbinsy,Axis_t ylow,Axis_t yup): + TH2F(name,title,nbinsx,xlow,xup + ,nbinsy,ylow,yup) +{ + fSigmaX2 = 1.; + fSigmaY2 = 1.; + fdx = 1; + fdy=1; + fFitMatrix.ResizeTo(5,1); +} + +AliH2F::~AliH2F() +{ +} + +AliH2F::AliH2F(const AliH2F &) +{ +} + +AliH2F & AliH2F::operator = (const AliH2F &) +{ + return *this; +} + +TClonesArray * AliH2F::FindPeaks(Float_t threshold, Float_t noise) +{ + //find peaks and write it in form of AliTPCcluster to array + + //firstly we need to create object for cluster finding + //and fill it with contents of histogram + AliClusterFinder cfinder; + cfinder.SetThreshold(threshold); + cfinder.SetNoise(noise); + cfinder.GetHisto(this); + return cfinder.FindPeaks3(); +} + +void AliH2F::ClearSpectrum() +{ + Int_t dimx = fXaxis.GetNbins(); + Int_t dimy = fYaxis.GetNbins(); + for (Int_t i = 0 ;iGaus(0,sn); + Float_t oldv =GetCellContent(i,j); + Float_t olds =GetCellError(i,j); + if (noise >0) + { + SetCellContent(i,j,noise+oldv); + SetCellError(i,j,TMath::Sqrt((noise*noise+olds*olds))); + } + } +} +void AliH2F::AddGauss(Float_t x, Float_t y, + Float_t sx, Float_t sy, Float_t max) +{ + //transform to histogram coordinata + Int_t dimx = fXaxis.GetNbins(); + Int_t dimy = fYaxis.GetNbins(); + Float_t dx =(GetXaxis()->GetXmax()-GetXaxis()->GetXmin())/Float_t(dimx); + Float_t dy =(GetYaxis()->GetXmax()-GetYaxis()->GetXmin())/Float_t(dimy); + // x=(x-GetXaxis()->GetXmin())/dx; + //y=(y-GetYaxis()->GetXmin())/dy; + sx/=dx; + sy/=dy; + + + for (Int_t i = 0 ;iGetBinCenter(i+1); + Float_t y2 =GetYaxis()->GetBinCenter(j+1); + Float_t dx2 = (x2-x)*(x2-x); + Float_t dy2 = (y2-y)*(y2-y); + Float_t amp =max*exp(-(dx2/(2*sx*sx)+dy2/(2*sy*sy))); + //Float_t oldv =GetCellContent(i+1,j+1); + // SetCellContent(i+1,j+1,amp+oldv); + Fill(x2,y2,amp); + } +} + +void AliH2F::ClearUnderTh(Int_t threshold) +{ + Int_t dimx = fXaxis.GetNbins(); + Int_t dimy = fYaxis.GetNbins(); + for (Int_t i = 0 ;i<=dimx;i++) + for (Int_t j = 0 ;j<=dimy;j++) + { + Float_t oldv =GetCellContent(i,j); + if (oldv GetBin(i,j); + Float_t val = GetBinContent(index1); + // sub->SetBinContent(index2,val); + // Float_t err = GetBinError(index1); + //sub->SetBinError(index2,GetBinError(index1)); + sub->SetCellContent(i,j,val); + } + return sub; +} + +TH1F *AliH2F::GetAmplitudes(Float_t zmin, Float_t zmax, Float_t th, Float_t xmin, Float_t xmax, + Float_t ymin, Float_t ymax) +{ + //this function return pointer to the new created + //histogram which is subhistogram of the + //calculate number + //subhistogram range must be inside histogram + + if (xmax<=xmin) { + xmin=fXaxis.GetXmin(); + xmax=fXaxis.GetXmax(); + } + if (ymax<=ymin) { + ymin=fYaxis.GetXmin(); + ymax=fYaxis.GetXmax(); + } + Int_t nx = Int_t((xmax-xmin)/(fXaxis.GetXmax()-fXaxis.GetXmin()) * + Float_t(fXaxis.GetNbins())); + Int_t ny = Int_t((ymax-ymin)/(fYaxis.GetXmax()-fYaxis.GetXmin()) * + Float_t(fYaxis.GetNbins())); + TString t1 = fName ; + TString t2 = fTitle ; + t1+="_amplitudes"; + t2+="_amplitudes"; + const Text_t * tt1 = t1; + const Text_t * tt2 = t2; + + TH1F * h = new TH1F(tt1,tt2,100,zmin,zmax); + + Int_t i1 = Int_t( Float_t(fXaxis.GetNbins())*(xmin-fXaxis.GetXmin())/ + (fXaxis.GetXmax()-fXaxis.GetXmin()) ) ; + Int_t i2 = Int_t( Float_t(fYaxis.GetNbins())*(ymin-fYaxis.GetXmin())/ + (fYaxis.GetXmax()-fYaxis.GetXmin()) ) ; + for (Int_t i=0;ith) h->Fill(val); + } + return h; +} + +Float_t AliH2F::GetOccupancy(Float_t th , Float_t xmin, Float_t xmax, + Float_t ymin, Float_t ymax) +{ + //this function return pointer to the new created + //histogram which is subhistogram of the + //calculate number + //subhistogram range must be inside histogram + + if (xmax<=xmin) { + xmin=fXaxis.GetXmin(); + xmax=fXaxis.GetXmax(); + } + if (ymax<=ymin) { + ymin=fYaxis.GetXmin(); + ymax=fYaxis.GetXmax(); + } + Int_t nx = Int_t((xmax-xmin)/(fXaxis.GetXmax()-fXaxis.GetXmin()) * + Float_t(fXaxis.GetNbins())); + Int_t ny = Int_t((ymax-ymin)/(fYaxis.GetXmax()-fYaxis.GetXmin()) * + Float_t(fYaxis.GetNbins())); + + Int_t over =0; + Int_t i1 = Int_t( Float_t(fXaxis.GetNbins())*(xmin-fXaxis.GetXmin())/ + (fXaxis.GetXmax()-fXaxis.GetXmin()) ) ; + Int_t i2 = Int_t( Float_t(fYaxis.GetNbins())*(ymin-fYaxis.GetXmin())/ + (fYaxis.GetXmax()-fYaxis.GetXmin()) ) ; + for (Int_t i=0;ith) over++; + } + Int_t all = nx*ny; + if (all>0) return Float_t(over)/Float_t(all); + else + return 0; +} + +//TH1F * AliH2F::GetSubrange1dx(Float_t xmin, Float_t xmax, Float_t y) +//{ +// +//} +//TH1F * AliH2F::GetSubrange1dy(Float_t x, Float_t ymin, Float_t ymax) +//{ +// +//} + +void AliH2F::SetSmoothSigma(Float_t sigmaX, Float_t sigmaY) +{ + Float_t wx = (fXaxis.GetXmax()-fXaxis.GetXmin()) / Float_t(fXaxis.GetNbins()); + Float_t wx2 = wx*wx; + Float_t wy = (fYaxis.GetXmax()-fYaxis.GetXmin()) / Float_t(fYaxis.GetNbins()) ; + Float_t wy2 =wy*wy; + fSigmaX2 = sigmaX*sigmaX/wx2; + fSigmaY2 = sigmaY*sigmaX/wy2; +} + +void AliH2F::SetSmoothRange(Float_t dx,Float_t dy) +{ + Float_t wx = (fXaxis.GetXmax()-fXaxis.GetXmin()) / Float_t(fXaxis.GetNbins()); + Float_t wy = (fYaxis.GetXmax()-fYaxis.GetXmin()) / Float_t(fYaxis.GetNbins()); + fdx = Int_t(dx/wx); + fdy = Int_t(dy/wy); +} + +TMatrix * AliH2F::GetFitMatrix(Int_t irow, Int_t icolumn) +{ + SmoothCell(irow,icolumn); + return &fFitMatrix; +} + +void AliH2F::SmoothCell(Int_t irow, Int_t icolumn) +{ + //calculate interpolation around point irow icollumn + //fitting by surface of second oreder + Int_t index; + Float_t x,y,z,x2,x3,x4,y2,y3,y4; + Float_t sz = 0.0,szx = 0.0 ,szy = 0.0 ,szx2 = 0.0,szy2 = 0.0; + Float_t sx = 0.,sx2 = 0.,sx3 = 0.,sx4 = 0.; + Float_t sy = 0.,sy2 = 0. ,sy3 = 0. ,sy4 = 0.; + Float_t sxy = 0.,sxy2 = 0. ,sx2y =0.0 ,sx2y2 =0.0; + Float_t w; + Float_t sumweight = 0; + for (Int_t i = -fdx; i <=fdx; i++) + for (Int_t j = -fdy; j <=fdy; j++) + { + index = GetBin(irow+i,icolumn+j); + w = 1/(Float_t(i*i)+fSigmaX2)*1/(Float_t(j*j)+fSigmaY2); + z = GetBinContent(index); + x = irow+i; + x2 = x*x; x3 = x2*x; x4 = x2*x2; + y = icolumn+j; + y2 = y*y; y3 = y2*y; y4 = y2*y2; + sz += z*w; sx += x*w; sy += y*w; + szx += z*x*w; szy += z*y*w; szx2+= z*x2*w; szy2 += z*y3*w; + sx2 += x2*w; sx3 += x3*w; sx4 += x4*w; + sy2 += y2*w; sy3 += y3*w; sy4 += y4*w; + sxy += x*y*w; sxy2+= x*y2*w; sx2y+=x2*y*w; sx2y2+= x2*y2*w; + sumweight +=w; + } + TMatrix mat(5,5); + if (!fFitMatrix.IsValid()) fFitMatrix.ResizeTo(5,1); + + fFitMatrix(0,0) = sz; + fFitMatrix(1,0) = szx; + fFitMatrix(2,0) = szy; + fFitMatrix(3,0) = szx2; + fFitMatrix(4,0) = szy2; + + mat(0,0) = sumweight; + mat(0,1) = sx; mat(0,2) = sy; mat(0,3) = sx2; mat(0,4) =sy2; + mat(1,0) = sx; mat(1,1) = sx2; mat(1,2) = sxy; mat(1,3) = sx3; mat(1,4) =sxy2; + mat(2,0) = sy; mat(2,1) = sxy; mat(2,2) = sy2; mat(2,3) = sx2y; mat(2,4) =sy3 ; + mat(3,0) = sx2; mat(3,1) = sx3; mat(3,2) = sx2y;mat(3,3) = sx4 ; mat(3,4) =sx2y2; + mat(4,0) = sy2; mat(4,1) = sxy2; mat(4,2) = sy3; mat(4,3) = sx2y2;mat(4,4) =sy4; +} diff --git a/TPC/AliH2F.h b/TPC/AliH2F.h new file mode 100644 index 00000000000..6ea5ddb97fb --- /dev/null +++ b/TPC/AliH2F.h @@ -0,0 +1,63 @@ +#ifndef TH2FSMOOTH_H +#define TH2FSMOOTH_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +// include files and class forward declarations + +#include "TH2.h" +#include "TMatrix.h" + +class TMatrix; +class TH1F; +class TClonesArray; + +class AliH2F : public TH2F { +public: + AliH2F(); + AliH2F(const Text_t *name,const Text_t *title,Int_t nbinsx, + Axis_t xlow,Axis_t xup,Int_t nbinsy,Axis_t ylow,Axis_t yup); + ~AliH2F(); + +public: + AliH2F(const AliH2F &); + AliH2F & operator = (const AliH2F &); + TClonesArray * FindPeaks(Float_t threshold, Float_t noise); + //find peaks and write it in form of AliTPCcluster to array + void ClearSpectrum(); + void AddGauss(Float_t x,Float_t y,Float_t sx, Float_t sy, Float_t max); + void AddNoise(Float_t sn); + void ClearUnderTh(Int_t threshold); + void Round(); + //round float values to integer values + // void Smooth(); + AliH2F * GetSubrange2d(Float_t xmin, Float_t xmax, + Float_t ymin, Float_t ymax); + //create new 2D histogram + Float_t GetOccupancy(Float_t th=1. , Float_t xmin=0, Float_t xmax=0, + Float_t ymin=0, Float_t ymax=0); + //calculate ration of channel over threshold to all channels + TH1F * GetAmplitudes(Float_t zmin, Float_t zmax, Float_t th=1. , Float_t xmin=0, Float_t xmax=0, + Float_t ymin=0, Float_t ymax=0); + //generate one dim histogram of amplitudes + void SetSmoothSigma(Float_t sigmaX, Float_t sigmaY); + void SetSmoothRange(Float_t dx,Float_t dy); + TMatrix * GetFitMatrix(Int_t irow, Int_t icolumn); + +public: + +protected: + +private: + void SmoothCell(Int_t irow, Int_t icolumn) ; + Float_t fSigmaX2; //sigma x used for weight calculation in smooth proces + Float_t fSigmaY2; //sigma x used for weight calculation in smooth proces + Int_t fdx; //dx range on which we are smoothing around 1 point + Int_t fdy; //dy range on which we are smoothing around 1 point + TMatrix fFitMatrix; //matrix with fitted parameters + ClassDef(AliH2F,1) +}; + +#endif /*TH2FSMOOTH_H */ diff --git a/TPC/AliSegmentArray.cxx b/TPC/AliSegmentArray.cxx new file mode 100644 index 00000000000..ecea7f85a8a --- /dev/null +++ b/TPC/AliSegmentArray.cxx @@ -0,0 +1,342 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:39:36 kowal2 + +New data structure handling + +*/ + +/////////////////////////////////////////////////////////////////////////////// +// // +// Alice segment manager object // +// +// AliSegmentIDArray object is array of pointers to object derived from +// AliSegmentID object // +// AliSegmentID - object in comparison with TObject enhalt +// additional information fSegmentID +// +// // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include "TClonesArray.h" +#include "TDirectory.h" +#include "AliArrayI.h" +#include "TError.h" +#include "TClass.h" + +#include "AliSegmentID.h" +#include "AliSegmentArray.h" +#include "TObjString.h" + + +//_____________________________________________________________________________ +ClassImp(AliSegmentArray) + +AliSegmentArray::AliSegmentArray() +{ + // + // + // + fNSegment=0; + fSegment =0; + fTreeIndex = 0; + fTree = 0; + fClass = 0; +} + +AliSegmentArray::AliSegmentArray(Text_t *classname, Int_t n) +{ + // + //constructor which + // + // Create an array of objects of classname. The class must inherit from + // AliSegmentID . The second argument adjust number of entries in + // the array. + fNSegment=0; + fSegment =0; + fTreeIndex = 0; + fTree = 0; + fClass = 0; + SetName("SegmentArray"); + SetTitle("SegmentArray"); + + SetClass(classname); + if (MakeArray(n)==kFALSE){ + Error("AliSegmentArray", "can't allocate %d segments in memory",n); + return; + } +} + +Bool_t AliSegmentArray::SetClass(Text_t *classname) +{ + // + //set class of stored object + if ( fClass !=0 ) { + delete fClass; + fClass = 0; + } + if (fTree !=0) { + delete fTree; + fTree = 0; + fBranch = 0; + delete fTreeIndex; + fTreeIndex = 0; + } + if (fSegment != 0) { + fSegment->Delete(); + delete fSegment; + fSegment = 0; + } + if (!gROOT) + ::Fatal("AliSegmentArray::AliSegmentArray", "ROOT system not initialized"); + + fClass = gROOT->GetClass(classname); + if (!fClass) { + Error("AliSegmentArray", "%s is not a valid class name", classname); + return kFALSE; + } + if (!fClass->InheritsFrom(AliSegmentID::Class())) { + Error("AliSegmentArray", "%s does not inherit from AliSegmentID", classname); + return kFALSE; + } + return kTRUE; +} + +AliSegmentArray::~AliSegmentArray() +{ + if (fNSegment>0){ + fSegment->Delete(); + delete fSegment; + } + if (fTree) delete fTree; + if (fTreeIndex) delete fTreeIndex; + if (fClass!=0) delete fClass; +} + +AliSegmentID * AliSegmentArray::NewSegment() +{ + // + //create object according class information + if (fClass==0) return 0; + AliSegmentID * segment = (AliSegmentID * )fClass->New(); + if (segment == 0) return 0; + return segment; +} + + +Bool_t AliSegmentArray::AddSegment(AliSegmentID *segment) +{ + // + // add segment to array + // + if (segment==0) return kFALSE; + if (fSegment==0) return kFALSE; + if (fClass==0) return kFALSE; + if (!(segment->IsA()->InheritsFrom(fClass))){ + Error("AliSegmentArray", "added class %s is not of proper type ", + segment->IsA()->GetName()); + return kFALSE; + } + fSegment->AddAt(segment,segment->GetID()); + fNSegment = fSegment->GetLast()+1; + return kTRUE; +} + +AliSegmentID * AliSegmentArray::AddSegment(Int_t index) +{ + // + // add segment to array + // + if (fSegment==0) return 0; + if (fClass==0) return 0; + AliSegmentID * segment = NewSegment(); + if (segment == 0) return 0; + fSegment->AddAt(segment,index); + segment->SetID(index); + fNSegment = fSegment->GetLast()+1; + return segment; +} + + +void AliSegmentArray::ClearSegment(Int_t index) +{ + // + //remove segment from active memory + // + if ((*fSegment)[index]){ + // (*fSegment)[index]->Delete(); //not working for TClonesArray + delete (*fSegment)[index]; //because problem with deleting TClonesArray + fSegment->RemoveAt(index); + } +} + + +Bool_t AliSegmentArray::MakeArray(Int_t n) +{ + // + //make array of pointers to Segments + // + if (fSegment) { + fSegment->Delete(); + delete fSegment; + } + fSegment = new TObjArray(n); + fNSegment=n; + if (fSegment) return kTRUE; + else return kFALSE; +} + + +void AliSegmentArray::MakeTree() +{ + // AliSegmentID segment; + AliSegmentID * psegment = NewSegment(); + if (fTree) delete fTree; + fTree = new TTree("Segment Tree","Tree with segments"); + fBranch = fTree->Branch("Segment",psegment->IsA()->GetName(),&psegment,64000,1); + delete psegment; +} + +Bool_t AliSegmentArray::MakeDictionary(Int_t size) +{ + // + //create index table for tree + // + if (size<1) return kFALSE; + if (fTreeIndex) delete fTreeIndex; + fTreeIndex = new AliArrayI(); + fTreeIndex->Set(size); + + AliSegmentID segment; + AliSegmentID * psegment = &segment; + fBranch->SetAddress(&psegment); + TBranch * brindix = fTree->GetBranch("fSegmentID"); + Int_t nevent = (Int_t)fTree->GetEntries(); + for (Int_t i = 0; iGetEvent(i); + Int_t treeIndex=segment.GetID(); + if (fTreeIndex->fNExpand(Int_t(Float_t(treeIndex)*1.5)+1); + // Int_t index = segment.GetID(); + (*fTreeIndex)[treeIndex]=i+1; // + } + return kTRUE; +} + +Bool_t AliSegmentArray::ConnectTree(const char * treeName) +{ + //connect tree from current directory + if (fTree){ + delete fTree; + fTree = 0; + fBranch = 0; + } + fTree =(TTree*)gDirectory->Get(treeName); + if (fTree == 0) return kFALSE; + fBranch = fTree->GetBranch("Segment"); + if (fBranch==0) return kFALSE; + MakeDictionary(TMath::Max(fNSegment,Int_t(fTree->GetEntries()))); + MakeArray(fTreeIndex->fN); + return kTRUE; +} + +AliSegmentID *AliSegmentArray::LoadSegment(Int_t index) +{ + // + //load segment with index to the memory + // + // + if (fTreeIndex ==0 ) MakeDictionary(3000); + //firstly try to load dictionary + if (fTreeIndex ==0 ) return 0; + if (fBranch==0) return 0; + if (index>fTreeIndex->fN) return 0; + AliSegmentID *s = (AliSegmentID*)(*fSegment)[index]; + if (s==0) s= NewSegment(); + s->SetID(index); + // new AliSegmentID(index); + + if (s!=0) { + Int_t treeIndex =(*fTreeIndex)[index]; + if (treeIndex<1) return 0; + else treeIndex--; //I don't like it Int table I have index shifted by 1 + fBranch->SetAddress(&s); + fTree->GetEvent(treeIndex); + (*fSegment)[index] = (TObject*) s; + } + else + return 0; + return s; + +} +AliSegmentID *AliSegmentArray::LoadEntry(Int_t index) +{ + // + //load segment at position inex in tree to the memory + // + // + if (fBranch==0) return 0; + if (index>fTree->GetEntries()) return 0; + AliSegmentID * s = NewSegment(); + + if (s) { + fBranch->SetAddress(&s); + fTree->GetEvent(index); + } + else + return 0; + Int_t nindex = s->GetID(); + ClearSegment(nindex); + (*fSegment)[nindex] = (TObject*) s; + return s; +} + +void AliSegmentArray::StoreSegment(Int_t index) +{ + // + //make segment persistent + // + const AliSegmentID * segment = (*this)[index]; + if (segment == 0 ) return; + if (fTree==0) MakeTree(); + fBranch->SetAddress(&segment); + fTree->Fill(); +} + + +void AliSegmentArray::Streamer(TBuffer &R__b) +{ + TObjString treeName, * ptreeName=&treeName; + if (R__b.IsReading()) { + Version_t R__v = R__b.ReadVersion(); if (R__v) { } + TNamed::Streamer(R__b); + R__b>>ptreeName; + if (fTree) delete fTree; + ConnectTree(ptreeName->String()); + } else { + R__b.WriteVersion(AliSegmentArray::IsA()); + TNamed::Streamer(R__b); + // char ch[200]; + // sprintf(ch,"%s",fTrre->GetTitle()); + treeName.String() = fTree->GetTitle(); + R__b<Write(); + } +} diff --git a/TPC/AliSegmentArray.h b/TPC/AliSegmentArray.h new file mode 100644 index 00000000000..6ac9caf270b --- /dev/null +++ b/TPC/AliSegmentArray.h @@ -0,0 +1,78 @@ +#ifndef ALISEGARRAY_H +#define ALISEGARRAY_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +//////////////////////////////////////////////// +// Manager class general Alice segment +// segment is for example one pad row in TPC // +//////////////////////////////////////////////// + +#include "TNamed.h" +#include "TError.h" +//#include "AliSegmentID.h" + +class TTree; +class TBranch; +class AliArrayI; +class AliSegmentID; +class TObjArray; + +class AliSegmentArray: public TNamed{ +public: + AliSegmentArray(); + AliSegmentArray(Text_t *classname, Int_t n); // + Bool_t SetClass(Text_t *classname); //set class of stored object + ~AliSegmentArray(); + inline const AliSegmentID * At(Int_t i); //return pointer to segment with index i + inline const AliSegmentID * operator[](Int_t i); //return pointer to segment with index i + + Bool_t AddSegment(AliSegmentID *segment); // add segment to array + AliSegmentID * AddSegment(Int_t index); //create objet and set index + Bool_t MakeArray(Int_t n); //make array of pointers to Segments + void ClearSegment(Int_t index); //remove segment from active + virtual AliSegmentID * NewSegment(); //dynamicaly create new segment + //input output functions + TTree * GetTree(){return fTree;} //return pointer to connected tree + + virtual void MakeTree(); //Make tree with the name + virtual Bool_t ConnectTree(const char * treeName); //connect tree from current directory + virtual AliSegmentID * LoadSegment(Int_t index);//load segment with index to the memory + virtual AliSegmentID * LoadEntry(Int_t index); //load segment entry from position index in tree + virtual void StoreSegment(Int_t index);//write segmen persistent + Bool_t MakeDictionary(Int_t size);//create index table for tree + TClass * GetClass() {return fClass;} + +public: + TObjArray * fSegment; //!pointer to array of pointers to segment + AliArrayI * fTreeIndex; //!pointers(index) table in tree + Int_t fNSegment; + TTree * fTree; //!tree with segment objects + TBranch * fBranch; //!total branch +private: + TClass * fClass; //!class type of included objects + ClassDef(AliSegmentArray,1) +}; + + + +const AliSegmentID* AliSegmentArray::operator[](Int_t i) +{ + // + //return segment with given index + // + if ( (i<0) || (i>=fNSegment)) return 0; + return (AliSegmentID *)((*fSegment)[i]); +} +const AliSegmentID* AliSegmentArray::At(Int_t i) +{ + // + //return segment with given index + // + if ( (i<0) || (i>=fNSegment)) return 0; + return (AliSegmentID *)((*fSegment)[i]); +} + +#endif //ALISEGARRAY_H diff --git a/TPC/AliSegmentID.cxx b/TPC/AliSegmentID.cxx new file mode 100644 index 00000000000..286a83c6dcc --- /dev/null +++ b/TPC/AliSegmentID.cxx @@ -0,0 +1,38 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:39:36 kowal2 + +New data structure handling + +*/ + +/////////////////////////////////////////////////////////////////////////////// +// // +// Alice AliSementID object // +// +// // +// // +/////////////////////////////////////////////////////////////////////////////// + + +#include "AliSegmentID.h" +AliSegmentID::AliSegmentID() +{ +} + +ClassImp(AliSegmentID) diff --git a/TPC/AliSegmentID.h b/TPC/AliSegmentID.h new file mode 100644 index 00000000000..3da7ee3832f --- /dev/null +++ b/TPC/AliSegmentID.h @@ -0,0 +1,27 @@ +#ifndef ALISEGMENTID_H +#define ALISEGMENTID_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +//////////////////////////////////////////////// +// Manager class generaol Alice segment +// segment is for example one pad row in TPC // +//////////////////////////////////////////////// + +#include "TObject.h" + +class AliSegmentID: public TObject{ +public: + AliSegmentID(); + AliSegmentID(Int_t index){fSegmentID = index;} + Int_t GetID() {return fSegmentID;} + void SetID(Int_t index){fSegmentID = index;} +protected: + Int_t fSegmentID; //identification number of Segment + ClassDef(AliSegmentID,1) +}; + +#endif //ALISEGMENTID_H + diff --git a/TPC/AliSimDigits.cxx b/TPC/AliSimDigits.cxx new file mode 100644 index 00000000000..32093fa0933 --- /dev/null +++ b/TPC/AliSimDigits.cxx @@ -0,0 +1,394 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:37:42 kowal2 + +Digits handling in a new data structure + +*/ + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Alice segment manager object // +// +// AliSimDigits object (derived from AliDigits) // +// provide additional track information to digit // +// +// Origin: Marian Ivanov GSI Darmstadt // +// +// // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include "TClass.h" +#include +#include "TError.h" +#include "AliSegmentID.h" +#include "AliH2F.h" +#include "AliArrayI.h" +#include "AliArrayS.h" +#include "AliDigits.h" +#include "AliSimDigits.h" +#include "AliTPC.h" + + + +//_____________________________________________________________________________ +//_____________________________________________________________________________ +//_____________________________________________________________________________ +ClassImp(AliSimDigits) + +AliSimDigits::AliSimDigits() +{ + // AliDigits::Invalite(); + fTracks = 0; + fTrIndex = 0; + InvalidateTrack(); +} +AliSimDigits::~AliSimDigits() +{ + // AliDigits::Invalidate(); + if (fTracks != 0) fTracks->Delete(); + if (fTrIndex != 0) fTrIndex->Delete(); + +} + +void AliSimDigits::InvalidateTrack() +{ + // + //set default (invalid parameters) + if ( fTracks != 0) delete fTracks; + fTracks = new AliArrayI; + if ( fTrIndex != 0) delete fTrIndex; + fTrIndex = new AliArrayI; + + for (Int_t i = 0; i<3; i++){ + fTracks->Set(0); + fTrIndex->Set(0); + } +} + +void AliSimDigits::AllocateTrack(Int_t length) +{ + // + //construct empty buffer fElements and fTracks with size fNrows x fNcols x + //length + InvalidateTrack(); + fNlevel = length; + fTracks->Set(fNcols*fNrows*fNlevel); + fTrIndex->Set(0); + fTrBufType =0; +} + +Int_t AliSimDigits::GetTrackID(Int_t row, Int_t column, Int_t level) +{ + // + //Get track ID + if (fTrBufType == 0) return GetTrackIDFast(row, column,level); + if (fTrBufType == 1) return GetTrackID1(row, column,level); + if (fTrBufType == 2) return GetTrackID2(row, column,level); + return 0; +} + +void AliSimDigits::ExpandTrackBuffer() +{ + // + //expand buffer to two dimensional array + if (fTrBufType<0) { + Error("ExpandBuffer", "buffer doesn't exist"); + return; + } + if (fTrBufType==0) return; //buffer expanded + if (fTrBufType==1) {ExpandTrackBuffer1(); return;} + if (fTrBufType==2) ExpandTrackBuffer2(); + +} + +void AliSimDigits::CompresTrackBuffer(Int_t bufType) +{ + // + //compres buffer according buffertype algorithm + // + if (fTrBufType<0) { + Error("CompressBuffer", "buffer doesn't exist"); + return; + } + if (fTrBufType == bufType) return; + // + if (fTrBufType>0) ExpandTrackBuffer(); + if (fTrBufType !=0) { + Error("CompressBuffer", "buffer doesn't exist"); + return; + } + //compress buffer of type 1 + + if (bufType==1) {CompresTrackBuffer1();return;} + if (bufType==2) CompresTrackBuffer2(); + +} + +Int_t AliSimDigits::GetTrackID1(Int_t row, Int_t column, Int_t level) +{ + //return track ID of digits - for buffer compresion 2 + Int_t i,n1,n2; + i = level*fNcols+column; + if ( (i+1)>=fTrIndex->fN) n2 = fTracks->fN; + else + n2 = fTrIndex->At(i+1); + n1 = fTrIndex->At(i); + Int_t rownew = 0; + Int_t rowold=0; + Int_t ID; + for (i = n1;(iAt(i); + if (num<0) { + rownew-=num; + rowold = rownew; + i++; + if (iAt(i); + rownew+=num; + i++; + ID = fTracks->At(i); + } + } + else { + rowold = rownew; + rownew+=num; + i++; + ID = fTracks->At(i); + } +ID-=2; + if ( (row>=rowold) && (row<=rownew) ) return ID; + if (row < rownew ) return -2; //empty track + } + return -2; +} + +void AliSimDigits::ExpandTrackBuffer1() +{ + // + //expand track compressed according algorithm 1 (track ID comression independent to the digit compression) + // !!in expanded tracks we don't use fTrIndex array + // + fTrBufType = 0; + Int_t i,j; + Int_t all = fNrows*fNcols; //total number of digits + Int_t elems = all*fNlevel; //length of the buffer + + AliArrayI * buf = new AliArrayI; + buf->Set(elems); + fTrIndex->Set(0); + // + Int_t level = 0; + Int_t col=0; + Int_t row = 0; + Int_t N=fTracks->fN; + // + for (i=0;iAt(i); + if (num<0) row-=num; //negative number mean number of zeroes (no tracks of gibven level no need to write to array) + else { + i++; + Int_t ID = fTracks->At(i); + for (j = 0; j=fNrows) { + row=0; + col++; + } + if (col>=fNcols) { + col=0; + level++; + } + }//end of loop over digits + delete fTracks; + fTracks = buf; +} + +void AliSimDigits::CompresTrackBuffer1() +{ + // + //comress track according algorithm 1 (track ID comression independent to the digit compression) + // + fTrBufType = 1; + + AliArrayI * buf = new AliArrayI; //create new buffer + buf->Set(fNrows*fNcols*fNlevel); //lets have the nearly the "worst case" + AliArrayI * index = new AliArrayI; + index->Set(fNcols*fNlevel); + + Int_t icurrent=-1; //current index + Int_t izero; //number of zero + Int_t inum; //number of digits with the same current track ID + Int_t lastID =0; //last track ID + for (Int_t lev =0; lev 0 ) { //if we have some tracks in buffer + icurrent++; + if ((icurrent+1)>=buf->fN) buf->Expand(icurrent*2); + (*buf)[icurrent] = inum; + icurrent++; + (*buf)[icurrent] = lastID; + inum = 0; + lastID = 0; + } + izero++; + } + else + if (ID != lastID) + if ( izero > 0 ) { + //if we have currently izero count of non tracks digits + icurrent++; + if (icurrent>=buf->fN) buf->Expand(icurrent*2); + (*buf)[icurrent]= -izero; //write how many under zero + inum++; + izero = 0; + lastID = ID; + } + else{ + //if we change track ID from another track ID + icurrent++; + if ((icurrent+1)>=buf->fN) buf->Expand(icurrent*2); + (*buf)[icurrent] = inum; + icurrent++; + (*buf)[icurrent] = lastID; + lastID = ID; + inum = 1; + izero = 0; + } + else { + inum++; + } + + }//end of loop over rows + if ( izero > 0 ) { + //if we have currently izero count of non tracks digits + icurrent++; + if (icurrent>=buf->fN) buf->Expand(icurrent*2); + (*buf)[icurrent]= -izero; //write how many under zero + } + if ( inum> 0 ) { //if we have some tracks in buffer + icurrent++; + if ((icurrent+1)>=buf->fN) buf->Expand(icurrent*2); + (*buf)[icurrent] = inum; + icurrent++; + (*buf)[icurrent] = ID; + } + }//end of loop over columns + }//end of loop over differnet track level + buf->Expand(icurrent+1); + delete fTracks; + fTracks = buf; + delete fTrIndex; + fTrIndex = index; +} + + + +void AliSimDigits::ExpandTrackBuffer2() +{ + // + //comress track according algorithm 2 (track ID comression according digit compression) + fTrBufType = 0; +} + +void AliSimDigits::CompresTrackBuffer2() +{ + // + //comress track according algorithm 2 (track ID comression according digit compression) + fTrBufType = 2; +} + + +Int_t AliSimDigits::GetTrackID2(Int_t row, Int_t column, Int_t level) +{ + //returnb track ID of digits - for buffer compresion 2 + return -2; +} + + + +AliH2F * AliSimDigits::DrawTracks( const char *option,Int_t level, + Float_t x1, Float_t x2, Float_t y1, Float_t y2) +{ + // + //draw digits in given array + // + //make digits histo + char ch[30]; + sprintf(ch,"Track Segment_%d level %d ",GetID(),level ); + if ( (fNrows<1)|| (fNcols<1)) { + return 0; + } + AliH2F * his = new AliH2F("Track histo",ch,fNrows,0,fNrows,fNcols,0,fNcols); + ExpandTrackBuffer(); + //set histogram values + for (Int_t i = 0; iFill(i,j,GetTrackIDFast(i,j,level)); + if (x1>=0) { + AliH2F *h2fsub = his->GetSubrange2d(x1,x2,y1,y2); + delete his; + his=h2fsub; + } + if (his==0) return 0; + if (option!=0) his->Draw(option); + else his->Draw(); + return his; +} + +TClonesArray * AliSimDigits::GenerTPCClonesArray(TClonesArray * arr) +{ + // + //generate TClonnesArray of digits + // + TClonesArray * digits; + if (arr==0) digits=new TClonesArray("AliTPCdigit",300); + else digits = arr; + Int_t index = digits->GetEntriesFast(); + for (Int_t row =0; rowGetThreshold()){ + AliTPCdigit dig; + dig.fPad = col; + dig.fTime = row; + dig.fSignal= amp; + dig.fPadRow =fSegmentID; + dig.fSector =fSegmentID; + dig.fTracks[0]= GetTrackID(row,col,0); + dig.fTracks[1]= GetTrackID(row,col,1); + dig.fTracks[2]= GetTrackID(row,col,2); + TClonesArray &ldigits = *digits; + new(ldigits[index++]) AliTPCdigit(dig); + } + } + return digits; +} + diff --git a/TPC/AliSimDigits.h b/TPC/AliSimDigits.h new file mode 100644 index 00000000000..61a3e44736d --- /dev/null +++ b/TPC/AliSimDigits.h @@ -0,0 +1,75 @@ +#ifndef ALISIMDIGITS_H +#define ALISIMDIGITS_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +//////////////////////////////////////////////// +// Manager class generaol Alice segment digits +// segment is for example one pad row in TPC // +//////////////////////////////////////////////// +#include "TError.h" +#include "AliArrayI.h" +#include "AliArrayS.h" +class AliH2F; + + +class AliSimDigits : public AliDigits{ +public: + AliSimDigits(); + ~AliSimDigits(); + void AllocateTrack(Int_t length); //construct empty buffer fTracks with size rows x column x length (number of tracks for one digit) + inline Int_t GetTrackIDFast(Int_t row, Int_t column,Int_t level); //return track ID at given row and collumn + inline void SetTrackIDFast(Int_t value,Int_t row, Int_t column,Int_t level); //set ID track at given row and collumn + virtual Int_t GetTrackID(Int_t row, Int_t column, Int_t level); + virtual void ExpandTrackBuffer(); //expand buffer to twodimensional array + virtual void CompresTrackBuffer(Int_t bufType); //compres buffer according buffertype algorithm + AliH2F * DrawTracks( const char *option=0,Int_t level=0, + Float_t x1=-1, Float_t x2=-1, Float_t y1=-1, Float_t y2=-1); //draw tracks + TClonesArray * GenerTPCClonesArray(TClonesArray * arr); //generate TClonnesArray of digits + //only for demonstration purpose +public: + void InvalidateTrack(); + + Int_t GetTrackID1(Int_t row, Int_t column, Int_t level); //returnb track ID of digits - for buffer compresion 1 + void ExpandTrackBuffer1(); //comress track according algorithm 1 (track ID comression independent to the digit compression) + void CompresTrackBuffer1(); //comress track according algorithm 1 (track ID comression independent to the digit compression) + + Int_t GetTrackID2(Int_t row, Int_t column, Int_t level); //returnb track ID of digits - for buffer compresion 2 + void ExpandTrackBuffer2(); //comress track according algorithm 2 (track ID comression according digit compression) + void CompresTrackBuffer2(); //comress track according algorithm 2 (track ID comression according digit compression) + + AliArrayI * fTracks; //buffer of track index + AliArrayI * fTrIndex; //index position of column + Int_t fNlevel; //number of tracks etries for one digit + Int_t fTrBufType; //buffer type of the tracks + // Bool_t ClassError( ); //signalize class error + ClassDef(AliSimDigits,1) +}; + + + +Int_t AliSimDigits::GetTrackIDFast(Int_t row, Int_t column,Int_t level) +{ + // + //return track ID at given row and column + // return fTracks[level].At(fTrIndex[level][column]+row); + return fTracks->At(level*fNrows*fNcols+fNrows*column+row); +} + +void AliSimDigits::SetTrackIDFast(Int_t value,Int_t row, Int_t column,Int_t level) +{ +value+=2; + //set ID track at given row and collumn + // fTracks[level][fTrIndex[level][column]+row]=value; + if ( (row<0) || (row>=fNrows) || (column<0) || (column>=fNcols) ) + ::Error("AliSimDigits::SetTrackIDFast", "row %d col %d out of bounds (size: %d x %d, this: 0x%08x)", + row, column, fNrows, fNcols, this); + if ( (level<0) || (level>=fNlevel)) ::Error("AliSimDigits::SetTrackIDFast", "index %d out of bounds", level); + (*fTracks)[level*fNrows*fNcols+fNrows*column+row]=value; +} + + + +#endif diff --git a/TPC/AliTPC.cxx b/TPC/AliTPC.cxx index 533e76bc5a2..67f385972d8 100644 --- a/TPC/AliTPC.cxx +++ b/TPC/AliTPC.cxx @@ -15,6 +15,19 @@ /* $Log$ +Revision 1.17.2.2 2000/04/10 08:15:12 kowal2 + +New, experimental data structure from M. Ivanov +New tracking algorithm +Different pad geometry for different sectors +Digitization rewritten + +Revision 1.17.2.1 2000/04/10 07:56:53 kowal2 +Not used anymore - removed + +Revision 1.17 2000/01/19 17:17:30 fca +Introducing a list of lists of hits -- more hits allowed for detector now + Revision 1.16 1999/11/05 09:29:23 fca Accept only signals > 0 @@ -57,11 +70,18 @@ Introduction of the Copyright and cvs Log #include #include "AliMC.h" -//MI change + #include "AliTPCParam.h" -#include "AliTPCD.h" #include "AliTPCPRF2D.h" #include "AliTPCRF1D.h" +#include "AliDigits.h" +#include "AliSimDigits.h" + +#include "AliTPCDigitsArray.h" +#include "AliCluster.h" +#include "AliClusters.h" +#include "AliTPCClustersRow.h" +#include "AliTPCClustersArray.h" @@ -81,9 +101,10 @@ AliTPC::AliTPC() fNsectors = 0; fNtracks = 0; fNclusters= 0; - - fDigParam= new AliTPCD(); - fDigits = fDigParam->GetArray(); + //MI changes + fDigitsArray = 0; + fClustersArray = 0; + fTPCParam = 0; } //_____________________________________________________________________________ @@ -97,23 +118,18 @@ AliTPC::AliTPC(const char *name, const char *title) // // Initialise arrays of hits and digits fHits = new TClonesArray("AliTPChit", 176); - gAlice->AddHitList(fHits); - // fDigits = new TClonesArray("AliTPCdigit",10000); - //MI change - fDigParam= new AliTPCD; - fDigits = fDigParam->GetArray(); - - AliTPCParam *fTPCParam = &(fDigParam->GetParam()); - + //MI change + fDigitsArray = 0; + fClustersArray= 0; + fTPCParam = 0; // // Initialise counters - // fClusters = 0; fTracks = 0; - fNsectors = fTPCParam->GetNSector(); + fNsectors = 0; fNtracks = 0; fNclusters= 0; - fDigitsIndex = new Int_t[fNsectors+1]; + // fIshunt = 0; // @@ -132,8 +148,10 @@ AliTPC::~AliTPC() delete fDigits; delete fClusters; delete fTracks; - delete fDigParam; - if (fDigitsIndex) delete [] fDigitsIndex; + if (fDigitsArray!=0) delete fDigitsArray; + if (fClustersArray!=0) delete fClustersArray; + + if (fTPCParam) delete fTPCParam; } //_____________________________________________________________________________ @@ -153,23 +171,11 @@ void AliTPC::AddCluster(const AliTPCcluster &c) // // Add a simulated cluster copy to the list // - if(!fClusters) fClusters=new TClonesArray("AliTPCcluster",10000); + if(!fClusters) fClusters=new TClonesArray("AliTPCcluster",900000); TClonesArray &lclusters = *fClusters; new(lclusters[fNclusters++]) AliTPCcluster(c); } -//_____________________________________________________________________________ -void AliTPC::AddDigit(Int_t *tracks, Int_t *digits) -{ - // - // Add a TPC digit to the list - // - // TClonesArray &ldigits = *fDigits; - //MI change - TClonesArray &ldigits = *fDigParam->GetArray(); - new(ldigits[fNdigits++]) AliTPCdigit(tracks,digits); -} - //_____________________________________________________________________________ void AliTPC::AddHit(Int_t track, Int_t *vol, Float_t *hits) { @@ -204,6 +210,7 @@ void AliTPC::AddTrack(const AliTPCtrack& t) //_____________________________________________________________________________ void AliTPC::BuildGeometry() { + // // Build TPC ROOT TNode geometry for the event display // @@ -215,7 +222,6 @@ void AliTPC::BuildGeometry() const Double_t kDegrad=TMath::Pi()/180; const Double_t kRaddeg=180./TMath::Pi(); - AliTPCParam * fTPCParam = &(fDigParam->GetParam()); Float_t InnerOpenAngle = fTPCParam->GetInnerAngle(); Float_t OuterOpenAngle = fTPCParam->GetOuterAngle(); @@ -246,8 +252,8 @@ void AliTPC::BuildGeometry() // inner sectors - rl = fTPCParam->GetInSecLowEdge(); - ru = fTPCParam->GetInSecUpEdge(); + rl = fTPCParam->GetInnerRadiusLow(); + ru = fTPCParam->GetInnerRadiusUp(); for(i=0;iGetOuSecLowEdge(); - ru = fTPCParam->GetOuSecUpEdge(); + rl = fTPCParam->GetOuterRadiusLow(); + ru = fTPCParam->GetOuterRadiusUp(); for(i=0;iSetLineColor(kColorTPC); fNodes->Add(Node); } + + } @@ -382,21 +390,21 @@ inline Double_t f3(Double_t x1,Double_t y1, } //_____________________________________________________________________________ -static int FindProlongation(AliTPCtrack& t, const AliTPCSector *sec, - int s, int rf=0) +static Int_t FindProlongation(AliTPCtrack& t, const AliTPCSector *sec, + Int_t s, Int_t rf=0) { //----------------------------------------------------------------- // This function tries to find a track prolongation. // // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch //----------------------------------------------------------------- - const int ROWS_TO_SKIP=int(0.5*sec->GetNRows()); + const Int_t ROWS_TO_SKIP=(t<10) ? 10 : Int_t(0.5*sec->GetNRows()); const Float_t MAX_CHI2=12.; - int try_again=ROWS_TO_SKIP; + Int_t try_again=ROWS_TO_SKIP; Double_t alpha=sec->GetAlpha(); - int ns=int(2*TMath::Pi()/alpha+0.5); + Int_t ns=Int_t(2*TMath::Pi()/alpha+0.5); - for (int nr=sec->GetRowNumber(t.GetX())-1; nr>=rf; nr--) { + for (Int_t nr=sec->GetRowNumber(t.GetX())-1; nr>=rf; nr--) { Double_t x=sec->GetX(nr), ymax=sec->GetMaxY(nr); if (!t.PropagateTo(x)) return 0; @@ -413,7 +421,7 @@ static int FindProlongation(AliTPCtrack& t, const AliTPCSector *sec, } if (row) { - for (int i=row.Find(y-road); ifY > y+road) break; if (c->IsUsed()) continue; @@ -426,9 +434,8 @@ static int FindProlongation(AliTPCtrack& t, const AliTPCSector *sec, } if (cl) { t.Update(cl,max_chi2); - Double_t ll=TMath::Sqrt((1+t.GetTgl()*t.GetTgl())/ + cl->fdEdX=sec->GetPadPitchWidth()*TMath::Sqrt((1+t.GetTgl()*t.GetTgl())/ (1-(t.GetC()*x-t.GetEta())*(t.GetC()*x-t.GetEta()))); - cl->fdEdX = cl->fQ/ll; try_again=ROWS_TO_SKIP; } else { if (try_again==0) break; @@ -444,12 +451,13 @@ static int FindProlongation(AliTPCtrack& t, const AliTPCSector *sec, } return 1; + } //_____________________________________________________________________________ -static void MakeSeeds(TObjArray& seeds,const AliTPCSector *sec, int max_sec, -int i1, int i2) +static void MakeSeeds(TObjArray& seeds,const AliTPCSector *sec, Int_t max_sec, +Int_t i1, Int_t i2) { //----------------------------------------------------------------- // This function creates track seeds. @@ -457,19 +465,19 @@ int i1, int i2) // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch //----------------------------------------------------------------- TMatrix C(5,5); TVector x(5); - double alpha=sec->GetAlpha(), shift=sec->GetAlphaShift(); - double cs=cos(alpha), sn=sin(alpha); - for (int ns=0; nsGetAlpha(), shift=sec->GetAlphaShift(); + Double_t cs=cos(alpha), sn=sin(alpha); + for (Int_t ns=0; nsGetX(i1), y1=r1[is]->fY, z1=r1[is]->fZ; - for (int js=0; js < nl+nm+nu; js++) { + for (Int_t is=0; is < r1; is++) { + Double_t x1=sec->GetX(i1), y1=r1[is]->fY, z1=r1[is]->fZ; + for (Int_t js=0; js < nl+nm+nu; js++) { const AliTPCcluster *cl; - int ks; - double x2=sec->GetX(i2), y2, z2, tmp; + Int_t ks; + Double_t x2=sec->GetX(i2), y2, z2, tmp; if (js5) continue; + + Double_t d=(x2-x1)*(0.-y2)-(0.-x2)*(y2-y1); if (d==0.) {cerr<<"MakeSeeds warning: Straight seed !\n"; continue;} + Double_t x3=0., y3=0.;//gRandom->Gaus(0.,TMath::Sqrt(cl->fSigmaY2)); + x(0)=y1; x(1)=z1; - x(2)=f1(x1,y1,x2,y2,0.,0.); - x(3)=f2(x1,y1,x2,y2,0.,0.); + x(2)=f1(x1,y1,x2,y2,x3,y3); + x(3)=f2(x1,y1,x2,y2,x3,y3); x(4)=f3(x1,y1,x2,y2,z1,z2); if (TMath::Abs(x(2)*x1-x(3)) >= 0.999) continue; @@ -508,20 +521,21 @@ int i1, int i2) Double_t a=asin(x(3)); Double_t zv=z1 - x(4)/x(2)*(a+asin(x(2)*x1-x(3))); - if (TMath::Abs(zv)>33.) continue; + if (TMath::Abs(zv)>10.) continue; TMatrix X(6,6); X=0.; X(0,0)=r1[is]->fSigmaY2; X(1,1)=r1[is]->fSigmaZ2; X(2,2)=cl->fSigmaY2; X(3,3)=cl->fSigmaZ2; - X(4,4)=3./12.; X(5,5)=3./12.; + X(4,4)=cl->fSigmaY2; X(5,5)=cl->fSigmaZ2; + //X(4,4)=3./12.; X(5,5)=3./12.; TMatrix F(5,6); F.UnitMatrix(); Double_t sy=sqrt(X(0,0)), sz=sqrt(X(1,1)); - F(2,0)=(f1(x1,y1+sy,x2,y2,0.,0.)-x(2))/sy; - F(2,2)=(f1(x1,y1,x2,y2+sy,0.,0.)-x(2))/sy; - F(2,4)=(f1(x1,y1,x2,y2,0.,0.+sy)-x(2))/sy; - F(3,0)=(f2(x1,y1+sy,x2,y2,0.,0.)-x(3))/sy; - F(3,2)=(f2(x1,y1,x2,y2+sy,0.,0.)-x(3))/sy; - F(3,4)=(f2(x1,y1,x2,y2,0.,0.+sy)-x(3))/sy; + F(2,0)=(f1(x1,y1+sy,x2,y2,x3,y3)-x(2))/sy; + F(2,2)=(f1(x1,y1,x2,y2+sy,x3,y3)-x(2))/sy; + F(2,4)=(f1(x1,y1,x2,y2,x3,y3+sy)-x(2))/sy; + F(3,0)=(f2(x1,y1+sy,x2,y2,x3,y3)-x(3))/sy; + F(3,2)=(f2(x1,y1,x2,y2+sy,x3,y3)-x(3))/sy; + F(3,4)=(f2(x1,y1,x2,y2,x3,y3+sy)-x(3))/sy; F(4,0)=(f3(x1,y1+sy,x2,y2,z1,z2)-x(4))/sy; F(4,1)=(f3(x1,y1,x2,y2,z1+sz,z2)-x(4))/sz; F(4,2)=(f3(x1,y1,x2,y2+sy,z1,z2)-x(4))/sy; @@ -533,7 +547,7 @@ int i1, int i2) C.Mult(t,TMatrix(TMatrix::kTransposed,F)); AliTPCtrack *track=new AliTPCtrack(r1[is], x, C, x1, ns*alpha+shift); - int rc=FindProlongation(*track,sec,ns,i2); + Int_t rc=FindProlongation(*track,sec,ns,i2); if (rc<0 || *track<(i1-i2)/2) delete track; else seeds.AddLast(track); } @@ -552,21 +566,22 @@ void AliTPC::Clusters2Tracks() //----------------------------------------------------------------- if (!fClusters) return; - AliTPCParam *p=&fDigParam->GetParam(); + AliTPCParam *p=fTPCParam; AliTPCSector::SetParam(p); - const int nis=p->GetNInnerSector()/2; + const Int_t nis=p->GetNInnerSector()/2; AliTPCSSector *ssec=new AliTPCSSector[nis]; - int nrow_low=ssec->GetNRows(); + Int_t nrow_low=ssec->GetNRows(); - const int nos=p->GetNOuterSector()/2; + const Int_t nos=p->GetNOuterSector()/2; AliTPCLSector *lsec=new AliTPCLSector[nos]; - int nrow_up=lsec->GetNRows(); + Int_t nrow_up=lsec->GetNRows(); - int ncl=fClusters->GetEntriesFast(); + Int_t ncl=fClusters->GetEntriesFast(); while (ncl--) { AliTPCcluster *c=(AliTPCcluster*)fClusters->UncheckedAt(ncl); Int_t sec=c->fSector, row=c->fPadRow; + if (sec 2.*TMath::Pi()) alpha -= 2.*TMath::Pi(); if (alpha < 0. ) alpha += 2.*TMath::Pi(); - int ns=int(alpha/lsec->GetAlpha())%nos; + Int_t ns=Int_t(alpha/lsec->GetAlpha())%nos; if (!FindProlongation(t,lsec,ns)) continue; alpha=t.GetAlpha() + 0.5*ssec->GetAlpha() - ssec->GetAlphaShift(); if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi(); if (alpha < 0. ) alpha += 2.*TMath::Pi(); - ns=int(alpha/ssec->GetAlpha())%nis; //index of the inner sector needed + ns=Int_t(alpha/ssec->GetAlpha())%nis; //index of the inner sector needed alpha=ns*ssec->GetAlpha() - t.GetAlpha(); if (!t.Rotate(alpha)) continue; - - if (!FindProlongation(t,ssec,ns)) continue; - if (t < int(0.4*nrows)) continue; + if (!FindProlongation(t,ssec,ns)) continue; - AddTrack(t); - t.UseClusters(); - cerr<= Int_t(0.4*nrows)) { + AddTrack(t); + t.UseClusters(); + cerr< q) return kFALSE; + if (bins[k-1 ].q > q) return kFALSE; + if (bins[k+max].q > q) return kFALSE; + if (bins[k+1 ].q > q) return kFALSE; + if (bins[k-max-1].q > q) return kFALSE; + if (bins[k+max-1].q > q) return kFALSE; + if (bins[k+max+1].q > q) return kFALSE; + if (bins[k-max+1].q > q) return kFALSE; + return kTRUE; +} +static void FindPeaks(Int_t k, Int_t max, Bin *bins, Peak *peaks, Int_t& n) { +//if (n>=31) return; + if (n<31) + if (IsMaximum(k,max,bins)) { + peaks[n].k=k; peaks[n].mask=(2<fSignal); +static void MarkPeak(Int_t k, Int_t max, Bin *bins, UInt_t m) { + UShort_t q=bins[k].q; - if (b.idx >= 0 && b.idx != c.idx) { - c.idx=b.idx; - c.npeaks++; - } - - if (q > TMath::Abs(c.summit->fSignal)) c.summit=b.dig; - + bins[k].mask |= m; + + if (bins[k-max].q <= q) + if ((bins[k-max].mask&m) == 0) MarkPeak(k-max,max,bins,m); + if (bins[k-1 ].q <= q) + if ((bins[k-1 ].mask&m) == 0) MarkPeak(k-1 ,max,bins,m); + if (bins[k+max].q <= q) + if ((bins[k+max].mask&m) == 0) MarkPeak(k+max,max,bins,m); + if (bins[k+1 ].q <= q) + if ((bins[k+1 ].mask&m) == 0) MarkPeak(k+1 ,max,bins,m); +} + +static void MakeCluster(Int_t k,Int_t max,Bin *bins,UInt_t m,AliTPCcluster &c){ + Float_t q=(Float_t)bins[k].q; + Int_t i=k/max, j=k-i*max; c.fY += i*q; c.fZ += j*q; c.fSigmaY2 += i*i*q; c.fSigmaZ2 += j*j*q; c.fQ += q; - c.ndigits++; - b.dig = 0; b.idx = c.idx; - - if (bins[(i-1)*maxj+j].dig) FindPreCluster(i-1,j,maxj,bins,c); - if (bins[i*maxj+(j-1)].dig) FindPreCluster(i,j-1,maxj,bins,c); - if (bins[(i+1)*maxj+j].dig) FindPreCluster(i+1,j,maxj,bins,c); - if (bins[i*maxj+(j+1)].dig) FindPreCluster(i,j+1,maxj,bins,c); + bins[k].mask = 0xFFFFFFFE; + if (bins[k-max].mask == m) MakeCluster(k-max,max,bins,m,c); + if (bins[k-1 ].mask == m) MakeCluster(k-1 ,max,bins,m,c); + if (bins[k+max].mask == m) MakeCluster(k+max,max,bins,m,c); + if (bins[k+1 ].mask == m) MakeCluster(k+1 ,max,bins,m,c); } //_____________________________________________________________________________ @@ -959,31 +995,26 @@ void AliTPC::Digits2Clusters() // // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch //----------------------------------------------------------------- - AliTPCParam *par = &(fDigParam->GetParam()); - - int inp=par->GetNPads(0, par->GetNRowLow()-1); - int onp=par->GetNPads(par->GetNSector()-1,par->GetNRowUp() -1); - const int MAXY=(inp>onp) ? inp+2 : onp+2; - const int MAXTBKT=int((z_end+6*par->GetZSigma())/par->GetZWidth())+1; - const int MAXZ=MAXTBKT+2; - const int THRESHOLD=20; - - TTree *t=(TTree*)gDirectory->Get("TreeD0_Param1"); - t->GetBranch("Digits")->SetAddress(&fDigits); - Int_t sectors_by_rows=(Int_t)t->GetEntries(); - - int ncls=0; - + AliTPCParam *par = fTPCParam; + const Int_t MAXZ=par->GetMaxTBin()+2; + + TTree *t = (TTree *)gDirectory->Get("TreeD_75x40_100x60"); + AliSimDigits digarr, *dummy=&digarr; + t->GetBranch("Segment")->SetAddress(&dummy); + Stat_t sectors_by_rows = t->GetEntries(); for (Int_t n=0; nGetEvent(n)) continue; - Bin *bins=new Bin[MAXY*MAXZ]; - AliTPCdigit *dig=(AliTPCdigit*)fDigits->UncheckedAt(0); - int sec=dig->fSector, row=dig->fPadRow; - int ndigits=fDigits->GetEntriesFast(); - - int npads, sign; + t->GetEvent(n); + Int_t sec, row; + if (!par->AdjustSectorRow(digarr.GetID(),sec,row)) { + cerr<<"AliTPC warning: invalid segment ID ! "<GetPadRowRadii(sec,row); + + Int_t npads, sign; { - int nis=par->GetNInnerSector(), nos=par->GetNOuterSector(); + Int_t nis=par->GetNInnerSector(), nos=par->GetNOuterSector(); if (sec < nis) { npads = par->GetNPadsLow(row); sign = (sec < nis/2) ? 1 : -1; @@ -993,173 +1024,107 @@ void AliTPC::Digits2Clusters() } } - int ndig; - for (ndig=0; ndigUncheckedAt(ndig); - int i=dig->fPad+1, j=dig->fTime+1; - if (i > npads) { - cerr<<"AliTPC::Digits2Clusters error: pad number is out of range ! "; - cerr< MAXTBKT) { - cerr<<"AliTPC::Digits2Clusters error: time bucket is out of range ! "; - cerr<GetZeroSup()) continue; + Int_t j=digarr.CurrentRow()+1, i=digarr.CurrentColumn()+1; + bins[i*MAXZ+j].q=dig; + bins[i*MAXZ+j].mask=1; + } while (digarr.Next()); + + Int_t ncl=0; + for (Int_t i=0; i30) continue; + + Int_t k,l; + for (k=0; k1 || dj>1) continue; + if (bins[peaks[k].k].q > bins[peaks[l].k].q) { + peaks[l].mask=peaks[k].mask; + peaks[l].k*=-1; + } else { + peaks[k].mask=peaks[l].mask; + peaks[k].k*=-1; + break; + } + } } - if (dig->fSignal >= THRESHOLD) bins[i*MAXZ+j].dig=dig; - if (i==1 || i==npads || j==1 || j==MAXTBKT) dig->fSignal*=-1; - } - int ncl=0; - int i,j; - - for (i=1; iGetPadPitchWidth()*par->GetPadPitchWidth(); - if (s2 != 0.) c.fSigmaY2 *= 0.17; - - s2 = c.fSigmaZ2/c.fQ - c.fZ*c.fZ; - c.fSigmaZ2 = s2 + 1./12.; - c.fSigmaZ2 *= par->GetZWidth()*par->GetZWidth(); - if (s2 != 0.) c.fSigmaZ2 *= 0.41; - - c.fY = (c.fY - 0.5 - 0.5*npads)*par->GetPadPitchWidth(); - c.fZ = par->GetZWidth()*c.fZ; - c.fZ -= 3.*par->GetZSigma(); // PASA delay - c.fZ = sign*(z_end - c.fZ); - - c.fSector=sec; - c.fPadRow=row; - c.fTracks[0]=c.summit->fTracks[0]; - c.fTracks[1]=c.summit->fTracks[1]; - c.fTracks[2]=c.summit->fTracks[2]; - - if (c.summit->fSignal<0) { - c.fSigmaY2 *= 25.; - c.fSigmaZ2 *= 4.; - } - - AddCluster(c); ncls++; ncl++; + for (k=0; kUncheckedAt(ndig); - int i=dig->fPad+1, j=dig->fTime+1; - if (i > npads) { - cerr<<"AliTPC::Digits2Clusters error: pad number is out of range ! "; - cerr< MAXTBKT) { - cerr<<"AliTPC::Digits2Clusters error: time bucket is out of range ! "; - cerr<GetPadPitchWidth(sec)*par->GetPadPitchWidth(sec); + if (s2 != 0.) { + c.fSigmaY2 *= 0.064*1.3*1.3; + if (secGetNInnerSector()) c.fSigmaY2 *= 1.44*1.44; + } + + s2 = c.fSigmaZ2/c.fQ - c.fZ*c.fZ; + c.fSigmaZ2 = s2 + 1./12.; + c.fSigmaZ2 *= par->GetZWidth()*par->GetZWidth(); + if (s2 != 0.) { + c.fSigmaZ2 *= 0.10*1.3*1.3; + if (secGetNInnerSector()) c.fSigmaZ2 *= 1.33*1.33; + } + + c.fY = (c.fY - 0.5 - 0.5*npads)*par->GetPadPitchWidth(sec); + c.fZ = par->GetZWidth()*(c.fZ-1); + c.fZ -= 3.*par->GetZSigma(); // PASA delay + c.fZ = sign*(z_end - c.fZ); + + if (rx<230./250.*TMath::Abs(c.fZ)) continue; + + c.fSector=sec; + c.fPadRow=row; + Int_t ki=peaks[k].k/MAXZ, kj=peaks[k].k - ki*MAXZ; + c.fTracks[0]=digarr.GetTrackID(kj-1,ki-1,0); + c.fTracks[1]=digarr.GetTrackID(kj-1,ki-1,1); + c.fTracks[2]=digarr.GetTrackID(kj-1,ki-1,2); + + c.fQ=bins[peaks[k].k].q; + + if (ki==1 || ki==npads || kj==1 || kj==MAXZ-2) { + c.fSigmaY2 *= 25.; + c.fSigmaZ2 *= 4.; + } + + AddCluster(c); ncl++; } - if (TMath::Abs(dig->fSignal)>=par->GetZeroSup()) bins[i*MAXZ+j].dig=dig; } - - for (i=1; i1) continue; //overlapped cluster - c.fY /= c.fQ; - c.fZ /= c.fQ; - - double s2 = c.fSigmaY2/c.fQ - c.fY*c.fY; - c.fSigmaY2 = s2 + 1./12.; - c.fSigmaY2 *= par->GetPadPitchWidth()*par->GetPadPitchWidth(); - if (s2 != 0.) c.fSigmaY2 *= 0.04; - - s2 = c.fSigmaZ2/c.fQ - c.fZ*c.fZ; - c.fSigmaZ2 = s2 + 1./12.; - c.fSigmaZ2 *= par->GetZWidth()*par->GetZWidth(); - if (s2 != 0.) c.fSigmaZ2 *= 0.10; - - c.fY = (c.fY - 0.5 - 0.5*npads)*par->GetPadPitchWidth(); - c.fZ = par->GetZWidth()*c.fZ; - c.fZ -= 3.*par->GetZSigma(); // PASA delay - c.fZ = sign*(z_end - c.fZ); - - c.fSector=sec; - c.fPadRow=row; - c.fTracks[0]=c.summit->fTracks[0]; - c.fTracks[1]=c.summit->fTracks[1]; - c.fTracks[2]=c.summit->fTracks[2]; - - if (c.summit->fSignal<0) { - c.fSigmaY2 *= 25.; - c.fSigmaZ2 *= 4.; - } - if (c.npeaks==0) {AddCluster(c); ncls++; ncl++;} - else { - new ((*fClusters)[c.idx]) AliTPCcluster(c); - } - } - } - - cerr<<"sector, row, digits, clusters: " - <Clear(); - + cerr<<"sector, row, compressed digits, clusters: " + <GetParam()); - Float_t driftl; - - Float_t z0=xyz[2]; - - driftl=z_end-TMath::Abs(xyz[2]); - - if(driftl<0.01) driftl=0.01; - - // check the attachment - - driftl=TMath::Sqrt(driftl); - - // Float_t sig_t = driftl*diff_t; - //Float_t sig_l = driftl*diff_l; - Float_t sig_t = driftl*fTPCParam->GetDiffT(); - Float_t sig_l = driftl*fTPCParam->GetDiffL(); - xyz[0]=gRandom->Gaus(xyz[0],sig_t); - xyz[1]=gRandom->Gaus(xyz[1],sig_t); - xyz[2]=gRandom->Gaus(xyz[2],sig_l); - - if (TMath::Abs(xyz[2])>z_end){ - xyz[2]=TMath::Sign(z_end,z0); - } - if(xyz[2]*z0 < 0.){ - Float_t eps = 0.0001; - xyz[2]=TMath::Sign(eps,z0); - } -} - //_____________________________________________________________________________ void AliTPC::Hits2Clusters() { @@ -1173,7 +1138,11 @@ void AliTPC::Hits2Clusters() // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl //----------------------------------------------------------------- - AliTPCParam * fTPCParam = &(fDigParam->GetParam()); + if(fTPCParam == 0){ + printf("AliTPCParam MUST be created firstly\n"); + return; + } + Float_t sigma_rphi,sigma_z,cl_rphi,cl_z; // TParticle *particle; // pointer to a given particle @@ -1191,22 +1160,19 @@ void AliTPC::Hits2Clusters() TTree *TH = gAlice->TreeH(); Stat_t ntracks = TH->GetEntries(); - Particles=gAlice->Particles(); //------------------------------------------------------------ - // Loop over all sectors (72 sectors) - // Sectors 0-35 are lower sectors, 0-17 z>0, 18-35 z<0 + // Loop over all sectors (72 sectors for 20 deg + // segmentation for both lower and upper sectors) + // Sectors 0-35 are lower sectors, 0-17 z>0, 17-35 z<0 // Sectors 36-71 are upper sectors, 36-53 z>0, 54-71 z<0 // // First cluster for sector 0 starts at "0" //------------------------------------------------------------ - - - // - int Nsectors=fDigParam->GetParam().GetNSector(); - for(Int_t isec=0; isecGetNSector();isec++){ //MI change - fTPCParam->AdjustAngles(isec,cph,sph); + fTPCParam->AdjustCosSin(isec,cph,sph); //------------------------------------------------------------ // Loop over tracks @@ -1220,11 +1186,13 @@ void AliTPC::Hits2Clusters() // to the particles // nhits=fHits->GetEntriesFast(); + Particles=gAlice->Particles(); // // Loop over hits // for(Int_t hit=0;hitUncheckedAt(hit); + if (tpcHit->fQ == 0.) continue; //information about track (I.Belikov) sector=tpcHit->fSector; // sector number if(sector != isec) continue; //terminate iteration ipart=tpcHit->fTrack; @@ -1255,45 +1223,202 @@ void AliTPC::Hits2Clusters() if(cl_z < 0.) cl_z=2.5e-5; // - // smearing --> rotate sectors firstly, + + // + // smearing --> rotate to the 1 (13) or to the 25 (49) sector, // then the inaccuracy in a X-Y plane is only along Y (pad row)! // - Float_t xprim= tpcHit->fX*cph + tpcHit->fY*sph; + //Float_t xprim= tpcHit->fX*cph + tpcHit->fY*sph; Float_t yprim=-tpcHit->fX*sph + tpcHit->fY*cph; xyz[0]=gRandom->Gaus(yprim,TMath::Sqrt(sigma_rphi)); // y - Double_t alpha=(sector < fTPCParam->GetNInnerSector()) ? - fTPCParam->GetInnerAngle() : fTPCParam->GetOuterAngle(); - if (TMath::Abs(xyz[0]/xprim) > TMath::Tan(0.5*alpha)) xyz[0]=yprim; xyz[1]=gRandom->Gaus(tpcHit->fZ,TMath::Sqrt(sigma_z)); // z - if (TMath::Abs(xyz[1]) > 250) xyz[1]=tpcHit->fZ; - xyz[2]=tpcHit->fQ+1;// q; let it be not equal to zero (Y.Belikov) + xyz[2]=tpcHit->fQ; // q xyz[3]=sigma_rphi; // fSigmaY2 xyz[4]=sigma_z; // fSigmaZ2 - - // and finally add the cluster - Int_t tracks[5]={tpcHit->fTrack, -1, -1, sector, tpcHit->fPadRow}; + + Int_t tracks[5]={tpcHit->fTrack, -1, -1, sector, tpcHit->fPadRow}; AddCluster(xyz,tracks); } // end of loop over hits - } // end of loop over tracks + } // end of loop over tracks - - } // end of loop over sectors + } // end of loop over sectors + +} // end of function + +//_________________________________________________________________ +void AliTPC::Hits2ExactClustersSector(Int_t isec) +{ + //-------------------------------------------------------- + //calculate exact cross point of track and given pad row + //resulting values are expressed in "digit" coordinata + //-------------------------------------------------------- + + //----------------------------------------------------------------- + // Origin: Marian Ivanov GSI Darmstadt, m.ivanov@gsi.de + //----------------------------------------------------------------- + // + if (fClustersArray==0){ + return; + } + // + TParticle *particle; // pointer to a given particle + AliTPChit *tpcHit; // pointer to a sigle TPC hit + TClonesArray *Particles; //pointer to the particle list + Int_t sector,nhits; + Int_t ipart; + const Int_t cmaxhits=30000; + TVector * xxxx = new TVector(cmaxhits*4); + TVector & xxx = *xxxx; + Int_t maxhits = cmaxhits; + //construct array for each padrow + for (Int_t i=0; iGetNRow(isec);i++) + fClustersArray->CreateRow(isec,i); + //--------------------------------------------------------------- + // Get the access to the tracks + //--------------------------------------------------------------- + + TTree *TH = gAlice->TreeH(); + Stat_t ntracks = TH->GetEntries(); + Particles=gAlice->Particles(); + Int_t npart = Particles->GetEntriesFast(); + + //------------------------------------------------------------ + // Loop over tracks + //------------------------------------------------------------ + for(Int_t track=0;trackGetEvent(track); + // + // Get number of the TPC hits and a pointer + // to the particles + // + nhits=fHits->GetEntriesFast(); + // + // Loop over hits + // + Int_t currentIndex=0; + Int_t lastrow=-1; //last writen row + for(Int_t hit=0;hitUncheckedAt(hit); + if (tpcHit==0) continue; + sector=tpcHit->fSector; // sector number + if(sector != isec) continue; + ipart=tpcHit->fTrack; + if (ipartUncheckedAt(ipart); + + //find row number + + Float_t x[3]={tpcHit->fX,tpcHit->fY,tpcHit->fZ}; + Int_t index[3]={1,isec,0}; + Int_t currentrow = fTPCParam->GetPadRow(x,index) ; + if (currentrow<0) continue; + if (lastrow<0) lastrow=currentrow; + if (currentrow==lastrow){ + if ( currentIndex>=maxhits){ + maxhits+=cmaxhits; + xxx.ResizeTo(4*maxhits); + } + xxx(currentIndex*4)=x[0]; + xxx(currentIndex*4+1)=x[1]; + xxx(currentIndex*4+2)=x[2]; + xxx(currentIndex*4+3)=tpcHit->fQ; + currentIndex++; + } + else + if (currentIndex>2){ + Float_t sumx=0; + Float_t sumx2=0; + Float_t sumx3=0; + Float_t sumx4=0; + Float_t sumy=0; + Float_t sumxy=0; + Float_t sumx2y=0; + Float_t sumz=0; + Float_t sumxz=0; + Float_t sumx2z=0; + Float_t sumq=0; + for (Int_t index=0;indexGetNPads(isec,lastrow)-1)/2; + Float_t det=currentIndex*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumx*sumx4-sumx2*sumx3)+ + sumx2*(sumx*sumx3-sumx2*sumx2); + + Float_t detay=sumy*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumxy*sumx4-sumx2y*sumx3)+ + sumx2*(sumxy*sumx3-sumx2y*sumx2); + Float_t detaz=sumz*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumxz*sumx4-sumx2z*sumx3)+ + sumx2*(sumxz*sumx3-sumx2z*sumx2); + + Float_t detby=currentIndex*(sumxy*sumx4-sumx2y*sumx3)-sumy*(sumx*sumx4-sumx2*sumx3)+ + sumx2*(sumx*sumx2y-sumx2*sumxy); + Float_t detbz=currentIndex*(sumxz*sumx4-sumx2z*sumx3)-sumz*(sumx*sumx4-sumx2*sumx3)+ + sumx2*(sumx*sumx2z-sumx2*sumxz); + + Float_t y=detay/det+CentralPad; + Float_t z=detaz/det; + Float_t by=detby/det; //y angle + Float_t bz=detbz/det; //z angle + sumy/=Float_t(currentIndex); + sumz/=Float_t(currentIndex); + AliCluster cl; + cl.fX=z; + cl.fY=y; + cl.fQ=sumq; + cl.fSigmaX2=bz; + cl.fSigmaY2=by; + cl.fTracks[0]=ipart; + + AliTPCClustersRow * row = (fClustersArray->GetRow(isec,lastrow)); + if (row!=0) row->InsertCluster(&cl); + currentIndex=0; + lastrow=currentrow; + } //end of calculating cluster for given row + + + + } // end of loop over hits + } // end of loop over tracks + //write padrows to tree + for (Int_t ii=0; iiGetNRow(isec);ii++) { + fClustersArray->StoreRow(isec,ii); + fClustersArray->ClearRow(isec,ii); + } + xxxx->Delete(); + } - +//__________________________________________________________________ void AliTPC::Hits2Digits() { - //---------------------------------------------------- - // Loop over all sectors (72 sectors) - // Sectors 0-35 are lower sectors, 0-17 z>0, 18-35 z<0 - // Sectors 36-71 are upper sectors, 36-53 z>0, 54-71 z<0 - //---- - int Nsectors=fDigParam->GetParam().GetNSector(); - for(Int_t isec=0;isecGetNSector();isec++) Hits2DigitsSector(isec); + } @@ -1312,7 +1437,7 @@ void AliTPC::Hits2DigitsSector(Int_t isec) // Get the access to the track hits //------------------------------------------------------- - AliTPCParam * fTPCParam = &(fDigParam->GetParam()); + TTree *TH = gAlice->TreeH(); // pointer to the hits tree Stat_t ntracks = TH->GetEntries(); @@ -1322,20 +1447,7 @@ void AliTPC::Hits2DigitsSector(Int_t isec) // Only if there are any tracks... //------------------------------------------- - - // TObjArrays for three neighouring pad-rows - - TObjArray **rowTriplet = new TObjArray* [3]; - - // TObjArray-s for each pad-row - TObjArray **row; - - for (Int_t trip=0;trip<3;trip++){ - rowTriplet[trip]=new TObjArray; - } - - printf("*** Processing sector number %d ***\n",isec); @@ -1354,203 +1466,38 @@ void AliTPC::Hits2DigitsSector(Int_t isec) Int_t i; - for (i=0;iGetTree()==0) fDigitsArray->MakeTree(); - if(i != 1 && i != nrows-1){ - MakeTriplet(i,rowTriplet,row); - } + for (i=0;iCreateRow(isec,i); - fDigParam->Fill(); + DigitizeRow(i,isec,row); - Int_t ndig=fDigParam->GetArray()->GetEntriesFast(); + fDigitsArray->StoreRow(isec,i); - printf("*** Sector, row, digits %d %d %d ***\n",isec,i,ndig); + Int_t ndig = dig->GetSize(); + + printf("*** Sector, row, compressed digits %d %d %d ***\n",isec,i,ndig); + + fDigitsArray->ClearRow(isec,i); - ResetDigits(); // reset digits for this row after storing them - + } // end of the sector digitization - - // delete the last triplet - for (i=0;i<3;i++) rowTriplet[i]->Delete(); - + for(i=0;iDelete(); + } + delete [] row; // delete the array of pointers to TObjArray-s } // ntracks >0 -} // end of Hits2Digits -//_____________________________________________________________________________ -void AliTPC::MakeTriplet(Int_t row, - TObjArray **rowTriplet, TObjArray **prow) -{ - //------------------------------------------------------------------ - // Makes the "triplet" of the neighbouring pad-row for the - // digitization including the cross-talk between the pad-rows - //------------------------------------------------------------------ - //----------------------------------------------------------------- - // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl - //----------------------------------------------------------------- +} // end of Hits2DigitsSector - AliTPCParam * fTPCParam = &(fDigParam->GetParam()); - Float_t gasgain = fTPCParam->GetGasGain(); - Int_t nTracks[3]; - Int_t nElements,nElectrons; - - TVector *pv; - TVector *tv; - - //------------------------------------------------------------------- - // pv is an "old" track, i.e. label + triplets of (x,y,z) - // for each electron - // - //------------------------------------------------------------------- - - - Int_t i1,i2; - Int_t nel,nt; - - if(row == 0 || row == 1){ - - // create entire triplet for the first AND the second row - - nTracks[0] = prow[0]->GetEntries(); - nTracks[1] = prow[1]->GetEntries(); - nTracks[2] = prow[2]->GetEntries(); - - for(i1=0;i1<3;i1++){ - nt = nTracks[i1]; // number of tracks for this row - - for(i2=0;i2At(i2); - TVector &v1 = *pv; - nElements = pv->GetNrows(); - nElectrons = (nElements-1)/3; - - tv = new TVector(4*nElectrons+1); // create TVector for a modified track - TVector &v2 = *tv; - v2(0)=v1(0); //track label - - for(nel=0;nelRndm())); - v2(idx2+1)= v1(idx1+1); - v2(idx2+2)= v1(idx1+2); - v2(idx2+3)= v1(idx1+3); - v2(idx2+4)= (Float_t)aval; // in number of electrons! - } // end of loop over electrons - // - // Add this track to a row - // - - rowTriplet[i1]->Add(tv); - - - } // end of loop over tracks for this row - - prow[i1]->Delete(); // remove "old" tracks - delete prow[i1]; // delete TObjArray for this row - prow[i1]=0; // set pointer to NULL - - } // end of loop over row triplets - - - } - else{ - - rowTriplet[0]->Delete(); // remove old lower row - - nTracks[0]=rowTriplet[1]->GetEntries(); // previous middle row - nTracks[1]=rowTriplet[2]->GetEntries(); // previous upper row - nTracks[2]=prow[row+1]->GetEntries(); // next row - - - //------------------------------------------- - // shift new tracks downwards - //------------------------------------------- - - for(i1=0;i1At(i1); - rowTriplet[0]->Add(pv); - } - - rowTriplet[1]->Clear(); // leave tracks on the heap!!! - - for(i1=0;i1At(i1); - rowTriplet[1]->Add(pv); - } - - rowTriplet[2]->Clear(); // leave tracks on the heap!!! - - //--------------------------------------------- - // Create new upper row - //--------------------------------------------- - - - - for(i1=0;i1At(i1); - TVector &v1 = *pv; - nElements = pv->GetNrows(); - nElectrons = (nElements-1)/3; - - tv = new TVector(4*nElectrons+1); // create TVector for a modified track - TVector &v2 = *tv; - v2(0)=v1(0); //track label - - for(nel=0;nelRndm())); - - v2(idx2+1)= v1(idx1+1); - v2(idx2+2)= v1(idx1+2); - v2(idx2+3)= v1(idx1+3); - v2(idx2+4)= (Float_t)aval; // in number of electrons! - } // end of loop over electrons - - rowTriplet[2]->Add(tv); - - } // end of loop over tracks - - prow[row+1]->Delete(); // delete tracks for this row - delete prow[row+1]; // delete TObjArray for this row - prow[row+1]=0; // set a pointer to NULL - - } - -} // end of MakeTriplet -//_____________________________________________________________________________ -void AliTPC::ExB(Float_t *xyz) -{ - //------------------------------------------------ - // ExB at the wires and wire number calulation - //------------------------------------------------ - - //----------------------------------------------------------------- - // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl - //----------------------------------------------------------------- - AliTPCParam * fTPCParam = &(fDigParam->GetParam()); - - Float_t x1=xyz[0]; - fTPCParam->GetWire(x1); //calculate nearest wire position - Float_t dx=xyz[0]-x1; - xyz[1]+=dx*fTPCParam->GetOmegaTau(); - -} // end of ExB //_____________________________________________________________________________ -void AliTPC::DigitizeRow(Int_t irow,Int_t isec,TObjArray **rowTriplet) +void AliTPC::DigitizeRow(Int_t irow,Int_t isec,TObjArray **rows) { //----------------------------------------------------------- // Single row digitization, coupling from the neighbouring @@ -1559,140 +1506,69 @@ void AliTPC::DigitizeRow(Int_t irow,Int_t isec,TObjArray **rowTriplet) //----------------------------------------------------------------- // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl + // Modified: Marian Ivanov GSI Darmstadt, m.ivanov@gsi.de //----------------------------------------------------------------- - AliTPCParam * fTPCParam = &(fDigParam->GetParam()); - Float_t chipgain= fTPCParam->GetChipGain(); Float_t zerosup = fTPCParam->GetZeroSup(); Int_t nrows =fTPCParam->GetNRow(isec); - const int MAXTBKT= - int((z_end+6*fTPCParam->GetZSigma())/fTPCParam->GetZWidth())+1; + fCurrentIndex[1]= isec; - Int_t nTracks[3]; - Int_t n_of_pads[3]; - Int_t IndexRange[4]; - Int_t i1; - Int_t iFlag; - - // - // iFlag = 0 -> inner row, iFlag = 1 -> the middle one, iFlag = 2 -> the outer one - // - nTracks[0]=rowTriplet[0]->GetEntries(); // lower row - nTracks[1]=rowTriplet[1]->GetEntries(); // middle row - nTracks[2]=rowTriplet[2]->GetEntries(); // upper row - - - if(irow == 0){ - iFlag=0; - n_of_pads[0]=fTPCParam->GetNPads(isec,0); - n_of_pads[1]=fTPCParam->GetNPads(isec,1); - } - else if(irow == nrows-1){ - iFlag=2; - n_of_pads[1]=fTPCParam->GetNPads(isec,irow-1); - n_of_pads[2]=fTPCParam->GetNPads(isec,irow); - } - else { - iFlag=1; - for(i1=0;i1<3;i1++){ - n_of_pads[i1]=fTPCParam->GetNPads(isec,irow-1+i1); - } - } - + Int_t n_of_pads = fTPCParam->GetNPads(isec,irow); + Int_t n_of_tbins = fTPCParam->GetMaxTBin(); + Int_t IndexRange[4]; // // Integrated signal for this row // and a single track signal - // - - TMatrix *m1 = new TMatrix(0,n_of_pads[iFlag]-1,0,MAXTBKT-1); // integrated - TMatrix *m2 = new TMatrix(0,n_of_pads[iFlag]-1,0,MAXTBKT-1); // single - + // + TMatrix *m1 = new TMatrix(0,n_of_pads,0,n_of_tbins); // integrated + TMatrix *m2 = new TMatrix(0,n_of_pads,0,n_of_tbins); // single // - TMatrix &Total = *m1; // Array of pointers to the label-signal list - Int_t NofDigits = n_of_pads[iFlag]*MAXTBKT; // number of digits for this row - + Int_t NofDigits = n_of_pads*n_of_tbins; // number of digits for this row Float_t **pList = new Float_t* [NofDigits]; Int_t lp; - + Int_t i1; for(lp=0;lpZero(); // clear single track signal matrix - - Float_t TrackLabel = - GetSignal(rowTriplet[iFlag],i1,n_of_pads[iFlag],m2,m1,IndexRange); - - GetList(TrackLabel,n_of_pads[iFlag],m2,IndexRange,pList); - - } - - // - // Cross talk from the neighbouring pad-rows - // - - TMatrix *m3 = new TMatrix(0,n_of_pads[iFlag]-1,0,MAXTBKT-1); // cross-talk - - TMatrix &Cross = *m3; - - if(iFlag == 0){ - - // cross-talk from the outer row only (first pad row) - - GetCrossTalk(0,rowTriplet[1],nTracks[1],n_of_pads,m3); - - } - else if(iFlag == 2){ - - // cross-talk from the inner row only (last pad row) - - GetCrossTalk(2,rowTriplet[1],nTracks[1],n_of_pads,m3); - - } - else{ - - // cross-talk from both inner and outer rows - - GetCrossTalk(3,rowTriplet[0],nTracks[0],n_of_pads,m3); // inner - GetCrossTalk(4,rowTriplet[2],nTracks[2],n_of_pads,m3); //outer + //calculate signal + // + Int_t row1 = TMath::Max(irow-fTPCParam->GetNCrossRows(),0); + Int_t row2 = TMath::Min(irow+fTPCParam->GetNCrossRows(),nrows-1); + for (Int_t row= row1;row<=row2;row++){ + Int_t nTracks= rows[row]->GetEntries(); + for (i1=0;i1Zero(); // clear single track signal matrix + Float_t TrackLabel = GetSignal(rows[row],i1,m2,m1,IndexRange); + GetList(TrackLabel,n_of_pads,m2,IndexRange,pList); + } + else GetSignal(rows[row],i1,0,m1,IndexRange); + } } - - Total += Cross; // add the cross-talk - - // - // Convert analog signal to ADC counts - // - + Int_t tracks[3]; - Int_t digits[5]; - - for(Int_t ip=0;ipGetRow(isec,irow); + for(Int_t ip=0;ipGaus(q,fTPCParam->GetNoise()); // apply noise - q *= (q_el*1.e15); // convert to fC - q *= chipgain; // convert to mV - q *= (adc_sat/dyn_range); // convert to ADC counts + q = gRandom->Gaus(q,fTPCParam->GetNoise()*fTPCParam->GetNoiseNormFac()); - if(q adc_sat) q = adc_sat; // saturation // @@ -1703,15 +1579,20 @@ void AliTPC::DigitizeRow(Int_t irow,Int_t isec,TObjArray **rowTriplet) tracks[j1] = (pList[gi]) ?(Int_t)(*(pList[gi]+j1)) : -1; } - digits[0]=isec; - digits[1]=irow; - digits[2]=ip; - digits[3]=it; - digits[4]= (Int_t)q; - - // Add this digit - - AddDigit(tracks,digits); +//Begin_Html +/* + + using of AliDigits object +*/ +//End_Html + dig->SetDigitFast((Short_t)q,it,ip); + if (fDigitsArray->IsSimulated()) + { + ((AliSimDigits*)dig)->SetTrackIDFast(tracks[0],it,ip,0); + ((AliSimDigits*)dig)->SetTrackIDFast(tracks[1],it,ip,1); + ((AliSimDigits*)dig)->SetTrackIDFast(tracks[2],it,ip,2); + } + } // end of loop over time buckets } // end of lop over pads @@ -1728,11 +1609,13 @@ void AliTPC::DigitizeRow(Int_t irow,Int_t isec,TObjArray **rowTriplet) delete m1; delete m2; - delete m3; + // delete m3; } // end of DigitizeRow + //_____________________________________________________________________________ -Float_t AliTPC::GetSignal(TObjArray *p1, Int_t ntr, Int_t np, TMatrix *m1, TMatrix *m2, + +Float_t AliTPC::GetSignal(TObjArray *p1, Int_t ntr, TMatrix *m1, TMatrix *m2, Int_t *IndexRange) { @@ -1744,111 +1627,55 @@ Float_t AliTPC::GetSignal(TObjArray *p1, Int_t ntr, Int_t np, TMatrix *m1, TMatr //----------------------------------------------------------------- // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl + // Modified: Marian Ivanov //----------------------------------------------------------------- TVector *tv; - AliTPCParam * fTPCParam = &(fDigParam->GetParam()); - AliTPCPRF2D * fPRF2D = &(fDigParam->GetPRF2D()); - AliTPCRF1D * fRF = &(fDigParam->GetRF()); - const int MAXTBKT= - int((z_end+6*fTPCParam->GetZSigma())/fTPCParam->GetZWidth())+1; - //to make the code faster we put parameters to the stack - - Float_t zwidth = fTPCParam->GetZWidth(); - Float_t zwidthm1 =1./zwidth; - tv = (TVector*)p1->At(ntr); // pointer to a track TVector &v = *tv; Float_t label = v(0); + Int_t CentralPad = (fTPCParam->GetNPads(fCurrentIndex[1],fCurrentIndex[3])-1)/2; - Int_t CentralPad = (np-1)/2; - Int_t PadNumber; Int_t nElectrons = (tv->GetNrows()-1)/4; - Float_t range=((np-1)/2 + 0.5)*fTPCParam->GetPadPitchWidth(); // pad range - - range -= 0.5; // dead zone, 5mm from the edge, according to H.G. Fischer - - Float_t IneffFactor = 0.5; // inefficiency in the gain close to the edge, as above - - - Float_t PadSignal[7]; // signal from a single electron - - TMatrix &signal = *m1; - TMatrix &total = *m2; - - IndexRange[0]=9999; // min pad IndexRange[1]=-1; // max pad IndexRange[2]=9999; //min time IndexRange[3]=-1; // max time + // Float_t IneffFactor = 0.5; // inefficiency in the gain close to the edge, as above + + TMatrix &signal = *m1; + TMatrix &total = *m2; // // Loop over all electrons // - for(Int_t nel=0; nelGetPadPitchWidth()){ - PadNumber=CentralPad; - } - else if (absy < range){ - PadNumber=(Int_t) ((absy-0.5*fTPCParam->GetPadPitchWidth())/fTPCParam->GetPadPitchWidth()+1.); - PadNumber=(Int_t) (TMath::Sign((Float_t)PadNumber, y)+CentralPad); - } - else continue; // electron out of pad-range , lost at the sector edge + Int_t idx=nel*4; + Float_t aval = v(idx+4); + Float_t eltoadcfac=aval*fTPCParam->GetTotalNormFac(); + Float_t xyz[3]={v(idx+1),v(idx+2),v(idx+3)}; + Int_t n = fTPCParam->CalcResponse(xyz,fCurrentIndex,fCurrentIndex[3]); - Float_t aval = (absyGetPadPitchWidth(); - for (Int_t i=0;i<7;i++){ - PadSignal[i]=fPRF2D->GetPRF(-dist+(i-3)*fTPCParam->GetPadPitchWidth(),xwire)*aval; - PadSignal[i] *= fTPCParam->GetPadCoupling(); - } - - Int_t LeftPad = TMath::Max(0,PadNumber-3); - Int_t RightPad = TMath::Min(np-1,PadNumber+3); - - Int_t pmin=LeftPad-PadNumber+3; // lower index of the pad_signal vector - Int_t pmax=RightPad-PadNumber+3; // upper index - - Float_t z_drift = z*zwidthm1; - Float_t z_offset = z_drift-(Int_t)z_drift; - - Int_t FirstBucket = (Int_t)z_drift; // numbering starts from "0" - - - // loop over time bins (4 bins is enough - 3 sigma truncated Gaussian) - - for (Int_t i2=0;i2<4;i2++){ - Int_t TrueTime = FirstBucket+i2; // current time bucket - Float_t dz = (Float_t(i2)+1.-z_offset)*zwidth; - Float_t ampl = fRF->GetRF(dz); - if( (TrueTime>MAXTBKT-1) ) break; // beyond the time range - - IndexRange[2]=TMath::Min(IndexRange[2],TrueTime); // min time - IndexRange[3]=TMath::Max(IndexRange[3],TrueTime); // max time - - // loop over pads, from pmin to pmax - for(Int_t i3=pmin;i3<=pmax;i3++){ - Int_t TruePad = LeftPad+i3-pmin; - IndexRange[0]=TMath::Min(IndexRange[0],TruePad); // min pad - IndexRange[1]=TMath::Max(IndexRange[1],TruePad); // max pad - signal(TruePad,TrueTime)+=(PadSignal[i3]*ampl); // not converted to charge!!! - total(TruePad,TrueTime)+=(PadSignal[i3]*ampl); // not converted to charge!!! - } // end of pads loop - } // end of time loop + if (n>0) for (Int_t i =0; iGetResBin(i); + Int_t pad=index[1]+CentralPad; //in digit coordinates central pad has coordinate 0 + if ( ( pad<(fTPCParam->GetNPads(fCurrentIndex[1],fCurrentIndex[3]))) && (pad>0)) { + Int_t time=index[2]; + Float_t weight = fTPCParam->GetResWeight(i); //we normalise response to ADC channel + weight *= eltoadcfac; + + if (m1!=0) signal(pad,time)+=weight; + total(pad,time)+=weight; + IndexRange[0]=TMath::Min(IndexRange[0],pad); + IndexRange[1]=TMath::Max(IndexRange[1],pad); + IndexRange[2]=TMath::Min(IndexRange[2],time); + IndexRange[3]=TMath::Max(IndexRange[3],time); + } + } } // end of loop over electrons - + return label; // returns track label when finished } @@ -1874,7 +1701,7 @@ void AliTPC::GetList(Float_t label,Int_t np,TMatrix *m,Int_t *IndexRange, // accept only the contribution larger than 500 electrons (1/2 s_noise) - if(signal(ip,it)<500.) continue; + if(signal(ip,it)<0.5) continue; Int_t GlobalIndex = it*np+ip; // GlobalIndex starts from 0! @@ -1943,7 +1770,6 @@ void AliTPC::GetList(Float_t label,Int_t np,TMatrix *m,Int_t *IndexRange, - }//end of GetList //___________________________________________________________________ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH, @@ -1960,9 +1786,9 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH, // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl //----------------------------------------------------------------- - AliTPCParam * fTPCParam = &(fDigParam->GetParam()); + Float_t gasgain = fTPCParam->GetGasGain(); Int_t i; - Float_t xyz[3]; + Float_t xyz[4]; AliTPChit *tpcHit; // pointer to a sigle TPC hit @@ -1976,7 +1802,7 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH, row[i] = new TObjArray; } Int_t *n_of_electrons = new Int_t [nrows]; // electron counter for each row - TVector **tr = new TVector* [nrows]; //pointers to the track vectors + TVector **tracks = new TVector* [nrows]; //pointers to the track vectors //-------------------------------------------------------------------- // Loop over tracks, the "track" contains the full history @@ -2003,7 +1829,7 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH, tpcHit = (AliTPChit*)fHits->UncheckedAt(hit); // get a pointer to a hit Int_t sector=tpcHit->fSector; // sector number - if(sector != isec) continue; //terminate iteration + if(sector != isec) continue; currentTrack = tpcHit->fTrack; // track number if(currentTrack != previousTrack){ @@ -2013,19 +1839,19 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH, for(i=0;i0){ - TVector &v = *tr[i]; + TVector &v = *tracks[i]; v(0) = previousTrack; - tr[i]->ResizeTo(3*n_of_electrons[i]+1); // shrink if necessary - row[i]->Add(tr[i]); + tracks[i]->ResizeTo(4*n_of_electrons[i]+1); // shrink if necessary + row[i]->Add(tracks[i]); } else{ - delete tr[i]; // delete empty TVector - tr[i]=0; + delete tracks[i]; // delete empty TVector + tracks[i]=0; } } n_of_electrons[i]=0; - tr[i] = new TVector(361); // TVectors for the next fTrack + tracks[i] = new TVector(481); // TVectors for the next fTrack } // end of loop over rows @@ -2038,7 +1864,9 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH, // Calculate the electron attachment probability //--------------------------------------------------- - Float_t time = 1.e6*(z_end-TMath::Abs(tpcHit->fZ))/fTPCParam->GetDriftV(); + + Float_t time = 1.e6*(fTPCParam->GetZLength()-TMath::Abs(tpcHit->fZ)) + /fTPCParam->GetDriftV(); // in microseconds! Float_t AttProb = fTPCParam->GetAttCoef()* fTPCParam->GetOxyCont()*time; // fraction! @@ -2046,41 +1874,43 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH, //----------------------------------------------- // Loop over electrons //----------------------------------------------- - + Int_t index[3]; + index[1]=isec; for(Int_t nel=0;nelRndm(0)) < AttProb) continue; // electron lost! xyz[0]=tpcHit->fX; xyz[1]=tpcHit->fY; - xyz[2]=tpcHit->fZ; - ElDiff(xyz); // Appply the diffusion + xyz[2]=tpcHit->fZ; + xyz[3]= (Float_t) (-gasgain*TMath::Log(gRandom->Rndm())); + index[0]=1; + + TransportElectron(xyz,index); //MI change -august Int_t row_number; - fTPCParam->XYZtoCRXYZ(xyz,isec,row_number,3); - - //transform position to local coordinates - //option 3 means that we calculate x position relative to - //nearest pad row - - if ((row_number<0)||row_number>=fTPCParam->GetNRow(isec)) continue; - ExB(xyz); // ExB effect at the sense wires + fTPCParam->GetPadRow(xyz,index); //MI change august + row_number = index[2]; + //transform position to local digit coordinates + //relative to nearest pad row + if ((row_number<0)||row_number>=fTPCParam->GetNRow(isec)) continue; n_of_electrons[row_number]++; //---------------------------------- // Expand vector if necessary //---------------------------------- if(n_of_electrons[row_number]>120){ - Int_t range = tr[row_number]->GetNrows(); - if(n_of_electrons[row_number] > (range-1)/3){ - tr[row_number]->ResizeTo(range+150); // Add 50 electrons + Int_t range = tracks[row_number]->GetNrows(); + if((n_of_electrons[row_number])>(range-1)/4){ + + tracks[row_number]->ResizeTo(range+400); // Add 100 electrons } } - TVector &v = *tr[row_number]; - Int_t idx = 3*n_of_electrons[row_number]-2; + TVector &v = *tracks[row_number]; + Int_t idx = 4*n_of_electrons[row_number]-3; - v(idx)= xyz[0]; // X - v(idx+1)=xyz[1]; // Y (along the pad-row) - v(idx+2)=xyz[2]; // Z - + v(idx)= xyz[0]; // X - pad row coordinate + v(idx+1)=xyz[1]; // Y - pad coordinate (along the pad-row) + v(idx+2)=xyz[2]; // Z - time bin coordinate + v(idx+3)=xyz[3]; // avalanche size } // end of loop over electrons } // end of loop over hits @@ -2092,172 +1922,22 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH, for(i=0;i0){ - TVector &v = *tr[i]; + TVector &v = *tracks[i]; v(0) = previousTrack; - tr[i]->ResizeTo(3*n_of_electrons[i]+1); // shrink if necessary - row[i]->Add(tr[i]); + tracks[i]->ResizeTo(4*n_of_electrons[i]+1); // shrink if necessary + row[i]->Add(tracks[i]); } else{ - delete tr[i]; - tr[i]=0; + delete tracks[i]; + tracks[i]=0; } } - delete [] tr; - delete [] n_of_electrons; - -} // end of MakeSector -//_____________________________________________________________________________ -void AliTPC::GetCrossTalk (Int_t iFlag,TObjArray *p,Int_t ntracks,Int_t *npads, - TMatrix *m) -{ - - //------------------------------------------------------------- - // Calculates the cross-talk from one row (inner or outer) - //------------------------------------------------------------- - - //----------------------------------------------------------------- - // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl - //----------------------------------------------------------------- - - // - // iFlag=2 & 3 --> cross-talk from the inner row - // iFlag=0 & 4 --> cross-talk from the outer row - // - AliTPCParam * fTPCParam = &(fDigParam->GetParam()); - AliTPCPRF2D * fPRF2D = &(fDigParam->GetPRF2D()); - AliTPCRF1D * fRF = &(fDigParam->GetRF()); - const int MAXTBKT= - int((z_end+6*fTPCParam->GetZSigma())/fTPCParam->GetZWidth())+1; + delete [] tracks; + delete [] n_of_electrons; - //to make code faster - - Float_t zwidth = fTPCParam->GetZWidth(); - Float_t zwidthm1 =1/fTPCParam->GetZWidth(); - - Int_t PadNumber; - Float_t xwire; - - Int_t nPadsSignal; // for this pads the signal is calculated - Float_t range; // sense wire range - Int_t nPadsDiff; - - Float_t IneffFactor=0.5; // gain inefficiency close to the edges - - if(iFlag == 0){ - // 1-->0 - nPadsSignal = npads[1]; - range = ((npads[1]-1)/2 + 0.5)*fTPCParam->GetPadPitchWidth(); - nPadsDiff = (npads[1]-npads[0])/2; - } - else if (iFlag == 2){ - // 1-->2 - nPadsSignal = npads[2]; - range = ((npads[1]-1)/2 + 0.5)*fTPCParam->GetPadPitchWidth(); - nPadsDiff = 0; - } - else if (iFlag == 3){ - // 0-->1 - nPadsSignal = npads[1]; - range = ((npads[0]-1)/2 + 0.5)*fTPCParam->GetPadPitchWidth(); - nPadsDiff = 0; - } - else{ - // 2-->1 - nPadsSignal = npads[2]; - range = ((npads[2]-1)/2 + 0.5)*fTPCParam->GetPadPitchWidth(); - nPadsDiff = (npads[2]-npads[1])/2; - } - - range-=0.5; // dead zone close to the edges - - TVector *tv; - TMatrix &signal = *m; - - Int_t CentralPad = (nPadsSignal-1)/2; - Float_t PadSignal[7]; // signal from a single electron - // Loop over tracks - for(Int_t nt=0;ntAt(nt); // pointer to a track - TVector &v = *tv; - Int_t nElectrons = (tv->GetNrows()-1)/4; - // Loop over electrons - for(Int_t nel=0; nelGetPadPitchLength(); - if (iFlag==2) xwire-=fTPCParam->GetPadPitchLength(); - if (iFlag==3) xwire-=fTPCParam->GetPadPitchLength(); - if (iFlag==4) xwire+=fTPCParam->GetPadPitchLength(); - - // electron acceptance for the cross-talk (only the closest wire) - - Float_t dxMax = fTPCParam->GetPadPitchLength()*0.5+fTPCParam->GetWWPitch(); - if(TMath::Abs(xwire)>dxMax) continue; - - Float_t y = v(idx+2); - Float_t z = v(idx+3); - Float_t absy=TMath::Abs(y); - - if(absy < 0.5*fTPCParam->GetPadPitchWidth()){ - PadNumber=CentralPad; - } - else if (absy < range){ - PadNumber=(Int_t) ((absy-0.5*fTPCParam->GetPadPitchWidth())/fTPCParam->GetPadPitchWidth() +1.); - PadNumber=(Int_t) (TMath::Sign((Float_t)PadNumber, y)+CentralPad); - } - else continue; // electron out of sense wire range, lost at the sector edge - - Float_t aval = (absyGetPadPitchWidth(); - - for (Int_t i=0;i<7;i++){ - PadSignal[i]=fPRF2D->GetPRF(-dist+(i-3)*fTPCParam->GetPadPitchWidth(),xwire)*aval; - - PadSignal[i] *= fTPCParam->GetPadCoupling(); - } - // real pad range - - Int_t LeftPad = TMath::Max(0,PadNumber-3); - Int_t RightPad = TMath::Min(nPadsSignal-1,PadNumber+3); - - Int_t pmin=LeftPad-PadNumber+3; // lower index of the pad_signal vector - Int_t pmax=RightPad-PadNumber+3; // upper index - - - Float_t z_drift = z*zwidthm1; - Float_t z_offset = z_drift-(Int_t)z_drift; - - Int_t FirstBucket = (Int_t)z_drift; // numbering starts from "0" - - for (Int_t i2=0;i2<4;i2++){ - Int_t TrueTime = FirstBucket+i2; // current time bucket - Float_t dz = (Float_t(i2)+1.- z_offset)*zwidth; - Float_t ampl = fRF->GetRF(dz); - if((TrueTime>MAXTBKT-1)) break; // beyond the time range - - - // loop over pads, from pmin to pmax - - for(Int_t i3=pmin;i3 nPadsSignal-nPadsDiff-1) continue; - - TruePad -= nPadsDiff; - signal(TruePad,TrueTime)+=(PadSignal[i3]*ampl); // not converted to charge! - - } // end of loop over pads - } // end of loop over time bins - - } // end of loop over electrons - - } // end of loop over tracks - -} // end of GetCrossTalk +} // end of MakeSector //_____________________________________________________________________________ @@ -2313,8 +1993,7 @@ void AliTPC::ResetDigits() // reset clusters // fNdigits = 0; - // if (fDigits) fDigits->Clear(); - if (fDigParam->GetArray()!=0) fDigParam->GetArray()->Clear(); + if (fDigits) fDigits->Clear(); fNclusters = 0; if (fClusters) fClusters->Clear(); } @@ -2430,6 +2109,42 @@ void AliTPC::SetGasMixt(Int_t nc,Int_t c1,Int_t c2,Int_t c3,Float_t p1, fMixtProp[2]=p3; +} +//_____________________________________________________________________________ + +void AliTPC::TransportElectron(Float_t *xyz, Int_t *index) +{ + // + // electron transport taking into account: + // 1. diffusion, + // 2.ExB at the wires + // 3. nonisochronity + // + // xyz and index must be already transformed to system 1 + // + + fTPCParam->Transform1to2(xyz,index); + + //add diffusion + Float_t driftl=xyz[2]; + if(driftl<0.01) driftl=0.01; + driftl=TMath::Sqrt(driftl); + Float_t sig_t = driftl*(fTPCParam->GetDiffT()); + Float_t sig_l = driftl*(fTPCParam->GetDiffL()); + xyz[0]=gRandom->Gaus(xyz[0],sig_t); + xyz[1]=gRandom->Gaus(xyz[1],sig_t); + xyz[2]=gRandom->Gaus(xyz[2],sig_l); + + // ExB + + if (fTPCParam->GetMWPCReadout()==kTRUE){ + Float_t x1=xyz[0]; + fTPCParam->Transform2to2NearestWire(xyz,index); + Float_t dx=xyz[0]-x1; + xyz[1]+=dx*(fTPCParam->GetOmegaTau()); + } + //add nonisochronity (not implemented yet) + } //_____________________________________________________________________________ void AliTPC::Streamer(TBuffer &R__b) @@ -2444,7 +2159,7 @@ void AliTPC::Streamer(TBuffer &R__b) R__b >> fNsectors; R__b >> fNclusters; R__b >> fNtracks; - fDigitsIndex = new Int_t[fNsectors+1]; + } else { R__b.WriteVersion(AliTPC::IsA()); AliDetector::Streamer(R__b); @@ -2483,8 +2198,10 @@ void AliTPCcluster::GetXYZ(Float_t *x, const AliTPCParam *par) const x[0]=par->GetPadRowRadii(fSector,fPadRow); x[1]=fY; x[2]=fZ; - par->CRXYZtoXYZ(x,fSector,fPadRow,1); - x[2]=fZ; + Float_t cs, sn, tmp; + par->AdjustCosSin(fSector,cs,sn); + tmp = x[0]*cs-x[1]*sn; + x[1]= x[0]*sn+x[1]*cs; x[0]=tmp; } //_____________________________________________________________________________ @@ -2554,6 +2271,7 @@ AliTPCtrack::AliTPCtrack(Float_t *hits) // fX=hits[0]; // This is dummy code ! } +//_________________________________________________________________________ AliTPCtrack::AliTPCtrack(const AliTPCcluster *c,const TVector& xx, const TMatrix& CC, Double_t xref, Double_t alpha): @@ -2582,15 +2300,15 @@ AliTPCtrack::AliTPCtrack(const AliTPCtrack& t) : x(t.x), C(t.C), fX=t.fX; fChi2=t.fChi2; fAlpha=t.fAlpha; - int n=t.fClusters.GetEntriesFast(); - for (int i=0; i= 0.999) { if (*this>4) cerr<<*this<<" AliTPCtrack warning: Filtering failed !\n"; x=savex; @@ -2738,13 +2437,13 @@ void AliTPCtrack::Update(const AliTPCcluster *c, Double_t chisq) TMatrix saveC=C; C.Mult(K,tmp); C-=saveC; C*=-1; - + fClusters.AddLast((AliTPCcluster*)c); fChi2 += chisq; } //_____________________________________________________________________________ -int AliTPCtrack::Rotate(Double_t alpha) +Int_t AliTPCtrack::Rotate(Double_t alpha) { //----------------------------------------------------------------- // This function rotates this track. @@ -2795,8 +2494,8 @@ void AliTPCtrack::UseClusters() const // // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch //----------------------------------------------------------------- - int num_of_clusters=fClusters.GetEntriesFast(); - for (int i=0; iUse(); @@ -2835,31 +2534,31 @@ Double_t AliTPCtrack::GetPredictedChi2(const AliTPCcluster *c) const } //_____________________________________________________________________________ -struct S { int lab; int max; }; -int AliTPCtrack::GetLabel(int nrows) const +struct S { Int_t lab; Int_t max; }; +Int_t AliTPCtrack::GetLabel(Int_t nrows) const { //----------------------------------------------------------------- // This function returns the track label. If label<0, this track is fake. // // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch //----------------------------------------------------------------- - int num_of_clusters=fClusters.GetEntriesFast(); + Int_t num_of_clusters=fClusters.GetEntriesFast(); S *s=new S[num_of_clusters]; - int i; + Int_t i; for (i=0; ifTracks[0]); - int j; + Int_t j; for (j=0; jmax) {max=s[i].max; lab=s[i].lab;} @@ -2871,9 +2570,9 @@ int AliTPCtrack::GetLabel(int nrows) const TMath::Abs(c->fTracks[2]) == lab ) max++; } - if (1.-float(max)/num_of_clusters > 0.10) return -lab; + if (1.-Float_t(max)/num_of_clusters > 0.10) return -lab; - int tail=int(0.08*nrows); + Int_t tail=Int_t(0.08*nrows); if (num_of_clusters < tail) return lab; max=0; @@ -2883,7 +2582,7 @@ int AliTPCtrack::GetLabel(int nrows) const lab == TMath::Abs(c->fTracks[1]) || lab == TMath::Abs(c->fTracks[2])) max++; } - if (max < int(0.5*tail)) return -lab; + if (max < Int_t(0.5*tail)) return -lab; return lab; } @@ -2914,19 +2613,18 @@ Double_t AliTPCtrack::GetdEdX(Double_t low, Double_t up) const { // // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch //----------------------------------------------------------------- - int ncl=fClusters.GetEntriesFast(); - int n=0; + Int_t ncl=fClusters.GetEntriesFast(); + Int_t n=0; Double_t *q=new Double_t[ncl]; - int i; - for (i=0; ifdEdX > 3000) continue; - if (cl->fdEdX <= 0) continue; - q[n++]=cl->fdEdX; + q[n++]=TMath::Abs(cl->fQ)/cl->fdEdX; + if (cl->fSector<36) q[n-1]*=1.1; } //stupid sorting - int swap; + Int_t swap; do { swap=0; for (i=0; ifY); + Int_t i=Find(c->fY); memmove(clusters+i+1 ,clusters+i,(num_of_clusters-i)*sizeof(AliTPCcluster*)); clusters[i]=c; num_of_clusters++; } +//___________________________________________________________________ -int AliTPCRow::Find(Double_t y) const { +Int_t AliTPCRow::Find(Double_t y) const { //----------------------------------------------------------------------- // Return the index of the nearest cluster // @@ -2970,11 +2669,12 @@ int AliTPCRow::Find(Double_t y) const { //----------------------------------------------------------------------- if (y <= clusters[0]->fY) return 0; if (y > clusters[num_of_clusters-1]->fY) return num_of_clusters; - int b=0, e=num_of_clusters-1, m=(b+e)/2; + Int_t b=0, e=num_of_clusters-1, m=(b+e)/2; for (; b clusters[m]->fY) b=m+1; else e=m; } return m; } +//________________________________________________________________________ diff --git a/TPC/AliTPC.h b/TPC/AliTPC.h index 8dd5b506e26..fc8c1814978 100644 --- a/TPC/AliTPC.h +++ b/TPC/AliTPC.h @@ -8,11 +8,9 @@ //////////////////////////////////////////////// // Manager class for TPC // //////////////////////////////////////////////// - #include "AliDetector.h" #include "AliHit.h" #include "AliDigit.h" -#include "AliTPCSecGeo.h" #include "AliTPCParam.h" #include #include @@ -21,8 +19,9 @@ class AliTPCcluster; class AliTPCtrack; class AliTPCParam; -//MI changes -class AliTPCD; + +class AliTPCDigitsArray; +class AliTPCClustersArray; class AliTPC : public AliDetector { protected: @@ -34,8 +33,12 @@ protected: Int_t fNsectors; // Number of sectors in TPC Int_t fNclusters; // Number of clusters in TPC Int_t fNtracks; // Number of tracks in TPC - Int_t *fClustersIndex; // Index for each sector in fClusters - Int_t *fDigitsIndex; // Index for each sector in fDigits + TClonesArray *fClusters; // List of clusters for all sectors + TClonesArray *fTracks; // List of reconstructed tracks + //MI changes + AliTPCDigitsArray * fDigitsArray; //detector digit object + AliTPCClustersArray * fClustersArray; //detector cluster object + AliTPCParam *fTPCParam; //MK changes @@ -44,19 +47,12 @@ protected: Int_t fMixtComp[3]; // drift gas components Float_t fMixtProp[3]; // mixture proportions - // - - TClonesArray *fClusters; // List of clusters for all sectors - TClonesArray *fTracks; // List of reconstructed tracks - //MI changes - AliTPCD * fDigParam; //detector parameters public: AliTPC(); AliTPC(const char *name, const char *title); virtual ~AliTPC(); virtual void AddCluster(Float_t*, Int_t*); /*virtual*/void AddCluster(const AliTPCcluster&); - virtual void AddDigit(Int_t*, Int_t*); virtual void AddHit(Int_t, Int_t*, Float_t*); virtual void AddTrack(Float_t*); /*virtual*/void AddTrack(const AliTPCtrack&); @@ -65,6 +61,7 @@ public: virtual void CreateGeometry() {} virtual void CreateMaterials(); virtual void Hits2Clusters(); + virtual void Hits2ExactClustersSector(Int_t isec); // MI change calculate "exact" cluster position virtual void Hits2Digits(); //MI change virtual void Hits2DigitsSector(Int_t isec); //MI change @@ -74,8 +71,7 @@ public: virtual void Clusters2Tracks(); TClonesArray *Clusters() {return fClusters;} TClonesArray *Tracks() {return fTracks;} - Int_t *GetClustersIndex() {return fClustersIndex;} - Int_t *GetDigitsIndex() {return fDigitsIndex;} + Int_t GetNsectors() {return fNsectors;} virtual void MakeBranch(Option_t *opt=" "); virtual void ResetDigits(); @@ -85,6 +81,9 @@ public: virtual void SetSecUps (Int_t s1,Int_t s2,Int_t s3,Int_t s4,Int_t s5, Int_t s6, Int_t s7,Int_t s8,Int_t s9,Int_t s10, Int_t s11, Int_t s12); virtual void SetSens(Int_t sens); + + //MK changes + //MK changes virtual void SetSide(Float_t side); @@ -93,24 +92,25 @@ public: virtual void StepManager()=0; virtual void DrawDetector() {} - AliTPCD* GetDigParam() {return fDigParam;} //MI change8 - void SetDigParam(AliTPCD* param) {fDigParam=param;} //MI must think about it + AliTPCDigitsArray* GetDigitsArray() {return fDigitsArray;} //MI change + AliTPCClustersArray* GetClustersArray(){return fClustersArray;} //MI change + AliTPCParam *GetParam(){return fTPCParam;} // M.K, M.I changes + void SetParam(AliTPCParam *param){fTPCParam=param;} // M.K, M.I changes + void SetDigitsArray(AliTPCDigitsArray* param) {fDigitsArray=param;} //MI change + void SetClustersArray(AliTPCClustersArray *clusters) {fClustersArray = clusters;} //MI change private: // - void ElDiff(Float_t *xyz); - void MakeTriplet(Int_t row,TObjArray **rowTriplet, - TObjArray **prow); - - void ExB(Float_t *xyz); void DigitizeRow(Int_t irow,Int_t isec,TObjArray **rowTriplet); - Float_t GetSignal(TObjArray *p1, Int_t ntr, Int_t np, TMatrix *m1, TMatrix *m2, + Float_t GetSignal(TObjArray *p1, Int_t ntr, TMatrix *m1, TMatrix *m2, Int_t *IndexRange); void GetList (Float_t label,Int_t np,TMatrix *m,Int_t *IndexRange, Float_t **pList); void MakeSector(Int_t isec,Int_t nrows,TTree *TH,Stat_t ntracks,TObjArray **row); - void GetCrossTalk (Int_t iFlag,TObjArray *p,Int_t ntracks,Int_t *npads, - TMatrix *m); - + void TransportElectron(Float_t *xyz, Int_t *index); + Int_t fCurrentIndex[4];// index[0] indicates coordinate system, + // index[1] sector number, + // index[2] pad row number + // index[3] pad row number for which signal is calculated ClassDef(AliTPC,2) // Time Projection Chamber class }; @@ -122,9 +122,9 @@ public: Int_t fTracks[3];//labels of overlapped tracks Int_t fSector; //sector number Int_t fPadRow; //PadRow number - Float_t fY; //Y of cluster - Float_t fZ; //Z of cluster - Float_t fQ; //Q of cluster (in ADC counts) + Float_t fY ; //Y of cluster + Float_t fZ ; //Z of cluster + Float_t fQ ; //Q of cluster (in ADC counts) Float_t fdEdX; //dE/dX inside this cluster Float_t fSigmaY2; //Sigma Y square of cluster Float_t fSigmaZ2; //Sigma Z square of cluster @@ -138,7 +138,7 @@ public: AliTPCcluster(Float_t *hits, Int_t*); virtual ~AliTPCcluster() {;} void Use() {fQ=-fQ;} //if fQ<0 cluster is already associated with a track - int IsUsed() const {return (fQ<0) ? 1 : 0;} + Int_t IsUsed() const {return (fQ<0) ? 1 : 0;} void GetXYZ(Float_t *x, const AliTPCParam *) const; //Get global x,y,z Bool_t IsSortable() const; Int_t Compare(TObject *o) ; @@ -194,22 +194,23 @@ class AliTPCtrack : public TObject { TObjArray fClusters; // clusters belonging to this track Double_t fChi2; // total chi2 value for this track public: + AliTPCtrack(): x(5), C(5,5), fClusters(200) {fAlpha=fX=fChi2=0.;} AliTPCtrack(Float_t *hits); AliTPCtrack(const AliTPCcluster *c, const TVector& xx, const TMatrix& CC, Double_t xr, Double_t alpha); AliTPCtrack(const AliTPCtrack& t); Int_t Compare(TObject *o); - int PropagateTo(Double_t xr, - Double_t x0=28.94,Double_t rho=0.9e-3,Double_t pm=0.139); + Int_t PropagateTo(Double_t xr, + Double_t x0=28.94,Double_t rho=0.9e-3,Double_t pm=0.139); void PropagateToVertex( Double_t x0=36.66,Double_t rho=1.2e-3,Double_t pm=0.139); void Update(const AliTPCcluster* c, Double_t chi2); - int Rotate(Double_t angle); + Int_t Rotate(Double_t angle); Bool_t IsSortable() const {return kTRUE;} void UseClusters() const ; Double_t GetPredictedChi2(const AliTPCcluster*) const ; - int GetLabel(int nrows) const ; + Int_t GetLabel(Int_t nrows) const ; void GetPxPyPz(Double_t&, Double_t&, Double_t&) const ; Double_t GetdEdX(Double_t low, Double_t up) const ; @@ -229,7 +230,10 @@ public: Double_t GetSigmaTgl2() const {return C(4,4);} Double_t GetAlpha() const {return fAlpha;} Double_t GetChi2() const {return fChi2;} - operator int() const {return fClusters.GetEntriesFast();} + operator Int_t() const {return fClusters.GetEntriesFast();} + const AliTPCcluster *GetCluster(Int_t i) const { + return (const AliTPCcluster *)fClusters.UncheckedAt(i); + } ClassDef(AliTPCtrack,1) // Time Projection Chamber reconstructed tracks }; @@ -251,9 +255,9 @@ public: AliTPCRow() {num_of_clusters=0;} void InsertCluster(const AliTPCcluster*); - operator int() const {return num_of_clusters;} - const AliTPCcluster* operator[](int i) const {return clusters[i];} - int Find(Double_t y) const; + operator Int_t() const {return num_of_clusters;} + const AliTPCcluster* operator[](Int_t i) const {return clusters[i];} + Int_t Find(Double_t y) const; }; class AliTPCSector { @@ -268,13 +272,14 @@ public: AliTPCSector() { row = 0; num_of_rows=0; } virtual ~AliTPCSector() { delete[] row; } static void SetParam(AliTPCParam *p) { param=p; } - AliTPCRow& operator[](int i) const { return *(row+i); } - int GetNRows() const { return num_of_rows; } - virtual Double_t GetX(int l) const = 0; - virtual Double_t GetMaxY(int l) const = 0; + AliTPCRow& operator[](Int_t i) const { return *(row+i); } + Int_t GetNRows() const { return num_of_rows; } + virtual Double_t GetX(Int_t l) const = 0; + virtual Double_t GetMaxY(Int_t l) const = 0; virtual Double_t GetAlpha() const = 0; virtual Double_t GetAlphaShift() const = 0; virtual Int_t GetRowNumber(Double_t x) const = 0; + virtual Double_t GetPadPitchWidth() const = 0; }; class AliTPCSSector : public AliTPCSector { @@ -291,16 +296,19 @@ public: row=new AliTPCRow[num_of_rows]; } virtual ~AliTPCSSector() {} - Double_t GetX(int l) const { return param->GetPadRowRadiiLow(l); } - Double_t GetMaxY(int l) const { return GetX(l)*tan(0.5*GetAlpha()); } + Double_t GetX(Int_t l) const { return param->GetPadRowRadiiLow(l); } + Double_t GetMaxY(Int_t l) const { return GetX(l)*tan(0.5*GetAlpha()); } Double_t GetAlpha() const {return param->GetInnerAngle();} Double_t GetAlphaShift() const {return param->GetInnerAngleShift();} + Double_t GetPadPitchWidth() const { + return param->GetInnerPadPitchWidth(); + } Int_t GetRowNumber(Double_t x) const { - Double_t r=param->GetInnerRadiusUp(); + Double_t r=param->GetPadRowRadiiLow(param->GetNRowLow()-1); if (x > r) return param->GetNRowLow(); - r=param->GetInnerRadiusLow(); + r=param->GetPadRowRadiiLow(0); if (x < r) return -1; - return int((x-r)/param->GetPadPitchLength() + 0.5); + return Int_t((x-r)/param->GetInnerPadPitchLength() + 0.5); } }; @@ -318,16 +326,19 @@ public: row=new AliTPCRow[num_of_rows]; } virtual ~AliTPCLSector() {} - Double_t GetX(int l) const { return param->GetPadRowRadiiUp(l); } - Double_t GetMaxY(int l) const { return GetX(l)*tan(0.5*GetAlpha()); } + Double_t GetX(Int_t l) const { return param->GetPadRowRadiiUp(l); } + Double_t GetMaxY(Int_t l) const { return GetX(l)*tan(0.5*GetAlpha()); } Double_t GetAlpha() const {return param->GetOuterAngle();} Double_t GetAlphaShift() const {return param->GetOuterAngleShift();} + Double_t GetPadPitchWidth() const { + return param->GetOuterPadPitchWidth(); + } Int_t GetRowNumber(Double_t x) const { - Double_t r=param->GetOuterRadiusUp(); + Double_t r=param->GetPadRowRadiiUp(param->GetNRowUp()-1); if (x > r) return param->GetNRowUp(); - r=param->GetOuterRadiusLow(); + r=param->GetPadRowRadiiUp(0); if (x < r) return -1; - return int((x-r)/param->GetPadPitchLength() + 0.5); + return Int_t((x-r)/param->GetOuterPadPitchLength() + 0.5); } }; diff --git a/TPC/AliTPCCluster.cxx b/TPC/AliTPCCluster.cxx new file mode 100644 index 00000000000..b337034ae6d --- /dev/null +++ b/TPC/AliTPCCluster.cxx @@ -0,0 +1,175 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:34:02 kowal2 + +Clusters handling in a new data structure + +*/ + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Time Projection Chamber clusters objects // +// +// Origin: Marian Ivanov , GSI Darmstadt +// // +// // +// // +/////////////////////////////////////////////////////////////////////////////// +#include "AliTPC.h" +#include "AliTPCCluster.h" +#include "TClonesArray.h" +#include "TDirectory.h" + + +const Int_t kDefSize = 1; //defalut size + + +ClassImp(AliTPCClustersRow) + + +//***************************************************************************** +// +//_____________________________________________________________________________ +AliTPCClustersRow::AliTPCClustersRow() +{ + // + //default constructor + fNclusters=0; + fClusters = new TClonesArray("AliTPCcluster",kDefSize); +} +//_____________________________________________________________________________ +AliTPCClustersRow::AliTPCClustersRow(Int_t size) +{ + fNclusters=0; + fClusters = new TClonesArray("AliTPCcluster",size); +} + +//_____________________________________________________________________________ +const AliTPCcluster* AliTPCClustersRow::operator[](Int_t i) +{ + // + // return cluster at internal position i + // + if (fClusters==0) return 0; + void * cl = fClusters->UncheckedAt(i); + if (cl==0) return 0; + return (AliTPCcluster*)cl; +} +//_____________________________________________________________________________ +void AliTPCClustersRow::Sort() +{ + // sort cluster + if (fClusters) fClusters->Sort(); +} + +//_____________________________________________________________________________ +void AliTPCClustersRow::InsertCluster(const AliTPCcluster * c) +{ + // + // Add a simulated cluster copy to the list + // + if(!fClusters) fClusters=new TClonesArray("AliTPCcluster",1000); + TClonesArray &lclusters = *fClusters; + new(lclusters[fNclusters++]) AliTPCcluster(*c); +} + +//_____________________________________________________________________________ +Int_t AliTPCClustersRow::Find(Double_t y) const +{ + // + // return index of cluster nearest to given y position + // + AliTPCcluster* cl; + cl=(AliTPCcluster*)fClusters->UncheckedAt(0); + if (y <= cl->fY) return 0; + cl=(AliTPCcluster*)fClusters->UncheckedAt(fNclusters-1); + if (y > cl->fY) return fNclusters; + //if (y <= clusters[0]->fY) return 0; + //if (y > clusters[num_of_clusters-1]->fY) return num_of_clusters; + Int_t b=0, e=fNclusters-1, m=(b+e)/2; + // Int_t b=0, e=num_of_clusters-1, m=(b+e)/2; + for (; bUncheckedAt(m); + if (y > cl->fY) b=m+1; + // if (y > clusters[m]->fY) b=m+1; + else e=m; + } + return m; +} + + +//_____________________________________________________________________________ + +ClassImp(AliTPCClustersArray) + +AliTPCClustersArray::AliTPCClustersArray() +{ + fParam = 0; +} + +AliTPCClustersArray::~AliTPCClustersArray() +{ + // + //object is only owner of fParam + // + if (fParam) delete fParam; +} + +const AliTPCClustersRow * AliTPCClustersArray::GetRow(Int_t sector,Int_t row) +{ + // + //return clusters ((AliTPCClustersRow *) per given sector and padrow + // + if (fParam==0) return 0; + Int_t index = fParam->GetIndex(sector,row); + return (AliTPCClustersRow *)(*this)[index]; +} + +Bool_t AliTPCClustersArray::LoadRow(Int_t sector,Int_t row) +{ + // + //return clusters ((AliTPCClustersRow *) per given sector and padrow + // + if (fParam==0) return 0; + Int_t index = fParam->GetIndex(sector,row); + return LoadSegment(index); +} + +Bool_t AliTPCClustersArray::StoreRow(Int_t sector,Int_t row) +{ + // + //return clusters ((AliTPCClustersRow *) per given sector and padrow + // + if (fParam==0) return 0; + Int_t index = fParam->GetIndex(sector,row); + StoreSegment(index); + return kTRUE; +} + + + +Bool_t AliTPCClustersArray::Setup(AliTPCParam *param) +{ + // + //setup function to adjust array parameters + // + if (param==0) return kFALSE; + fParam = new AliTPCParam(*param); + return MakeArray(fParam->GetNRowsTotal()); +} diff --git a/TPC/AliTPCCluster.h b/TPC/AliTPCCluster.h new file mode 100644 index 00000000000..7cd217255fa --- /dev/null +++ b/TPC/AliTPCCluster.h @@ -0,0 +1,60 @@ +#ifndef TPCClusters_H +#define TPCClusters_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +//////////////////////////////////////////////// +// Manager class for TPC clusters // +//////////////////////////////////////////////// + +#include "AliDetector.h" +#include "AliHit.h" +#include "AliDigit.h" +#include "AliSegmentArray.h" +#include "AliTPCParam.h" + +#include +#include +#include + + +class TClonesArray; +class TObjArray; + + +class AliTPCClustersRow : public AliSegmentID{ +public: + AliTPCClustersRow(); + AliTPCClustersRow(Int_t size); + void InsertCluster(const AliTPCcluster* c ); //insert copy of cluster + const AliTPCcluster* operator[](Int_t i); + Int_t Find(Double_t y) const; //find nearest cluster in y direction + void Sort(); +public: + TClonesArray * fClusters; + Int_t fNclusters; + ClassDef(AliTPCClustersRow,1) +}; + + +class AliTPCClustersArray : public AliSegmentArray { +public: + AliTPCClustersArray(); + ~AliTPCClustersArray(); + const AliTPCClustersRow * GetRow(Int_t sector,Int_t row); + Bool_t LoadRow(Int_t sector,Int_t row); + Bool_t StoreRow(Int_t sector,Int_t row); + Bool_t Setup(AliTPCParam *param); + //construct array according parameters in fParam + const AliTPCParam & GetParam() {return *fParam;} +private: + AliSegmentID * NewSegment(){ return (AliSegmentID*)new AliTPCClustersRow;} + AliTPCParam * fParam; //pointer to TPC parameters + //AliTPCClustersRow ** fRow; //pointer to array of pointers to cluster row + ClassDef(AliTPCClustersArray,1) +}; + +#endif + diff --git a/TPC/AliTPCClustersArray.cxx b/TPC/AliTPCClustersArray.cxx new file mode 100644 index 00000000000..d9c38c858e4 --- /dev/null +++ b/TPC/AliTPCClustersArray.cxx @@ -0,0 +1,178 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:34:02 kowal2 + +Clusters handling in a new data structure + +*/ + +/////////////////////////////////////////////////////////////////////////////// +// // +// Time Projection Chamber clusters objects // +// +// Origin: Marian Ivanov , GSI Darmstadt +// // +// // +// // +/////////////////////////////////////////////////////////////////////////////// +#include "AliTPC.h" +#include "AliTPCParam.h" +#include "AliSegmentArray.h" +#include "AliCluster.h" +#include "AliClusters.h" +#include "AliClustersArray.h" +#include "AliTPCClustersRow.h" + +#include "AliTPCClustersArray.h" +#include "TClonesArray.h" +#include "TDirectory.h" + + + +//_____________________________________________________________________________ + +ClassImp(AliTPCClustersArray) + +AliTPCClustersArray::AliTPCClustersArray() +{ + fParam = 0; + SetClass("AliTPCClustersRow"); +} + +AliTPCClustersArray::~AliTPCClustersArray() +{ + // + //object is only owner of fParam + // + if (fParam) delete fParam; +} + + + +AliTPCClustersRow * AliTPCClustersArray::GetRow(Int_t sector,Int_t row) +{ + // + //return clusters ((AliTPCClustersRow *) per given sector and padrow + // + if (fParam==0) return 0; + Int_t index = ((AliTPCParam*)fParam)->GetIndex(sector,row); + return (AliTPCClustersRow *)(*this)[index]; +} + +AliTPCClustersRow * AliTPCClustersArray::CreateRow(Int_t sector, Int_t row) +{ + // + //create digits row + // + //if row just exist - delete it + AliTPCParam * param = (AliTPCParam*)fParam; + Int_t index = param->GetIndex(sector,row); + AliTPCClustersRow * clusters = (AliTPCClustersRow *)(*this)[index]; + if (clusters !=0) delete clusters; + + clusters = (AliTPCClustersRow *) AddSegment(index); + if (clusters == 0) return 0; + return clusters; +} + +AliTPCClustersRow * AliTPCClustersArray::LoadRow(Int_t sector,Int_t row) +{ + // + //return clusters ((AliTPCClustersRow *) per given sector and padrow + // + if (fParam==0) return 0; + Int_t index = ((AliTPCParam*)fParam)->GetIndex(sector,row); + return ( AliTPCClustersRow *) LoadSegment(index); +} + +Bool_t AliTPCClustersArray::StoreRow(Int_t sector,Int_t row) +{ + // + //return clusters ((AliTPCClustersRow *) per given sector and padrow + // + if (fParam==0) return 0; + Int_t index = ((AliTPCParam*)fParam)->GetIndex(sector,row); + StoreSegment(index); + return kTRUE; +} + +Bool_t AliTPCClustersArray::ClearRow(Int_t sector,Int_t row) +{ + // + //return clusters ((AliTPCDigitsRow *) per given sector and padrow + // + if (fParam==0) return 0; + Int_t index = ((AliTPCParam*)fParam)->GetIndex(sector,row); + ClearSegment(index); + return kTRUE; +} + + + +Bool_t AliTPCClustersArray::Setup(AliDetectorParam *param) +{ + // + //setup function to adjust array parameters + // + if (param==0) return kFALSE; + fParam = param; + return MakeArray(((AliTPCParam*)fParam)->GetNRowsTotal()); + +} +Bool_t AliTPCClustersArray::Update() +{ + // + //setup function to adjust array parameters + // + if (fParam ==0 ) return kFALSE; + if (fTree!=0) return MakeDictionary( ((AliTPCParam*)fParam)->GetNRowsTotal()) ; + ((AliTPCParam*)fParam)->Update(); + return MakeArray(((AliTPCParam*)fParam)->GetNRowsTotal()); +} + + +/* +void AliTPCClustersArray::MakeTree() +{ + // AliSegmentID segment; + if (fClusterType==0) { + Error("AliTPCCLustersArray", "cluster type isn't adjusted"); + return; + } + AliClusters * psegment = (AliClusters *)NewSegment(); + psegment->SetClass(fClusterType->GetName()); + psegment->SetArray(100); + if (fTree) delete fTree; + fTree = new TTree("Segment Tree","Tree with segments"); + fBranch = fTree->Branch("Segment",psegment->IsA()->GetName(),&psegment,64000,1); + delete psegment; +} +*/ +AliSegmentID * AliTPCClustersArray::NewSegment() +{ + // + //create object according class information + if (fClusterType==0) { + Error("AliTPCCLustersArray", "cluster type isn't adjusted"); + return 0; + } + AliSegmentID *segment=AliSegmentArray::NewSegment(); + ((AliTPCClustersRow*)segment)->SetClass(fClusterType->GetName()); + ((AliTPCClustersRow*)segment)->SetArray(100); + return segment; +} diff --git a/TPC/AliTPCClustersArray.h b/TPC/AliTPCClustersArray.h new file mode 100644 index 00000000000..08f891a5e30 --- /dev/null +++ b/TPC/AliTPCClustersArray.h @@ -0,0 +1,49 @@ +#ifndef ALITPCCLUSTERSARRAY_H +#define ALITPCCLUSTERSARRAY_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +//////////////////////////////////////////////// +// Manager class for TPC clusters // +//////////////////////////////////////////////// + +#include "AliDetector.h" +#include "AliHit.h" +#include "AliDigit.h" +#include "AliSegmentArray.h" +#include "AliClustersArray.h" +#include "AliTPCParam.h" + +#include +#include +#include +#include + +class TClonesArray; +class TObjArray; +class AliTPCClustersRow; +//class TClass; + +class AliTPCClustersArray : public AliClustersArray { +public: + AliTPCClustersArray(); + ~AliTPCClustersArray(); + AliTPCClustersRow * GetRow(Int_t sector,Int_t row); + AliTPCClustersRow * CreateRow(Int_t sector, Int_t row); // + AliTPCClustersRow * LoadRow(Int_t sector,Int_t row); + Bool_t StoreRow(Int_t sector,Int_t row); + Bool_t ClearRow(Int_t sector,Int_t row); + Bool_t Setup(AliDetectorParam *param); + //construct array according parameters in fParam + Bool_t Update(); //blabla + AliSegmentID * NewSegment(); //create new segment - AliTPCClustersRow +protected: + //void MakeTree(); + +private: + ClassDef(AliTPCClustersArray,1) +}; + +#endif //ALITPCCLUSTERSARRAY_H diff --git a/TPC/AliTPCClustersRow.cxx b/TPC/AliTPCClustersRow.cxx new file mode 100644 index 00000000000..f44e6f9a7ec --- /dev/null +++ b/TPC/AliTPCClustersRow.cxx @@ -0,0 +1,54 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/////////////////////////////////////////////////////////////////////////////// +// // +// Time Projection Chamber AliTPCClusterRow objects +// - clusters for given segment of TPC // +// +// Origin: Marian Ivanov , GSI Darmstadt +// // +// // +/////////////////////////////////////////////////////////////////////////////// +#include "AliTPC.h" +#include "AliCluster.h" +#include "AliClusters.h" +#include "AliTPCClustersRow.h" +#include "TDirectory.h" + + +const Int_t kDefSize = 1; //defalut size + + +ClassImp(AliTPCClustersRow) + + +//***************************************************************************** +// +//_____________________________________________________________________________ +AliTPCClustersRow::AliTPCClustersRow() +{ + // + //default constructor + fNclusters=0; +} + +//_____________________________________________________________________________ +//AliTPCClustersRow::AliTPCClustersRow(Int_t size) +//{ +// fNclusters=0; +// fClusters = new TClonesArray("AliTPCcluster",size); +//} + diff --git a/TPC/AliTPCClustersRow.h b/TPC/AliTPCClustersRow.h new file mode 100644 index 00000000000..c7a5bd7ad70 --- /dev/null +++ b/TPC/AliTPCClustersRow.h @@ -0,0 +1,32 @@ +#ifndef ALITPCCLUSTERROW_H +#define ALITPCCLUSTERROW_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +//////////////////////////////////////////////// +// Manager class for TPC clusters // +//////////////////////////////////////////////// + +#include "AliDetector.h" +#include "AliSegmentArray.h" +#include "AliClusters.h" + + +#include + + +class TClonesArray; +class TObjArray; + + +class AliTPCClustersRow : public AliClusters{ +public: + AliTPCClustersRow(); + +public: + + ClassDef(AliTPCClustersRow,1) +}; +#endif //ALITPCCLUSTERROW_H diff --git a/TPC/AliTPCD.cxx b/TPC/AliTPCD.cxx deleted file mode 100644 index 3df93fef987..00000000000 --- a/TPC/AliTPCD.cxx +++ /dev/null @@ -1,158 +0,0 @@ -/************************************************************************** - * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * * - * Author: The ALICE Off-line Project. * - * Contributors are mentioned in the code where appropriate. * - * * - * Permission to use, copy, modify and distribute this software and its * - * documentation strictly for non-commercial purposes is hereby granted * - * without fee, provided that the above copyright notice appears in all * - * copies and that both the copyright notice and this permission notice * - * appear in the supporting documentation. The authors make no claims * - * about the suitability of this software for any purpose. It is * - * provided "as is" without express or implied warranty. * - **************************************************************************/ - -/* -$Log$ -*/ - -//----------------------------------------------------------------------------- -// -// Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk -// -// Implementation of class AliTPCD -// -//----------------------------------------------------------------------------- - -#include -#include "AliTPCParam.h" -#include "AliTPCRF1D.h" -#include "AliTPCPRF2D.h" -#include "AliTPCD.h" -#include "TClonesArray.h" -#include "TClass.h" -#include "TBranchClones.h" -#include "TTree.h" -#include "TDirectory.h" - - - -// other include files follow here - - -ClassImp(AliTPCD) - //_____________________________________________________________ -AliTPCD::AliTPCD(Text_t * name, - AliTPCParam * param, AliTPCPRF2D* prf, AliTPCRF1D* prfz) -{ - //construct new object's or accept objects sent to constructor - //AliTPCD handle sent object and is repsonsible for - //deleting it - -//Begin_Html -/* - -*/ -//End_Html - SetName(name); - if ((param!=0) && - ( (param->IsA()->InheritsFrom("AliTPCParam")==kTRUE ) )) - fParam=param; - else - fParam= new AliTPCParam; - if ( (prf!=0) && (prf->IsA()->InheritsFrom("AliTPCPRF2D")==kTRUE) ) - fPRF=prf; - else - fPRF = new AliTPCPRF2D; - if ( (prfz!=0) && (prfz->IsA()->InheritsFrom("AliTPCRF1D")==kTRUE) ) - fRF=prfz; - else - fRF = new AliTPCRF1D(kTRUE); - fDigits = new TClonesArray("AliTPCdigit",5000); - fpthis=this; -} - -AliTPCD::~AliTPCD() -{ - if (fParam!=0) fParam->Delete(); - if (fPRF!=0) fPRF->Delete(); - if (fRF!=0) fRF->Delete(); - if (fDigits!=0) fDigits->Delete(); -} - - -Bool_t AliTPCD::SetTree(Int_t nevent, TDirectory *dir ) -{ - char treeName[100]; - // Get Hits Tree header from file - sprintf(treeName,"TreeD%d_%s",nevent,GetName()); - fTreeD = (TTree*)dir->Get(treeName); - if (fTreeD == 0) return kFALSE; - //set Digit branch - TBranch *b = fTreeD->GetBranch("Digits"); - if (b==0) return kFALSE; - b->SetAddress(&fDigits); - return kTRUE; -} - - -Bool_t AliTPCD::MakeTree(Int_t nevent) -{ - char treeName[100]; - // Get Hits Tree header from file - sprintf(treeName,"TreeD%d_%s",nevent,GetName()); - fTreeD = new TTree(treeName,treeName); - if (fTreeD == 0) return kFALSE; - //set Digit branch - TBranch *b = fTreeD->Branch("Digits",&fDigits,40000); - if (b==0) return kFALSE; - b->SetAddress(&fDigits); - - return kTRUE; -} - -void AliTPCD::Fill() -{ - if (fTreeD!=0) fTreeD->Fill(); -} - - - - - -void AliTPCD::Streamer(TBuffer &R__b) -{ - // Stream an object of class AliTPCD. - if (R__b.IsReading()) { - Version_t R__v = R__b.ReadVersion(); if (R__v) { } - TNamed::Streamer(R__b); - if (fParam!=0) { - fParam->Delete(); - fParam = new AliTPCParam; - } - if (fPRF!=0) { - fPRF->Delete(); - fPRF = new AliTPCPRF2D; - } - if (fRF!=0) { - fRF->Delete(); - fRF = new AliTPCRF1D; - } - if (fTreeD!=0) { - fRF->Delete(); - fRF = new AliTPCRF1D; - } - R__b >>fParam; - R__b >>fPRF; - R__b >>fRF; - SetTree(); - } else { - R__b.WriteVersion(AliTPCD::IsA()); - TNamed::Streamer(R__b); - R__b <Write(); - } -} diff --git a/TPC/AliTPCD.h b/TPC/AliTPCD.h deleted file mode 100644 index 104c1bd7cad..00000000000 --- a/TPC/AliTPCD.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef ALITPCD_H -#define ALITPCD_H -/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * See cxx source for full Copyright notice */ - -/* $Id$ */ - -// include files and class forward declarations - - -// Documentation -/** - * Object with the TPC parameters - * - * - * - */ -#include "TNamed.h" -#include "TTree.h" -class AliTPCPRF2D; -class AliTPCRF1D; -class AliTPCParam; -class TClonesArray; -class TTree; -class TDirectory; -R__EXTERN TDirectory * gDirectory; -//class TBranch; - -class AliTPCD : public TNamed{ - -public: - AliTPCD( - Text_t * name ="DIGIT", - AliTPCParam *param=0, - AliTPCPRF2D *prf=0, - AliTPCRF1D *prfz=0); - ~AliTPCD(); - -public: - - AliTPCParam & GetParam() {return *fParam;} - //give us reference to the parameters - AliTPCPRF2D & GetPRF2D() {return *fPRF;} - //give us reference to 2-dimensional pad response function object - //this is responsible for respnse in x and y dimension - AliTPCRF1D & GetRF() {return *fRF;} - //give us reference to 1 dimensionl response - //this is responsible for z-direction - TClonesArray * GetArray() {return fDigits;} - //return reference for digits array - - TTree * GetTree() { return fTreeD;} - //return refeence to actual tree - Bool_t SetTree(Int_t nevent=0, TDirectory *dir = gDirectory); - //map tree from given directory - Bool_t MakeTree(Int_t nevent=0); - //map tree from given directory - void Fill(); - -protected: - -public: - AliTPCParam * fParam; //geometry and gas parameters object - AliTPCPRF2D * fPRF; //x and y pad response function object - AliTPCRF1D * fRF; //z (time) response function object - TClonesArray *fDigits; //aray of tpc Digits - TTree *fTreeD; //tree -private: - AliTPCD *fpthis; //pointer to object - ClassDef(AliTPCD,2) -}; - - -#endif /* ALITPCD_H */ diff --git a/TPC/AliTPCDigitDisplay.C b/TPC/AliTPCDigitDisplay.C new file mode 100644 index 00000000000..a5ea3154dc2 --- /dev/null +++ b/TPC/AliTPCDigitDisplay.C @@ -0,0 +1,64 @@ +void AliTPCDigitDisplay(int sec, int row, int lab=-1, + int max_t_chan=500, float min_t=0., float max_t=500., + int max_p_chan=150, float min_p=0., float max_p=150.) +{ +// Dynamically link some shared libs + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } + +// Connect the Root Galice file containing Geometry, Kine and Hits + TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + if (f) f->Close(); + //f = new TFile("galice.root"); + f = TFile::Open("rfio:galice.root"); + + AliTPCParam *par=(AliTPCParam *)f.Get("75x40_100x60"); + + char s[80]; + sprintf(s,"Sector %d Row %d\n",sec,row); + TH2F *h = new TH2F("h",s,max_t_chan,min_t,max_t,max_p_chan,min_p,max_p); + + TTree *t=(TTree*)f.Get("TreeD_75x40_100x60"); + AliSimDigits dummy, *digit=&dummy; + t->GetBranch("Segment")->SetAddress(&digit); + for (int i=0; iGetEntries(); i++) { + t->GetEvent(i); + int ss,rr; + par->AdjustSectorRow(digit->GetID(),ss,rr); + if (ss==sec && rr==row) goto ok; + } + return; + +ok: + int imax=0, jmax=0, qmax=0; + digit->First(); + do { + Short_t dig=digit->CurrentDigit(); + int i=digit->CurrentRow(), j=digit->CurrentColumn(); + if (lab >= 0) { + int lab0=digit->GetTrackID(i,j,0); + int lab1=digit->GetTrackID(i,j,1); + int lab2=digit->GetTrackID(i,j,2); + if (lab0!=lab) if (lab1!=lab) if (lab2!=lab) continue; + if (dig>qmax) {imax=i; jmax=j; qmax=dig;} + cerr<Fill(i,j,dig); + } while (digit->Next()); + if (qmax>0) {cerr<<"Peak (time,pad,q) : "<SetMaximum(100); + gStyle->SetOptStat(0); + TCanvas *c1=new TCanvas("c1","TPC digits display",0,0,1110,680); + TPad *p1=new TPad("p1","",0,0,1,0.5); + p1->Draw(); + TPad *p2=new TPad("p2","",0,0.5,1,1); + p2->Draw(); + p2->cd(); + h->Draw("lego"); + p1->cd(); + h->Draw("colz"); +} + diff --git a/TPC/AliTPCDigitsArray.cxx b/TPC/AliTPCDigitsArray.cxx new file mode 100644 index 00000000000..6a5991a0133 --- /dev/null +++ b/TPC/AliTPCDigitsArray.cxx @@ -0,0 +1,169 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:37:42 kowal2 + +Digits handling in a new data structure + +*/ + +/////////////////////////////////////////////////////////////////////////////// +// // +// Time Projection Chamber clusters objects // +// +// Origin: Marian Ivanov , GSI Darmstadt +// // +// // +// // +/////////////////////////////////////////////////////////////////////////////// +#include "AliTPCParam.h" +#include "AliTPCParam.h" +#include "AliTPCRF1D.h" +#include "AliTPCPRF2D.h" + +#include "TObjArray.h" +#include "AliSegmentID.h" +#include "AliSegmentArray.h" + +#include "AliArrayI.h" +#include "AliArrayS.h" + + +#include "AliDigits.h" +#include "AliSimDigits.h" +#include "AliDigitsArray.h" +#include "AliTPCDigitsArray.h" +//#include "TClonesArray.h" +#include "TDirectory.h" + + + +//_____________________________________________________________________________ + +ClassImp(AliTPCDigitsArray) + +AliTPCDigitsArray::AliTPCDigitsArray(Bool_t sim) +{ + // + //default constructor + fParam = 0; + fBSim = sim; + if ( sim == kTRUE) SetClass("AliSimDigits"); + else + SetClass("AliDigits"); + fParam = 0; + // fPRF = 0; + //fRF = 0; + fCompression = 1; + fTrackLevel = 3; +} + +AliTPCDigitsArray::~AliTPCDigitsArray() +{ + // + + // +} + +AliDigits * AliTPCDigitsArray::CreateRow(Int_t sector, Int_t row) +{ + // + //create digits row + // + //if row just exist - delete it + AliTPCParam * param = (AliTPCParam*)fParam; + Int_t index = param->GetIndex(sector,row); + AliDigits * dig = (AliDigits *)(*this)[index]; + if (dig !=0) delete dig; + + dig = (AliDigits *) AddSegment(index); + if (dig == 0) return 0; + dig->Allocate(param->GetMaxTBin(),param->GetNPads(sector,row)); + if (fBSim == kTRUE) ((AliSimDigits*) dig)->AllocateTrack(fTrackLevel); + return dig; +} + + +AliDigits * AliTPCDigitsArray::GetRow(Int_t sector,Int_t row) +{ + // + //return clusters ((AliTPCDigitsRow *) per given sector and padrow + // + if (fParam==0) return 0; + Int_t index = ((AliTPCParam*)fParam)->GetIndex(sector,row); + return (AliDigits *)(*this)[index]; +} + +AliDigits * AliTPCDigitsArray::LoadRow(Int_t sector,Int_t row) +{ + // + //return clusters ((AliTPCDigitsRow *) per given sector and padrow + // + if (fParam==0) return 0; + Int_t index = ((AliTPCParam*)fParam)->GetIndex(sector,row); + return (AliDigits *)LoadSegment(index); +} + +Bool_t AliTPCDigitsArray::StoreRow(Int_t sector,Int_t row) +{ + // + //return clusters ((AliTPCDigitsRow *) per given sector and padrow + // + AliTPCParam * param = (AliTPCParam*)fParam; + if (fParam==0) return 0; + Int_t index = param->GetIndex(sector,row); + ( (AliDigits *)At(index))->CompresBuffer(fCompression,param->GetZeroSup()); + if (fBSim == kTRUE) ( (AliSimDigits *)At(index))->CompresTrackBuffer(1); + StoreSegment(index); + return kTRUE; +} + +Bool_t AliTPCDigitsArray::ClearRow(Int_t sector,Int_t row) +{ + // + //return clusters ((AliTPCDigitsRow *) per given sector and padrow + // + if (fParam==0) return 0; + Int_t index = ((AliTPCParam*)fParam)->GetIndex(sector,row); + ClearSegment(index); + return kTRUE; +} + + + +Bool_t AliTPCDigitsArray::Setup(AliDetectorParam *param) +{ + // + //setup function to adjust array parameters + // + if (param==0) return kFALSE; + if (fParam !=0) delete fParam; + // fParam = new AliTPCParam((AliTPCParam&)(*param)); + fParam = param; + return MakeArray(((AliTPCParam*)fParam)->GetNRowsTotal()); +} + +Bool_t AliTPCDigitsArray::Update() +{ + // + //setup function to adjust array parameters + // + if (fParam ==0 ) return kFALSE; + if (fTree!=0) return MakeDictionary( ((AliTPCParam*)fParam)->GetNRowsTotal()) ; + ((AliTPCParam*)fParam)->Update(); + return MakeArray(((AliTPCParam*)fParam)->GetNRowsTotal()); +} diff --git a/TPC/AliTPCDigitsArray.h b/TPC/AliTPCDigitsArray.h new file mode 100644 index 00000000000..ba39fe59140 --- /dev/null +++ b/TPC/AliTPCDigitsArray.h @@ -0,0 +1,51 @@ +#ifndef ALITPCDIGITSARRAY_H +#define ALITPCDIGITSARRAY_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +//////////////////////////////////////////////// +// Manager class for TPC clusters // +//////////////////////////////////////////////// + +#include "AliDetector.h" +#include "AliHit.h" +#include "AliDigits.h" +#include "AliSegmentArray.h" +#include "AliDigitsArray.h" +#include "AliTPCParam.h" + +#include +#include +#include + + +class TClonesArray; +class TObjArray; +class AliTPCPRF2D; +class AliTPCRF1D; + +class AliTPCDigitsArray : public AliDigitsArray { +public: + AliTPCDigitsArray(Bool_t sim=kTRUE); + ~AliTPCDigitsArray(); + AliDigits * GetRow(Int_t sector,Int_t row); //return pointer to row from array + AliDigits * CreateRow(Int_t sector, Int_t row); // + AliDigits * LoadRow(Int_t sector,Int_t row); + Bool_t StoreRow(Int_t sector,Int_t row); + Bool_t ClearRow(Int_t sector,Int_t row); + Bool_t Setup(AliDetectorParam *param); + + Bool_t IsSimulated(){return fBSim;} + Bool_t Update(); // +private: + //AliTPCPRF2D * fPRF; //x and y pad response function object + //AliTPCRF1D * fRF; //z (time) response function object + Bool_t fBSim; //signalize if we have digits with track ID + Int_t fCompression; //default compression for AliDigits - used in storing + Int_t fTrackLevel; //default level for track ID storing + ClassDef(AliTPCDigitsArray,1) +}; + +#endif //ALITPCCLUSTERSARRAY_H diff --git a/TPC/AliTPCDigitsDisplay.C b/TPC/AliTPCDigitsDisplay.C deleted file mode 100644 index a6e64551f6e..00000000000 --- a/TPC/AliTPCDigitsDisplay.C +++ /dev/null @@ -1,53 +0,0 @@ -void AliTPCDigitsDisplay(int sec, int row, - int max_t_chan=500, float min_t=0., float max_t=500., - int max_p_chan=200, float min_p=0., float max_p=200.) -{ -// Dynamically link some shared libs - if (gClassTable->GetID("AliRun") < 0) { - gROOT->LoadMacro("loadlibs.C"); - loadlibs(); - } else { - delete gAlice; - gAlice=0; - } - -// Connect the Root Galice file containing Geometry, Kine and Hits - TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); - if (f) f->Close(); - f = new TFile("galice.root"); - - TClonesArray *fDigits=new TClonesArray("AliTPCdigit",10000); - TTree *t=(TTree*)f->Get("TreeD0_Param1"); - t->GetBranch("Digits")->SetAddress(&fDigits); - Int_t sectors_by_rows=(Int_t)t->GetEntries(); - for (Int_t n=0; nGetEvent(n)) continue; - AliTPCdigit *dig=(AliTPCdigit*)fDigits->UncheckedAt(0); - - if (sec < dig->fSector) break; - if (sec != dig->fSector) continue; - if (row != dig->fPadRow) continue; - - char s[80]; - sprintf(s,"Sector %d Row %d\n",sec,row); - TH2F *h = new TH2F("h",s,max_t_chan,min_t,max_t,max_p_chan,min_p,max_p); - Int_t ndigits=fDigits->GetEntriesFast(); - for (Int_t ndig=0; ndigUncheckedAt(ndig); - if (dig->fSignal < 0) continue; //cluster finder threshold - h->Fill(dig->fTime,dig->fPad,dig->fSignal); - } - h->SetMaximum(200); - gStyle->SetOptStat(0); - TCanvas *c1=new TCanvas("c1","TPC digits display",0,0,1110,680); - TPad *p1=new TPad("p1","",0,0,1,0.5); - p1->Draw(); - TPad *p2=new TPad("p2","",0,0.5,1,1); - p2->Draw(); - p2->cd(); - h->Draw("lego"); - p1->cd(); - h->Draw("colz"); - } -} - diff --git a/TPC/AliTPCDigitsH.cxx b/TPC/AliTPCDigitsH.cxx new file mode 100644 index 00000000000..d101d7db144 --- /dev/null +++ b/TPC/AliTPCDigitsH.cxx @@ -0,0 +1,644 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.4.2 2000/04/10 11:37:42 kowal2 + +Digits handling in a new data structure + +*/ + +//----------------------------------------------------------------------------- +// +// +// Author: Marian Ivanov +// +// Implementation of class TTPCDigitsH +// +//----------------------------------------------------------------------------- +//////////////////////////////////////////////// +// Manager class for AliTPCDigitsH // +//////////////////////////////////////////////// + +#include +#include "TMath.h" +// other include files follow here +#include "TFile.h" +//*KEEP,TFile. +#include "TROOT.h" +#include "TGraph.h" +#include "AliRun.h" +#include "AliDisplay.h" +#include "TPad.h" +#include "TCanvas.h" +#include "TCanvasImp.h" +#include "TPaveText.h" +//*KEEP,TH1. +#include "TH1.h" +//*KEEP,TH2 +#include "AliH2F.h" +//*KEEP,TF2. +#include "TF2.h" +//*KEEP,TClonesArray,T=C++. +#include "TClonesArray.h" +#include "TTree.h" +//GALICE includes +#include "GParticle.h" +#include "AliTPC.h" +#include "AliTPCParam.h" +#include "AliTPCD.h" +#include "AliTPCDigitsH.h" + + +R__EXTERN TSystem * gSystem; +R__EXTERN AliRun * gAlice; + + + +ClassImp(AliTPCDigitsH) + +AliTPCDigitsH::AliTPCDigitsH() +{ +//Begin_Html +/* + +*/ +//End_Html + + fsec = 1; + frow = 1; + fpad = 1; + fTimeN = 500; + fTimeStart = 0; + fTimeStop = 500; + fOccuN =25; + fbDelHisto = kFALSE; + fEventN = 0; //event nuber connected to digit tree + fThreshold = 5; + + fParticles = 0; + fDigits= 0; + + fDParam =0; + + fbIOState = kFALSE; + fbDigState = kFALSE; +} + +AliTPCDigitsH::~AliTPCDigitsH() +{ + +} + +AliTPCDigitsH::AliTPCDigitsH(const AliTPCDigitsH &) +{ +} + +AliTPCDigitsH & AliTPCDigitsH::operator = (const AliTPCDigitsH &) +{ + return *this; +} +void AliTPCDigitsH::SetDParam(AliTPCD * dig) +{ + if (dig!=0) + { + fDParam =dig; + fTPCParam = &(fDParam->GetParam()); + } + else + { + fTPCParam = 0; + fDParam =0; + } +} + +AliTPCParam *& AliTPCDigitsH::GetParam() +{ + return fTPCParam; +} + + +void AliTPCDigitsH::CloseFiles() +{ + if (fin) + { + fin->Close(); + //try + // { + delete fin; + // // } + // //catch(...) + // // { + // cout<<"FIN Delete error. Contact autor of root \n"; + // }; + fin = 0; + }; + if (fout) + { + fout->Close(); + //try + //{ + // delete fout; + //} + // catch(...) + //{ + // cout<<"Out Delete error. Contact autor of root \n"; + //}; + fout =0; + }; + fbIOState = kFALSE; + fbDigState = kFALSE; +} + +Bool_t AliTPCDigitsH::SetIO(const char * inFile, const char* outFile ) +{ + /// Set input and output file + /// control permisions and so on + /// if all is OK then set flag fbIOState = kTRUE + fbIOState = kFALSE; + TString s1=inFile; + TString s2=outFile; + // important ---- it close previious open file if this file exist + if (fin) + { + if (fin == fout) fout = NULL; + fin->Close(); + // try + //{ + delete fin; + //} + //catch(...) + //{ + // cout<<"Fin Delete error. Contact autor of root \n"; + //}; + fin = 0; + }; + // important ---- it close previous open file if this file exist + if (fout) + { + fout->Close(); + //try + //{ + delete fout; + //} + //catch(...) + //{ + // cout<<"Fout Delete error. Contact autor of root \n"; + //}; + fout = 0; + }; + + //close the files if exist in root enviroment + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject((char*)inFile); + if (file) file->Close(); + file = (TFile*)gROOT->GetListOfFiles()->FindObject((char*)outFile); + if (file) file->Close(); + //if input file is the output file + if (s1 == s2 ) + { + if (gSystem->AccessPathName((char*)inFile, kWritePermission ) == kFALSE) + fin = new TFile((char*)inFile,"UPDATE","trees with digits"); + if (!(fin)) + { + cout<<"Input file couldn't be open for writing \n"; + cout<<"Loook if the file exiest or if you have permision to write \n"; + return kFALSE; + } + else + { + fout = fin; + fbIOState = kTRUE; + return kTRUE; + } + } + //open input file + if (gSystem->AccessPathName((char*)inFile, kReadPermission ) == kFALSE) + fin = new TFile((char*)inFile,"UPDATE","trees with digits"); + else + { + cout<<"Input file couldn't be open\n"; + cout<<"Maybe the file is not open \n"; + return kFALSE ; + } + if (!(fin)) + { + cout<<"Input file couldn't be open\n"; + cout<<"Probably not root file \n"; + return kFALSE ; + } + + //open output file + if (gSystem->AccessPathName((char*)outFile, kWritePermission) == kFALSE) + fout = new TFile((char *)outFile,"UPDATE"); + else + fout = new TFile((char *)outFile,"NEW"); + + if (!(fout)) + { + cout<<"Output file couldn't be open\n"; + return kFALSE ; + } + //if input and output file is OK set state variable to true + fbIOState = kTRUE; + return kTRUE; +} + +Bool_t AliTPCDigitsH::SetEventN(Int_t EventN=0) +{ + if (!(fin)) + { + cout<<"Warning: Input file not open !!! \n"; + return kFALSE; + } + fin->cd(); + if (EventN>-1) fEventN = EventN; + fParticles = 0; + if (gAlice) + { + delete gAlice; + gAlice =0; + } + gAlice = (AliRun*) fin->Get("gAlice"); + if (gAlice == 0 ) + cout<<" Warning : AliRun objects not found in input file \n."; + else + { + gAlice->GetEvent(fEventN); + fParticles = gAlice->Particles(); + } + if (fParticles == 0) + return kFALSE; + else + return kTRUE; +} + + + +Bool_t AliTPCDigitsH::SetTree(Int_t eventn ) +{ + fbDigState = kFALSE; + ftree = 0; + if ( fbIOState == kFALSE) + { + cout<<"IO files not adjusted \n FIX IT!!!"; + return kFALSE; + } + fin->cd(); + if (fDParam->SetTree(eventn)==0){ + fbDigState = kFALSE; + cout<<"Input tree doesn't exist !!! \n"; + return kFALSE; + } + fDigits = fDParam->GetArray(); + ftree = fDParam->GetTree(); + fbDigState=kTRUE; + return kTRUE; +} + +void AliTPCDigitsH::SetSecRowTime(Int_t sec , Int_t row , Int_t TimeN, Float_t TimeStart, Float_t TimeStop ) +{ + fsec = sec; + frow = row; + fTimeN =TimeN; + fTimeStart = TimeStart; + fTimeStop = TimeStop; +} + +void AliTPCDigitsH::SetParticles(Int_t sec = -1, Int_t row = -1 , + Int_t size1 = 30000,Int_t size2=300, + Bool_t all=kTRUE ) +{ + if (sec>0) fsec = sec; + if (row>-1) frow =row; + char s[80]; + char sh[80]; + // create particles histograms + sprintf(s,"Sector %d Row %d\n",fsec,frow); + sprintf(sh,"Particles%d_%d",fsec,frow); + fHParticles = new TH1F(sh,s,size1,4,size1); + + sprintf(s,"Sector %d Row %d\n",fsec,frow); + sprintf(sh,"All particles%d_%d",fsec,frow); + fHAllP = new TH1F(sh,s,200,1,25); + + sprintf(s,"Sector %d Row %d\n",fsec,frow); + sprintf(sh,"Secondary Particles%d_%d",fsec,frow); + fHSecondaryP = new TH1F(sh,s,200,1,25); + + if (!(fin)) + { + cout<<"Input file not open, open file before \n"; + } + else +{ + fin->cd(); + Int_t sectors_by_rows=(Int_t)ftree->GetEntries(); + GParticle * particle; + // loop over all sectors and rows + for (Int_t n=0; nGetEvent(n)) continue; + AliTPCdigit *dig=(AliTPCdigit*)fDigits->UncheckedAt(0); + if (fsec < dig->fSector) break; + if (fsec != dig->fSector) continue; + if (frow != dig->fPadRow) continue; + + Int_t ndigits=fDigits->GetEntriesFast(); + //loop over all digits in sector pad + for (Int_t ndig=0; ndigUncheckedAt(ndig); + fHParticles->Fill(dig->fTracks[0]); + // get pointer to particle information and fill All and secondary histo + particle = (GParticle*) fParticles->UncheckedAt(dig->fTracks[0]); + fHAllP->Fill(particle->GetKF()); + // Int_t id = particle->GetKF(); + x = (Float_t)particle->GetVx(); + y = (Float_t)particle->GetVy(); + if ( (x*x+y*y ) > 1 ) + fHSecondaryP->Fill(particle->GetKF()); + if (all==kTRUE) + { + fHParticles->Fill(dig->fTracks[1]); + particle = (GParticle*) fParticles->UncheckedAt(dig->fTracks[1]); + fHAllP->Fill(particle->GetKF()); + x = (Float_t)particle->GetVx(); + y = (Float_t)particle->GetVy(); + if ( (x*x+y*y ) > 1 ) + fHSecondaryP->Fill(particle->GetKF()); + fHParticles->Fill(dig->fTracks[2]); + particle = (GParticle*) fParticles->UncheckedAt(dig->fTracks[2]); + fHAllP->Fill(particle->GetKF()); + x = (Float_t)particle->GetVx(); + y = (Float_t)particle->GetVy(); + if ( (x*x+y*y ) > 1 ) + fHSecondaryP->Fill(particle->GetKF()); + } + } + } + //make histogram with multiplicity + char s[80]; + char sh[80]; + if (all==kTRUE) + sprintf(s,"Number of AliDigits over threshold per one track in sector %d Row %d\n (all three most important track recorded)",fsec,frow); + else + sprintf(s,"Number of AliDigits over threshold per sector %d Row %d\n (only most important track)",fsec,frow); + sprintf(sh,"His_%d_%d",fsec,frow); + fHPartMultiplicity = new TH1F(sh,s,size2,1,size2); + for (Int_t i=1;iGetBinContent(i)); + if (mul>0) fHPartMultiplicity->Fill(mul); + } + if (fout) + { + fout->cd(); + fHParticles->Write(); + fHPartMultiplicity->Write(); + //fHSecondaryP->Write(); + //fHAllP->Write(); + } + } +} + + +void AliTPCDigitsH::Anal() +{ + if (fbIOState == kFALSE) + { + cout<<"Input output problem. \n Do you initialize IO files ? \n"; + return; + } + if (fbDigState == kFALSE) + { + cout<<"Input file doesn't enhalt selected tree \n"; + return; + } + fout->cd(); + +//if we dont want let histogram in memory then we delete old histogram + if ( (fH2Digit) && (fbDelHisto == kTRUE) ) + { + // try + //{ + // delete fH2Digit; + //} + // catch(...) + //{ + // cout<<"Delete error. Contact autor of root \n"; + //}; + fH2Digit = 0; + } + char s[80]; + char sh[80]; + sprintf(s,"Sector %d Row %d\n",fsec,frow); + sprintf(sh,"h%d_%d",fsec,frow); + + if ( (fout) && (fbDelHisto == kFALSE) ) + { + fH2Digit = (AliH2F *) fout->Get(sh); + if (fH2Digit) return; + } + + Int_t n_of_pads =fTPCParam->GetNPads(fsec,frow); + + fH2Digit = new AliH2F(sh, s, fTimeN, fTimeStart, fTimeStop, n_of_pads, 0, n_of_pads-1); + + if (!(fout)) + { + cout<<"Input file not open, open file before \n"; + } + else + { + //fin->cd(); + Int_t sectors_by_rows=(Int_t)ftree->GetEntries(); + //loop over all sectors and rows + for (Int_t n=0; nGetEvent(n)) continue; + AliTPCdigit *dig=(AliTPCdigit*)fDigits->UncheckedAt(0); + if (fsec < dig->fSector) break; + if (fsec != dig->fSector) continue; + if (frow != dig->fPadRow) continue; + + Int_t ndigits=fDigits->GetEntriesFast(); + //loop over all digits in sector pad + for (Int_t ndig=0; ndigUncheckedAt(ndig); + fH2Digit->Fill(dig->fTime,dig->fPad,dig->fSignal); + } + } + if (fout) fout->cd(); + fH2Digit->Write(); + } + +} +void AliTPCDigitsH::Draw(Option_t * opt1 ="cont1" , Option_t * opt2 = "error", + Option_t * opt3 = "L" ) +{ + TString o1 = opt1; + o1.ToLower(); + + TString o2 = opt2; + o2.ToLower(); + + TString o3 = opt3; + o3.ToLower(); + + fcanvas = new TCanvas("dh","Digits Histograms",700,900); + + if (fTitle) + { + // try + //{ + //delete fTitle; + //} + // catch(...) + //{ + // cout<<"Delete error. Contact autor of root \n"; + //}; + fTitle = 0; + } + fTitle = new TPaveText(0.2,0.96,0.8,0.995); + fTitle->AddText("Occupancy calculation for TPC"); + fTitle->Draw(); + + fpad1 = new TPad("pad1","",0.05,0.7,0.95,0.95,21); + fpad1->Draw(); + fpad2 = new TPad("pad2","",0.05,0.4,0.95,0.65,21); + fpad2->Draw(); + fpad3 = new TPad("pad3","",0.05,0.05,0.95,0.35,21); + fpad3->Draw(); + + fpad1->cd(); + // pad1->TPaveText::title.SetSize(0.1); + if (fH2Digit) + { + fH2DigitBW->Draw(o1); + fH2DigitBW->SetXTitle("time bin"); + fH2DigitBW->SetYTitle("pad number"); + } + fpad2->cd(); + fH1Occu->Fit("pol0"); + if (fH1Occu) + { + fH1Occu->Draw(o2); + fH1Occu->SetXTitle("time bin"); + fH1Occu->SetYTitle("occupancy"); + } + fpad3->cd(); + if (fH1Digit) + { + fH1Digit->Draw(o3); + fH1Digit->SetXTitle("time bin"); + fH1Digit->SetYTitle("ADC amplitude "); + } + +}; + +void AliTPCDigitsH::DeleteHisto(const Text_t *namecycle) +{ + if (fout) fout->Delete(namecycle); +} + +void AliTPCDigitsH::SetHisto(Int_t pad = 1 ) +{ + + Int_t n_of_pads = fTPCParam->GetNPads(fsec,frow); + if (pad > (n_of_pads-1)) + { + cout<<"Pad number is greater then actula number of pads in thi row \n"; + cout<<"Noch einmal \n"; + return; + } + + fpad = pad; + Anal(); + + // if ( (fH1Digit) && (fbDelHisto == kTRUE)) + // { + // try + // { + // // delete fH1Digit; + // } + // catch(...) + // { + // cout<<"Delete error. Contact autor of root \n"; + // }; + // fH1Digit = 0; + // } + + char s[80]; + char sh[80]; + sprintf(s,"example sector %d Row %d Pad %d",fsec,frow,fpad); + sprintf(sh,"h%d_%d_%d",fsec,frow,fpad); + fH2DigitBW = new AliH2F("bw", "", fTimeN, fTimeStart, fTimeStop, n_of_pads, 0, n_of_pads-1); + fH1Digit = new TH1F(sh,s,fTimeN,fTimeStart,fTimeStop); + + for (Int_t i = 0;iGetBin(i,pad); + Float_t weight = fH2Digit->GetBinContent(index); + fH1Digit->Fill(i,weight); + }; + + + sprintf(s,"Occupancy in sector %d Row %d threshold = %d",fsec,frow,fThreshold); + sprintf(sh,"hoccu%d_%d_%d",fsec,frow,fpad); + fH1Occu = new TH1F(sh,s,fOccuN,fTimeStart,fTimeStop); + + for (Int_t i = 0;iGetBin(itime,ipad); + if ( (ipad>3) && ((ipad+3)GetBinContent(index) >fThreshold) over++ ; + } + if (fH2Digit->GetBinContent(index) >fThreshold) + fH2DigitBW->Fill(itime,ipad,1); + else + fH2DigitBW->Fill(itime,ipad,0); + } + } + Float_t occu = ((Float_t)over) /((Float_t) (all)); + // Float_t time = ((fTimeStop-fTimeStart)/fOccuN)*i+fTimeStart; + + fH1Occu->SetBinContent(i,occu); + // Int_t index = fH1Occu->GetBin(i); + Float_t error = sqrt( ((Float_t) ((over)/25+1)) )/((Float_t)(all)/25.); + fH1Occu->SetBinError(i,error); + + }; + + +} + + + +void AliTPCDigitsH::Streamer(TBuffer & R__b) +{ + if (R__b.IsReading()) { + // Version_t R__v = R__b.ReadVersion(); + } else { + R__b.WriteVersion(AliTPCDigitsH::IsA()); + } +} diff --git a/TPC/AliTPCDigitsH.h b/TPC/AliTPCDigitsH.h new file mode 100644 index 00000000000..c29beb62c55 --- /dev/null +++ b/TPC/AliTPCDigitsH.h @@ -0,0 +1,114 @@ +#ifndef TTPCDIGITSH_H +#define TTPCDIGITSH_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +//////////////////////////////////////////////// +// Manager class for AliTPCDigitsH // +//////////////////////////////////////////////// + + +// include files and class forward declarations + +class TFile; +class TH2F; +class AliH2F; +class TH1F; +class TPaveText; +class TPad; +class TCanvas; +class AliTPCParam; +class AliTPCD; +class TClonesArray; +class TTree; +#include "TObject.h" +#include "TUnixSystem.h" + +class AliTPCDigitsH :public TObject{ +public: + ~AliTPCDigitsH(); + AliTPCDigitsH(const AliTPCDigitsH &); + AliTPCDigitsH(); + AliTPCDigitsH & operator = (const AliTPCDigitsH &); + AliTPCD * GetDParam() {return fDParam;} + void SetDParam(AliTPCD * dig); + AliTPCParam *& GetParam(); + //get tpc parameters + TFile * GetIn() {return fin;} + TFile * GetOut() {return fout;} + void Anal(); //get two dimensional histogram time*pad*amplitude for given + void SetSecRowTime(Int_t sec , Int_t row = 1, + Int_t TimeN = 500 , + Float_t TimeStart = 0, Float_t TimeStop = 500); + //set section row and timing histogram + //ranges and calculate histograms + void SetHisto( Int_t pad = 1 ); + virtual void Draw(Option_t * opt1 ="cont1" , Option_t * opt2 = "error", + Option_t * opt3 = "L" ); + + void CloseFiles(); //close input and output file + void DeleteHisto(const Text_t *namecycle); // + + Bool_t SetIO(const char * inFile, const char* outFile); + Bool_t SetTree(Int_t eventn =0 ); + void SetParticles(Int_t sec = -1, Int_t row = -1 , + Int_t size1 = 30000,Int_t size2=300, + Bool_t all=1 ); + Bool_t SetEventN(Int_t EventN=0); //set event number connected to analisys + + void SetbDelHisto(Bool_t bDelHisto) { fbDelHisto = bDelHisto;} // + void SetThreshold(Int_t threshold = 10 ) { fThreshold = threshold ;} // + ///////////// + AliH2F & GetHis1() { return *fH2Digit;} + AliH2F & GetHisBW() { return *fH2DigitBW;} + TH1F & GetHis2() { return *fH1Digit;} + TH1F & GetHis3() { return *fH1Occu;} + TPad & GetPad1() {return *fpad1;} + TPad & GetPad2() {return *fpad2;} + TPad & GetPad3() {return *fpad3;} + TCanvas &GetCanvas(){return *fcanvas;} +protected: + +private: + TFile *fin; //input TTRE file with digits + TFile *fout; //output file + TPad * fpad1; + TPad * fpad2; + TPad * fpad3; + TCanvas * fcanvas; + AliTPCParam * fTPCParam; + AliTPCD *fDParam; + Bool_t fbIOState; + //state of Input and Output file : kTRUE if all is OK + Bool_t fbDigState; + //state of Input digits tree kTRUE if ftree point to valid digit tree + TClonesArray *fDigits; //pointer to digits object used inanal + TClonesArray *fParticles; //pointer to particles array + TTree *ftree; //pointer to tree with digits + Int_t fsec; //actual sector of TPC + Int_t frow; //actual row of TPC + Int_t fpad; //actual pad + Int_t fEventN; //event number connected to + Int_t fTimeN; //division number of the time + Float_t fTimeStart,fTimeStop; //start and stop time for histograms + Int_t fOccuN; //time division for occupancy calculating + TPaveText * fTitle; // + Int_t fThreshold; //treshold for the ocupancy definition + Bool_t fbDelHisto; //swith which tell if we want to delete produced histogram + + AliH2F *fH2Digit; //two dimensional histogram - sector row + AliH2F *fH2DigitBW; //black and white histogram over treshold + TH1F *fH1Digit; //one dimensional histogram sector row pad + TH1F *fH1Occu; //occupancy graph + TH1F *fHParticles; //histogram of particles contributing to digits + TH1F *fHPartMultiplicity; + //histogram of particles multiplicity + TH1F *fHAllP; //histogram with accepted time bin for all particles + TH1F *fHSecondaryP; + //histogram with accepted time bin for secondary particles + + ClassDef(AliTPCDigitsH,1) +}; +#endif /* TTPCDIGITSH_H */ diff --git a/TPC/AliTPCHits2Digits.C b/TPC/AliTPCHits2Digits.C index c47f93a8939..54c2d024428 100644 --- a/TPC/AliTPCHits2Digits.C +++ b/TPC/AliTPCHits2Digits.C @@ -1,4 +1,3 @@ - void AliTPCHits2Digits(const char * name= "pokusD_") { @@ -9,6 +8,7 @@ void AliTPCHits2Digits(const char * name= "pokusD_") } //names of trees + const char * inFile = "galice.root"; // const * char ident= "TreeD1par_"; @@ -42,8 +42,8 @@ void AliTPCHits2Digits(const char * name= "pokusD_") AliTPCPRF2D &prf = paramd->GetPRF2D(); AliTPCRF1D & rf = paramd->GetRF(); - param.SetPadLength(2.0); - param.SetPadWidth(0.3); + param.SetPadLength(2.05); + param.SetPadWidth(0.35); param.SetPadPitchLength(2.05); param.SetPadPitchWidth(0.35); param.SetNWires(5); @@ -53,19 +53,11 @@ void AliTPCHits2Digits(const char * name= "pokusD_") param.SetNoise(500); param.SetGasGain(1.e4); param.SetChipGain(24); - param.SetSectorAngles(20.,0.,20.,0.); - param.SetInnerRadiusLow(83.9); - param.SetInnerRadiusUp(141.3); + param.SetSectorAngles(40.,0.,20.,10.); + param.SetInnerRadiusLow(83.7); + param.SetInnerRadiusUp(132.9); param.SetOuterRadiusLow(146.9); param.SetOuterRadiusUp(249.4); - param.SetTSample(1.9e-7); - param.SetTSigma(1.5e-7/2.35); - param.SetInSecLowEdge(81.6); - param.SetInSecUpEdge(143.6); - param.SetOuSecLowEdge(144.2); - param.SetOuSecUpEdge(252.1); - param.SetEdge(1.5); - param.SetDeadZone(1.15); param.Update(); //Set z (time) response function @@ -74,7 +66,7 @@ void AliTPCHits2Digits(const char * name= "pokusD_") rf.SetGauss(param.GetZSigma(),param.GetZWidth(),0.4); rf.Update(); //Set two dimensional pad response function - TFile f("$(ALICE_ROOT)/TPC/AliTPCprf2d.root"); + TFile f("TPC/AliTPCprf2d.root"); // prf.Read("prf_205035_Gati_062074_d03"); prf.Read("prf_205035_Gati_062074_d03"); f.Close(); @@ -89,18 +81,7 @@ void AliTPCHits2Digits(const char * name= "pokusD_") prf.Dump(); printf("**********Digit object dump end********************\n"); - TPC->Hits2DigitsSector(1); - TPC->Hits2DigitsSector(2); - TPC->Hits2DigitsSector(3); - TPC->Hits2DigitsSector(1+18); - TPC->Hits2DigitsSector(2+18); - TPC->Hits2DigitsSector(3+18); - TPC->Hits2DigitsSector(1+36); - TPC->Hits2DigitsSector(2+36); - TPC->Hits2DigitsSector(3+36); - TPC->Hits2DigitsSector(1+36+18); - TPC->Hits2DigitsSector(2+36+18); - TPC->Hits2DigitsSector(3+36+18); + TPC->Hits2DigitsSector(0); file->cd(); diff --git a/TPC/AliTPCPRF2D.cxx b/TPC/AliTPCPRF2D.cxx index 57b073bc3c5..bf0df1ec312 100644 --- a/TPC/AliTPCPRF2D.cxx +++ b/TPC/AliTPCPRF2D.cxx @@ -15,13 +15,23 @@ /* $Log$ +Revision 1.3.8.2 2000/04/10 08:40:46 kowal2 + +Small changes by M. Ivanov, improvements of algorithms + +Revision 1.3.8.1 2000/04/10 07:56:53 kowal2 +Not used anymore - removed + +Revision 1.3 1999/10/05 17:15:46 fca +Minor syntax for the Alpha OSF + Revision 1.2 1999/09/29 09:24:34 fca Introduction of the Copyright and cvs Log */ /////////////////////////////////////////////////////////////////////////////// -// AliTPCPRF2D - // +// AliTPCPRF2D - // // Pad response function object in two dimesions // // This class contains the basic functions for the // // calculation of PRF according generic charge distribution // @@ -33,6 +43,8 @@ Introduction of the Copyright and cvs Log // Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk // // // /////////////////////////////////////////////////////////////////////////////// + + #include "TMath.h" #include "AliTPCPRF2D.h" #include "TF2.h" @@ -45,6 +57,7 @@ Introduction of the Copyright and cvs Log #include "TH2.h" #include "TPaveText.h" #include "TText.h" +// extern TStyle * gStyle; @@ -54,6 +67,7 @@ static const Int_t NPRF = 100; static Double_t funGauss2D(Double_t *x, Double_t * par) { +//Gauss function -needde by the generic function object return ( TMath::Exp(-(x[0]*x[0])/(2*par[0]*par[0]))* TMath::Exp(-(x[1]*x[1])/(2*par[1]*par[1]))); @@ -61,14 +75,14 @@ static Double_t funGauss2D(Double_t *x, Double_t * par) static Double_t funCosh2D(Double_t *x, Double_t * par) { + //Cosh function -needde by the generic function object return ( 1/(TMath::CosH(3.14159*x[0]/(2*par[0]))* TMath::CosH(3.14159*x[1]/(2*par[1])))); } static Double_t funGati2D(Double_t *x, Double_t * par) { - //par[1] = is equal to k3X - //par[0] is equal to pad wire distance + //Gati function -needde by the generic function object Float_t K3=par[1]; Float_t K3R=TMath::Sqrt(K3); Float_t K2=(TMath::Pi()/2)*(1-K3R/2.); @@ -89,9 +103,6 @@ static Double_t funGati2D(Double_t *x, Double_t * par) return res; } - -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// @@ -99,20 +110,24 @@ ClassImp(AliTPCPRF2D) AliTPCPRF2D::AliTPCPRF2D() { + //default constructor for response function object ffcharge = 0; fNPRF =NPRF ; fSigmaX = 0; + fSigmaY = 0; fGRF = 0; fkNorm = 1; - forigsigmaY=0; - forigsigmaX=0; + fOrigSigmaY=0; + fOrigSigmaX=0; fNdiv = 5; + //set daault angels + fChargeAngle = 0; + fCosAngle = 0; //chewron default values SetPad(0.8,0.8); SetChevron(0.2,0.0,1.0); SetY(-0.2,0.2,2); - // SetGauss(0.22,0.22,1); } AliTPCPRF2D::~AliTPCPRF2D() @@ -159,8 +174,10 @@ void AliTPCPRF2D::SetChParam(Float_t width, Float_t height, Float_t AliTPCPRF2D::GetPRF(Float_t xin, Float_t yin, Bool_t inter) { - if (ffcharge==0) return 0; - // Float_t y=Float_t(fNYdiv-1)*(yin-fY1)/(fY2-fY1); + //function which return pad response + //for the charge in distance xin + //return cubic aproximation of PRF or PRF at nearest virtual wire + if (ffcharge==0) return 0; //transform position to "wire position" Float_t y=fDYtoWire*(yin-fY1); if (fNYdiv == 1) y=fY1; @@ -203,16 +220,16 @@ Float_t AliTPCPRF2D::GetPRF(Float_t xin, Float_t yin, Bool_t inter) c=K-d; Float_t dy=y-Float_t(i); Float_t res = a+b*dy+c*dy*dy+d*dy*dy*dy; - //Float_t res = z1*(1-dy)+z2*dy; return res; } + return 0.; } Float_t AliTPCPRF2D::GetPRFActiv(Float_t xin) { - //x xin DStep unit - //return splaine aproximaton + //GEt response function on given charege line + //return spline aproximaton Float_t x = (xin*fDStepM1)+fNPRF/2; Int_t i = Int_t(x); @@ -234,6 +251,8 @@ Float_t AliTPCPRF2D::GetPRFActiv(Float_t xin) Float_t AliTPCPRF2D::GetGRF(Float_t xin, Float_t yin) { + //function which returnoriginal charge distribution + //this function is just normalised for fKnorm if (fGRF != 0 ) return fkNorm*fGRF->Eval(xin,yin)/fInteg; else @@ -244,15 +263,16 @@ Float_t AliTPCPRF2D::GetGRF(Float_t xin, Float_t yin) void AliTPCPRF2D::SetParam( TF2 * GRF, Float_t kNorm, Float_t sigmaX, Float_t sigmaY) { + //adjust parameters of the original charge distribution + //and pad size parameters if (fGRF !=0 ) fGRF->Delete(); fGRF = GRF; fkNorm = kNorm; if (sigmaX ==0) sigmaX=(fWidth+fK*fHeightS)/sqrt12; if (sigmaY ==0) sigmaY=(fWidth+fK*fHeightS)/sqrt12; - forigsigmaX=sigmaX; - forigsigmaY=sigmaY; + fOrigSigmaX=sigmaX; + fOrigSigmaY=sigmaY; fDStep = TMath::Sqrt(sigmaX*sigmaX+fWidth*fWidth/6.)/10.; - // Update(); sprintf(fType,"User"); } @@ -260,6 +280,9 @@ void AliTPCPRF2D::SetParam( TF2 * GRF, Float_t kNorm, void AliTPCPRF2D::SetGauss(Float_t sigmaX, Float_t sigmaY, Float_t kNorm) { + // + // set parameters for Gauss generic charge distribution + // fkNorm = kNorm; if (fGRF !=0 ) fGRF->Delete(); fGRF = new TF2("fun",funGauss2D,-5.,5.,-5.,5.,4); @@ -267,18 +290,19 @@ void AliTPCPRF2D::SetGauss(Float_t sigmaX, Float_t sigmaY, funParam[1]=sigmaY; funParam[2]=fK; funParam[3]=fHeightS; - forigsigmaX=sigmaX; - forigsigmaY=sigmaY; + fOrigSigmaX=sigmaX; + fOrigSigmaY=sigmaY; fGRF->SetParameters(funParam); fDStep = TMath::Sqrt(sigmaX*sigmaX+fWidth*fWidth/6.)/10.; //by default I set the step as one tenth of sigma - //Update(); sprintf(fType,"Gauss"); } void AliTPCPRF2D::SetCosh(Float_t sigmaX, Float_t sigmaY, Float_t kNorm) -{ +{ + // set parameters for Cosh generic charge distribution + // fkNorm = kNorm; if (fGRF !=0 ) fGRF->Delete(); fGRF = new TF2("fun", funCosh2D,-5.,5.,-5.,5.,4); @@ -287,11 +311,10 @@ void AliTPCPRF2D::SetCosh(Float_t sigmaX, Float_t sigmaY, funParam[2]=fK; funParam[3]=fHeightS; fGRF->SetParameters(funParam); - forigsigmaX=sigmaX; - forigsigmaY=sigmaY; + fOrigSigmaX=sigmaX; + fOrigSigmaY=sigmaY; fDStep = TMath::Sqrt(sigmaX*sigmaX+fWidth*fWidth/6.)/10.; //by default I set the step as one tenth of sigma - //Update(); sprintf(fType,"Cosh"); } @@ -299,6 +322,8 @@ void AliTPCPRF2D::SetGati(Float_t K3X, Float_t K3Y, Float_t padDistance, Float_t kNorm) { + // set parameters for Gati generic charge distribution + // fkNorm = kNorm; if (fGRF !=0 ) fGRF->Delete(); fGRF = new TF2("fun", funGati2D,-5.,5.,-5.,5.,5); @@ -311,11 +336,10 @@ void AliTPCPRF2D::SetGati(Float_t K3X, Float_t K3Y, funParam[3]=fHeightS; funParam[4]=K3Y; fGRF->SetParameters(funParam); - forigsigmaX=padDistance; - forigsigmaY=padDistance; + fOrigSigmaX=padDistance; + fOrigSigmaY=padDistance; fDStep = TMath::Sqrt(padDistance*padDistance+fWidth*fWidth/6.)/10.; //by default I set the step as one tenth of sigma - //Update(); sprintf(fType,"Gati"); } @@ -323,102 +347,144 @@ void AliTPCPRF2D::SetGati(Float_t K3X, Float_t K3Y, void AliTPCPRF2D::Update() { - for (Int_t i=0; iEval(Float_t(ix)*dx,Float_t(iy)*dy)*dx*dy; + ///////////////////////////////////////////////////// + fInteg =dInteg; + if ( fInteg == 0 ) fInteg = 1; + + for (i=0; iEval(x,y)*dx*dy; - fInteg*=4; - ///////////////////////////////////////////////////// - - - if ( fInteg == 0 ) fInteg = 1; - + Double_t x,dx,ddx,ddy,dddx,dddy; + Double_t cos = TMath::Cos(fChargeAngle); + Double_t sin = TMath::Sin(fChargeAngle); + //integrate charge over pad for different distance of pad for (i =0; i0) x1 = (y2-y1)*fK-(fWidth+fK*fHeightS)/2.; else x1 =-(fWidth+fK*fHeightS)/2. ; - Float_t x2=x1+fWidth; + Double_t x2=x1+fWidth; if (y2>y1) { - if ((x2-x1)*fNdiv(fCurrentY-(4.0*fOrigSigmaY))) && + (y<(fCurrentY+(4.0*fOrigSigmaY)))){ + Double_t xt=x-k*fK*(y-y1); + if ((TMath::Abs(xch-xt)<4*fOrigSigmaX)){ + + ddx = xch-(xt+dx/2.); + ddy = fCurrentY-(y+dy/2.); + dddx = cos*ddx-sin*ddy; + dddy = sin*ddx+cos*ddy; + Double_t z0=fGRF->Eval(dddx,dddy); //middle point + + ddx = xch-(xt+dx/2.); + ddy = fCurrentY-(y); + dddx = cos*ddx-sin*ddy; + dddy = sin*ddx+cos*ddy; + Double_t z1=fGRF->Eval(dddx,dddy); //point down + + ddx = xch-(xt+dx/2.); + ddy = fCurrentY-(y+dy); + dddx = cos*ddx-sin*ddy; + dddy = sin*ddx+cos*ddy; + Double_t z3=fGRF->Eval(dddx,dddy); //point up + + ddx = xch-(xt); + ddy = fCurrentY-(y+dy/2.); + dddx = cos*ddx-sin*ddy; + dddy = sin*ddx+cos*ddy; + Double_t z2=fGRF->Eval(dddx,dddy); //point left + + ddx = xch-(xt+dx); + ddy = fCurrentY-(y+dy/2.); + dddx = cos*ddx-sin*ddy; + dddy = sin*ddx+cos*ddy; + Double_t z4=fGRF->Eval(dddx,dddy); //point right - for (x=x1;x(fActualY-(4.0*forigsigmaY))) && - (y<(fActualY+(4.0*forigsigmaY)))){ - Float_t xt=x-k*fK*(y-y1); - if ((TMath::Abs(xch-xt)<4*forigsigmaX)){ - - Float_t z0=fGRF->Eval(xch-(xt+dx/2.),fActualY-(y+dy/2.)); - - Float_t z1=fGRF->Eval(xch-(xt+dx/2.),fActualY-y); - Float_t z2=fGRF->Eval(xch-xt,fActualY-(y+dy/2.)); - Float_t z3=fGRF->Eval(xch-(xt-dx/2.),fActualY-y); - Float_t z4=fGRF->Eval(xch-xt,fActualY-(y-dy/2.)); if (z0<0) z0=0; if (z1<0) z1=0; if (z2<0) z2=0; if (z3<0) z3=0; if (z4<0) z4=0; - - // Float_t a=(z1-z3)/2; - // Float_t b=(z2-z4)/2; - Float_t c= (z3+z1-2*z0)/2.; - Float_t d= (z2+z4-2*z0)/2.; - Float_t z= (z0+c/12.+d/12.); - - //Float_t z= fGRF->Eval(xch-xt,fActualY-y); - if (z>0.) fcharge[i]+=z*dx*dy/fInteg; + + Double_t c= (z3+z1-2*z0)/2.; + Double_t d= (z2+z4-2*z0)/2.; + Double_t z= (z0+c/12.+d/12.); + + if (z>0.) fcharge[i]+=fkNorm*z*dx*dy/fInteg; } } } @@ -426,27 +492,47 @@ void AliTPCPRF2D::Update1() k*=-1; } }; - - fSigmaX = 0; + +} + +void AliTPCPRF2D::UpdateSigma() +{ + // + //calulate effective sigma X and sigma y of PRF + fMeanX = 0; + fMeanY = 0; + fSigmaX = 0; + fSigmaY = 0; + Float_t sum =0; - Float_t mean=0; - for (x =-fNPRF*fDStep; x0){ - mean/=sum; - fSigmaX = TMath::Sqrt(fSigmaX/sum-mean*mean); + fMeanX/=sum; + fMeanY/=sum; + fSigmaX = TMath::Sqrt(fSigmaX/sum-fMeanX*fMeanX); + fSigmaY = TMath::Sqrt(fSigmaY/sum-fMeanY*fMeanY); } else fSigmaX=0; - //calculate conversion coefitient to convert position to virtual wire - fDYtoWire=Float_t(fNYdiv-1)/(fY2-fY1); - fDStepM1=1/fDStep; } + void AliTPCPRF2D::Streamer(TBuffer &R__b) { // Stream an object of class AliTPCPRF2D @@ -455,30 +541,27 @@ void AliTPCPRF2D::Streamer(TBuffer &R__b) Version_t R__v = R__b.ReadVersion(); if (R__v) { } TObject::Streamer(R__b); //read chewron parameters - R__b >> fSigmaX; R__b >> fHeightFull; R__b >> fHeightS; R__b >> fShiftY; R__b >> fWidth; R__b >> fK; - R__b >> fActualY; - //read charge parameters - R__b >> fType[0]; - R__b >> fType[1]; - R__b >> fType[2]; - R__b >> fType[3]; - R__b >> fType[4]; - R__b >> forigsigmaX; - R__b >> forigsigmaY; + R__b >> fSigmaX; + R__b >> fSigmaY; + R__b >> fMeanX; + R__b >> fMeanY; + //read charge parameters + R__b.ReadFastArray(fType,5); + R__b >> fOrigSigmaX; + R__b >> fOrigSigmaY; R__b >> fkNorm; R__b >> fK3X; R__b >> fK3Y; R__b >> fPadDistance; - R__b >> fInteg; - + R__b >> fInteg; //read functions if (fGRF!=0) { - delete [] fGRF; + fGRF->Delete(); fGRF=0; } if (strncmp(fType,"User",3)==0){ @@ -490,8 +573,7 @@ void AliTPCPRF2D::Streamer(TBuffer &R__b) if (strncmp(fType,"Cosh",3)==0) fGRF = new TF2("fun",funCosh2D,-5.,5.,-5.,5.,4); if (strncmp(fType,"Gati",3)==0) - fGRF = new TF2("fun",funGati2D,-5.,5.,-5.,5.,5); - + fGRF = new TF2("fun",funGati2D,-5.,5.,-5.,5.,5); //read interpolation parameters R__b >>fY1; R__b >>fY2; @@ -510,22 +592,19 @@ void AliTPCPRF2D::Streamer(TBuffer &R__b) R__b.WriteVersion(AliTPCPRF2D::IsA()); TObject::Streamer(R__b); //write chewron parameters - R__b << fSigmaX; R__b << fHeightFull; R__b << fHeightS; R__b << fShiftY; R__b << fWidth; R__b << fK; - R__b << fActualY; + R__b << fSigmaX; + R__b << fSigmaY; + R__b << fMeanX; + R__b << fMeanY; //write charge parameters - R__b << fType[0]; - R__b << fType[1]; - R__b << fType[2]; - R__b << fType[3]; - R__b << fType[4]; - - R__b << forigsigmaX; - R__b << forigsigmaY; + R__b.WriteFastArray(fType,5); + R__b << fOrigSigmaX; + R__b << fOrigSigmaY; R__b << fkNorm; R__b << fK3X; R__b << fK3Y; @@ -549,6 +628,7 @@ void AliTPCPRF2D::Streamer(TBuffer &R__b) void AliTPCPRF2D::DrawX(Float_t x1 ,Float_t x2,Float_t y, Bool_t inter) { + //draw pad response function at interval at given y position if (fGRF==0) return ; const Int_t N=100; char s[100]; @@ -559,15 +639,12 @@ void AliTPCPRF2D::DrawX(Float_t x1 ,Float_t x2,Float_t y, Bool_t inter) TPad * pad2 = new TPad("pad2PRF","",0.05,0.22,0.95,0.60,21); pad2->Draw(); - // pad1->cd(); - //pad2->cd(); gStyle->SetOptFit(1); gStyle->SetOptStat(0); sprintf(s,"PRF response function for chevron pad"); TH1F * hPRFc = new TH1F("hPRFc",s,N+1,x1,x2); Float_t x=x1; Float_t y1; - // Float_t y2; for (Float_t i = 0;iAddText(s); sprintf(s,"Y position: %2.2f ",y); comment->AddText(s); - sprintf(s,"Sigma x of original distribution: %2.2f ",forigsigmaX); + sprintf(s,"Sigma x of original distribution: %2.2f ",fOrigSigmaX); comment->AddText(s); - sprintf(s,"Sigma y of original distribution: %2.2f ",forigsigmaY); + sprintf(s,"Sigma y of original distribution: %2.2f ",fOrigSigmaY); comment->AddText(s); sprintf(s,"Type of original distribution: %s ",fType); comment->AddText(s); @@ -664,9 +741,9 @@ void AliTPCPRF2D::Draw(Float_t x1 ,Float_t x2,Float_t y1, Float_t y2, comment->AddText(s); sprintf(s,"Overlap factor: %2.2f",fK*fHeightS/fWidth); comment->AddText(s); - sprintf(s,"Sigma x of original distribution: %2.2f ",forigsigmaX); + sprintf(s,"Sigma x of original distribution: %2.2f ",fOrigSigmaX); comment->AddText(s); - sprintf(s,"Sigma y of original distribution: %2.2f ",forigsigmaY); + sprintf(s,"Sigma y of original distribution: %2.2f ",fOrigSigmaY); comment->AddText(s); sprintf(s,"Type of original distribution: %s ",fType); comment->AddText(s); @@ -697,14 +774,16 @@ void AliTPCPRF2D::DrawDist(Float_t x1 ,Float_t x2,Float_t y1, Float_t y2, Float_t dy=(y2-y1)/Float_t(Ny) ; Float_t x,y,z,ddx; // Float_t y2; - for ( x = x1;x<(x2+dx/2.);x+=dx) - for(y = y1;y<=(y2+dx/2.);y+=dy) + for ( x = x1;x<(x2+3.1*dx);x+=dx) + for(y = y1;y<(y2+3.1*dx);y+=dy) { Float_t sumx=0; Float_t sum=0; - for (Float_t padx=-fWidth;padx<(fWidth*1.1);padx+=fWidth) + for (Int_t i=-3;i<=3;i++) + // for (Float_t padx=-fWidth;padx<(fWidth*1.1);padx+=fWidth) { - z = GetPRF(x-padx,y,inter); + Float_t padx=Float_t(i)*fWidth; + z = GetPRF(x-padx,y,inter); if (z>thr){ sum+=z; sumx+=z*padx; @@ -743,9 +822,9 @@ void AliTPCPRF2D::DrawDist(Float_t x1 ,Float_t x2,Float_t y1, Float_t y2, comment->AddText(s); sprintf(s,"Overlap factor: %2.2f",fK*fHeightS/fWidth); comment->AddText(s); - sprintf(s,"Sigma x of original distribution: %2.2f ",forigsigmaX); + sprintf(s,"Sigma x of original distribution: %2.2f ",fOrigSigmaX); comment->AddText(s); - sprintf(s,"Sigma y of original distribution: %2.2f ",forigsigmaY); + sprintf(s,"Sigma y of original distribution: %2.2f ",fOrigSigmaY); comment->AddText(s); sprintf(s,"Type of original distribution: %s ",fType); comment->AddText(s); diff --git a/TPC/AliTPCPRF2D.h b/TPC/AliTPCPRF2D.h index 3646f77448f..64aec8434c1 100644 --- a/TPC/AliTPCPRF2D.h +++ b/TPC/AliTPCPRF2D.h @@ -4,9 +4,8 @@ * See cxx source for full Copyright notice */ /* $Id$ */ - //////////////////////////////////////////////// -// Manager class for AliTPCPRF2D // +// Manager class for AliTPCPRF2D // //////////////////////////////////////////////// @@ -18,24 +17,22 @@ #include "TObject.h" #include "TMath.h" class TF2; -class TArrayF; +class TArrayF; class AliTPCPRF2D : public TObject { public : AliTPCPRF2D(); ~AliTPCPRF2D(); - + void Update(); //recalculate tables for charge calculation Float_t GetGRF(Float_t xin, Float_t yin); //return generic response function in xin Float_t GetPRF(Float_t xin, Float_t yin, Bool_t inter=kFALSE); //return PRF in point xin,yin - void SetY(Float_t y1, Float_t y2, Int_t nYdiv) ; void DrawX(Float_t x1, Float_t x2,Float_t y, Bool_t inter=kFALSE); //draw one dimensional response for //fixed y // void DrawY(Float_t y1, Float_t y2,Float_t x); //draw one dimensional response for fixed x - void Draw(Option_t *) {} void Draw(Float_t x1, Float_t x2, Float_t y1, Float_t y2, Bool_t inter=kFALSE, Int_t Nx=20, Int_t Ny=20); //draw two dimensional PRF @@ -45,7 +42,17 @@ public : Float_t thr=0); //draw distortion of COG method //we suppose threshold equal to thr - + + void SetPad(Float_t width, Float_t height); + //set base chevron parameters + void SetChevron(Float_t hstep, Float_t shifty, Float_t fac); + //set chevron parameters + void SetChParam(Float_t width, Float_t height, + Float_t hstep, Float_t shifty, Float_t fac); + //set all geometrical parameters + void SetY(Float_t y1, Float_t y2, Int_t nYdiv) ; + void SetChargeAngle(Float_t angle){fChargeAngle = angle;} //set angle of pad and charge distribution + //axes void SetGauss(Float_t sigmaX,Float_t sigmaY , Float_t kNorm=1); //adjust PRF with GAUSIAN as generic GRF //if direct = kTRUE then it does't convolute distribution @@ -56,25 +63,30 @@ public : Float_t kNorm=1); void SetParam(TF2 * GRF,Float_t kNorm, Float_t sigmaX=0, Float_t sigmaY=0); - void SetPad(Float_t width, Float_t height); - //set base chevron parameters - void SetChevron(Float_t hstep, Float_t shifty, Float_t fac); - //set chevron parameters - void SetChParam(Float_t width, Float_t height, - Float_t hstep, Float_t shifty, Float_t fac); - //set all geometrical parameters void SetNdiv(Int_t Ndiv){fNdiv=Ndiv;} - void Update(); + Float_t GetSigmaX() const {return fSigmaX;} + Float_t GetSigmaY() const {return fSigmaY;} + + protected: - void Update1(); + void Update1(); + void UpdateSigma(); //recalculate sigma of PRF Float_t GetPRFActiv(Float_t xin); //return PRF in point xin and actual y - Float_t * fcharge; // field with PRF - Float_t fY1; - Float_t fY2; - Int_t fNYdiv; + Float_t * fcharge; //field with PRF + Float_t fY1; //position of first "virtual" vire + Float_t fY2; //position of last virtual vire + Int_t fNYdiv; //number of wires Float_t * ffcharge; //pointer to array of arrays private: + + //chevron parameters + Float_t fHeightFull; //height of the full pad + Float_t fHeightS; //height of the one step + Float_t fShiftY; //shift of the step + Float_t fWidth; //width of the pad + Float_t fK; //k factor of the chewron + Double_t funParam[5];//parameters of used charge function Int_t fNPRF; //number of interpolations point Int_t fNdiv; //number of division to calculate integral @@ -83,27 +95,27 @@ private: Float_t fInteg; //integral of GRF on +- infinity TF2 * fGRF; //charge distribution function - Float_t fK3X; - Float_t fK3Y; - Float_t fPadDistance; + Float_t fK3X; //KX parameter (only for Gati parametrization) + Float_t fK3Y; //KY parameter (only for Gati parametrisation) + Float_t fPadDistance; //pad anode distnce (only for Gati parametrisation) + + Float_t fOrigSigmaX; //sigma of original distribution; + Float_t fOrigSigmaY; //sigma of original distribution; + Float_t fChargeAngle;//'angle' of charge distribution refernce system to pad reference system + Float_t fCosAngle; //'angle' of the pad assymetry - Float_t forigsigmaX;//sigma of original distribution; - Float_t forigsigmaY;//sigma of original distribution; - Float_t fSigmaX; //sigma of PAD response function + Float_t fSigmaX; //sigma X of PAD response function + Float_t fSigmaY; //sigma Y of PAD response function + Float_t fMeanX; //mean X value + Float_t fMeanY; //mean Y value //calculated during update - //chewron parameters - Float_t fHeightFull; //height of the full pad - Float_t fHeightS; //height of the one step - Float_t fShiftY; //shift of the step - Float_t fWidth; //width of the pad - Float_t fK; //k factor of the chewron - Float_t fActualY; //in reality we calculate PRF only for - //one fixed y - char fType[5]; //charge type - //to make calculation faster we reduce division - Float_t fDYtoWire; //used to make PRF calculation faster in GetPRF - Float_t fDStepM1; //used in GetPRFActiv + + + char fType[5]; //charge type + Float_t fCurrentY; //in reality we calculate PRF only for one fixed y + Float_t fDYtoWire; //! used to make PRF calculation faster in GetPRF + Float_t fDStepM1; //! used in GetPRFActiv to make calculation faster ClassDef(AliTPCPRF2D,1) }; diff --git a/TPC/AliTPCParam.cxx b/TPC/AliTPCParam.cxx index 33c6e3894cf..4f398d6aeb1 100644 --- a/TPC/AliTPCParam.cxx +++ b/TPC/AliTPCParam.cxx @@ -15,6 +15,17 @@ /* $Log$ +Revision 1.7.8.2 2000/04/10 08:44:51 kowal2 + +New transformations added +Different pad and pad-rows geometries for different sectors + +Revision 1.7.8.1 2000/04/10 07:56:53 kowal2 +Not used anymore - removed + +Revision 1.7 1999/10/08 13:10:35 fca +Values in SetDefault are in radiants + Revision 1.6 1999/10/08 06:27:59 fca Defaults updated @@ -41,242 +52,266 @@ Introduction of the Copyright and cvs Log #include #include #include -#include "AliTPCSecGeo.h" +#include #include ClassImp(AliTPCParam) -const static Int_t kMaxRows=600; - - -// default values -const static Int_t kMaxTBin =512; - - -const static Float_t kInnerRadiusLow = 83.9; -const static Float_t kOuterRadiusLow = 146.9; -const static Float_t kInnerRadiusUp = 141.3; -const static Float_t kOuterRadiusUp = 249.4; - -const static Float_t kInnerAngle = 0.34906585; // 20 degrees -const static Float_t kInnerAngleShift = 0; -const static Float_t kOuterAngle = 0.34906585; // 20 degrees -const static Float_t kOuterAngleShift = 0; - -const static Float_t kPadPitchLength = 2.05; -const static Float_t kPadPitchWidth = 0.35; -const static Float_t kPadLength = 2.05; -const static Float_t kPadWidth = 0.35; - -// Number of wires per pad and wire-wire pitch -const static Int_t knWires = 5; +const static Int_t kMaxRows=600; +// +//sector default parameters +// +const static Float_t kInnerRadiusLow = 81.6; +const static Float_t kOuterRadiusLow = 144.2; +const static Float_t kInnerRadiusUp = 143.6; +const static Float_t kOuterRadiusUp = 252.1; +const static Float_t kInnerAngle = 20; // 20 degrees +const static Float_t kInnerAngleShift = 10; +const static Float_t kOuterAngle = 20; // 20 degrees +const static Float_t kOuterAngleShift = 10; +const static Float_t kInnerFrameSpace = 1.5; +const static Float_t kOuterFrameSpace = 1.5; +const static Float_t kInnerWireMount = 1.15; +const static Float_t kOuterWireMount = 1.15; +const static Float_t kZLength =250.; +const static Int_t kGeometryType = 0; //straight rows +// +//wires default parameters +// +const static Int_t kNInnerWiresPerPad = 5; +const static Int_t kInnerDummyWire = 2; +const static Float_t kInnerOffWire = 0.5; +const static Int_t kNOuterWiresPerPad = 5; +const static Int_t kOuterDummyWire = 2; +const static Float_t kOuterOffWire = 0.5; +// +//pad default parameters +// +const static Float_t kInnerPadPitchLength = 2.05; +const static Float_t kInnerPadPitchWidth = 0.35; +const static Float_t kInnerPadLength = 2.05; +const static Float_t kInnerPadWidth = 0.35; +const static Float_t kOuterPadPitchLength = 2.05; +const static Float_t kOuterPadPitchWidth = 0.35; +const static Float_t kOuterPadLength = 2.05; +const static Float_t kOuterPadWidth = 0.35; +const static Bool_t kBMWPCReadout = kTRUE; //MWPC readout - another possibility GEM +const static Int_t kNCrossRows = 1; //number of rows to cross-talk + +// +//gas default parameters +// const static Float_t kDiffT = 2.2e-2; -const static Float_t kDiffL = 2.2e-2; +const static Float_t kDiffL = 2.2e-2; +const static Float_t kGasGain = 2.e4; const static Float_t kDriftV =2.85e6; - const static Float_t kOmegaTau = 0.145; const static Float_t kAttCoef = 250.; const static Float_t kOxyCont = 5.e-6; - - -const static Float_t kChipGain = 12; -const static Float_t kGasGain = 2e4; -const static Float_t kTSample = 2.e-7; //TSAMPLE -const static Float_t kTFWHM = 2.5e-7; //fwhm of charge distribution - -const static Float_t kNoise = 1000; //default noise = 1000 el -const static Int_t kZeroSup=5; +// +//electornic default parameters +// const static Float_t kPadCoupling=0.5; +const static Int_t kZeroSup=5; +const static Float_t kNoise = 1000; +const static Float_t kChipGain = 12; +const static Float_t kChipNorm = 0.4; +const static Float_t kTSample = 2.e-7; +const static Float_t kTFWHM = 1.9e-7; //fwhm of charge distribution +const static Int_t kMaxTBin =512; +const static Int_t kADCSat =1024; +const static Float_t kADCDynRange =2000.; +// +// +// +const static Float_t kBField =0.2; +const static Float_t kNPrimLoss =10.9; +const static Float_t kNTotalLoss =39.9; // -const static Float_t kEdgeSectorSpace = 1.15; +//transformation coeficients +// const static Float_t kDegtoRad = 0.01745329251994; const static Float_t kRadtoDeg = 57.29577951309; - +// +//response constants +// +const static Int_t kNResponseMax=100; +const static Float_t kResponseThreshold=0.01; //___________________________________________ AliTPCParam::AliTPCParam() { - //constructor set the default parameters + // + //constructor sets the default parameters + // + + fResponseBin = 0; + fResponseWeight = 0; + fRotAngle = 0; SetDefault(); } - -void AliTPCParam::SetSectorAngles(Float_t innerangle, Float_t innershift, Float_t outerangle, - Float_t outershift, Bool_t inDegree) +AliTPCParam::~AliTPCParam() { // - // set opening angles - fInnerAngle = innerangle; //opening angle of Inner sector - fInnerAngleShift = innershift; //shift of first inner sector center to the 0 - fOuterAngle = outerangle; //opening angle of outer sector - fOuterAngleShift = outershift; //shift of first sector center to the 0 - if (inDegree==kTRUE){ - fInnerAngle *=kDegtoRad; - fInnerAngleShift *=kDegtoRad; - fOuterAngle *=kDegtoRad; - fOuterAngleShift *=kDegtoRad; - } + //destructor deletes some dynamicaly alocated variables + // + + if (fResponseBin!=0) delete [] fResponseBin; + if (fResponseWeight!=0) delete [] fResponseWeight; + if (fRotAngle !=0) delete [] fRotAngle; + } -void AliTPCParam::CRXYZtoXYZ(Float_t *xyz, - const Int_t §or, const Int_t & padrow, Int_t option) const -{ - //transform relative coordinates to absolute - Bool_t rel = ( (option&2)!=0); - Float_t row_first; - row_first = (sector<=fNInnerSector) ? fPadRowLow[0] : fPadRowUp[0]; - if (rel==kTRUE) //if the position is relative to pad row + + +Int_t AliTPCParam::Transform0to1(Float_t *xyz, Int_t * index) const +{ + // + // calculates sector number (index[1], undefined on input) + // xyz intact + // + + Float_t angle,x1; + Int_t sector; + Float_t r = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]); + if ((xyz[0]==0)&&(xyz[1]==0)) angle = 0.; + else { - xyz[0]+=row_first; - xyz[0]+=(Int_t) padrow*fPadPitchLength; - } - - xyz[2]=z_end-xyz[2]; - if (sector=(fNInnerSector>>1)) xyz[2]*=-1.; - } else { - if ( (sector-fNInnerSector) >= (fNOuterSector>>1) ) xyz[2]*=-1; - } + angle =TMath::ASin(xyz[1]/r); + if (xyz[0]<0) angle=TMath::Pi()-angle; + if ( (xyz[0]>0) && (xyz[1]<0) ) angle=2*TMath::Pi()+angle; + } - Float_t x1=xyz[0]; - Float_t y1=xyz[1]; + sector=Int_t((angle-fInnerAngleShift)/fInnerAngle); + Float_t cos,sin; - AdjustAngles(sector,cos,sin); - xyz[0]= x1*cos - y1*sin; - xyz[1]= x1*sin + y1*cos; -} + AdjustCosSin(sector,cos,sin); + x1=xyz[0]*cos + xyz[1]*sin; -void AliTPCParam::XYZtoCRXYZ(Float_t *xyz, - Int_t §or, Int_t & padrow, Int_t option) -{ - //transform global position to the position relative to the sector padrow - //if option=0 X calculate absolute calculate sector - //if option=1 X absolute use input sector - //if option=2 X relative to pad row calculate sector - //if option=3 X relative use input sector - //!!!!!!!!! WE start to calculate rows from row = 0 - - Bool_t rel = ( (option&2)!=0); - //option 0 and 2 means that we don't have information about sector - //we calculate sector - if ((option&1)==0){ - Float_t angle; - Float_t r = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]); - if ((xyz[0]==0)&&(xyz[1]==0)) angle = 0; - else - { - angle =TMath::ASin(xyz[1]/r); - if (xyz[0]<0) angle=TMath::Pi()-angle; - if ( (xyz[0]>0) && (xyz[1]<0) ) angle=2*TMath::Pi()+angle; - } - //transform global position to the position relative to the sector padrow - //fistly calculate xyz[0] radius for lover sector - //bacause in this moment we dont know in which sector we are - sector=Int_t((angle-fInnerAngleShift)/fInnerAngle); - Float_t x1; - Float_t y1; - //firstly we suppose that we are in inner sector - Float_t cos,sin; - AdjustAngles(sector,cos,sin); - - x1=xyz[0]*cos + xyz[1]*sin; - y1=-xyz[0]*sin + xyz[1]*cos; - if (x1>fOuterRadiusLow) - { - sector=Int_t((angle-fOuterAngleShift)/fOuterAngle)+fNInnerSector; - AdjustAngles(sector,cos,sin); - x1=xyz[0]*cos + xyz[1]*sin; - y1=-xyz[0]*sin + xyz[1]*cos; - if (xyz[2]<0) sector+=(fNOuterSector>>1); - } + if (x1>fOuterRadiusLow) + { + sector=Int_t((angle-fOuterAngleShift)/fOuterAngle)+fNInnerSector; + if (xyz[2]<0) sector+=(fNOuterSector>>1); + } else if (xyz[2]<0) sector+=(fNInnerSector>>1); + index[1]=sector; // calculated sector number + index[0]=1; // indicates system after transformation + return sector; +} - if (x1fNtRows)) return kFALSE; - Int_t outindex = fNInnerSector*fnRowLow; + Int_t outindex = fNInnerSector*fNRowLow; if (index=GetNRow(isec))) return -1; - else return row; -} - -void AliTPCParam::SetDefault() -{ - //set default TPC param fbStatus = kFALSE; - //set sector parameters - fInnerRadiusLow = kInnerRadiusLow; - fOuterRadiusLow = kOuterRadiusLow; - fInnerRadiusUp = kInnerRadiusUp; - fOuterRadiusUp = kOuterRadiusUp; - SetSectorAngles(kInnerAngle,kInnerAngleShift, kOuterAngle, kOuterAngleShift,kFALSE); - // set default pad size and shape - fPadPitchLength = kPadPitchLength; - fPadPitchWidth = kPadPitchWidth; - fPadLength = kPadLength; - fPadWidth = kPadWidth; // - fnWires = knWires; - fWWPitch= kPadPitchLength/Float_t(knWires); - fDiffT = kDiffT; - fDiffL = kDiffL; - fOmegaTau = kOmegaTau; - fOxyCont = kOxyCont; - fAttCoef = kAttCoef; - fNoise = kNoise; - fChipGain = kChipGain; - fGasGain = kGasGain; - fZeroSup= kZeroSup; - fPadCoupling= kPadCoupling; - fTSample =kTSample; - fTSigma =kTFWHM/2.35; - fDriftV=kDriftV; - fMaxTBin = kMaxTBin; - fbStatus = Update(); -} - -void AliTPCParam::AdjustAngles(Int_t isec, Float_t &cos, Float_t &sin) const -{ + //set sector parameters + // + SetInnerRadiusLow(kInnerRadiusLow); + SetOuterRadiusLow(kOuterRadiusLow); + SetInnerRadiusUp(kInnerRadiusUp); + SetOuterRadiusUp(kOuterRadiusUp); + SetInnerFrameSpace(kInnerFrameSpace); + SetOuterFrameSpace(kOuterFrameSpace); + SetInnerWireMount(kInnerWireMount); + SetOuterWireMount(kOuterWireMount); + SetSectorAngles(kInnerAngle,kInnerAngleShift,kOuterAngle,kOuterAngleShift); + SetZLength(kZLength); + SetGeometryType(kGeometryType); + // + //set wire parameters + // + SetInnerNWires(kNInnerWiresPerPad); + SetInnerDummyWire(kInnerDummyWire); + SetInnerOffWire(kInnerOffWire); + SetOuterNWires(kNOuterWiresPerPad); + SetOuterDummyWire(kOuterDummyWire); + SetOuterOffWire(kOuterOffWire); + // + //set pad parameter // - //set cosinus and sinus of rotation angles for sector isec + SetInnerPadPitchLength(kInnerPadPitchLength); + SetInnerPadPitchWidth(kInnerPadPitchWidth); + SetInnerPadLength(kInnerPadLength); + SetInnerPadWidth(kInnerPadWidth); + SetOuterPadPitchLength(kOuterPadPitchLength); + SetOuterPadPitchWidth(kOuterPadPitchWidth); + SetOuterPadLength(kOuterPadLength); + SetOuterPadWidth(kOuterPadWidth); + SetMWPCReadout(kBMWPCReadout); + SetNCrossRows(kNCrossRows); // - cos=fRotAngle[isec*2]; - sin=fRotAngle[isec*2+1]; + //set gas paremeters + // + SetDiffT(kDiffT); + SetDiffL(kDiffL); + SetGasGain(kGasGain); + SetDriftV(kDriftV); + SetOmegaTau(kOmegaTau); + SetAttCoef(kAttCoef); + SetOxyCont(kOxyCont); + // + //set electronivc parameters + // + SetPadCoupling(kPadCoupling); + SetZeroSup(kZeroSup); + SetNoise(kNoise); + SetChipGain(kChipGain); + SetChipNorm(kChipNorm); + SetTSample(kTSample); + SetTFWHM(kTFWHM); + SetMaxTBin(kMaxTBin); + SetADCSat(kADCSat); + SetADCDynRange(kADCDynRange); + //set magnetic field + SetBField(kBField); + SetNPrimLoss(kNPrimLoss); + SetNTotalLoss(kNTotalLoss); + // + //set response parameters + // + SetNResponseMax(kNResponseMax); + SetResponseThreshold(kResponseThreshold); } + Bool_t AliTPCParam::Update() { @@ -379,77 +433,71 @@ Bool_t AliTPCParam::Update() Int_t i,j; //loop variables because HP //-----------------Sector section------------------------------------------ //calclulate number of sectors - fNInnerSector = Int_t(4*TMath::Pi()/fInnerAngle+0.2); // number of inner sectors - factor 0.2 to don't - //be influnced by inprecision + fNInnerSector = Int_t(4*TMath::Pi()/fInnerAngle+0.2); + // number of inner sectors - factor 0.2 to don't be influnced by inprecision if (fNInnerSector%2) return kFALSE; fNOuterSector = Int_t(4*TMath::Pi()/fOuterAngle+0.2); if (fNOuterSector%2) return kFALSE; fNSector = fNInnerSector+fNOuterSector; + + if (fRotAngle!=0) delete [] fRotAngle; + fRotAngle = new Float_t[4*fNSector]; //calculate sin and cosine of rotations angle //sectors angles numbering from 0 - j=fNInnerSector; + + j=fNInnerSector*2; Float_t angle = fInnerAngleShift; - for (i=0; ifPadPitchLength){ - cout<<"ERROR !!! Small pad pitch length \n"<fnRowUp) return kFALSE; - - fnRowLow = Int_t((0.01+fInnerRadiusUp-fInnerRadiusLow)/fPadPitchLength)+1; - if ( kMaxRowsfnRowLow) return kFALSE; - // adjust upper sectors pad row positions and pad numbers - for (i = 0;i> fInnerRadiusLow; - R__b >> fInnerRadiusUp; - R__b >> fOuterRadiusLow; - R__b >> fOuterRadiusUp; - R__b >> fInnerAngle; - R__b >> fInnerAngleShift; - R__b >> fOuterAngle; - R__b >> fOuterAngleShift; - //pad parameters - R__b >> fPadPitchLength; - R__b >> fPadPitchWidth; - R__b >> fPadLength; - R__b >> fPadWidth; - - R__b >> fnWires; - //gas parameters - R__b >>fDiffT; - R__b >>fDiffL; - R__b >>fGasGain; - R__b >>fDriftV; - R__b >>fOmegaTau; - R__b >>fOxyCont; - R__b >>fAttCoef; - - R__b >>fPadCoupling; - R__b >>fZeroSup; - R__b >>fNoise; - R__b >>fChipGain; - - R__b >>fTSample; - R__b >>fTSigma; - // - Update(); + //--------------------------------------------------------------------- + // ALICE TPC sector geometry + //-------------------------------------------------------------------- + R__b >> fInnerRadiusLow; // lower radius of inner sector-IP + R__b >> fInnerRadiusUp; // upper radius of inner sector-IP + R__b >> fOuterRadiusUp; // upper radius of outer sector-IP + R__b >> fOuterRadiusLow; // lower radius of outer sector-IP + R__b >> fInnerAngle; //opening angle of Inner sector + R__b >> fInnerAngleShift; //shift of first inner sector center to the 0 + R__b >> fOuterAngle; //opening angle of outer sector + R__b >> fOuterAngleShift; //shift of first sector center to the 0 + R__b >> fInnerFrameSpace; //spce for inner frame in the phi direction + R__b >> fOuterFrameSpace; //spce for outer frame in the phi direction + R__b >> fInnerWireMount; + R__b >> fOuterWireMount; + //R__b >> fNInnerSector; //!number of inner sectors - calculated + //R__b >> fNOuterSector; //!number of outer sectors -calculated + //R__b >> fNSector; //! total number of sectors -calculated + R__b >> fZLength; //length of the drift region of the TPC + //R__b.ReadFastArray(fRotAngle,fNSector*4); // sin and cos of rotation angles for + R__b >> fGeometryType; //type of geometry -0 straight rows + // diferent sectors + //--------------------------------------------------------------------- + // ALICE TPC wires geometry + //-------------------------------------------------------------------- + R__b >> fNInnerWiresPerPad;// Number of wires per pad + //R__b >> fInnerWWPitch; // pitch between wires in inner sector - calculated + R__b >> fInnerDummyWire; //number of wires without pad readout + R__b >> fInnerOffWire;//oofset of first wire to the begining of the sector + //R__b >> fRInnerFirstWire; //position of the first wire -calculated + //R__b >> fRInnerLastWire; //position of the last wire -calculated + R__b >> fNOuterWiresPerPad;// Number of wires per pad + //R__b >> fOuterWWPitch; // pitch between wires in outer sector - calculated + R__b >> fOuterDummyWire; //number of wires without pad readout + R__b >> fOuterOffWire;//oofset of first wire to the begining of the sector + //R__b >> fROuterFirstWire; //position of the first wire -calulated + //R__b >> fROuterLastWire; //position of the last wire -calculated + //--------------------------------------------------------------------- + // ALICE TPC pad parameters + //-------------------------------------------------------------------- + R__b >> fInnerPadPitchLength; //Inner pad pitch length + R__b >> fInnerPadPitchWidth; //Inner pad pitch width + R__b >> fInnerPadLength; //Inner pad length + R__b >> fInnerPadWidth; //Inner pad width + R__b >> fOuterPadPitchLength; //Outer pad pitch length + R__b >> fOuterPadPitchWidth; //Outer pad pitch width + R__b >> fOuterPadLength; //Outer pad length + R__b >> fOuterPadWidth; //Outer pad width + R__b >> fBMWPCReadout; //indicate wire readout + R__b >> fNCrossRows; //number of pad rows to crostalk + R__b >> fNRowLow; // number of pad rows per low sector + R__b >> fNRowUp; // number of pad rows per sector up + //R__b >> fPadRowLow[600]; // Lower sector, pad row radii + //R__b >> fPadRowUp[600]; // Upper sector, pad row radii + //R__b >> fNPadsLow[600]; // Lower sector, number of pads per row + //R__b >> fNPadsUp[600]; // Upper sector, number of pads per row + //--------------------------------------------------------------------- + // ALICE TPC Gas Parameters + //-------------------------------------------------------------------- + R__b >> fDiffT; //tangencial diffusion constant + R__b >> fDiffL; //longutudinal diffusion constant + R__b >> fGasGain; //gas gain constant + R__b >> fDriftV; //drift velocity constant + R__b >> fOmegaTau; //omega tau ExB coeficient + R__b >> fAttCoef; //attachment coefitients + R__b >> fOxyCont; //oxygen content + //--------------------------------------------------------------------- + // ALICE TPC Electronics Parameters + //-------------------------------------------------------------------- + R__b >> fPadCoupling; //coupling factor ration of anode signal + //and total pads signal + R__b >> fZeroSup; //zero suppresion constant + R__b >> fNoise; //noise sigma constant + R__b >> fChipGain; //preamp shaper constant + R__b >> fChipNorm; //preamp shaper normalisation + R__b >> fTSample; // sampling time + R__b >> fZWidth; //derived value calculated using TSample and driftw + R__b >> fTSigma; // width of the Preamp/Shaper function + R__b >> fMaxTBin; //maximum time bin number + R__b >> fADCSat; //saturation value of ADC (10 bits) + R__b >> fADCDynRange; // input dynamic range (mV) + //-------------------------------------------------------- } else { R__b.WriteVersion(AliTPCParam::IsA()); - TObject::Streamer(R__b); - R__b << fInnerRadiusLow; - R__b << fInnerRadiusUp; - R__b << fOuterRadiusLow; - R__b << fOuterRadiusUp; - R__b << fInnerAngle; - R__b << fInnerAngleShift; - R__b << fOuterAngle; - R__b << fOuterAngleShift; - - R__b << fPadPitchLength; - R__b << fPadPitchWidth; - R__b << fPadLength; - R__b << fPadWidth; - - R__b << fnWires; - - R__b <=(fNInnerSector>>1)) xyz[2]*=-1.; + else + if ( (index[1]-fNInnerSector) > (fNOuterSector>>1) ) xyz[2]*=-1; + index[0]=1; +} + +inline void AliTPCParam::Transform2to2(Float_t *xyz, Int_t *index, Int_t *oindex) const +{ + //transform rotated coordinats of one sector to rotated + //coordinates relative to another sector + Transform2to1(xyz,index); + Transform1to2(xyz,oindex); + index[0]=2; + index[1]=oindex[1]; +} + +inline Float_t AliTPCParam::Transform2to2NearestWire(Float_t *xyz, Int_t *index) const +{ + // + // asigns the x-position of the closest wire to xyz[0], return the + // electron to closest wire distance + // + Float_t xnew,dx; + if (index[1]0) && (xyz[1]<0) ) angle=2*TMath::Pi()+angle; + } + xyz[0]=r; + xyz[1]=angle; + index[0]=5; +} + +inline void AliTPCParam::Transform5to2( Float_t *xyz, Int_t *index) const +{ + // + //transform [r,rphi,z] to [x,y,z] + // + Float_t r = xyz[0]; + Float_t angle= xyz[1]; + xyz[0]=r*TMath::Cos(angle); + xyz[1]=r*TMath::Sin(angle); + index[0]=2; +} + +inline void AliTPCParam::Transform4to8(Float_t *xyz, Int_t *index) const +{ + // + //transform xyz coordinates to 'digit' coordinates + // + if (index[1] +#include +#include +#include + + + +ClassImp(AliTPCParamCR) +const static Int_t kMaxRows=600; +const static Float_t kEdgeSectorSpace = 2.5; + +AliTPCParamCR::AliTPCParamCR() +{ + // + //constructor set the default parameters + fInnerPRF=0; + fOuterPRF=0; + fTimeRF = 0; + fFacSigma = Float_t(2.); + SetDefault(); + Update(); +} + +AliTPCParamCR::~AliTPCParamCR() +{ + // + //destructor destroy some dynmicaly alocated variables + if (fInnerPRF != 0) delete fInnerPRF; + if (fOuterPRF != 0) delete fOuterPRF; + if (fTimeRF != 0) delete fTimeRF; +} + +void AliTPCParamCR::SetDefault() +{ + //set default TPC param + fbStatus = kFALSE; + AliTPCParam::SetDefault(); +} + +Int_t AliTPCParamCR::CalcResponse(Float_t* xyz, Int_t * index) +{ + // + //calculate bin response as function of the input position -x + //return number of valid response bin + // + //we suppose that coordinata is expressed in float digits + // it's mean coordinate system 8 + //xyz[0] - float padrow xyz[1] is float pad (center pad is number 0) and xyz[2] is float time bin + if ( (fInnerPRF==0)||(fOuterPRF==0)||(fTimeRF==0) ){ + Error("AliTPCParamCR", "response function were not adjusted"); + return -1; + } + + Float_t sfpadrow; // sigma of response function + Float_t sfpad; // sigma of + Float_t sftime= fFacSigma*fTimeRF->GetSigma()/fZWidth; //3 sigma of time response + if (index[1]GetSigmaY()/fInnerPadPitchLength; + sfpad =fFacSigma*fInnerPRF->GetSigmaX()/fInnerPadPitchWidth; + }else{ + sfpadrow =fFacSigma*fOuterPRF->GetSigmaY()/fOuterPadPitchLength; + sfpad =fFacSigma*fOuterPRF->GetSigmaX()/fOuterPadPitchWidth; + } + + Int_t fpadrow = TMath::Nint(xyz[0]-sfpadrow); //"first" padrow + Int_t fpad = TMath::Nint(xyz[1]-sfpad); //first pad + Int_t ftime = TMath::Nint(xyz[2]+fTimeRF->GetOffset()-sftime); // first time + Int_t lpadrow = TMath::Min(TMath::Nint(xyz[0]+sfpadrow),fpadrow+19); //"last" padrow + Int_t lpad = TMath::Min(TMath::Nint(xyz[1]+sfpad),fpad+19); //last pad + Int_t ltime = TMath::Min(TMath::Nint(xyz[2]+fTimeRF->GetOffset()+sftime),ftime+19); // last time + + Float_t padres[20][20]; //I don't expect bigger number of bins + Float_t timeres[20]; + //calculate padresponse function + Int_t padrow; + for (padrow = fpadrow;padrow<=lpadrow;padrow++) + for (Int_t pad = fpad;pad<=lpad;pad++){ + Float_t dy = (xyz[0]-Float_t(padrow)); + Float_t dx = (xyz[1]-Float_t(pad)); + if (index[1]GetPRF(dx*fInnerPadPitchWidth,dy*fInnerPadPitchLength); + else + padres[padrow-fpadrow][pad-fpad]=fOuterPRF->GetPRF(dx*fOuterPadPitchWidth,dy*fOuterPadPitchLength); + } + //calculate time response function + + Int_t time; + for (time = ftime;time<=ltime;time++) timeres[time-ftime]= fTimeRF->GetRF((xyz[2]-Float_t(time))*fZWidth); + + //write over threshold values to stack + Int_t cindex3=-1; + Int_t cindex=0; + Float_t cweight = 0; + for (padrow = fpadrow;padrow<=lpadrow;padrow++) + for (Int_t pad = fpad;pad<=lpad;pad++) + for (time = ftime;time<=ltime;time++){ + cweight = timeres[time-ftime]*padres[padrow-fpadrow][pad-fpad]; + if (cweight>fResponseThreshold) { + fResponseBin[++cindex3]=padrow; + fResponseBin[++cindex3]=pad; + fResponseBin[++cindex3]=time; + fResponseWeight[++cindex]=cweight; + } + } + fCurrentMax=cindex; + return fCurrentMax; +} + +void AliTPCParamCR::CRXYZtoXYZ(Float_t *xyz, + const Int_t §or, const Int_t & padrow, Int_t option) const +{ + //transform relative coordinates to absolute + Bool_t rel = ( (option&2)!=0); + Int_t index[2]={sector,padrow}; + if (rel==kTRUE) Transform4to3(xyz,index);//if the position is relative to pad row + Transform2to1(xyz,index); +} + +void AliTPCParamCR::XYZtoCRXYZ(Float_t *xyz, + Int_t §or, Int_t & padrow, Int_t option) const +{ + //transform global position to the position relative to the sector padrow + //if option=0 X calculate absolute calculate sector + //if option=1 X absolute use input sector + //if option=2 X relative to pad row calculate sector + //if option=3 X relative use input sector + //!!!!!!!!! WE start to calculate rows from row = 0 + Int_t index[2]; + Bool_t rel = ( (option&2)!=0); + + //option 0 and 2 means that we don't have information about sector + if ((option&1)==0) Transform0to1(xyz,index); //we calculate sector number + else + index[0]=sector; + Transform1to2(xyz,index); + Transform2to3(xyz,index); + //if we store relative position calculate position relative to pad row + if (rel==kTRUE) Transform3to4(xyz,index); + sector = index[0]; + padrow = index[1]; +} + + + +Bool_t AliTPCParamCR::Update() +{ + + // + // update some calculated parameter which must be updated after changing "base" + // parameters + // for example we can change size of pads and according this recalculate number + // of pad rows, number of of pads in given row .... + Int_t i; + if (AliTPCParam::Update()==kFALSE) return kFALSE; + fbStatus = kFALSE; + + // adjust lower sectors pad row positions and pad numbers + fNRowLow = (Int_t(1.0001*(fRInnerLastWire-fRInnerFirstWire)/fInnerWWPitch) + -2*fInnerDummyWire)/fNInnerWiresPerPad; + if ( kMaxRowsfNRowLow) return kFALSE; + Float_t firstpad = fRInnerFirstWire+(fInnerDummyWire-0.5)*fInnerWWPitch + +fInnerPadPitchLength/2.; + + for (i = 0;ifNRowUp) return kFALSE; + firstpad = fROuterFirstWire+(fOuterDummyWire-0.5)*fOuterWWPitch + +fOuterPadPitchLength/2.; + + for (i = 0;i +#include +#include +#include + + + +ClassImp(AliTPCParamSR) +const static Int_t kMaxRows=600; +const static Float_t kEdgeSectorSpace = 2.5; +const static Float_t kFacSigmaPadRow=2.; +const static Float_t kFacSigmaPad=3.; +const static Float_t kFacSigmaTime=3.; + + +AliTPCParamSR::AliTPCParamSR() +{ + // + //constructor set the default parameters + fInnerPRF=0; + fOuterPRF=0; + fTimeRF = 0; + fFacSigmaPadRow = Float_t(kFacSigmaPadRow); + fFacSigmaPad = Float_t(kFacSigmaPad); + fFacSigmaTime = Float_t(kFacSigmaTime); + + + SetDefault(); + Update(); +} + +AliTPCParamSR::~AliTPCParamSR() +{ + // + //destructor destroy some dynmicaly alocated variables + if (fInnerPRF != 0) delete fInnerPRF; + if (fOuterPRF != 0) delete fOuterPRF; + if (fTimeRF != 0) delete fTimeRF; +} + +void AliTPCParamSR::SetDefault() +{ + //set default TPC param + fbStatus = kFALSE; + AliTPCParam::SetDefault(); +} + +Int_t AliTPCParamSR::CalcResponse(Float_t* xyz, Int_t * index, Int_t row) +{ + // + //calculate bin response as function of the input position -x + //return number of valid response bin + // + //we suppose that coordinate is expressed in float digits + // it's mean coordinate system 8 + //xyz[0] - float padrow xyz[1] is float pad (center pad is number 0) and xyz[2] is float time bin + if ( (fInnerPRF==0)||(fOuterPRF==0)||(fTimeRF==0) ){ + Error("AliTPCParamSR", "response function was not adjusted"); + return -1; + } + + Float_t sfpadrow; // sigma of response function + Float_t sfpad; // sigma of + Float_t sftime= fFacSigmaTime*fTimeRF->GetSigma()/fZWidth; //3 sigma of time response + if (index[1]GetSigmaY()/fInnerPadPitchLength; + sfpad =fFacSigmaPad*fInnerPRF->GetSigmaX()/fInnerPadPitchWidth; + }else{ + sfpadrow =fFacSigmaPadRow*fOuterPRF->GetSigmaY()/fOuterPadPitchLength; + sfpad =fFacSigmaPad*fOuterPRF->GetSigmaX()/fOuterPadPitchWidth; + } + + Int_t fpadrow = TMath::Max(TMath::Nint(index[2]+xyz[0]-sfpadrow),0); //"first" padrow + Int_t fpad = TMath::Nint(xyz[1]-sfpad); //first pad + Int_t ftime = TMath::Max(TMath::Nint(xyz[2]+GetZOffset()/GetZWidth()-sftime),0); // first time + Int_t lpadrow = TMath::Min(TMath::Nint(index[2]+xyz[0]+sfpadrow),fpadrow+19); //"last" padrow + lpadrow = TMath::Min(GetNRow(index[1])-1,lpadrow); + Int_t lpad = TMath::Min(TMath::Nint(xyz[1]+sfpad),fpad+19); //last pad + Int_t ltime = TMath::Min(TMath::Nint(xyz[2]+GetZOffset()/GetZWidth()+sftime),ftime+19); // last time + ltime = TMath::Min(ltime,GetMaxTBin()-1); + + if (row>=0) { //if we are interesting about given pad row + if (fpadrow<=row) fpadrow =row; + else + return 0; + if (lpadrow>=row) lpadrow = row; + else + return 0; + } + + + Float_t padres[20][20]; //I don't expect bigger number of bins + Float_t timeres[20]; + Int_t cindex3=0; + Int_t cindex=0; + Float_t cweight = 0; + if (fpadrow>=0) { + //calculate padresponse function + Int_t padrow, pad; + for (padrow = fpadrow;padrow<=lpadrow;padrow++) + for (pad = fpad;pad<=lpad;pad++){ + Float_t dy = (-xyz[0]+Float_t(index[2]-padrow)); + Float_t dx = (-xyz[1]+Float_t(pad)); + if (index[1]GetPRF(dx*fInnerPadPitchWidth,dy*fInnerPadPitchLength); + else + padres[padrow-fpadrow][pad-fpad]=fOuterPRF->GetPRF(dx*fOuterPadPitchWidth,dy*fOuterPadPitchLength); } + //calculate time response function + Int_t time; + for (time = ftime;time<=ltime;time++) + timeres[time-ftime]= fTimeRF->GetRF((-xyz[2]+Float_t(time))*fZWidth); + //write over threshold values to stack + for (padrow = fpadrow;padrow<=lpadrow;padrow++) + for (pad = fpad;pad<=lpad;pad++) + for (time = ftime;time<=ltime;time++){ + cweight = timeres[time-ftime]*padres[padrow-fpadrow][pad-fpad]; + if (cweight>fResponseThreshold) { + fResponseBin[cindex3]=padrow; + fResponseBin[cindex3+1]=pad; + fResponseBin[cindex3+2]=time; + cindex3+=3; + fResponseWeight[cindex]=cweight; + cindex++; + } + } + } + fCurrentMax=cindex; + return fCurrentMax; +} + +void AliTPCParamSR::TransformTo8(Float_t *xyz, Int_t *index) const +{ + // + // transformate point to digit coordinate + // + if (index[0]==0) Transform0to1(xyz,index); + if (index[0]==1) Transform1to2(xyz,index); + if (index[0]==2) Transform2to3(xyz,index); + if (index[0]==3) Transform3to4(xyz,index); + if (index[0]==4) Transform4to8(xyz,index); +} + +void AliTPCParamSR::TransformTo2(Float_t *xyz, Int_t *index) const +{ + // + //transformate point to rotated coordinate + // + //we suppose that + if (index[0]==0) Transform0to1(xyz,index); + if (index[0]==1) Transform1to2(xyz,index); + if (index[0]==4) Transform4to3(xyz,index); + if (index[0]==8) { //if we are in digit coordinate system transform to global + Transform8to4(xyz,index); + Transform4to3(xyz,index); + } +} + +void AliTPCParamSR::CRXYZtoXYZ(Float_t *xyz, + const Int_t §or, const Int_t & padrow, Int_t option) const +{ + //transform relative coordinates to absolute + Bool_t rel = ( (option&2)!=0); + Int_t index[2]={sector,padrow}; + if (rel==kTRUE) Transform4to3(xyz,index);//if the position is relative to pad row + Transform2to1(xyz,index); +} + +void AliTPCParamSR::XYZtoCRXYZ(Float_t *xyz, + Int_t §or, Int_t & padrow, Int_t option) const +{ + //transform global position to the position relative to the sector padrow + //if option=0 X calculate absolute calculate sector + //if option=1 X absolute use input sector + //if option=2 X relative to pad row calculate sector + //if option=3 X relative use input sector + //!!!!!!!!! WE start to calculate rows from row = 0 + Int_t index[2]; + Bool_t rel = ( (option&2)!=0); + + //option 0 and 2 means that we don't have information about sector + if ((option&1)==0) Transform0to1(xyz,index); //we calculate sector number + else + index[0]=sector; + Transform1to2(xyz,index); + Transform2to3(xyz,index); + //if we store relative position calculate position relative to pad row + if (rel==kTRUE) Transform3to4(xyz,index); + sector = index[0]; + padrow = index[1]; +} + +Float_t AliTPCParamSR::GetPrimaryLoss(Float_t *x, Int_t *index, Float_t *angle) +{ + // + // + Float_t padlength=GetPadPitchLength(index[1]); + Float_t a1=TMath::Sin(angle[0]); + a1*=a1; + Float_t a2=TMath::Sin(angle[1]); + a2*=a2; + Float_t length =padlength*TMath::Sqrt(1+a1+a2); + return length*fNPrimLoss; +} + +Float_t AliTPCParamSR::GetTotalLoss(Float_t *x, Int_t *index, Float_t *angle) +{ + // + // + Float_t padlength=GetPadPitchLength(index[1]); + Float_t a1=TMath::Sin(angle[0]); + a1*=a1; + Float_t a2=TMath::Sin(angle[1]); + a2*=a2; + Float_t length =padlength*TMath::Sqrt(1+a1+a2); + return length*fNTotalLoss; + +} + + +void AliTPCParamSR::GetClusterSize(Float_t *x, Int_t *index, Float_t *angle, Int_t mode, Float_t *sigma) +{ + // + //return cluster sigma2 (x,y) for particle at position x + // in this case x coordinata is in drift direction + //and y in pad row direction + //we suppose that input coordinate system is digit system + + Float_t xx; + Float_t lx[3] = {x[0],x[1],x[2]}; + Int_t li[3] = {index[0],index[1],index[2]}; + TransformTo2(lx,li); + // Float_t sigmadiff; + sigma[0]=0; + sigma[1]=0; + + xx = lx[2]; //calculate drift length in cm + if (xx>0) { + sigma[0]+= xx*GetDiffL()*GetDiffL(); + sigma[1]+= xx*GetDiffT()*GetDiffT(); + } + + + //sigma[0]=sigma[1]=0; + if (GetTimeRF()!=0) sigma[0]+=GetTimeRF()->GetSigma()*GetTimeRF()->GetSigma(); + if ( (index[1]GetSigmaX()*GetInnerPRF()->GetSigmaX(); + if ( (index[1]>=fNInnerSector) && (GetOuterPRF()!=0)) + sigma[1]+=GetOuterPRF()->GetSigmaX()*GetOuterPRF()->GetSigmaX(); + + + sigma[0]/= GetZWidth()*GetZWidth(); + sigma[1]/=GetPadPitchWidth(index[0])*GetPadPitchWidth(index[0]); +} + + + + +void AliTPCParamSR::GetSpaceResolution(Float_t *x, Int_t *index, Float_t *angle, + Float_t amplitude, Int_t mode, Float_t *sigma) +{ + // + // + // + +} +Float_t AliTPCParamSR::GetAmp(Float_t *x, Int_t *index, Float_t *angle) +{ + // + // + // + return 0; +} + +Float_t * AliTPCParamSR::GetAnglesAccMomentum(Float_t *x, Int_t * index, Float_t* momentum, Float_t *angle) +{ + // + //calculate angle of track to padrow at given position + // for given magnetic field and momentum of the particle + // + + TransformTo2(x,index); + AliDetectorParam::GetAnglesAccMomentum(x,index,momentum,angle); + Float_t addangle = TMath::ASin(x[1]/GetPadRowRadii(index[1],index[2])); + angle[1] +=addangle; + return angle; +} + + +Bool_t AliTPCParamSR::Update() +{ + + // + // update some calculated parameter which must be updated after changing "base" + // parameters + // for example we can change size of pads and according this recalculate number + // of pad rows, number of of pads in given row .... + Int_t i; + if (AliTPCParam::Update()==kFALSE) return kFALSE; + fbStatus = kFALSE; + + // adjust lower sectors pad row positions and pad numbers + fNRowLow = (Int_t(1.001+((fRInnerLastWire-fRInnerFirstWire)/fInnerWWPitch)) + -2*fInnerDummyWire)/fNInnerWiresPerPad; + if ( kMaxRowsfNRowLow) return kFALSE; + + //Float_t firstpad = fRInnerFirstWire+(fInnerDummyWire-0.5)*fInnerWWPitch + // +fInnerPadPitchLength/2.; + Float_t lastpad = fRInnerLastWire-(fInnerDummyWire-0.5)*fInnerWWPitch + -fInnerPadPitchLength/2.; + Float_t firstpad = lastpad-Float_t(fNRowLow-1)*fInnerPadPitchLength; + + for (i = 0;ifNRowUp) return kFALSE; + firstpad = fROuterFirstWire+(fOuterDummyWire-0.5)*fOuterWWPitch + +fOuterPadPitchLength/2.; + + for (i = 0;iDelete(); } Float_t AliTPCRF1D::GetRF(Float_t xin) { - //x xin DSTEP unit + //function which return response + //for the charge in distance xin //return linear aproximation of RF Float_t x = TMath::Abs((xin-fOffset)*fDSTEPM1)+fNRF/2; Int_t i1=Int_t(x); @@ -111,6 +116,8 @@ Float_t AliTPCRF1D::GetRF(Float_t xin) Float_t AliTPCRF1D::GetGRF(Float_t xin) { + //function which returnoriginal charge distribution + //this function is just normalised for fKnorm if (fGRF != 0 ) return fkNorm*fGRF->Eval(xin)/fInteg; else @@ -121,6 +128,8 @@ Float_t AliTPCRF1D::GetGRF(Float_t xin) void AliTPCRF1D::SetParam( TF1 * GRF,Float_t padwidth, Float_t kNorm, Float_t sigma) { + //adjust parameters of the original charge distribution + //and pad size parameters fpadWidth = padwidth; fGRF = GRF; fkNorm = kNorm; @@ -135,7 +144,9 @@ void AliTPCRF1D::SetParam( TF1 * GRF,Float_t padwidth, void AliTPCRF1D::SetGauss(Float_t sigma, Float_t padWidth, Float_t kNorm) { - // char s[120]; + // + // set parameters for Gauss generic charge distribution + // fpadWidth = padWidth; fkNorm = kNorm; if (fGRF !=0 ) fGRF->Delete(); @@ -144,15 +155,16 @@ void AliTPCRF1D::SetGauss(Float_t sigma, Float_t padWidth, forigsigma=sigma; fGRF->SetParameters(funParam); fDSTEPM1 = 10./TMath::Sqrt(sigma*sigma+fpadWidth*fpadWidth/12); - //by default I set the step as one tenth of sigma - // Update(); + //by default I set the step as one tenth of sigma sprintf(fType,"Gauss"); } void AliTPCRF1D::SetCosh(Float_t sigma, Float_t padWidth, Float_t kNorm) { - // char s[120]; + // + // set parameters for Cosh generic charge distribution + // fpadWidth = padWidth; fkNorm = kNorm; if (fGRF !=0 ) fGRF->Delete(); @@ -162,14 +174,15 @@ void AliTPCRF1D::SetCosh(Float_t sigma, Float_t padWidth, forigsigma=sigma; fDSTEPM1 = 10./TMath::Sqrt(sigma*sigma+fpadWidth*fpadWidth/12); //by default I set the step as one tenth of sigma - // Update(); sprintf(fType,"Cosh"); } void AliTPCRF1D::SetGati(Float_t K3, Float_t padDistance, Float_t padWidth, Float_t kNorm) { - // char s[120]; + // + // set parameters for Gati generic charge distribution + // fpadWidth = padWidth; fkNorm = kNorm; if (fGRF !=0 ) fGRF->Delete(); @@ -180,12 +193,14 @@ void AliTPCRF1D::SetGati(Float_t K3, Float_t padDistance, Float_t padWidth, forigsigma=padDistance; fDSTEPM1 = 10./TMath::Sqrt(padDistance*padDistance+fpadWidth*fpadWidth/12); //by default I set the step as one tenth of sigma - // Update(); sprintf(fType,"Gati"); } void AliTPCRF1D::Draw(Float_t x1,Float_t x2,Int_t N) { + // + //Draw prf in selected region with nuber of diviision = n + // char s[100]; TCanvas * c1 = new TCanvas("canRF","Pad response function",700,900); c1->cd(); @@ -222,7 +237,11 @@ void AliTPCRF1D::Draw(Float_t x1,Float_t x2,Int_t N) void AliTPCRF1D::Update() { - //initialize to 0 + // + //update fields with interpolated values for + //PRF calculation + + //at the begining initialize to 0 for (Int_t i =0; iIntegral(-5*forigsigma,5*forigsigma,funParam,0.00001); @@ -264,7 +283,7 @@ void AliTPCRF1D::Update() void AliTPCRF1D::Streamer(TBuffer &R__b) { - // Stream an object of class AliTPC. + // Stream an object of class AliTPCRF1D. if (R__b.IsReading()) { Version_t R__v = R__b.ReadVersion(); if (R__v) { } @@ -285,7 +304,7 @@ void AliTPCRF1D::Streamer(TBuffer &R__b) R__b >> fOffset; //read functions if (fGRF!=0) { - delete fGRF; + delete [] fGRF; fGRF=0; } if (strncmp(fType,"User",3)==0){ @@ -327,10 +346,7 @@ void AliTPCRF1D::Streamer(TBuffer &R__b) R__b <GetID("AliRun") < 0) { gROOT->LoadMacro("loadlibs.C"); loadlibs(); @@ -14,6 +15,7 @@ void AliTPCTestClustering() { // Connect the Root Galice file containing Geometry, Kine and Hits TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); if (!file) file = new TFile("galice.root"); + //if (!file) file = TFile::Open("rfio:galice.root"); // Get AliRun object from file or create it if not on file if (!gAlice) { @@ -28,8 +30,8 @@ void AliTPCTestClustering() { int ver=TPC->IsVersion(); cerr<<"TPC version "<Get(pname); - if (dig!=0) TPC->SetDigParam(dig); + AliTPCParam *dig=(AliTPCParam *)file->Get(pname); + if (dig!=0) TPC->SetParam(dig); else cerr<<"Warning: default TPC parameters will be used !\n"; switch (ver) { @@ -49,12 +51,11 @@ void AliTPCTestClustering() { int n=c->GetEntriesFast(); cerr<<"Number of clusters "<GetDigParam()->GetParam(); Float_t x[3]; TPolyMarker3D *pm=new TPolyMarker3D(n); for (int i=0; iUncheckedAt(i); - cl->GetXYZ(x,par); + cl->GetXYZ(x,dig); Double_t xx=x[0], yy=x[1], zz=x[2]; pm->SetPoint(i,xx,yy,zz); } diff --git a/TPC/AliTPCTestTracking.C b/TPC/AliTPCTestTracking.C index c84bb159d3b..778b3b6cb8e 100644 --- a/TPC/AliTPCTestTracking.C +++ b/TPC/AliTPCTestTracking.C @@ -1,8 +1,16 @@ +struct GoodTrack { + Int_t lab; + Int_t code; + Float_t px,py,pz; + Float_t x,y,z; +}; +Int_t good_tracks(GoodTrack *gt, Int_t max); + void AliTPCTestTracking() { - const char *pname="Param1"; - const char *tname="TreeD0_Param1"; + const char *pname="75x40_100x60"; // Dynamically link some shared libs + if (gClassTable->GetID("AliRun") < 0) { gROOT->LoadMacro("loadlibs.C"); loadlibs(); @@ -14,6 +22,7 @@ void AliTPCTestTracking() { // Connect the Root Galice file containing Geometry, Kine and Hits TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); if (!file) file = new TFile("galice.root"); + //if (!file) file = TFile::Open("rfio:galice.root"); // Get AliRun object from file or create it if not on file if (!gAlice) { @@ -24,191 +33,146 @@ void AliTPCTestTracking() { gAlice->GetEvent(0); - TClonesArray *particles=gAlice->Particles(); - int np=particles->GetEntriesFast(); - int *good=new int[np]; - for (int ii=0; iiGetDetector("TPC"); - int ver=TPC->IsVersion(); + Int_t ver=TPC->IsVersion(); cerr<<"TPC version "<Get(pname); - if (digp!=0) TPC->SetDigParam(digp); + AliTPCParam *digp= (AliTPCParam*)file->Get(pname); + if (digp!=0) TPC->SetParam(digp); else cerr<<"Warning: default TPC parameters will be used !\n"; - int nrow_up=TPC->GetDigParam()->GetParam().GetNRowUp(); - int nrows=TPC->GetDigParam()->GetParam().GetNRowLow()+nrow_up; - int zero=TPC->GetDigParam()->GetParam().GetZeroSup(); - int gap=int(0.125*nrows); - int good_number=int(0.4*nrows); + Int_t nrow_up=TPC->GetParam()->GetNRowUp(); + Int_t nrows=TPC->GetParam()->GetNRowLow()+nrow_up; switch (ver) { case 1: cerr<<"Making clusters...\n"; TPC->Hits2Clusters(); - TClonesArray *clusters=TPC->Clusters(); - if (!clusters) {cerr<<"No clusters found !\n"; return;} - int n=clusters->GetEntriesFast(); - cerr<<"Number of clusters "<UncheckedAt(i); - int lab=c->fTracks[0]; - if (lab<0) continue; //noise cluster - lab=TMath::Abs(lab); - int row=c->fPadRow; - if (row==nrow_up-1 ) good[lab]|=0x1000; - if (row==nrow_up-1-gap) good[lab]|=0x800; - good[lab]++; - } - break; case 2: cerr<<"Looking for clusters...\n"; TPC->Digits2Clusters(); - TClonesArray *clusters=TPC->Clusters(); - if (!clusters) {cerr<<"No clusters found !\n"; return;} - int n=clusters->GetEntriesFast(); - cerr<<"Number of clusters "<Get(tname); - TClonesArray *digits=TPC->Digits(); - TD->GetBranch("Digits")->SetAddress(&digits); - - int *count = new int[np]; - int i; - for (i=0; iGetEntries(); - for (i=0; iGetEvent(i)) continue; - int row; - int ndigits=digits->GetEntriesFast(); - int j; - for (j=0; jUncheckedAt(j); - int idx0=dig->fTracks[0]; - int idx1=dig->fTracks[1]; - int idx2=dig->fTracks[2]; - row=dig->fPadRow; - if (idx0>=0 && dig->fSignal>=zero) count[idx0]+=1; - if (idx1>=0 && dig->fSignal>=zero) count[idx1]+=1; - if (idx2>=0 && dig->fSignal>=zero) count[idx2]+=1; - } - for (j=0; j1) { - int ks; - if (row==nrow_up-1 ) good[j]|=0x1000; - if (row==nrow_up-1-gap) good[j]|=0x800; - good[j]++; - } - count[j]=0; - } - } - delete[] count; - break; default: cerr<<"Invalid TPC version !\n"; return; } + TClonesArray *clusters=TPC->Clusters(); + Int_t n=clusters->GetEntriesFast(); + cerr<<"Number of clusters "<Clusters2Tracks(); - int nt=0; + timer.Stop(); timer.Print(); + Int_t nt=0; TClonesArray *tracks=TPC->Tracks(); if (tracks) nt=tracks->GetEntriesFast(); cerr<<"Number of found tracks "<>gt[ngood].lab>>gt[ngood].code + >>gt[ngood].px >>gt[ngood].py>>gt[ngood].pz + >>gt[ngood].x >>gt[ngood].y >>gt[ngood].z) { + ngood++; + cerr<SetFillColor(4); - TH1F *hl=new TH1F("hl","LAMBDA resolution",50,-100,100); hl->SetFillColor(4); + TH1F *hp=new TH1F("hp","PHI resolution",50,-20.,20.); hp->SetFillColor(4); + TH1F *hl=new TH1F("hl","LAMBDA resolution",50,-20,20);hl->SetFillColor(4); TH1F *hpt=new TH1F("hpt","Relative Pt resolution",30,-10.,10.); hpt->SetFillColor(2); - TH1F *hd=new TH1F("hd","Impact parameter distribution ",30,0,25); - hd->SetFillColor(6); + TH1F *hmpt=new TH1F("hmpt","Relative Pt resolution (pt>4GeV/c)",30,-60,60); + hmpt->SetFillColor(6); - TH1F *hgood=new TH1F("hgood","Good tracks",20,0,10); - TH1F *hfound=new TH1F("hfound","Found tracks",20,0,10); - TH1F *hfake=new TH1F("hfake","Fake tracks",20,0,10); - TH1F *hg=new TH1F("hg","",20,0,10); //efficiency for good tracks + TH1F *hgood=new TH1F("hgood","Good tracks",20,0,7); + TH1F *hfound=new TH1F("hfound","Found tracks",20,0,7); + TH1F *hfake=new TH1F("hfake","Fake tracks",20,0,7); + TH1F *hg=new TH1F("hg","",20,0,7); //efficiency for good tracks hg->SetLineColor(4); hg->SetLineWidth(2); - TH1F *hf=new TH1F("hf","Efficiency for fake tracks",20,0,10); + TH1F *hf=new TH1F("hf","Efficiency for fake tracks",20,0,7); hf->SetFillColor(1); hf->SetFillStyle(3013); hf->SetLineWidth(2); - TH1F *he =new TH1F("he","dE/dX for pions with 0.4UncheckedAt(i); - if (p->GetFirstMother()>=0) continue; //secondary particle - if (good[i] < 0x1000+0x800+2+good_number) continue; - Double_t ptg=p->Pt(),pxg=p->Px(),pyg=p->Py(),pzg=p->Pz(); - if (ptg<0.100) continue; - if (fabs(pzg/ptg)>0.999) continue; + TH1F *he =new TH1F("he","dE/dX for pions with 0.4Fill(ptg); - int found=0; - for (int j=0; jUncheckedAt(j); - int lab=track->GetLabel(nrows); - if (fabs(lab)!=i) continue; - - found=1; - - Double_t xk=76.; - track->PropagateTo(xk); - xk-=0.11; - track->PropagateTo(xk,42.7,2.27); //C - xk-=26.; - track->PropagateTo(xk,36.2,1.98e-3); //C02 - xk-=0.051; - track->PropagateTo(xk,42.7,2.27); //C - xk-=25.; - track->PropagateTo(xk,36.7,1.29e-3);//Air - xk-=0.4; // + - track->PropagateTo(xk,21.82,2.33);//ITS+beam_pipe+etc (approximately) - - track->PropagateToVertex(); //comparison should be done at the vertex - - if (lab==i) hfound->Fill(ptg); - else { hfake->Fill(ptg); cerr<GetPt());track->GetPxPyPz(px,py,pz); - Double_t phig=TMath::ATan(pyg/pxg); - Double_t phi =TMath::ATan(py /px ); - hp->Fill((phi - phig)*1000.); - Double_t lamg=TMath::ATan(pzg/ptg); - Double_t lam =TMath::ATan(pz /pt ); - hl->Fill((lam - lamg)*1000.); - hpt->Fill((pt - ptg)/ptg*100.); - Double_t x=track->GetX(), y=track->GetY(), z=track->GetZ(); - hd->Fill(sqrt(x*x + y*y + z*z)*10.); - - Double_t mom=track->GetP(); - Double_t dedx=track->GetdEdX(0.05,0.80)/ - digp->GetParam().GetPadPitchLength(); - - hep->Fill(mom,dedx,1.); - if (p->GetPdgCode()==211 || p->GetPdgCode()==-211) - if (mom>0.4 && mom<0.5) - he->Fill(dedx,1.); - - break; + + AliTPCtrack *track; + Int_t i; + for (i=0; iUncheckedAt(i); + tlab=track->GetLabel(nrows); + if (lab==TMath::Abs(tlab)) break; } - if (!found) cerr<<"Track number "<GetPadRowRadii(0,0); + track->PropagateTo(xk); - delete[] good; + if (lab==tlab) hfound->Fill(ptg); + else { hfake->Fill(ptg); cerr<GetPt());track->GetPxPyPz(px,py,pz); + + if (TMath::Abs(gt[ngood].code)==11 && ptg>4.) { + hmpt->Fill((1/pt - 1/ptg)/(1/ptg)*100.); + } else { + Float_t phig=TMath::ATan2(gt[ngood].py,gt[ngood].px); + Float_t phi =TMath::ATan2(py,px ); + hp->Fill((phi - phig)*1000.); - Stat_t ngood =hgood->GetEntries(); cerr<<"Good tracks "<GetEntries(); - if (ngood!=0) - cerr<<"Integral efficiency is about "<Fill((lam - lamg)*1000.); + + hpt->Fill((1/pt - 1/ptg)/(1/ptg)*100.); + } + Float_t mom=track->GetP(); + Float_t dedx=track->GetdEdX(0.05,0.70); + hep->Fill(mom,dedx,1.); + if (TMath::Abs(gt[ngood].code)==211) + if (mom>0.4 && mom<0.5) { + he->Fill(dedx,1.); + } + } + + Stat_t ng=hgood->GetEntries(); cerr<<"Good tracks "<GetEntries(); + if (ng!=0) + cerr<<"Integral efficiency is about "<SetOptStat(111110); gStyle->SetOptFit(1); @@ -229,7 +193,7 @@ void AliTPCTestTracking() { TPad *p4=new TPad("p4","",0.5,0,1,0.3); p4->Draw(); p4->cd(); p4->SetFillColor(42); p4->SetFrameFillColor(10); - hd->SetXTitle("(mm)"); hd->Draw(); c1->cd(); + hmpt->SetXTitle("(%)"); hmpt->Fit("gaus"); c1->cd(); TPad *p5=new TPad("p5","",0,0.6,1,1); p5->Draw(); p5->cd(); p5->SetFillColor(41); p5->SetFrameFillColor(10); @@ -241,9 +205,9 @@ void AliTPCTestTracking() { hg->SetXTitle("Pt (GeV/c)"); hg->Draw(); - TLine *line1 = new TLine(0,1.0,2,1.0); line1->SetLineStyle(4); + TLine *line1 = new TLine(0,1.0,7,1.0); line1->SetLineStyle(4); line1->Draw("same"); - TLine *line2 = new TLine(0,0.9,2,0.9); line2->SetLineStyle(4); + TLine *line2 = new TLine(0,0.9,7,0.9); line2->SetLineStyle(4); line2->Draw("same"); hf->SetFillColor(1); @@ -273,6 +237,129 @@ void AliTPCTestTracking() { hep->SetXTitle("p (Gev/c)"); hep->SetYTitle("dE/dX (Arb. Units)"); hep->Draw(); c1->cd(); +} + +Int_t good_tracks(GoodTrack *gt, Int_t max) { + const char *tname="TreeD_75x40_100x60"; + + Int_t nt=0; + + AliTPC *TPC = (AliTPC*)gAlice->GetDetector("TPC"); + Int_t ver=TPC->IsVersion(); + AliTPCParam *digp= (AliTPCParam*)TPC->GetParam(); + + Int_t nrow_up=TPC->GetParam()->GetNRowUp(); + Int_t nrows=TPC->GetParam()->GetNRowLow()+nrow_up; + Int_t zero=TPC->GetParam()->GetZeroSup(); + Int_t gap=Int_t(0.125*nrows); + Int_t good_number=Int_t(0.4*nrows); + + //gAlice->GetEvent(0); + TClonesArray *particles=gAlice->Particles(); + Int_t np=particles->GetEntriesFast(); + Int_t *good=new Int_t[np]; + for (Int_t ii=0; iiClusters(); + Int_t n=0; + if (clusters) n=clusters->GetEntriesFast(); + for (Int_t i=0; iUncheckedAt(i); + Int_t lab=c->fTracks[0]; + if (lab<0) continue; //noise cluster + lab=TMath::Abs(lab); + Int_t sec=c->fSector, row=c->fPadRow; + if (sec>=digp->GetNInnerSector()) + if (row==nrow_up-1 ) good[lab]|=0x1000; + if (sec>=digp->GetNInnerSector()) + if (row==nrow_up-1-gap) good[lab]|=0x800; + good[lab]++; + } + break; + case 2: + TTree *TD=(TTree*)gDirectory->Get(tname); + AliSimDigits da, *digits=&da; + TD->GetBranch("Segment")->SetAddress(&digits); + Int_t *count = new Int_t[np]; + Int_t i; + for (i=0; iGetEntries(); + for (i=0; iGetEvent(i)) continue; + Int_t sec,row; + digp->AdjustSectorRow(digits->GetID(),sec,row); + cerr<First(); + while (digits->Next()) { + Int_t it=digits->CurrentRow(), ip=digits->CurrentColumn(); + Short_t dig = digits->GetDigit(it,ip); + Int_t idx0=digits->GetTrackID(it,ip,0); + Int_t idx1=digits->GetTrackID(it,ip,1); + Int_t idx2=digits->GetTrackID(it,ip,2); + if (idx0>=0 && dig>=zero) count[idx0]+=1; + if (idx1>=0 && dig>=zero) count[idx1]+=1; + if (idx2>=0 && dig>=zero) count[idx2]+=1; + } + for (Int_t j=0; j1) { + if (sec>=digp->GetNInnerSector()) + if (row==nrow_up-1 ) good[j]|=0x1000; + if (sec>=digp->GetNInnerSector()) + if (row==nrow_up-1-gap) good[j]|=0x800; + good[j]++; + } + count[j]=0; + } + } + delete[] count; + break; + default: + cerr<<"Invalid TPC version !\n"; + return; + } + + TTree *TH=gAlice->TreeH(); + TClonesArray *hits=TPC->Hits(); + Int_t npart=TH->GetEntries(); + + while (npart--) { + TPC->ResetHits(); + TH->GetEvent(npart); + Int_t nhits=hits->GetEntriesFast(); + if (nhits==0) continue; + AliTPChit *hit; + Int_t j; + for (j=0; jUncheckedAt(j); + if (hit->fQ==0.) break; + } + if (j==nhits-1) continue; + AliTPChit *hit1=(AliTPChit*)hits->UncheckedAt(j+1); + if (hit1->fQ != 0.) continue; + Int_t i=hit->fTrack; + TParticle *p = (TParticle*)particles->UncheckedAt(i); + if (p->GetFirstMother()>=0) continue; //secondary particle + if (good[i] < 0x1000+0x800+2+good_number) continue; + if (p->Pt()<0.100) continue; + if (TMath::Abs(p->Pz()/p->Pt())>0.999) continue; + + gt[nt].lab=i; + gt[nt].code=p->GetPdgCode(); +//**** px py pz - in global coordinate system, x y z - in local ! + gt[nt].px=hit->fX; gt[nt].py=hit->fY; gt[nt].pz=hit->fZ; + Float_t cs,sn; digp->AdjustCosSin(hit1->fSector,cs,sn); + gt[nt].x = hit1->fX*cs + hit1->fY*sn; + gt[nt].y =-hit1->fX*sn + hit1->fY*cs; + gt[nt].z = hit1->fZ; + nt++; + + cerr<SNJ z1GF;&ECm5eOCpe934ppGIS&QEn+i~o;xChGehpi({ekyxbc`hQOpjq`!M|Vj;4BIS zg(f^>)^rdNeXn7kag!G&IIfdeOB45e*vfh&v?t15$!2u zi&q21HlIhWU-EH}P-y(#)Iu@4BwW3&wX?hQy`W}=W#?@TrZm+XR=FU8pX5-@KQJ1$ zdaY;Sl+jtxS3ZuKMmtuoD(&L)2I6o1`k-e-Kej9T1 z-Ng0uluFd9xmJkfwO?YQLY|$~Ndszfsi>o{*>o4E5$CICjYBLAnz#5zp_<}( zm4>1xOEWd6?mjLYxjkXX`e)NwPTPK7c=ZmK^l_&Q2B#?QkX@u_TSi$p_Co)8p^)r* z%aHSOUpGFzsS0XMV&%^f&A_YG3m~LuHHOlWj#$DZ=O-jsato)PNp3$WdH|#&6YWHg zf<;=gVix1Is%@reEmIEcu~9re-qiMiqiB>(+7r4~bjPb2&0adXFW>6>{qEPY)n{|4 zt~GB9#;Y1hxkOYR2f9oA0K%v1RHKG&jMb%duzZipIn*L?k-+!F%;CqXPvUw_*H|T3 zv>@wPg+zrpt<9dVLta#m9xh}fV9TQW=xtjT;{X$bH`nmo{#Co$E9H?SLUb=z!?%N6 zgQd6>)RWiJ&z>~5;o0hsR^98VJP)BgDcdJL`txi3dfXCfJ|MD@Tf9LCfyUyKD74%O z+*`t{+uSBMGt6}8VbzG_X#cApALRy+yzS|3UNj#99D1&7cvly|y?yX=lAexRGFdROI}7<#rocS2L(DLr_TE)0Q)-eMwtlVZp}!Irfj^bz|Oo z#SjMzqRPFqNPLYBLgPan-Ow3?;v1|vHpZc>I0y@bPYkKSN3|3B?$kY-*y#8~2xiX? z!ljuiQBB6aUYwUwzP^#WM=_=E&lYMn>(aWrcc3v)mgslp{j5Ly3^j#!5njH%dV1i zsLzadsF(Y&pVIq~v+s~3*(fvBUT4mYUe!fUG|R^J@|M)fSnj9aO8P|8kg$ zg)!S5lTr5`ELvbZ*q|t)R{^3ZbzmWdWsAjka&^Yr(6lT!(S~|YV6d~S5mE}+IC1L6 z&cLJeP%i-nTs=otCyOn_w2N z)~96f*j<%Ky>Yz8q9p0Ibpy}LdQa9{?K^ZiVHs=r^~hU5JLj9Z-5(?y$XRo{2#@#I zFB9Cbj$Lf%yB8@Oe!T^cI5`^pyc`tPk&1Nmxb1N|k^1|Es{kp?qToc>NzOZ!cCjjO zxB?M4tPU!X+_Zzb$~3;g2?0M0biPITuNc=A8NJ~9G-CUOFQj~p8Kcv~2xdJdk8l2Y zbF$(p#A-KJL6PnFkLG>XO<5~RvnZFlY#Y{)XWPrMV5ePl_jF8})`;7c8ZrFsrC`DYb8G`kNw9%vOnk3#XE2SqP5-hXb>HEc_CXwA! z(82L+T4_o4+0JhI!@HLBt^VbdbLNq%jJEw5pA2ln`O|+F?;N1C{J1TDWpp@BmgjN_ z1P(X%9Z5C|C26j36dEYPjRstv2t}RZ!g>)noM9!>rJJgq&TOkgzvwXO;PGL!_e4W{ z?IzYWL~hc&KSSEUb=Eo-e)_oMOjYkRkxxn=-UnM_`1#1isJ*Y@M55$Lc9BwJL- z2DR*NM6Q%Ftx^+mW)Hv_XK6j?JVFkEW-= zRV3t+gK|#0ESmV1nH43QsJybdE9&)ZhY7!tO;0&{-_J_!zKFM{FrP4o6;rxwn_fxi zQ%g&I$6oG$X=^qH+A&hiJSU;69~qu;rfMJL2X$Mf%_0dL-?GlBoveGbuK(fAf`+Td zMLNsenxGem@=^H|N6tHle;y?2|d8Rwo`Xo(Jwi7aWcGnH>=V}QoyyrWpXK0%g+{xg#2)& zp(L!n$0ms7yK>JiN&QgMno61(I%l~=s!PxUF#biczxehK0RB&WyM!=G^s8*yTcv=pRd1k$^!7wRQs-YG>Fp0%d#y7{$T zLoqNhzVz^T7}i-zjWGm0o*}*C0l#nNwB0nz_b`o{JCB?>M)1xp45cPnJh+1-EVVY{ zjQD&eF-u`n_UIJ-N;(p|yzS2~qEG4s5gAjkCSF0)ETtcvO;!HF%#76v`{kIhq{TX< zMda-qJ+B zUa+Z2+x~!s=1C&ak$#n<{%CDqf1o$f{(a^57v6nmo`=Lc35o+FB9gsW< z%A0)?Qt-92H%9Oso;Z)qLV5eT!9*PGUWzGbT|XFz88HTzmJ@fCh}h13yndsOK*~F9 z^{nKRx$5UhgEaP2mP04`u*Y0voFDQY=y3zd?lNuNZXDcL?x=CZi3DgU$GOqO6;XL+ z7Mto4Emr;1eYD7OH^h_3oKq=G4>u1g%fmHPHgRzUjl?jR>{gq#Yi&~A%jvl%m1DiZ zaNlf-S@P`+U=;Q#UH-S_7g2blN8OHT%v`=DlbSIhk|x-Ku_&N}(K^6I%rL!E@e!N{ zw?LT$nvNGUD;`>#gN{}03YtVX&9#?!c^FQkxH*b>RyN#T`Q#=i9a{6b65E&L&x(X& zM^@#oLBB8Y!PNz>Jg^hjRu8z*IxDu&ivSiHh~`YMlAYa|AOFgYSW>v!IY~y+Du=aui#dMTs*SKJ!K3F7I!f#+WQlug(y_R{oZyw8gG2Bt|Lfc+?c zb1j!gB;A*xQ&&fIYg4CG_*QNtt?0Eq~620I=Y0k1A}sK7ZhlPIf)YvHwB9@#WvJkZ}{ynA>2S0I$~Z zsP}xiTVvf@5)e9LP&nZk+%oY{O-n4M)K&fDN*GMvMW#+NW%ibdhZ$Q+I92S_T$ikL zly~Vf?TNa?g6k4@b9Jdp5Xx~DUCA&+Pd$1lZUUXzlKqG{d)TGx;m<{XPQQHA=M5|Q zpbbu%4KKUTUTtDq*5gETzW`ghZ)oTCXt%^|!lFx~Z@gEg5ldfds}sqftuh`VQ>Suv zkjuYQg+?cOMn&+y&S7|V1(Fr=%nI-Ee4(+Qr`psi+HYE?{c*w^d$Xb+A)P@cKn4^T zUN(5Y94a(z68k=gT2Ny>N^?GFV=7|ED#Ty#z`8u`+V(nEjM|Ism;|;>y06&w4edfi zCjR>)mwm#!lShB59F;}A`@u&SP5EMmzHH+`|JBAXr|5s#Spk>Ie`CJ>HyZMP093w( AJOBUy diff --git a/TPC/AliTPCv0.cxx b/TPC/AliTPCv0.cxx index 7bb121986f3..8b6e1b8b7db 100644 --- a/TPC/AliTPCv0.cxx +++ b/TPC/AliTPCv0.cxx @@ -15,6 +15,16 @@ /* $Log$ +Revision 1.13.8.2 2000/04/10 08:33:44 kowal2 + +Updated readout chambers + +Revision 1.13.8.1 2000/04/10 07:56:53 kowal2 +Not used anymore - removed + +Revision 1.13 1999/11/04 17:28:06 fca +Correct barrel part of HV Degrader + Revision 1.12 1999/10/08 06:27:23 fca Corrected bug in the HV degrader geometry, thanks to G.Tabary @@ -47,12 +57,11 @@ Introduction of the Copyright and cvs Log #include "AliRun.h" #include #include - #include "AliMC.h" #include "AliConst.h" #include "AliTPCParam.h" -#include "AliTPCD.h" +#include "AliTPCDigitsArray.h" ClassImp(AliTPCv0) @@ -70,7 +79,7 @@ void AliTPCv0::CreateGeometry() { // // Creation of the TPC coarse geometry (version 0) - // Origin Marek Kowalski Crakow + // Origin Marek Kowalski Cracow // //Begin_Html /* @@ -83,7 +92,6 @@ void AliTPCv0::CreateGeometry() */ //End_Html - AliTPCParam * fTPCParam = &(fDigParam->GetParam()); Int_t *idtmed = fIdtmed->GetArray(); @@ -187,20 +195,21 @@ void AliTPCv0::CreateGeometry() Int_t nOuterSector = fTPCParam->GetNOuterSector()/2; - Float_t InSecLowEdge = fTPCParam->GetInSecLowEdge(); - Float_t InSecUpEdge = fTPCParam->GetInSecUpEdge(); + Float_t InSecLowEdge = fTPCParam->GetInnerRadiusLow(); + Float_t InSecUpEdge = fTPCParam->GetInnerRadiusUp(); - Float_t OuSecLowEdge = fTPCParam->GetOuSecLowEdge(); - Float_t OuSecUpEdge = fTPCParam->GetOuSecUpEdge(); + Float_t OuSecLowEdge = fTPCParam->GetOuterRadiusLow(); + Float_t OuSecUpEdge = fTPCParam->GetOuterRadiusUp(); Float_t SecThick = 2.225; // Al - Float_t edge = fTPCParam->GetEdge(); // S (Inner) sectors - dm[0] = InSecLowEdge*TMath::Tan(0.5*InnerOpenAngle)-edge; - dm[1] = InSecUpEdge*TMath::Tan(0.5*InnerOpenAngle)-edge; + Float_t LowEdge = fTPCParam->GetInnerFrameSpace(); + + dm[0] = InSecLowEdge*TMath::Tan(0.5*InnerOpenAngle)-LowEdge; + dm[1] = InSecUpEdge*TMath::Tan(0.5*InnerOpenAngle)-LowEdge; dm[2] = SecThick; dm[3] = 0.5*(InSecUpEdge-InSecLowEdge); @@ -210,8 +219,10 @@ void AliTPCv0::CreateGeometry() // L (Outer) sectors - dm[0] = OuSecLowEdge*TMath::Tan(0.5*OuterOpenAngle)-edge; - dm[1] = OuSecUpEdge*TMath::Tan(0.5*OuterOpenAngle)-edge; + Float_t UpEdge = fTPCParam->GetOuterFrameSpace(); + + dm[0] = OuSecLowEdge*TMath::Tan(0.5*OuterOpenAngle)-UpEdge; + dm[1] = OuSecUpEdge*TMath::Tan(0.5*OuterOpenAngle)-UpEdge; dm[2] = SecThick; dm[3] = 0.5*(OuSecUpEdge-OuSecLowEdge); diff --git a/TPC/AliTPCv0.h b/TPC/AliTPCv0.h index 4559c050905..b123d9149b5 100644 --- a/TPC/AliTPCv0.h +++ b/TPC/AliTPCv0.h @@ -8,6 +8,7 @@ //////////////////////////////////////////////// // Version 0 for TPC // //////////////////////////////////////////////// + #include "AliTPC.h" diff --git a/TPC/AliTPCv1.cxx b/TPC/AliTPCv1.cxx index 70090d90991..4240ad84ac0 100644 --- a/TPC/AliTPCv1.cxx +++ b/TPC/AliTPCv1.cxx @@ -15,6 +15,17 @@ /* $Log$ +Revision 1.15.8.2 2000/04/10 08:29:48 kowal2 + +Different pad geometry for different sectors +Updated readouch chambers geometry + +Revision 1.15.8.1 2000/04/10 07:56:53 kowal2 +Not used anymore - removed + +Revision 1.15 1999/11/04 17:28:07 fca +Correct barrel part of HV Degrader + Revision 1.14 1999/10/08 06:27:23 fca Corrected bug in the HV degrader geometry, thanks to G.Tabary @@ -53,7 +64,7 @@ Introduction of the Copyright and cvs Log #include "AliConst.h" #include "AliTPCParam.h" -#include "AliTPCD.h" +#include "AliTPCDigitsArray.h" ClassImp(AliTPCv1) @@ -85,7 +96,6 @@ void AliTPCv1::CreateGeometry() */ //End_Html - AliTPCParam * fTPCParam = &(fDigParam->GetParam()); Int_t *idtmed = fIdtmed->GetArray(); @@ -189,20 +199,20 @@ void AliTPCv1::CreateGeometry() Int_t nOuterSector = fTPCParam->GetNOuterSector()/2; - Float_t InSecLowEdge = fTPCParam->GetInSecLowEdge(); - Float_t InSecUpEdge = fTPCParam->GetInSecUpEdge(); + Float_t InSecLowEdge = fTPCParam->GetInnerRadiusLow(); + Float_t InSecUpEdge = fTPCParam->GetInnerRadiusUp(); - Float_t OuSecLowEdge = fTPCParam->GetOuSecLowEdge(); - Float_t OuSecUpEdge = fTPCParam->GetOuSecUpEdge(); + Float_t OuSecLowEdge = fTPCParam->GetOuterRadiusLow(); + Float_t OuSecUpEdge = fTPCParam->GetOuterRadiusUp(); Float_t SecThick = 2.225; // Al - Float_t edge = fTPCParam->GetEdge(); - // S (Inner) sectors - dm[0] = InSecLowEdge*TMath::Tan(0.5*InnerOpenAngle)-edge; - dm[1] = InSecUpEdge*TMath::Tan(0.5*InnerOpenAngle)-edge; + Float_t LowEdge = fTPCParam->GetInnerFrameSpace(); + + dm[0] = InSecLowEdge*TMath::Tan(0.5*InnerOpenAngle)-LowEdge; + dm[1] = InSecUpEdge*TMath::Tan(0.5*InnerOpenAngle)-LowEdge; dm[2] = 0.5*SecThick; dm[3] = 0.5*(InSecUpEdge-InSecLowEdge); @@ -212,8 +222,10 @@ void AliTPCv1::CreateGeometry() // L (Outer) sectors - dm[0] = OuSecLowEdge*TMath::Tan(0.5*OuterOpenAngle)-edge; - dm[1] = OuSecUpEdge*TMath::Tan(0.5*OuterOpenAngle)-edge; + Float_t UpEdge = fTPCParam->GetOuterFrameSpace(); + + dm[0] = OuSecLowEdge*TMath::Tan(0.5*OuterOpenAngle)-UpEdge; + dm[1] = OuSecUpEdge*TMath::Tan(0.5*OuterOpenAngle)-UpEdge; dm[2] = 0.5*SecThick; dm[3] = 0.5*(OuSecUpEdge-OuSecLowEdge); @@ -242,7 +254,7 @@ void AliTPCv1::CreateGeometry() Float_t r1,r2,zz; Float_t StripThick = 0.01; // 100 microns - Float_t dead = fTPCParam->GetDeadZone(); + Float_t dead; gMC->Gsvolu("TSST", "TRD1", idtmed[4], dm, 0); @@ -252,6 +264,8 @@ void AliTPCv1::CreateGeometry() // S-sector + dead = fTPCParam->GetInnerWireMount(); + for (ns = 0; ns < fTPCParam->GetNRowLow(); ns++) { r1 = fTPCParam->GetPadRowRadiiLow(ns); @@ -322,6 +336,8 @@ void AliTPCv1::CreateGeometry() dm[7] = 250.; + dead = fTPCParam->GetOuterWireMount(); + Float_t xx = dead/TMath::Tan(0.5*OuterOpenAngle); for(ns=0;nsGetNRowUp();ns++){ @@ -847,7 +863,7 @@ void AliTPCv1::DrawDetector() gMC->Gsatt("TPCO","SEEN",1); gMC->Gsatt("TPOV","SEEN",1); gMC->Gsatt("TPVD","SEEN",1); - // + gMC->Gdopt("hide", "on"); gMC->Gdopt("shad", "on"); gMC->Gsatt("*", "fill", 7); @@ -893,8 +909,6 @@ void AliTPCv1::StepManager() Int_t vol[2]; TLorentzVector p; TClonesArray &lhits = *fHits; - - AliTPCParam *fTPCParam = &(fDigParam->GetParam()); // @@ -909,6 +923,24 @@ void AliTPCv1::StepManager() vol[1]=copy-1; // row id=gMC->CurrentVolOffID(1,copy); vol[0]=copy+fTPCParam->GetNInnerSector()-1; // sector + + //I.Belikov's modification + if (vol[1]==0) { + gMC->TrackMomentum(p); + hits[0]=p[0]; + hits[1]=p[1]; + hits[2]=p[2]; + hits[3]=0.; // this hit has no energy loss + new(lhits[fNhits++]) AliTPChit(fIshunt,gAlice->CurrentTrack(),vol,hits); + + gMC->TrackPosition(p); + hits[0]=p[0]; + hits[1]=p[1]; + hits[2]=p[2]; + hits[3]=0.; // this hit has no energy loss + new(lhits[fNhits++]) AliTPChit(fIshunt,gAlice->CurrentTrack(),vol,hits); + } + //end of I.Belikov's modification } else if(id==fIdSens2) { // S @@ -916,11 +948,30 @@ void AliTPCv1::StepManager() vol[1]=copy-1; // row id=gMC->CurrentVolOffID(1,copy); // sector vol[0]=copy-1; + + //I.Belikov's modification + if (vol[1]==0) { + gMC->TrackMomentum(p); + hits[0]=p[0]; + hits[1]=p[1]; + hits[2]=p[2]; + hits[3]=0.; // this hit has no energy loss + new(lhits[fNhits++]) AliTPChit(fIshunt,gAlice->CurrentTrack(),vol,hits); + + gMC->TrackPosition(p); + hits[0]=p[0]; + hits[1]=p[1]; + hits[2]=p[2]; + hits[3]=0.; // this hit has no energy loss + new(lhits[fNhits++]) AliTPChit(fIshunt,gAlice->CurrentTrack(),vol,hits); + } + //end of I.Belikov's modification + } else return; gMC->TrackPosition(p); for(i=0;i<3;++i) hits[i]=p[i]; - hits[3]=0; + hits[3]=1; //I'd like to have something positive here (I.Belikov) new(lhits[fNhits++]) AliTPChit(fIshunt,gAlice->CurrentTrack(),vol,hits); } } diff --git a/TPC/AliTPCv1.h b/TPC/AliTPCv1.h index 8b2a6ece6f9..04001b2061b 100644 --- a/TPC/AliTPCv1.h +++ b/TPC/AliTPCv1.h @@ -8,6 +8,7 @@ //////////////////////////////////////////////// // Version 1 for TPC // //////////////////////////////////////////////// + #include "AliTPC.h" diff --git a/TPC/AliTPCv2.cxx b/TPC/AliTPCv2.cxx index 5bf4ede875c..7fa8c4e57a4 100644 --- a/TPC/AliTPCv2.cxx +++ b/TPC/AliTPCv2.cxx @@ -15,6 +15,18 @@ /* $Log$ +Revision 1.19.8.2 2000/04/10 08:31:52 kowal2 + +Different geometry for different sectors +Updated readout chambers +Some modifications to StepManager by J.Belikov + +Revision 1.19.8.1 2000/04/10 07:56:53 kowal2 +Not used anymore - removed + +Revision 1.19 1999/11/04 17:28:07 fca +Correct barrel part of HV Degrader + Revision 1.18 1999/10/14 16:52:08 fca Only use PDG codes and not GEANT ones @@ -46,7 +58,7 @@ Introduction of the Copyright and cvs Log #include #include "AliTPCv2.h" -#include "AliTPCD.h" +#include "AliTPCDigitsArray.h" #include "AliRun.h" #include "AliConst.h" #include "AliPDG.h" @@ -82,7 +94,6 @@ void AliTPCv2::CreateGeometry() */ //End_Html - AliTPCParam * fTPCParam = &(fDigParam->GetParam()); Int_t *idtmed = fIdtmed->GetArray(); @@ -220,9 +231,9 @@ void AliTPCv2::CreateGeometry() Float_t z_side = dm[2]; // 1/2 of the side gas thickness - //----------------------------------------------------------- + //------------------------------------------------------------ // Readout chambers , 25% of X0, I use Al as the material - //----------------------------------------------------------- + //------------------------------------------------------------ Float_t InnerOpenAngle = fTPCParam->GetInnerAngle(); Float_t OuterOpenAngle = fTPCParam->GetOuterAngle(); @@ -230,21 +241,21 @@ void AliTPCv2::CreateGeometry() Float_t InnerAngleShift = fTPCParam->GetInnerAngleShift(); Float_t OuterAngleShift = fTPCParam->GetOuterAngleShift(); - Float_t InSecLowEdge = fTPCParam->GetInSecLowEdge(); - Float_t InSecUpEdge = fTPCParam->GetInSecUpEdge(); + Float_t InSecLowEdge = fTPCParam->GetInnerRadiusLow(); + Float_t InSecUpEdge = fTPCParam->GetInnerRadiusUp(); - Float_t OuSecLowEdge = fTPCParam->GetOuSecLowEdge(); - Float_t OuSecUpEdge = fTPCParam->GetOuSecUpEdge(); + Float_t OuSecLowEdge = fTPCParam->GetOuterRadiusLow(); + Float_t OuSecUpEdge = fTPCParam->GetOuterRadiusUp(); Float_t SecThick = 2.225; // Al - Float_t edge = fTPCParam->GetEdge(); + Float_t LowEdge = fTPCParam->GetInnerFrameSpace(); // S (Inner) sectors - dm[0] = InSecLowEdge*TMath::Tan(0.5*InnerOpenAngle)-edge; - dm[1] = InSecUpEdge*TMath::Tan(0.5*InnerOpenAngle)-edge; + dm[0] = InSecLowEdge*TMath::Tan(0.5*InnerOpenAngle)-LowEdge; + dm[1] = InSecUpEdge*TMath::Tan(0.5*InnerOpenAngle)-LowEdge; dm[2] = 0.5*SecThick; dm[3] = 0.5*(InSecUpEdge-InSecLowEdge); @@ -254,8 +265,10 @@ void AliTPCv2::CreateGeometry() // L (Outer) sectors - dm[0] = OuSecLowEdge*TMath::Tan(0.5*OuterOpenAngle)-edge; - dm[1] = OuSecUpEdge*TMath::Tan(0.5*OuterOpenAngle)-edge; + Float_t UpEdge = fTPCParam->GetOuterFrameSpace(); + + dm[0] = OuSecLowEdge*TMath::Tan(0.5*OuterOpenAngle)-UpEdge; + dm[1] = OuSecUpEdge*TMath::Tan(0.5*OuterOpenAngle)-UpEdge; dm[2] = 0.5*SecThick; dm[3] = 0.5*(OuSecUpEdge-OuSecLowEdge); @@ -288,13 +301,15 @@ void AliTPCv2::CreateGeometry() Float_t r1,r2,zz; Float_t StripThick = 0.01; // 100 microns - Float_t dead = fTPCParam->GetDeadZone(); + Float_t dead; gMC->Gsvolu("TSST", "TRD1", idtmed[4], dm, 0); dm[2] = 0.5*(250. - 0.002); dm[3] = 0.5 * StripThick; + dead= fTPCParam->GetInnerWireMount(); + for (ns = 0; ns < fTPCParam->GetNRowLow(); ns++) { @@ -353,7 +368,7 @@ void AliTPCv2::CreateGeometry() Float_t rmax = dm[6]; Float_t r1,r2; - Float_t dead = fTPCParam->GetDeadZone(); + Float_t dead = fTPCParam->GetOuterWireMount(); Float_t StripThick = 0.01; // 100 microns @@ -1022,10 +1037,6 @@ void AliTPCv2::StepManager() const Float_t prim = 14.35; // number of primary collisions per 1 cm const Float_t poti = 20.77e-9; // first ionization potential for Ne/CO2 const Float_t w_ion = 35.97e-9; // energy for the ion-electron pair creation - - // const Float_t prim = 17.65; - // const Float_t poti = 19.02e-9; - // const Float_t w_ion = 33.06e-9; const Float_t big = 1.e10; @@ -1035,8 +1046,6 @@ void AliTPCv2::StepManager() Int_t vol[2]; TClonesArray &lhits = *fHits; TLorentzVector pos; - - AliTPCParam *fTPCParam = &(fDigParam->GetParam()); vol[1]=0; @@ -1068,6 +1077,17 @@ void AliTPCv2::StepManager() vol[1] = copy-1; // row number id = gMC->CurrentVolOffID(1,copy); vol[0] = copy-1; // sector number (S-sector) + + //I.Belikov's modification + if (vol[1]==0) { + gMC->TrackMomentum(pos); + hits[0]=pos[0]; + hits[1]=pos[1]; + hits[2]=pos[2]; + hits[3]=0.; // this hit has no energy loss + new(lhits[fNhits++]) AliTPChit(fIshunt,gAlice->CurrentTrack(),vol,hits); + } + //end of I.Belikov's modification gMC->TrackPosition(pos); hits[0]=pos[0]; @@ -1081,6 +1101,17 @@ void AliTPCv2::StepManager() vol[1] = copy-1; // row number id = gMC->CurrentVolOffID(1,copy); vol[0] = copy+fTPCParam->GetNInnerSector()-1; // sector number (L-sector) + + //I.Belikov's modification + if (vol[1]==0) { + gMC->TrackMomentum(pos); + hits[0]=pos[0]; + hits[1]=pos[1]; + hits[2]=pos[2]; + hits[3]=0.; // this hit has no energy loss + new(lhits[fNhits++]) AliTPChit(fIshunt,gAlice->CurrentTrack(),vol,hits); + } + //end of I.Belikov's modification gMC->TrackPosition(pos); hits[0]=pos[0]; @@ -1121,7 +1152,7 @@ void AliTPCv2::StepManager() Float_t beta_gamma = ptot/gMC->TrackMass(); Int_t pid=gMC->TrackPid(); - if((pid==kElectron || pid==kPositron || pid==kGamma) && ptot > 0.002) + if((pid==kElectron || pid==kPositron) && ptot > 0.002) { pp = prim*1.58; // electrons above 20 MeV/c are on the plateau! } diff --git a/TPC/AliTPCv2.h b/TPC/AliTPCv2.h index 83a88eba83c..d5afe7608e2 100644 --- a/TPC/AliTPCv2.h +++ b/TPC/AliTPCv2.h @@ -8,6 +8,7 @@ //////////////////////////////////////////////// // Version 2 for TPC // //////////////////////////////////////////////// + #include "AliTPC.h" diff --git a/TPC/AliTPCv3.cxx b/TPC/AliTPCv3.cxx index b907e4e9e35..6c2a49e67b1 100644 --- a/TPC/AliTPCv3.cxx +++ b/TPC/AliTPCv3.cxx @@ -15,6 +15,17 @@ /* $Log$ +Revision 1.11.8.2 2000/04/10 08:36:12 kowal2 + +Updated readout chambers +Some modifications to StepManager by M. Kowalski + +Revision 1.11.8.1 2000/04/10 07:56:53 kowal2 +Not used anymore - removed + +Revision 1.11 1999/11/04 17:28:07 fca +Correct barrel part of HV Degrader + Revision 1.10 1999/10/14 16:52:08 fca Only use PDG codes and not GEANT ones @@ -44,12 +55,11 @@ Introduction of the Copyright and cvs Log #include #include - #include "AliTPCv3.h" #include "AliRun.h" #include "AliConst.h" -#include "AliTPCD.h" -#include "AliTPCParam.h" +#include "AliTPCDigitsArray.h" +#include"AliTPCParam.h" #include "AliPDG.h" ClassImp(AliTPCv3) @@ -59,7 +69,7 @@ AliTPCv3::AliTPCv3(const char *name, const char *title) : AliTPC(name, title) { // - // Standard constructor for Time Projection Chamber version 2 + // Standard constructor for Time Projection Chamber version 3 // SetBufferSize(128000); @@ -69,8 +79,8 @@ AliTPCv3::AliTPCv3(const char *name, const char *title) : void AliTPCv3::CreateGeometry() { // - // Creation of the TPC coarse geometry (version 0) - // Origin Marek Kowalski Crakow + // Creation of the TPC coarse geometry (version 3) + // Origin Marek Kowalski Cracow // //Begin_Html /* @@ -83,8 +93,6 @@ void AliTPCv3::CreateGeometry() */ //End_Html - AliTPCParam * fTPCParam = &(fDigParam->GetParam()); - Int_t *idtmed = fIdtmed->GetArray(); Float_t dm[21]; @@ -187,20 +195,20 @@ void AliTPCv3::CreateGeometry() Int_t nOuterSector = fTPCParam->GetNOuterSector()/2; - Float_t InSecLowEdge = fTPCParam->GetInSecLowEdge(); - Float_t InSecUpEdge = fTPCParam->GetInSecUpEdge(); + Float_t InSecLowEdge = fTPCParam->GetInnerRadiusLow(); + Float_t InSecUpEdge = fTPCParam->GetInnerRadiusUp(); - Float_t OuSecLowEdge = fTPCParam->GetOuSecLowEdge(); - Float_t OuSecUpEdge = fTPCParam->GetOuSecUpEdge(); + Float_t OuSecLowEdge = fTPCParam->GetOuterRadiusLow(); + Float_t OuSecUpEdge = fTPCParam->GetOuterRadiusUp(); Float_t SecThick = 2.225; // Al - Float_t edge = fTPCParam->GetEdge(); + Float_t LowEdge = fTPCParam->GetInnerFrameSpace(); // S (Inner) sectors - dm[0] = InSecLowEdge*TMath::Tan(0.5*InnerOpenAngle)-edge; - dm[1] = InSecUpEdge*TMath::Tan(0.5*InnerOpenAngle)-edge; + dm[0] = InSecLowEdge*TMath::Tan(0.5*InnerOpenAngle)-LowEdge; + dm[1] = InSecUpEdge*TMath::Tan(0.5*InnerOpenAngle)-LowEdge; dm[2] = SecThick; dm[3] = 0.5*(InSecUpEdge-InSecLowEdge); @@ -210,8 +218,10 @@ void AliTPCv3::CreateGeometry() // L (Outer) sectors - dm[0] = OuSecLowEdge*TMath::Tan(0.5*OuterOpenAngle)-edge; - dm[1] = OuSecUpEdge*TMath::Tan(0.5*OuterOpenAngle)-edge; + Float_t UpEdge = fTPCParam->GetOuterFrameSpace(); + + dm[0] = OuSecLowEdge*TMath::Tan(0.5*OuterOpenAngle)-UpEdge; + dm[1] = OuSecUpEdge*TMath::Tan(0.5*OuterOpenAngle)-UpEdge; dm[2] = SecThick; dm[3] = 0.5*(OuSecUpEdge-OuSecLowEdge); @@ -802,7 +812,7 @@ void AliTPCv3::StepManager() Float_t beta_gamma = ptot/gMC->TrackMass(); Int_t pid=gMC->TrackPid(); - if((pid==kElectron || pid==kPositron || pid==kGamma) && ptot > 0.002) + if((pid==kElectron || pid==kPositron) && ptot > 0.002) { pp = prim*1.58; // electrons above 20 MeV/c are on the plateau! } diff --git a/TPC/AliTPCv3.h b/TPC/AliTPCv3.h index 03f7e9ccec0..6b4f43076e6 100644 --- a/TPC/AliTPCv3.h +++ b/TPC/AliTPCv3.h @@ -8,6 +8,7 @@ //////////////////////////////////////////////// // Version 3 for TPC // //////////////////////////////////////////////// + #include "AliTPC.h" diff --git a/TPC/CLFinderDemo.C b/TPC/CLFinderDemo.C new file mode 100644 index 00000000000..dc3a995d15d --- /dev/null +++ b/TPC/CLFinderDemo.C @@ -0,0 +1,41 @@ +//Begin_Html +/* + +*/ +//End_Html +void CLFinderDemo() +{ + + AliTPCDigitsArray *gDigitsArray= GetDigitsArray(); + AliTPCClustersArray *gExactClusters = GetExactClustersArray(); + + + AliH2F * his = gDigitsArray->LoadRow(0,0)->GenerHisto()->GetSubrange2d(440,470,60,90); + + AliClusterFinder cf; + cf.SetThreshold(3); + cf.SetNoise(1); + Int_t index[3]={1,0,0}; + cf.SetDetectorIndex(index); + cf.SetDetectorParam(gTPCParam); + cf.GetHisto(his); + + cf.SetBFit(kFALSE); + cf.GetMinuit()->SetPrintLevel(-1); + cf.GetMinuit()->SetMaxIterations(100); + cf.FindPeaks1()->GetEntriesFast(); + + + TCanvas *c0 = new TCanvas("signals", "Cluster finder drawing", 600,1100); + c0->Divide(1,3); + c0->cd(1); + cf.Draw("lego2"); + + c0->cd(2); + cf.Draw("cont1"); + cf.DrawCluster(4,5,5); + c0->cd(3); + cf.DrawBorders("lego2"); + +} + diff --git a/TPC/ClassTree.C b/TPC/ClassTree.C new file mode 100644 index 00000000000..d09214023f9 --- /dev/null +++ b/TPC/ClassTree.C @@ -0,0 +1,204 @@ +{ +//=========Macro generated from canvas: ClassTree/ +//========= (Tue Jun 1 17:01:38 1999) by ROOT version 2.21/07 + TCanvas *ClassTree = new TCanvas("ClassTree", "",186,135,594,449); + ClassTree->SetHighLightColor(2); + ClassTree->Range(0,5,20,20); + ClassTree->SetFillColor(33); + ClassTree->SetBorderSize(2); + TLine *line = new TLine(0.5,18.15,4.4,18.15); + line->Draw(); + line = new TLine(4.4,17.725,4.4,18.575); + line->Draw(); + + TPaveLabel *pl = new TPaveLabel(1,17.895,4.205,18.405,"TArray","br"); + pl->SetFillColor(30); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(0.5,16.875,1,16.875); + line->Draw(); + + pl = new TPaveLabel(1,16.62,4.205,17.13,"TAttFill","br"); + pl->SetFillColor(30); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(0.5,16.025,1,16.025); + line->Draw(); + + pl = new TPaveLabel(1,15.77,4.205,16.28,"TAttLine","br"); + pl->SetFillColor(30); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(0.5,15.175,1,15.175); + line->Draw(); + + pl = new TPaveLabel(1,14.92,4.205,15.43,"TAttMarker","br"); + pl->SetFillColor(30); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(0.5,9.775,4.4,9.775); + line->Draw(); + line = new TLine(4.4,7.65,4.4,12.325); + line->Draw(); + + pl = new TPaveLabel(1,9.52,4.205,10.03,"TObject","br"); + pl->SetFillColor(5); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(4.4,12.325,4.9,12.325); + line->Draw(); + + pl = new TPaveLabel(4.9,12.07,8.105,12.58,"AliArrayI","br"); + pl->SetFillColor(18); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(4.4,11.475,4.9,11.475); + line->Draw(); + + pl = new TPaveLabel(4.9,11.22,8.105,11.73,"AliArrayS","br"); + pl->SetFillColor(18); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(4.4,18.575,4.9,18.575); + line->Draw(); + + pl = new TPaveLabel(4.9,18.32,8.105,18.83,"TArrayI","br"); + pl->SetFillColor(30); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(4.4,17.725,4.9,17.725); + line->Draw(); + + pl = new TPaveLabel(4.9,17.47,8.105,17.98,"TArrayS","br"); + pl->SetFillColor(30); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(4.4,10.2,8.3,10.2); + line->Draw(); + + pl = new TPaveLabel(4.9,9.945,8.105,10.455,"TCollection","br"); + pl->SetFillColor(18); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(4.4,7.65,8.3,7.65); + line->Draw(); + line = new TLine(8.3,6.8,8.3,8.075); + line->Draw(); + + pl = new TPaveLabel(4.9,7.395,8.105,7.905,"TNamed","br"); + pl->SetFillColor(18); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(8.3,8.075,12.2,8.075); + line->Draw(); + + pl = new TPaveLabel(8.8,7.82,12.005,8.33,"AliSegmentArray","br"); + pl->SetFillColor(18); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(8.3,10.2,12.2,10.2); + line->Draw(); + + pl = new TPaveLabel(8.8,9.945,12.005,10.455,"TSeqCollection","br"); + pl->SetFillColor(18); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(8.3,6.8,8.8,6.8); + line->Draw(); + + pl = new TPaveLabel(8.8,6.545,12.005,7.055,"TTree","br"); + pl->SetFillColor(18); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(12.2,8.075,12.7,8.075); + line->Draw(); + + pl = new TPaveLabel(12.7,7.82,15.905,8.33,"AliTPCClustersArray","br"); + pl->SetFillColor(18); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(12.2,10.2,16.1,10.2); + line->Draw(); + + pl = new TPaveLabel(12.7,9.945,15.905,10.455,"TObjArray","br"); + pl->SetFillColor(18); + pl->SetTextSize(0.9); + pl->Draw(); + line = new TLine(16.1,10.2,16.6,10.2); + line->Draw(); + + pl = new TPaveLabel(16.6,9.945,19.805,10.455,"TClonesArray","br"); + pl->SetFillColor(18); + pl->SetTextSize(0.9); + pl->Draw(); + + pl = new TPaveLabel(0.1,19.1,18.2,19.9,"*AliSegmet:*AliSegmentArray:*AliArrayI:*AliArrayS:TTree:*TObjArray","br"); + pl->SetFillColor(42); + pl->SetTextSize(0.7); + pl->Draw(); + line = new TLine(11.4041,6.8,14.3025,10.2); + line->SetLineColor(6); + line->SetLineStyle(3); + line->Draw(); + line = new TLine(11.4842,6.8,14.3025,10.2); + line->SetLineColor(6); + line->SetLineStyle(3); + line->Draw(); + line = new TLine(6.5025,12.325,6.5025,18.575); + line->SetLineColor(4); + line->SetLineStyle(2); + line->Draw(); + line = new TLine(6.5025,11.475,6.5025,17.725); + line->SetLineColor(4); + line->SetLineStyle(2); + line->Draw(); + line = new TLine(10.4025,6.8,2.6025,16.025); + line->SetLineColor(4); + line->SetLineStyle(2); + line->Draw(); + line = new TLine(10.4025,6.8,2.6025,16.875); + line->SetLineColor(4); + line->SetLineStyle(2); + line->Draw(); + line = new TLine(10.4025,6.8,2.6025,15.175); + line->SetLineColor(4); + line->SetLineStyle(2); + line->Draw(); + TArrow *arrow = new TArrow(5.43417,10.2,6.5025,10.2,0.008,"|>"); + arrow->SetFillColor(2); + arrow->SetFillStyle(1001); + arrow->SetLineColor(2); + arrow->Draw(); + arrow = new TArrow(6.85861,10.2,2.6025,9.775,0.008,"|>"); + arrow->SetFillColor(2); + arrow->SetFillStyle(1001); + arrow->SetLineColor(2); + arrow->Draw(); + arrow = new TArrow(9.60125,8.075,14.3025,10.2,0.008,"|>"); + arrow->SetFillColor(2); + arrow->SetFillStyle(1001); + arrow->SetLineColor(2); + arrow->Draw(); + arrow = new TArrow(10.1354,8.075,6.5025,12.325,0.008,"|>"); + arrow->SetFillColor(2); + arrow->SetFillStyle(1001); + arrow->SetLineColor(2); + arrow->Draw(); + arrow = new TArrow(11.2037,8.075,10.4025,6.8,0.008,"|>"); + arrow->SetFillColor(2); + arrow->SetFillStyle(1001); + arrow->SetLineColor(2); + arrow->Draw(); + arrow = new TArrow(13.9019,10.2,2.6025,9.775,0.008,"|>"); + arrow->SetFillColor(2); + arrow->SetFillStyle(1001); + arrow->SetLineColor(2); + arrow->Draw(); + arrow = new TArrow(19.2708,10.2,14.3025,10.2,0.008,"|>"); + arrow->SetFillColor(2); + arrow->SetFillStyle(1001); + arrow->SetLineColor(2); + arrow->Draw(); + ClassTree->Modified(); + ClassTree->cd(); +} diff --git a/TPC/Makefile b/TPC/Makefile index 02ae0a064fb..5abb456d973 100644 --- a/TPC/Makefile +++ b/TPC/Makefile @@ -10,12 +10,19 @@ PACKAGE = TPC # C++ sources SRCS = AliTPC.cxx AliTPCv0.cxx AliTPCv1.cxx AliTPCv2.cxx \ - AliTPCD.cxx AliTPCPRF2D.cxx AliTPCRF1D.cxx AliTPCParam.cxx \ - AliTPCv3.cxx + AliTPCv3.cxx AliDetectorParam.cxx AliTPCParam.cxx \ + AliTPCParamSR.cxx AliTPCParamCR.cxx AliTPCPRF2D.cxx \ + AliTPCRF1D.cxx AliArrayI.cxx AliArrayS.cxx \ + AliSegmentID.cxx AliSegmentArray.cxx AliDigits.cxx \ + AliSimDigits.cxx AliDigitsArray.cxx AliTPCDigitsArray.cxx \ + AliCluster.cxx AliClusters.cxx AliClustersArray.cxx \ + AliClusterFinder.cxx AliTPCClustersRow.cxx \ + AliTPCClustersArray.cxx AliH2F.cxx + # C++ Headers -HDRS = $(SRCS:.cxx=.h) AliTPCSecGeo.h TPCLinkDef.h +HDRS = $(SRCS:.cxx=.h) TPCLinkDef.h # Library dictionary @@ -37,13 +44,14 @@ OBJS = $(patsubst %.cxx,tgt_$(ALICE_TARGET)/%.o,$(SRCS)) $(DICTO) # C++ compilation flags -CXXFLAGS = $(CXXOPTS) -I$(ROOTSYS)/include -I. -I$(ALICE_ROOT)/include/ +CXXFLAGS = $(CXXOPTS) -g -I$(ROOTSYS)/include -I. -I$(ALICE_ROOT)/include +#CXXFLAGS = $(CXXOPTS) -I$(ROOTSYS)/include -I. -I$(ALICE_ROOT)/include/ # FORTRAN compilation flags FFLAGS = $(FOPT) -##### TARGETS ##### +##### TARGETS ####### # Target @@ -65,19 +73,6 @@ include $(ALICE_ROOT)/conf/GeneralMacros ############################ Dependencies ##################################### --include tgt_$(ALICE_TARGET)/Make-depend - -### Target check creates violation reports (.viol), which depend on -### stripped files (.ii), which in turn depend on preprocessed -### files (.i). Dependences are in conf/GeneralDef. - -CHECKS = $(patsubst %.cxx,check/%.viol,$(SRCS)) - -check: $(CHECKS) - - - - - +include tgt_$(ALICE_TARGET)/Make-depend diff --git a/TPC/ParamTest.C b/TPC/ParamTest.C new file mode 100644 index 00000000000..bfa035cb986 --- /dev/null +++ b/TPC/ParamTest.C @@ -0,0 +1,15 @@ +TFile f("prf2d.root"); +AliTPCPRF2D prf1; +AliTPCPRF2D prf2; +AliTPCRF1D rf(kTRUE); +rf.SetGauss(0.3,0.5,1) +rf.Update(); +prf1.Read("prf_205035_Gati_062074_d03"); +prf2.Read("prf_205035_Gati_062074_d03"); +AliTPCParamSR param; +param.SetInnerPRF(&prf1) +param.SetOuterPRF(&prf2) +param.SetTimeRF(&rf); +Float_t x[3]={5.1,0,100} +Int_t index[3] +param.CalcResponse(x,index) diff --git a/TPC/TPCAnal.C b/TPC/TPCAnal.C new file mode 100644 index 00000000000..29cea2554c7 --- /dev/null +++ b/TPC/TPCAnal.C @@ -0,0 +1,542 @@ +/* +#include "alles.h" +extern AliTPCParam *gTPCParam; +extern AliTPCClustersArray * gCalcClusters; +extern AliTPCClustersArray * gDifClusters; +*/ + + + +TH1F * GetDX(Float_t x1=-2, Float_t x2=3, Float_t a1=-1, Float_t a2=1) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hd = new TH1F("delta x", "dx",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + // if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + // if ( (cl->fGenerTrack != cl->fTracks[0])) continue; + if ( (cl->fAngleXfAngleX>a1) ) hd->Fill(cl->fDx); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + +TH1F * GetDY(Float_t x1=-2, Float_t x2=3, Float_t a1=-1, Float_t a2=1) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hd = new TH1F("delta y", "dy",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + //if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + //if ( (cl->fGenerTrack != cl->fTracks[0])) continue; + // if (cl->fNy!=2) continue; + if ((cl->fAngleYfAngleY>a1) ) hd->Fill(cl->fDy); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + + + +TH1F * GetNX(Float_t x1=0, Float_t x2=7, Float_t a1=-1, Float_t a2=1) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hd = new TH1F("N x", "N x",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ((cl->fAngleXfAngleX>a1) ) hd->Fill(cl->fNx); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + +TH1F * GetNY(Float_t x1=-0, Float_t x2=7, Float_t a1=-1, Float_t a2=1) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hd = new TH1F("N y", "N y",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + if ( (cl->fAngleYfAngleY>a1) ) hd->Fill(cl->fNy); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + + + + +TH1F * GetAngleX(Float_t x1=-2, Float_t x2=3) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hdx = new TH1F("Angle x", "Angle x",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hdx->Fill(cl->fAngleX); + } + arr->ClearSegment(clrow->GetID()); + } + return hdx; +} + +TH1F * GetAngleX2(Float_t x1=-2, Float_t x2=3) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hdx = new TH1F("Angle x2", "Angle x2",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hdx->Fill(cl->fAngleX*cl->fAngleX); + } + arr->ClearSegment(clrow->GetID()); + } + return hdx; +} + +TH1F * GetAngleY(Float_t x1=-2, Float_t x2=3) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hdx = new TH1F("Angle y", "Angle y",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hdx->Fill(cl->fAngleY); + } + arr->ClearSegment(clrow->GetID()); + } + return hdx; +} + +TH1F * GetAngleY2(Float_t x1=-2, Float_t x2=3) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hdx = new TH1F("Angle y2", "Angle y2",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hdx->Fill(cl->fAngleY*cl->fAngleY); + } + arr->ClearSegment(clrow->GetID()); + } + return hdx; +} + + +TH1F * GetKmax(Float_t x1=0, Float_t x2=200) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hd = new TH1F("Max ADC", "Max ADC",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(cl->fMax); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + + +TH1F * GetQ(Float_t x1=0, Float_t x2=200) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hd = new TH1F("Integral Q", "Integral Q",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(cl->fQ); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + + +TH1F * GetCalcQ(Float_t x1=0, Float_t x2=1) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hd = new TH1F("kCalcQ", "kCalcQ",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(cl->fOrigQ); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + + +TH1F * GetCalcQSQR(Float_t x1=0, Float_t x2=1) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hd = new TH1F("kCalcQSQRt", "kCalcQSQRt",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(TMath::Sqrt(cl->fOrigQ)); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + + + +TH1F * GetQDivQ(Float_t x1=0, Float_t x2=1) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hd = new TH1F("kQdivCalcQ", "kQDivCalcQ",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + // if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(cl->fQ/cl->fOrigQ); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + + + +TH1F * GetKmaxDivQ(Float_t x1=0, Float_t x2=1) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hd = new TH1F("kMaxdivQ", "kMaxDivQ",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(cl->fMax/cl->fQ); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + + + + + + + + +TH2F * GetDXvRow(Float_t x1=0, Float_t x2=20, Float_t y1=0, Float_t y2=3) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH2F * hd = new TH2F("delta x versur row ", "DXvRow",33,x1,x2,33,y1,y2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + Int_t sector,row; + gTPCParam->AdjustSectorRow(clrow->GetID(),sector,row); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(row,cl->fDx,1); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + + +TH1F * GetSigmaX(Float_t x1=0, Float_t x2=2) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hd = new TH1F("SigmaX", "SigmaX",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(TMath::Sqrt(cl->fSigmaX2)); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + + +TH1F * GetSigmaY(Float_t x1=0, Float_t x2=2) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hd = new TH1F("SigmaY", "SigmaY",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(TMath::Sqrt(cl->fSigmaY2)); + } + arr->ClearSegment(clrow->GetID()); + } + + return hd; +} + +TH1F * GetArea(Float_t x1=0, Float_t x2=40) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH1F * hd = new TH1F("Cluster area", "cluster area",33,x1,x2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(cl->fArea); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + + +TH2F * GetSigmaXvX(Float_t x1=0, Float_t x2=500,Float_t y1=0, Float_t y2=1) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH2F * hd = new TH2F("SigmaXvX", "SigmaXvX",33,x1,x2,33,y1,y2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(cl->fX,TMath::Sqrt(cl->fSigmaX2),1); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + +TH2F * GetSigmaYvX(Float_t x1=0, Float_t x2=500,Float_t y1=0, Float_t y2=1) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH2F * hd = new TH2F("SigmaYvX", "SigmaYvX",33,x1,x2,33,y1,y2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(cl->fX,TMath::Sqrt(cl->fSigmaY2),1); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + +TH2F * GetDeltaXvX(Float_t x1=0, Float_t x2=500,Float_t y1=0, Float_t y2=3) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH2F * hd = new TH2F("DeltaXvX", "DeltaXvX",33,x1,x2,33,y1,y2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(cl->fX,cl->fDy,1); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + +TH2F * GetDeltaYvX(Float_t x1=0, Float_t x2=500,Float_t y1=0, Float_t y2=0.5) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH2F * hd = new TH2F("DeltaYvX", "DeltaYvX",33,x1,x2,33,y1,y2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(cl->fX,cl->fDy,1); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + +TH2F * GetAreavX(Float_t x1=0, Float_t x2=500,Float_t y1=0, Float_t y2=20) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH2F * hd = new TH2F("AreavX", "AreavX",33,x1,x2,33,y1,y2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(cl->fX,cl->fArea,1); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + + +TH2F * GetKvX(Float_t x1=0, Float_t x2=500,Float_t y1=0, Float_t y2=20) +{ + AliTPCClustersArray *arr=gDifClusters; + if (arr==0) return 0; + TH2F * hd = new TH2F("KvX", "KvX",33,x1,x2,33,y1,y2); + Int_t nsegment = (Int_t)arr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + if (clrow==0) continue; + Int_t ncluster = clrow->GetArray()->GetEntriesFast(); + for (Int_t i = 0; iGetArray()->UncheckedAt(i); + if ( (cl->fGenerTrack != cl->fTracks[0]) || (cl->fTracks[1]>0)) continue; + hd->Fill(cl->fX,cl->fMax,1); + } + arr->ClearSegment(clrow->GetID()); + } + return hd; +} + diff --git a/TPC/TPCConfig.C b/TPC/TPCConfig.C new file mode 100644 index 00000000000..4fb40839c01 --- /dev/null +++ b/TPC/TPCConfig.C @@ -0,0 +1,80 @@ +void Config() +{ +//======================================================================= +// Create the output file + +TFile *rootfile = new TFile("galice.root","recreate"); +rootfile->SetCompressionLevel(2); + +//======================================================================= +// ******* GEANT STEERING parameters FOR ALICE SIMULATION ******* +geant3->SetTRIG(1); //Number of events to be processed +geant3->SetSWIT(4,1); +geant3->SetDEBU(0,0,1); +//geant3->SetSWIT(2,2); +geant3->SetDCAY(1); +geant3->SetPAIR(1); +geant3->SetCOMP(1); +geant3->SetPHOT(1); +geant3->SetPFIS(0); +geant3->SetDRAY(0); +geant3->SetANNI(1); +geant3->SetBREM(1); +geant3->SetMUNU(1); +geant3->SetCKOV(1); +geant3->SetHADR(1); //Select pure GEANH (HADR 1) or GEANH/NUCRIN (HADR 3) +geant3->SetLOSS(2); +geant3->SetMULS(1); +geant3->SetRAYL(1); +geant3->SetAUTO(1); //Select automatic STMIN etc... calc. (AUTO 1) or manual (AUTO 0) +geant3->SetABAN(0); //Restore 3.16 behaviour for abandoned tracks +geant3->SetOPTI(2); //Select optimisation level for GEANT geometry searches (0,1,2) +Float_t cut = 1.e-3; // 1MeV cut by default +Float_t tofmax = 1.e10; +// GAM ELEC NHAD CHAD MUON EBREM MUHAB EDEL MUDEL MUPA TOFMAX +geant3->SetCUTS(cut,cut, cut, cut, cut, cut, cut, cut, cut, cut, tofmax); +// +//======================================================================= +// ************* STEERING parameters FOR ALICE SIMULATION ************** +// --- Specify event type to be tracked through the ALICE setup +// --- All positions are in cm, angles in degrees, and P and E in GeV +AliGenHIJINGpara *gener = new AliGenHIJINGpara(1000); +gener->SetMomentumRange(0,100); +gener->SetPhiRange(0,360); +gener->SetThetaRange(20,160); +gener->SetOrigin(0,0,0); //vertex position +gener->SetSigma(0,0,0); //Sigma in (X,Y,Z) (cm) on IP position +gener->Init(); + +gAlice->SetField(-999,2); //Specify maximum magnetic field in Tesla (neg. ==> default field) + +//=================== Alice BODY parameters ============================= +AliBODY *BODY = new AliBODY("BODY","Alice envelop"); + + + +//============================ TPC parameters ================================ +// --- This allows the user to specify sectors for the SLOW (TPC geometry 2) +// --- Simulator. TPCSECL (TPSECU) <0 means that ALL lower (upper) +// --- sectors are specified, any value other than that requires at least one +// --- sector (lower or upper)to be specified! +// --- Reminder: sectors 1-24 are lower sectors (1-12 -> z>0, 13-24 -> z<0) +// --- sectors 25-72 are the upper ones (25-48 -> z>0, 49-72 -> z<0) +// --- TPCLOWS - number of lower sectors specified (up to 6) +// --- TPCUPS - number of upper sectors specified (up to 12) +// --- TPCSENS - sensitive strips for the Slow Simulator !!! +// --- This does NOT work if all S or L-sectors are specified, i.e. +// --- if TPCSECL or TPCSECU < 0 +//----------------------------------------------------------------------------- + +AliTPC *TPC = new AliTPCv1("TPC","Normal TPC"); +TPC->SetSecAL(1); +TPC->SetSecAU(1); +TPC->SetSecLows(1, -1, -1, -1, -1, -1); +TPC->SetSecUps(25, 26, 48, -1, -1, -1, -1, -1, -1, -1, -1, -1); +TPC->SetSens(1); + + + + +} diff --git a/TPC/TPCDigits2Clusters.C b/TPC/TPCDigits2Clusters.C new file mode 100644 index 00000000000..c7e2cfb5e89 --- /dev/null +++ b/TPC/TPCDigits2Clusters.C @@ -0,0 +1,220 @@ + +/* +#include "alles.h" +extern AliTPCParam *gTPCParam; +extern AliTPCClustersArray * gCalcClusters; +extern AliTPCClustersArray * gDifClusters; +AliTPCDigitsArray * GetDigitsArray(); + AliTPCClustersArray * GetExactClustersArray(); +AliTPCClustersArray * GetCalcClustersArray(Bool_t newtree=kFALSE); +AliTPCClustersArray * GetDifClustersArray(Bool_t newtree=kFALSE); +TClonesArray * CompareClusters(TClonesArray *calcclusters,TClonesArray *exactclusters, + TClonesArray *diffclusters, Float_t shx, Float_t shy); +*/ + +void TPCDigits2Clusters(AliTPCDigitsArray * digarr, AliTPCClustersArray *calcarr, + AliTPCClustersArray *exarr=0, AliTPCClustersArray *difarr=0) +{ + // + //calculate clusters position from digits information + // + + + //initialisation of cluster finder + AliClusterFinder cf; + cf.SetThreshold(gTPCParam->GetZeroSup()); + cf.SetDetectorParam(gTPCParam); + cf.SetBFit(kFALSE); + cf.GetMinuit()->SetPrintLevel(-1); + cf.GetMinuit()->SetMaxIterations(20); + + if (digarr ==0) digarr = GetDigitsArray(); + if ( (digarr == 0) || (digarr->GetTree()==0)) return; + if (exarr==0) exarr =GetExactClustersArray(); + if ((exarr!=0)&&(difarr==0)) difarr= GetDifClustersArray(); + + if (calcarr==0) calcarr = GetCalcClustersArray(kTRUE); + //loop over all writen digits segments + Int_t nsegment = (Int_t)digarr->GetTree()->GetEntries(); + Int_t segment; + for (segment = 0; segmentLoadEntry(segment); + Int_t sector,row; + ((AliTPCParam*)digarr->GetParam())->AdjustSectorRow(digrow->GetID(),sector,row); + + AliTPCClustersRow * clrow = calcarr->CreateRow(sector,row); + AliTPCClustersRow * difrow= difarr->CreateRow(sector,row); + AliTPCClustersRow * exrow = exarr->GetRow(sector,row); + if (exrow==0) exrow = exarr->LoadRow(sector,row); + TH2F *his = (TH2F*)digrow->GenerHisto(); + digrow->ExpandTrackBuffer(); + if (his==0) return; + + //set current index for cluster finder + Int_t index[3]= {0,sector,row}; + cf.GetHisto(his); + cf.SetDetectorIndex(index); + cf.FindPeaks3(clrow->GetArray()); + + //get cluster tracks ID + Int_t ncl = clrow->GetArray()->GetEntriesFast(); + for (Int_t icl = 0 ;iclGetArray()->UncheckedAt(icl); + Int_t i = (Int_t)cl->fMaxX; + Int_t j = (Int_t)cl->fMaxY; + cl->fTracks[0]=digrow->GetTrackIDFast(i,j,0); + cl->fTracks[1]=digrow->GetTrackIDFast(i,j,1); + cl->fTracks[2]=digrow->GetTrackIDFast(i,j,2); + } + Float_t shx = gTPCParam->GetZOffset()/gTPCParam->GetZWidth()+0.5; + Float_t shy= 0.5; + CompareClusters(clrow->GetArray(),exrow->GetArray(),difrow->GetArray(),shx,shy); + calcarr->StoreRow(sector,row); + difarr->StoreRow(sector,row); + digarr->ClearRow(sector,row); + } + //STORING RESULTS + char treeName[100]; + sprintf(treeName,"TreeCCalc_%s",gTPCParam->GetTitle()); + calcarr->GetTree()->Write(treeName); + if (difarr!=0){ + char treeName[100]; + sprintf(treeName,"TreeCDif_%s",gTPCParam->GetTitle()); + difarr->GetTree()->Write(treeName); + } + +} + + +AliTPCClustersArray * GetCalcClustersArray(Bool_t newtree=kFALSE, const char* name=0) +{ + // + //construct AliTPCClusters Array object + // + AliTPCClustersArray * arr=0; + // if ( (gAlice!=0) && (gAlice->GetDetector("TPC")!=0) ) { + // arr = ((AliTPC*)gAlice->GetDetector("TPC"))->GetClustersArray(); + // if (arr!=0) arr->Update(); + //} + if (arr==0) { + arr = new AliTPCClustersArray; + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + if (file==0) file = new TFile("galice.root","update"); + arr->SetClusterType("AliDigitCluster"); + arr->Setup(gTPCParam); + cout<<"Update status : "<Update()<<"\n"; + char treeName[100]; + if (name==0) + sprintf(treeName,"TreeCExact_%s",gTPCParam->GetTitle()); + else + sprintf(treeName,"TreeCCalc_%s",gTPCParam->GetTitle()); + if (newtree!=kTRUE){ + cout<<"Connect tree status : "<ConnectTree(treeName)<<"\n"; + } + else { + arr->MakeTree(); + } + } + gCalcClusters = arr; + return arr; +} + + +AliTPCClustersArray * GetDifClustersArray(Bool_t newtree=kFALSE, const char* name=0) +{ + // + //construct AliTPCClusters Array object + // + AliTPCClustersArray * arr=0; + // if ( (gAlice!=0) && (gAlice->GetDetector("TPC")!=0) ) { + // arr = ((AliTPC*)gAlice->GetDetector("TPC"))->GetClustersArray(); + // if (arr!=0) arr->Update(); + //} + if (arr==0) { + arr = new AliTPCClustersArray; + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + if (file==0) file = new TFile("galice.root","update"); + arr->SetClusterType("AliDifCluster"); + arr->Setup(gTPCParam); + cout<<"Update status : "<Update()<<"\n"; + char treeName[100]; + if (name==0) + sprintf(treeName,"TreeCExact_%s",gTPCParam->GetTitle()); + else + sprintf(treeName,"TreeCDif_%s",gTPCParam->GetTitle()); + if (newtree!=kTRUE){ + cout<<"Connect tree status : "<ConnectTree(treeName)<<"\n"; + } + else { + arr->MakeTree(); + } + } + gDifClusters = arr; + return arr; +} + + + +TClonesArray * CompareClusters(TClonesArray *calcclusters,TClonesArray *exactclusters, + TClonesArray *diffclusters, Float_t shx, Float_t shy) +{ + if (calcclusters==0) return 0; + if (exactclusters==0) return 0; + if (diffclusters==0) return 0; + TClonesArray & diff=*diffclusters; + + + Int_t nclusters2 = calcclusters->GetEntriesFast(); + Int_t nclusters1 = exactclusters->GetEntriesFast(); + + for(Int_t i=0; iUncheckedAt(i); + AliDigitCluster *cl2; + AliDifCluster diffc; + Int_t index=-1; + Float_t dx=10000; + Float_t dy=10000; + for (Int_t j=0; jUncheckedAt(j); + if ( (cl2!=0)&& (cl1!=0)){ + Float_t ddx = (cl2->fX-shx)-cl1->fX; + Float_t ddy = (cl2->fY-shy)-cl1->fY; + if ((ddx*ddx+ddy*ddy)<(dx*dx+dy*dy)){ + dx=ddx; + dy=ddy; + index=j; + } + } + } + + cl2 = (AliDigitCluster*)calcclusters->UncheckedAt(index); + if (cl2!=0){ + diffc.fDx =dx; + diffc.fDy =dy; + + diffc.fAngleX = cl1->fSigmaX2; + diffc.fAngleY = cl1->fSigmaY2; + diffc.fTracks[0] = cl2->fTracks[0]; + diffc.fTracks[1] = cl2->fTracks[1]; + diffc.fTracks[2] = cl2->fTracks[2]; + diffc.fGenerTrack= cl1->fTracks[0]; + + diffc.fX = cl2->fX; + diffc.fY = cl2->fY; + diffc.fNx = cl2->fNx; + diffc.fNy = cl2->fNy; + diffc.fQ = cl2->fQ; + diffc.fOrigQ = cl1->fQ; + diffc.fSigmaX2 = cl2->fSigmaX2; + diffc.fSigmaY2 = cl2->fSigmaY2; + diffc.fArea = cl2->fArea; + diffc.fMax = cl2->fMax; + } + else cout<<"pici[ici/n"; + + new(diff[i]) AliDifCluster(diffc); + } + return diffclusters; +} diff --git a/TPC/TPCHits2ExactClusters.C b/TPC/TPCHits2ExactClusters.C new file mode 100644 index 00000000000..e14b9b30ffc --- /dev/null +++ b/TPC/TPCHits2ExactClusters.C @@ -0,0 +1,73 @@ +//#include "alles.h" + +void TPCHits2ExactClusters() +{ + if (gTPCParam==0) { + cout<<"TPC Param Not Initialised\n"; + return; + } + // Dynamically link some shared libs + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } + // Connect the Root Galice file containing Geometry, Kine and Hits + const char * inFile = "galice.root"; + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(inFile); + if (file) file->Close(); + file = new TFile(inFile,"UPDATE"); + // Get AliRun object from file or create it if not on file + // if (!gAlice) { + gAlice = (AliRun*)file->Get("gAlice"); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); + // }; + gAlice->GetEvent(0); + AliTPC *TPC = (AliTPC*)gAlice->GetDetector("TPC"); + + //setup AliTPCClustersArray + AliTPCClustersArray * arr=new AliTPCClustersArray; + arr->SetClusterType("AliCluster"); + arr->Setup(gTPCParam); + TPC->SetParam(gTPCParam); + arr->MakeTree(); + + TPC->SetClustersArray(arr); + TPC->Hits2ExactClustersSector(0); + //write results + char treeName[100]; + sprintf(treeName,"TreeCExact_%s",gTPCParam->GetTitle()); + TPC->GetClustersArray()->GetTree()->Write(treeName); +} + + +AliTPCClustersArray * GetExactClustersArray(Bool_t newtree=kFALSE, const char* name=0 ) +{ + AliTPCClustersArray * arr; + if ( (gAlice!=0) && (gAlice->GetDetector("TPC")!=0) ) { + arr = ((AliTPC*)gAlice->GetDetector("TPC"))->GetClustersArray(); + if (arr!=0) arr->Update(); + } + if (arr==0) { + arr = new AliTPCClustersArray; + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + if (file==0) file = new TFile("galice.root","update"); + arr->SetClusterType("AliCluster"); + arr->Setup(gTPCParam); + cout<<"Update status : "<Update()<<"\n"; + char treeName[100]; + if (name==0) + sprintf(treeName,"TreeCExact_%s",gTPCParam->GetTitle()); + else sprintf(treeName,"TreeCExact_%s",name); + if (newtree!=kTRUE){ + cout<<"Connect tree status : "<ConnectTree(treeName)<<"\n"; + } + else + arr->MakeTree(); + } + return arr; +} + + + + diff --git a/TPC/TPCLinkDef.h b/TPC/TPCLinkDef.h index df86d4c83eb..c6f824b16ea 100644 --- a/TPC/TPCLinkDef.h +++ b/TPC/TPCLinkDef.h @@ -19,10 +19,35 @@ #pragma link C++ class AliTPCtrack; #pragma link C++ class AliTPCParam-; -#pragma link C++ class AliTPCD-; +#pragma link C++ class AliTPCParamSR-; +#pragma link C++ class AliTPCParamCR-; #pragma link C++ class AliTPCRF1D-; #pragma link C++ class AliTPCPRF2D-; +#pragma link C++ class AliArrayI-; +#pragma link C++ class AliArrayS-; +#pragma link C++ class AliDetectorParam; +#pragma link C++ class AliSegmentID; +#pragma link C++ class AliSegmentArray-; +#pragma link C++ class AliCluster; +#pragma link C++ class AliDigitCluster; +#pragma link C++ class AliDifCluster; +#pragma link C++ class AliClusters; +#pragma link C++ class AliClustersArray; + +#pragma link C++ class AliTPCClustersRow; +#pragma link C++ class AliTPCClustersArray; + +#pragma link C++ class AliDigits; +#pragma link C++ class AliSimDigits; +#pragma link C++ class AliDigitsArray; +#pragma link C++ class AliTPCDigitsArray; + + +#pragma link C++ class AliClusterFinder-; +#pragma link C++ class AliCell; +#pragma link C++ class AliH2F; + #endif diff --git a/TPC/TPCtest.C b/TPC/TPCtest.C new file mode 100644 index 00000000000..ba48bf75a5e --- /dev/null +++ b/TPC/TPCtest.C @@ -0,0 +1,27 @@ +void TPCtest() +{ +// Connect the Root Galice file containing Geometry, Kine and Hits +TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + if (!file) file = new TFile("galice.root","UPDATE"); + +// Get AliRun object from file or create it if not on file + if (!gAlice) { + gAlice = (AliRun*)file->Get("gAlice"); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); + } + +gAlice->GetEvent(0); +AliDetector *TPC = gAlice->GetDetector("TPC"); +Int_t en; + +((AliTPC*)TPC)->Hits2Digits(); + +TClonesArray *Digits = TPC->Digits(); + +en = gAlice->TreeD()->GetEntries(); +printf("entries = %d\n",en); + +gAlice->TreeD()->Write(); + +} diff --git a/TPC/TestAliTPCDigitsArray.C b/TPC/TestAliTPCDigitsArray.C new file mode 100644 index 00000000000..80986907277 --- /dev/null +++ b/TPC/TestAliTPCDigitsArray.C @@ -0,0 +1,74 @@ +TFile f("pokus.root","recreate") +arr.MakeTree() +TBrowser b; +arr.AddSegment(1) +arr[1] +arr[1]->Dump() +arr.AddSegment(2) +arr[2]->Dump() +dig.StoreSegment(1) +arr.StoreSegment(1) +arr.StoreSegment(2) +arr.SetClass("AliDigits") +arr.ConnectTree() +TBrowser b; +arr.SetClass("AliDigits") +arr.MakeArray(100) +arr.AddSegment(1) +arr.AddSegment(2) +arr.StoreSegment(1) +arr.StoreSegment(2) +arr.GetTree()->Write("pokus1") +arr.GetTree()->Close() +arr.SetClass("AliSimDigits") +arr.MakeArray(1000) +arr.ConnectTree("pokus1") +arr.LoadSegment(1) +arr[1] +arr[1]->Dump() +arr[2] +arr.LoadSegment(2) +arr[2]->Dump() +.q +.! ddd root.exe & +.q +.! ddd root.exe & +AliTPCDigitsArray arr +AliTPCDigitsArray brr +.q +AliTPCDigitsArray arr +AliTPCParam par; +arr.Setup(&par) +arr.GetRow(1,1) +.q +.x mkhtml.C +.q +AliTPCDigitsArray arr; +arr.CreateRow(0,4) +.q +AliTPCDigitsArray arr; +AliTPCParam par; +arr.Setup(&par) +arr.CreateRow(0,4) +arr.Getrow(9,4) +arr.GetRow(0,4) +arr.GetRow(0,4)->Dump() +arr.GetRow(0,4)->IsA()->GetName() +AliTPCParam par; +par.Update() +par.GetMaxTBin() +.q +AliTPCParam par; +par.GetMaxTBin() +AliTPCDigitsArray arr; +arr.Setup(&par) +arr.CreateRow(0,4) +arr.GetRow(0,4)->Dump() +arr.GetIndex(0,4) +par.GetIndex(0,4) +arr.GetParam()->GetIndex(0,4) +(AliTPCParam* arr.GetParam())->GetIndex(0,4) +(AliTPCParam* arr.GetParam()))->GetIndex(0,4) +( (AliTPCParam*) arr.GetParam())->GetIndex(0,4) +arr.GetRow(0,4)->GetSegmentID() +arr.GetRow(0,4)->GetID() diff --git a/TPC/TestSimDigits.C b/TPC/TestSimDigits.C new file mode 100644 index 00000000000..bfd88fc4ebf --- /dev/null +++ b/TPC/TestSimDigits.C @@ -0,0 +1,34 @@ +AliSimDigits dig; +dig.Allocate(10,10); +dig.AllocateTrack(3); + +dig.SetTrackIDFast(550,5,5,0); +dig.SetTrackIDFast(551,5,5,1); +dig.SetTrackIDFast(552,5,5,2); + + +dig.SetTrackIDFast(550,6,5,0); +dig.SetTrackIDFast(551,6,5,1); +dig.SetTrackIDFast(552,6,5,2); + +dig.SetTrackIDFast(550,7,5,0); +dig.SetTrackIDFast(551,7,5,1); +dig.SetTrackIDFast(552,7,5,2); + + +dig.SetTrackIDFast(440,4,4,0); +dig.SetTrackIDFast(441,4,4,1); +dig.SetTrackIDFast(442,4,4,2); + + + + +dig.CompresTrackBuffer(1); + +dig.GetTrackID(5,5,0); +dig.ExpandTrackBuffer() ; +dig.GetTrackIDFast(5,5,0); +dig.GetTrackIDFast(5,5,0); +dig.GetTrackIDFast(5,5,1); +dig.GetTrackIDFast(5,5,2); +f diff --git a/TPC/diganal.C b/TPC/diganal.C new file mode 100644 index 00000000000..77d14f5dbd9 --- /dev/null +++ b/TPC/diganal.C @@ -0,0 +1,664 @@ +TH1F * h2max = 0; +void tpcstart(const char * param= "Param2",const char * out="out.root", + Int_t nevent=0, Float_t th=3) +{ + + + gtpc.SetIO("galice.root", "out.root"); + + AliTPCD * dig=new AliTPCD; + dig.SetName(param); + gtpc.GetIn()->cd(); + dig.Read(param); + gtpc.SetDParam(dig); + gtpc.SetTree(nevent); + + gtpc.SetbDelHisto(kTRUE); + gtpc.SetThreshold(3); +} + + + +void tpccfind(Int_t threshold, Float_t thr = 2, + Int_t i1 = 2, Int_t i2 = 2, + Int_t tharea =20, Int_t thmax=100) +{ + ///////////////////////GRAPHICS//DECLARATION////////////////////// + TCanvas * c1 = new TCanvas("padcluster","Cluster finder 1",700,900); + c1->cd(); + TCanvas * c2 = new TCanvas("padcluster2","Cluster finder 2",700,900); + c2->cd(); + c1->cd(); + TPad * pad11 = new TPad("pad11","",0.01,0.76,0.48,0.95,21); + pad11->Draw(); + TPad * pad12 = new TPad("pad12","",0.51,0.76,0.95,0.95,21); + pad12->Draw(); + TPad * pad21 = new TPad("pad21","",0.01,0.56,0.49,0.74,21); + pad21->Draw(); + TPad * pad22 = new TPad("pad22","",0.51,0.56,0.95,0.74,21); + pad22->Draw(); + TPad * pad31 = new TPad("pad31","",0.01,0.36,0.49,0.54,21); + pad31->Draw(); + TPad * pad32 = new TPad("pad32","",0.51,0.36,0.95,0.54,21); + pad32->Draw(); + TPad * pad41 = new TPad("pad41","",0.01,0.16,0.49,0.34,21); + pad41->Draw(); + TPad * pad42 = new TPad("pad42","",0.51,0.16,0.95,0.34,21); + pad42->Draw(); + + c2->cd(); + TPad * pad11_2 = new TPad("pad11_2","",0.01,0.76,0.48,0.95,21); + pad11_2->Draw(); + TPad * pad12_2 = new TPad("pad12_2","",0.51,0.76,0.95,0.95,21); + pad12_2->Draw(); + /////////////////////HISTOGRAMS///DECLARATION/////////////////////// + pad11->cd(); + TH1F * hsx = new TH1F("hsx","Sigma of distribution in time",40,0,2); + pad12->cd(); + TH1F * hsy = new TH1F("hsy","Sigma of distribution in pads",40,0,2); + + pad21->cd(); + TProfile * hsx2 = new TProfile("hsx2","Sigma of distribution in time", + 20,100,500); + pad22->cd(); + TProfile * hsy2 = new TProfile("hsy2","Sigma of distribution in pads", + 20,100,500); + + pad31->cd(); + TH1F * harea = new TH1F("harea","Area of the peak",26,0,52); + pad32->cd(); + TH1F * hmax = new TH1F("hmax","Maximal amplitude in peak",30,0,150); + + + pad41->cd(); + TProfile * harea2= new TProfile("harea2","Area dependence z coordinata", + 20,100,500); + pad42->cd(); + TProfile * hmax2 = new TProfile("hmax2","Maximal amplitude dependence", + 20,100,500); + pad41->cd(); + + pad11_2->cd(); + TProfile * harea2p= new TProfile("harea2p","Area dependence on pad coordinata", + 20,0,100); + pad12_2->cd(); + TProfile * hmax2p = new TProfile("hmax2p","Maximal amplitude dependence on pad", + 20,0,50); + //////////////////CALCULATION////////////////////////////////////////// + + for (Int_t k = i1;k <=i2; k++) + { + tpcanal(1,k,10,0,kFALSE); + TClusterFinder * cf=new TClusterFinder(0,0,threshold,1); + cf->GetHisto(>pc.GetHis1()); + TClonesArray * arr = cf->FindClusters(); + cf->Delete(); + Int_t size = arr->GetEntries(); + + if ( size>0 ) + for (Int_t i=0 ; iUncheckedAt(i); + hsx->Fill(TMath::Sqrt(c.fSigmaX2)); + hsy->Fill(TMath::Sqrt(c.fSigmaY2)); + if (TMath::Sqrt(c.fSigmaX2)Fill(c.fX,TMath::Sqrt(c.fSigmaX2),1); + if (TMath::Sqrt(c.fSigmaY2)Fill(c.fX,TMath::Sqrt(c.fSigmaY2),1); + hmax->Fill(c.fMax); + harea->Fill(c.fArea); + if (c.fAreaFill(c.fX,c.fArea,1); + if (c.fMaxFill(c.fX,c.fMax,1); + if (c.fAreaFill(c.fY,c.fArea,1); + if (c.fMaxFill(c.fY,c.fMax,1); + + } + } + gStyle->SetOptStat(1); + pad11->cd(); + hsx->Draw(); + pad12->cd(); + hsy->Draw(); + + pad21->cd(); + hsx2->Draw(); + pad22->cd(); + hsy2->Draw(); + + pad31->cd(); + harea->Draw(); + pad32->cd(); + hmax->Draw(); + + pad41->cd(); + harea2->Draw(); + pad42->cd(); + hmax2->Draw(); + + + c1->cd(); + TPaveText * comment = new TPaveText(0.05,0.02,0.95,0.14,"NDC"); + comment->SetTextAlign(12); + comment->SetFillColor(42); + comment->ReadFile("clusters.txt"); + comment->Draw(); + c2->cd(); + pad11_2->cd(); + harea2p->Draw(); + pad12_2->cd(); + hmax2p->Draw(); + + +} + + +void tpcanal(Int_t sec, Int_t row, Int_t pad, Float_t * res=0, + Bool_t bdraw = kTRUE,Float_t xmin=400,Float_t xmax=500) +{ + //calculate occupancy + Double_t par[3]; + gtpc.SetSecRowTime(sec,row); + gtpc.SetHisto(pad); + //fit occupancy dependence + + gStyle->SetOptStat(0); + g1 = new TF1("pol0_r","pol0",xmin,xmax); + gtpc.GetHis3()->Fit("pol0_r","R0Q"); + char s[100]; + + if (bdraw == kTRUE) + { + gtpc.Draw("box"); + gtpc.GetPad3().cd(); + gtpc.GetPad3().SetGridx(); + gtpc.GetPad3().SetGridy(); + gtpc.GetPad3().SetLogy(); + gtpc.GetPad3().Draw(); + gtpc.GetPad2().cd(); + gtpc.GetPad2().SetGridx(); + gtpc.GetPad2().SetGridy(); + fitText = new TPaveText(0.1,0.7,0.4,0.9,"NDC"); + gtpc.GetHis3()->Draw(); + sprintf(s,"p0 fit on interval %3.0f+- %3.0f",xmin,xmax); + fitText->AddText(s); + } + g1->GetParameters(&par[0]); + Float_t error = g1->GetParError(0); + + sprintf(s,"%0.3f+- %0.3f",par[0],error); + if (bdraw == kTRUE) + { + gtpc.GetHis3()->Fit("pol0_r","R0Q"); + fitText->AddText(s); + fitText->Draw(); + gtpc.GetPad2().Update(); + + //plot histograms with specified options + //move pads to another position be possible add text + gtpc.GetPad1().SetPad(0.05,0.72,0.95,0.95); + gtpc.GetPad2().SetPad(0.05,0.47,0.95,0.70); + gtpc.GetPad3().SetPad(0.05,0.22,0.95,0.45); + //add comments to the histograms + gtpc.GetCanvas().cd(); + TPaveText * comment = new TPaveText(0.05,0.03,0.95,0.2,"NDC"); + comment->SetTextAlign(12); + comment->SetFillColor(42); + comment->ReadFile("comment.txt"); + comment->Draw(); + } + if (res != 0) + { + res[0] = par[0]; + res[1] = error; + cout<GetParam(); + //make window for displaying results + TCanvas * c_occu = new TCanvas("coccu","Occupancy dependence",700,900); + c_occu->Update(); + TPad * pad1 = new TPad("occupancy","occupancy",0.05,0.25,0.95,0.95,21); + pad1->Draw(); + //add comments to the histograms + TPaveText * comment = new TPaveText(0.05,0.03,0.95,0.2,"NDC"); + comment->SetTextAlign(12); + comment->SetFillColor(42); + comment->ReadFile("comment.txt"); + comment->Draw(); + //prepare histogram + Int_t irow = tpcparam->GetNRow(isec); + Float_t xmin = tpcparam->GetPadRowRadii(isec,1); + Float_t xmax = tpcparam->GetPadRowRadii(isec,irow); + pad1->cd(); + char s[220]; + char sh[220]; + sprintf(s,"occu_sector%d",isec); + sprintf(sh,"Occupancy in sector %d as function of pad raw",isec); + TH1F * occudep = new TH1F(s,sh,300,xmin,xmax); + Float_t res[20]; + Float_t x; + for (Int_t i=2;iGetPadRowRadii(isec,i) ; + Int_t index = (300*(x-xmin))/(xmax-xmin); + cout<SetBinContent(index,res[0]); + occudep->SetBinError(index,res[1]); + } + //plot occupancy histogram + + pad1->SetGridx(); + pad1->SetGridy(); + gStyle->SetOptFit(0); + occudep->Draw("error"); + occudep->SetXTitle("pad row center position [cm]"); + occudep->SetYTitle("occupancy"); + + //fit occupancy dependence + //linear fit + TF1 * g1 = new TF1("pol1_r","pol1"); + occudep->Fit("pol1_r","+Q"); + Double_t par[3]; + Float_t error[3]; + Float_t chi; + g1->GetParameters(&par[0]); + error[0]=g1->GetParError(0); + error[1]=g1->GetParError(1); + Float_t chi = g1->GetChisquare(); + sprintf(s,"Linear fit ocupancy = (%2.3f - %2.3f) +(%2.1f+- %2.1f).r chi2 = %2.2f", + par[0],error[0],1000*par[1],1000*error[1],chi); + comment->AddText(s); + //(1-exp([0]1/(r*2+[1]**2) fit + TF1 * g1 = new TF1("polm1",occur,1,00,1); + occudep->Fit("polm1","+Q"); + Double_t par[3]; + Float_t error[3]; + g1->GetParameters(&par[0]); + error[0]=g1->GetParError(0); + // error[1]=g1->GetParError(1); + chi = g1->GetChisquare(); + sprintf(s,"(1-exp(P1/(x^2) fit P1=(%2.3f+- %2.3f) chi2=%2.2f ", + par[0],error[0],chi); + comment->AddText(s); + c_occu->Update(); + +} + +void tpcanalspectra(Int_t isec =1, Int_t r1= 2) +{ + AliTPCParam * tpcparam = gtpc->GetParam(); + //make window for displaying results + TCanvas * c_occu = new TCanvas("occuhis","Occupancy dependence",700,900); + c_occu->Update(); + TPad * pad1 = new TPad("ocpad1","occupancy1",0.05,0.61,0.95,0.95,21); + pad1->Draw(); + TPad * pad2 = new TPad("ocpad2","occupancy",0.05,0.61,0.95,0.95,21); + pad2->Draw(); + + TPad * pad3 = new TPad("ocpad3","occupancy1",0.05,0.25,0.95,0.60,21); + pad3->Draw(); + TPad * pad4 = new TPad("ocpad4","occupancy",0.05,0.25,0.95,0.60,21); + pad4->Draw(); + + //add comments to the histograms + TPaveText * comment = new TPaveText(0.05,0.03,0.95,0.2,"NDC"); + comment->SetTextAlign(12); + comment->SetFillColor(42); + comment->ReadFile("comment.txt"); + comment->Draw(); + TH2F his + //prepare histogram + for (Int_t i=1;iSetGridx(); + pad1->SetGridy(); +} + + + + +void tpcdraw(Int_t sec, Int_t row, Int_t pad) +{ + gStyle->SetOptStat(0); + //calculate occupancy for selected sector and pad row + //for selected pad is obtained signal shape + Double_t par[3]; + gtpc.SetSecRowTime(sec,row); + gtpc.SetHisto(pad); + gtpc.Draw("box"); + //plot histograms with specified options + //move pads to another position be possible add text + gtpc.GetPad1().SetPad(0.05,0.72,0.95,0.95); + gtpc.GetPad2().SetPad(0.05,0.47,0.95,0.70); + gtpc.GetPad3().SetPad(0.05,0.22,0.95,0.45); + //fit histogram of occupancy on specified range <150,500> + gtpc.GetPad2().cd(); + g1 = new TF1("pol0_r","pol0",150,500); + gtpc.GetHis3()->Fit("pol0_r","R0Q"); + g1->GetParameters(&par[0]); + Float_t error = g1->GetParError(0); + fitText = new TPaveText(0.15,0.7,0.3,0.9,"NDC"); + fitText->AddText("p0 fit on interval <150-500>"); + char s[100]; + sprintf(s,"%0.3f+- %0.3f",par[0],error); + fitText->AddText(s); + fitText->Draw(); + gtpc.GetPad2().Update(); + //set logarithmic + gtpc.GetPad3().cd(); + gtpc.GetPad3().SetLogy(); + gtpc.GetPad3().Draw(); + //add comments to the histograms + gtpc.GetCanvas().cd(); + TPaveText * comment = new TPaveText(0.05,0.03,0.95,0.2,"NDC"); + comment->SetTextAlign(12); + comment->SetFillColor(42); + comment->ReadFile("comment.txt"); + comment->Draw(); + gtpc.GetCanvas().Update(); + + +} + + +void oDependence() +{ + //set plot options + gStyle->SetOptFit(1); + gStyle->SetOptStat(1); + TCanvas * c1 = new TCanvas("canPRF","Pad response function",700,900); + TPad * pad1 = new TPad("pad1THR","",0.05,0.55,0.45,0.95,21); + pad1->Draw(); + TPad * pad2 = new TPad("pad2PRF","",0.55,0.55,0.95,0.95,21); + pad2->Draw(); + TPad * pad3 = new TPad("pad3PRF","",0.55,0.05,0.95,0.45,21); + pad3->Draw(); + + pad1->cd(); + pad1->SetGridx(); + pad1->SetGridy(); + pad2->SetGridx(); + pad2->SetGridy(); + pad3->SetGridx(); + pad3->SetGridy(); + + //make histogram of threshold dependence + TH1F * hotd =new TH1F("Occupancy dependence on threshold", + "Ocupancy at first pad row as function of threshold", + 25,0.,25.); + + hotd->SetBinContent(5,0.625); + hotd->SetBinError(5,0.02); + hotd->SetBinContent(10,0.559); + hotd->SetBinError(10,0.02); + hotd->SetBinContent(20,0.478); + hotd->SetBinError(20,0.02); + hotd->SetXTitle("Threshold [channels]"); + hotd->SetYTitle("occupancy"); + hotd->Fit("pol1","+"); + hotd->Draw("error"); + //make histogram of PRF dependence + TH1F * hoprfd =new TH1F("Occupancy dependence on PRF width", + "Occupancy at first pad row as function of generic PRF sigma for 2.05x0.35 cm pad size ", + 65, 0.,6.5); + hoprfd->SetBinContent(10,0.492); + hoprfd->SetBinError(10,0.02); + + hoprfd->SetBinContent(20,0.524); + hoprfd->SetBinError(20,0.02); + + hoprfd->SetBinContent(30,0.559); + hoprfd->SetBinError(30,0.02); + hoprfd->SetXTitle("Sigma of PRF [mm]"); + hoprfd->SetYTitle("occupancy"); + pad2->cd(); + hoprfd->Fit("pol1","+"); + hoprfd->Draw("error"); + pad2->Draw(); + //pad 3 histogram + pad3->cd(); + TH1F * hoprfd88 =new TH1F("Occupancy dependence on PRF width 08x08", + "Occupancy at first pad row as function of generic PRF sigma for 0.8x0.8 cm pad size ", + 65, 0.,6.5); + + hoprfd88->SetBinContent(20,0.322); + hoprfd88->SetBinError(20,0.02); + + hoprfd88->SetBinContent(30,0.344); + hoprfd88->SetBinError(30,0.02); + + hoprfd88->SetBinContent(40,0.369); + hoprfd88->SetBinError(40,0.02); + + hoprfd88->SetBinContent(60,0.416); + hoprfd88->SetBinError(60,0.02); + hoprfd88->SetXTitle("Sigma of PRF [mm]"); + hoprfd88->SetYTitle("occupancy"); + hoprfd88->Fit("pol1","+"); + hoprfd88->Draw("error"); + c1->cd(); + TPaveText * comment = new TPaveText(0.05,0.15,0.45,0.35,"NDC"); + comment->SetTextAlign(12); + comment->SetFillColor(42); + comment->ReadFile("commentdep.txt"); + comment->Draw(); + +} + +void produceHisto() +{ + TH1F * hmostimp =new TH1F("number most important", + "Mean value number of over threshold digits produced by \ +most important particle", + 20,0.,23.); + gStyle->SetOptStat(0); + hmostimp->Fill(1.,33.51); + hmostimp->Fill(5.,34.32); + hmostimp->Fill(10.,35.78); + hmostimp->Fill(15.,36.85); + hmostimp->Fill(20.,37.61); + hmostimp->Write(); + hmostimp->SetMinimum(32.); + delete hmostimp; + + TH1F * hall =new TH1F("number all3", + "Mean value Number of over threshold digits produced by \ +alll three stored particles", + 20,0.,23.); + gStyle->SetOptStat(0); + hall->Fill(1.,77.05); + hall->Fill(5.,76.905); + hall->Fill(10.,71.9); + hall->Fill(15.,69.7); + hall->Fill(20.,65.15); + hall->Write(); + hall->SetMinimum(32.); +} + +void create6() +{ + TCanvas *cnumber =new TCanvas("Number","Number",600,900); + TPad *pad1 =new TPad("pad1","pad1",0.05,0.7,0.45,0.95); + pad1->cd(); + pad1->Draw(); + gtpc.fout->Get("His_1_1").Draw(); + pad1->Update(); + TPad *pad2 =new TPad("pad2","pad2",0.55,0.7,0.95,0.95); + TPad *pad3 =new TPad("pad3","pad3",0.05,0.35,0.45,0.66); + TPad *pad4 =new TPad("pad4","pad4",0.55,0.35,0.95,0.66); + TPad *pad5 =new TPad("pad5","pad5",0.05,0.05,0.45,0.32); + TPad *pad6 =new TPad("pad5","pad6",0.55,0.05,0.95,0.32); +} + +Double_t xtom1(Double_t *x, Double_t *par) +{ + Double_t xm=x[0]/100.; + return (par[0]/(xm*xm)); +} + +Double_t xtomo(Double_t *x, Double_t *par) +{ + Double_t xm=x[0]/100.; + return (par[0]/(xm**par[1])); +} + +Double_t occur(Double_t *x, Double_t *par) +{ + Double_t xm=x[0]/100.; + return (1-exp(-par[0]/(xm**2))); +} + +void probability(Float_t param = 1, Float_t x1 = 0.9, Float_t x2 = 1.3, + Float_t over = 2,const char * com ="", Int_t N=20) +{ + + //create canvas for drawing + TCanvas * c1 = new TCanvas("canprob","Pad response function",700,900); + TPad * pad1 = new TPad("Theoretical probability","",0.05,0.22,0.95,0.95,21); + pad1->Draw(); + + //create histogram with estimated occupancy + //normalised to obtained occupancy at first pad + Float_t y1=0; + Float_t y2; + char s[120]; + sprintf(s,"1-exp(-[1]/x**%f)",over); + cout<SetParameters(1,param); + sprintf(s,"Probability according 1-exp(-%1.3f/x**%1.1f distribution)", + param,over); + pad1->cd(); + TH1F * hOccuT = new TH1F("hOccuT",s,5*N,x1,x2); + Float_t x=x1; + Float_t y; + + for (Float_t i = 0;iEval(x); + hOccuT->Fill(x,y); + x+=(x2-x1)/Float_t(N); + }; + //fitting calculated dependence with linear fit and with + //generic function + pad1->cd(); + sprintf(s,"[1]/(x**%1.1f)",over); + TF1 *lin1 = new TF1("lin1","pol1",x1,x2); + lin1->SetLineColor(2); + lin1->SetLineWidth(5); + lin1->SetLineStyle(1); + hOccuT->Draw(); + hOccuT->Fit("lin1","S+"); + + sprintf(s,"[1]/(x**%1.1f)",over); + TF1 *funorig = new TF1("funorig",s,x1,x2); + funorig->SetLineColor(3); + funorig->SetLineWidth(5); + funorig->SetLineStyle(2); + hOccuT->Fit("funorig","S+"); + + //find minimum and maximum and scale histo + if (y1 == 0) + { + Float_t ymin,ymax; + y1=lin1->Eval(x2); + y2=lin1->Eval(x1); + ymin= funorig->Eval(x2); + ymax= funorig->Eval(x1); + if (yminy2) y2=ymax; + } + gStyle->SetOptFit(0); + gStyle->SetOptStat(0); + hOccuT->SetMaximum(y2); + hOccuT->SetMinimum(y1); + hOccuT->SetXTitle("r position [m]"); + hOccuT->SetYTitle("probability"); + //add comments to the histograms + c1->cd(); + TPaveText * comment = new TPaveText(0.05,0.03,0.95,0.20,"NDC"); + comment->SetTextAlign(12); + comment->SetFillColor(42); + TText *title = comment->AddText("Estimation of occupancy dependence on R position"); + title->SetTextSize(0.04); + comment->AddText("Observed efect of probability saturation"); + sprintf(s,"Supposed generic flux dependence : %1.3f/(x**%1.1f)",param,over); + comment->AddText(s); + comment->AddText("Probility : 1-exp(-flux*mean particle \"pad x time\" area)"); + comment->AddText("Full line linear fit "); + comment->AddText("Dashed line : fit by generic flux function "); + + comment->AddText(com); + comment->Draw(); +} + + + +void digamp(Float_t t1, Float_t t2, Float_t p1, Float_t p2, Float_t th) +{ + gStyle->SetOptStat(1); + TH1F * h2max = new TH1F("all amplitudes","all amplitude", 20, 1,600); + for (Int_t itime = t1;itime th) h2max->Fill(weight); + }; + h2max->Draw(); +} + +void digampM(Float_t t1, Float_t t2, Float_t p1, Float_t p2, Float_t th) +{ + gStyle->SetOptStat(1); + + //create canvas for drawing + // TCanvas * c1 = new TCanvas("dh","Amplitude",700,900); + //TPad * pad1 = new TPad("amplitude","",0.05,0.22,0.95,0.95,21); + //pad1->Draw(); + + if (h2max == 0) h2max = new TH1F("max amplitudes","max amplitude", 25, 1,250); + for (Int_t itime = t1;itimeth) + { + for (Int_t i = -1;i<2;i++) + for (Int_t j = -1;j<2;j++) + if (!((0==i)&&(0==j))) + { + index = gtpc.GetHis1().GetBin(itime+i,ipad+j); + Float_t weightl = gtpc.GetHis1().GetBinContent(index); + if (!(weightlFill(weight); + } + }; + h2max->Draw("error"); + +} + + + +void digampMALL(Float_t t1, Float_t t2, Float_t p1, Float_t p2, Float_t th ) +{ + for (Int_t i=1;i<20;i++) + { + tpcanal(1,i,10); + digampM(t1,t2,p1,p2,th); + } +} diff --git a/TPC/template.C b/TPC/template.C new file mode 100644 index 00000000000..51db59f1e51 --- /dev/null +++ b/TPC/template.C @@ -0,0 +1,48 @@ +void MakeClusterTree(Int_t n) +{ + TFile * f = new TFile("pokus.root","recreate"); + AliTPCClustersArray arr; + arr.MakeArray(10000); + arr.MakeTree(); + for (Int_t i=0;iSetIndex(i); + arr.AddSegment(row); + } + for (Int_t i=0;iWrite("pokus1"); + + +} + + +void MakeTree(Int_t n) +{ + AliSegmentArray arr; + + TFile * f= new TFile("pokus.root","recreate"); + arr.MakeArray(10000); + arr.MakeTree(); + // for (Int_t i=0;iRndm())*n))); + + //for (Int_t i=0;iRndm())*n)); + for (Int_t i=0;iWrite("pokus1"); +} + +void ConnectTree(Int_t n,AliSegmentArray *a) +{ + AliSegmentArray &arr= *a; + // TFile * f = new TFile("pokus.root","update"); + TFile * f = new TFile("pokus.root","update"); + arr.MakeArray(10000); + arr.ConnectTree("pokus1"); + for (Int_t i=0;iGetID()!=i) cout<= 0.999) { + cerr<<"Propagation failed !\n"; + return 0; + } + + Double_t x1=fX, x2=x1+(xk-x1), dx=x2-x1;//, y1=x(0), z1=x(1); + Double_t c1=x(2)*x1 - x(3), r1=sqrt(1.- c1*c1); + Double_t c2=x(2)*x2 - x(3), r2=sqrt(1.- c2*c2); + + x(0) += dx*(c1+c2)/(r1+r2); + x(1) += dx*(c1+c2)/(c1*r2 + c2*r1)*x(4); + + return 1; +} + +static int Rotate(TVector &x, Double_t fX, Double_t alpha) { + Double_t x1=fX, y1=x(0); + Double_t ca=cos(alpha), sa=sin(alpha); + Double_t r1=x(2)*fX - x(3); + + fX = x1*ca + y1*sa; + x(0)=-x1*sa + y1*ca; + x(3)=x(3)*ca + (x(2)*y1 + sqrt(1.- r1*r1))*sa; + + Double_t r2=x(2)*fX - x(3); + if (TMath::Abs(r2) >= 0.999) { + //cerr<<"Rotation failed !\n"; + return 0; + } + + Double_t y0=x(0) + sqrt(1.- r2*r2)/x(2); + if ((x(0)-y0)*x(2) >= 0.) { + //cerr<<"Rotation failed !!!\n"; + return 0; + } + + return 1; +} + +//_____________________________________________________________________________ +static int templ(TVector par, Double_t x, Double_t dy, Double_t dz, + const AliTPCSector *sec, int s, int rf=0) +{ + //----------------------------------------------------------------- + // This function tries to find a track prolongation. + // + // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch + //----------------------------------------------------------------- + int accepted=0; + const int ROWS_TO_SKIP=100; + int try_again=ROWS_TO_SKIP; + Double_t alpha=sec->GetAlpha(); + int ns=int(2*TMath::Pi()/alpha+0.5); + + Double_t xold=x; + for (int nr=sec->GetRowNumber(x)-1; nr>=rf; nr--,xold=x) { + //cerr<GetX(nr), ymax=sec->GetMaxY(nr); + if (!PropagateTo(par,xold,x)) return 0; + + AliTPCcluster *cl=0; + const AliTPCRow& row=sec[s][nr]; + Double_t road=dy, y=par(0), z=par(1); + + if (road>30) { + return 0; + } + + if (row) { + for (int i=row.Find(y-road); ifY > y+road) break; + if (TMath::Abs(c->fZ - z) > dz) continue; + cl=c; + } + } + if (cl) { + par(0)=cl->fY; par(1)=cl->fZ; + //dy=TMath::Sqrt(cl->fSigmaY2); dz=TMath::Sqrt(cl->fSigmaZ2); + //cerr<fTracks[0]<<' '<fTracks[1]<<' '<fTracks[2]< ymax) { + s = (s+1) % ns; + if (!Rotate(par,x,alpha)) return 0; + dy*=2; + } else if (y <-ymax) { + s = (s-1+ns) % ns; + if (!Rotate(par,x,-alpha)) return 0; + dy*=2; + } + try_again--; + } + } + + //cerr<