--- /dev/null
+/**************************************************************************
+ * 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);
+ }
+}
--- /dev/null
+#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
+
--- /dev/null
+/**************************************************************************
+ * 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);
+ }
+}
+
--- /dev/null
+#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
--- /dev/null
+/**************************************************************************
+ * 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
+/*
+<img src="gif/AliTPCCluster.gif">
+*/
+//End_Html
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "AliCluster.h"
+
+ClassImp(AliCluster)
+//_____________________________________________________________________________
+Int_t AliCluster::Compare(TObject * o)
+{
+ //
+ // compare two clusters according y coordinata
+ AliCluster *cl= (AliCluster *)o;
+ if (fY<cl->fY) return -1;
+ if (fY==cl->fY) return 0;
+ return 1;
+}
+
+Bool_t AliCluster::IsSortable() const
+{
+ //
+ //make AliCluster sortabale
+ return kTRUE;
+}
+
+ClassImp(AliDigitCluster)
+ClassImp(AliDifCluster)
--- /dev/null
+#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
--- /dev/null
+/**************************************************************************
+ * 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;i<nbins; i++) {
+ Float_t x = points->At(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; i<idim;i++)
+ for (Int_t j = 0; j<jdim;j++)
+ {
+ Int_t index = his2->GetBin(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; i<fDimX; i++)
+ for (Int_t j=0;j<fDimY; j++)
+ if (IsMaximum(i,j)) cout<<i<<" "<<j<<"\n";
+}
+
+
+void AliClusterFinder::Transform(AliDigitCluster * c)
+{
+ //transform coordinata from bin coordinata to "normal coordinata"
+ //for example if we initialize finder with histogram
+ //it transform values from bin coordinata to the histogram coordinata
+ c->fX=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; i<fStackIndex;i+=3){
+ Int_t x = fStack->At(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 (x<minx) minx=x;
+ if (y<miny) miny=y;
+ if (x>maxx) 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; i<fStackIndex;i+=3){
+ Int_t x = fStack->At(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 (x<minx) minx=x;
+ if (y<miny) miny=y;
+ if (x>maxx) 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<size;i++) dig[i] = 0;
+}
+
+
+
+void AliClusterFinder::ResetStatus()
+{
+ //reset status of signals to not used
+ Int_t size = fDimX*fDimY;
+ AliCell *dig=fDigits;
+ if (rOK==kTRUE) for (Int_t i=0 ; i<size;i++)
+ dig[i].SetStatus(0);
+}
+
+
+AliCell * AliClusterFinder::GetCell(Int_t i, Int_t j)
+{
+ //return reference to the cell with index i,j
+ if (rOK == kTRUE)
+ if ( (i>=0) && (i<fDimX) && (j>=0) && (j<fDimY) )
+ return &fDigits[i+j*fDimX];
+ return 0;
+}
+
+Float_t AliClusterFinder::GetVirtualSignal(Float_t ri, Float_t rj)
+{
+ //it generate virtual cell as mean value from different cels
+ //after using it must be destructed !!!
+ Int_t i=(Int_t)ri;
+ Int_t j=(Int_t)rj;
+ Int_t ddi = (ri>i)? 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])<TMath::Abs(index[1])){
+ index[4]=index[0];
+ index[5]=index[3];
+ }
+ else
+ if (index[0]==index[1]) {
+ index[4]=0;
+ index[5]=0;
+ }
+ else{
+ index[4]=index[2];
+ index[5]=index[1];
+ }
+ return;
+}
+
+//***********************************************************************
+//***********************************************************************
+
+TClonesArray * AliClusterFinder::FindPeaks1(TClonesArray *arr)
+{
+ //find peaks and write it in form of AliTPCcluster to array
+ TClonesArray * clusters;
+ if (arr==0) clusters=new TClonesArray("AliDigitCluster",300);
+ else clusters = arr;
+ fClustersArray = clusters;
+ AliDigitCluster c;
+ Int_t index = clusters->GetEntriesFast();
+ ResetStatus();
+
+ for (Int_t i=0; i<fDimX; i++)
+ for (Int_t j=0;j<fDimY; j++)
+ {
+ fStackIndex=0;
+ fBDistType = kFALSE;
+ AliCell * cell = GetCell(i,j);
+ if (!(cell->IsChecked())) 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="<<c.fX<<" fy"<<c.fY<<"\n";
+ }
+ }
+ return clusters;
+}
+
+
+TClonesArray * AliClusterFinder::FindPeaks2(TClonesArray *arr)
+{
+ //find peaks and write it in form of AliTPCcluster to array
+ TClonesArray * clusters;
+ if (arr==0) clusters=new TClonesArray("AliDigitCluster",300);
+ else clusters = arr;
+ fClustersArray = clusters;
+ AliDigitCluster c;
+ fIndex = clusters->GetEntriesFast();
+
+ ResetStatus();
+
+ for (Int_t i=0; i<fDimX; i++)
+ for (Int_t j=0;j<fDimY; j++)
+ {
+ fStackIndex=0;
+ if (IsMaximum(i,j) == kTRUE){
+ SetSigma2(i,j,fCurrentSigmaX2,fCurrentSigmaY2);
+ fBDistType = kTRUE;
+ 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[fIndex++]) AliDigitCluster(c);
+ // cout<<"fx="<<c.fX<<" fy"<<c.fY<<"\n";
+ }
+ }
+ }
+ return clusters;
+}
+
+
+TClonesArray * AliClusterFinder::FindPeaks3(TClonesArray *arr)
+{
+ //find peaks and write it in form of AliTPCcluster to array
+ TClonesArray * clusters;
+ if (arr==0) clusters=new TClonesArray("AliDigitCluster",300);
+ else clusters = arr;
+ fClustersArray = clusters;
+ AliDigitCluster c;
+ fIndex = clusters->GetEntriesFast();
+
+ ResetStatus();
+
+ Int_t dmax=5;
+ Int_t naccepted =1;
+ for (Int_t i=0; i<fDimX; i++)
+ for (Int_t j=0;j<fDimY; j++)
+ {
+ fStackIndex=0;
+ if (IsMaximum(i,j) == kTRUE){
+ SetSigma2(i,j,fCurrentSigmaX2,fCurrentSigmaY2);
+ AddToStack(i,j,GetCell(i,j)->GetSignal());
+
+ //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="<<c.fX<<" fy"<<c.fY<<"\n";
+ }
+ } //lopp over all digits
+
+ return clusters;
+}
+
+
+
+
+
+
+void AliClusterFinder::Adjacent(Int_t i,Int_t j)
+{
+ //
+ //recursive agorithm program
+ //
+ if (fBDistType==kTRUE) {
+ Float_t delta = (i-fCurrentMaxX)*(i-fCurrentMaxX)/fCurrentSigmaX2;
+ delta+=(j-fCurrentMaxY)*(j-fCurrentMaxY)/fCurrentSigmaY2;
+ if (delta > 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; i<fDimX;i++)
+ for (Int_t j = 0; j<fDimY;j++){
+ Float_t x = ItoX(i);
+ Float_t y= JtoY(j);
+ his->Fill(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;i<ncl;i++){
+ AliCluster *cl = (AliCluster*)fClustersArray->UncheckedAt(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; i<fDimX;i++)
+ for (Int_t j = 0; j<fDimY;j++){
+ Float_t x = ItoX(i);
+ Float_t y= JtoY(j);
+ if (((type==1)||(type==0))&&IsMaximum(0,i,j)) his->Fill(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;
+}
--- /dev/null
+#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 */
--- /dev/null
+/**************************************************************************
+ * 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 <TROOT.h>
+#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 (; b<e; m=(b+e)/2) {
+ cl = (AliCluster*)fClusters->UncheckedAt(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;i<ncl;i++){
+ AliCluster *cl = (AliCluster*)fClusters->UncheckedAt(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();
+ }
+}
+
--- /dev/null
+#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
--- /dev/null
+/**************************************************************************
+ * 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 <TROOT.h>
+#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;
+}
--- /dev/null
+#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
--- /dev/null
+/**************************************************************************
+ * 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<radius2)
+ angle[1]= TMath::ASin(radius1/radius2);
+ else
+ angle[1]=0;
+ return angle;
+}
+
+
+
+
+
+ClassImp(AliDetectorParam)
--- /dev/null
+#ifndef ALIDPARAM_H
+#define ALIDPARAM_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+
+////////////////////////////////////////////////
+// Manager class for detector parameters //
+////////////////////////////////////////////////
+
+
+
+// rootcint problems befor including AliDetectorParam.h you must include TObject.h
+
+#include <TNamed.h>
+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
--- /dev/null
+/**************************************************************************
+ * 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 <iostream.h>
+#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; i<fNcols;i++,k+=fNrows)
+ (*fIndex)[i]=k;
+ fBufType =0;
+}
+
+
+Short_t AliDigits::GetDigit(Int_t row, Int_t column)
+{
+ if (fBufType ==0) return GetDigitFast(row,column);
+ if (fBufType ==1) return GetDigit1(row,column);
+
+ return 0;
+}
+
+
+void AliDigits::ExpandBuffer()
+{
+ //
+ //expand buffer to two dimensional array
+ if (fBufType<0) {
+ Error("ExpandBuffer", "buffer doesn't exist");
+ return;
+ }
+ if (fBufType==0) return;
+
+ //expanding of buffer type 1
+ if (fBufType==1) ExpandBuffer1();
+
+ fBufType = 0;
+}
+
+void AliDigits::CompresBuffer(Int_t bufferType,Int_t threshold)
+{
+ //
+ //compres buffer according buffertype algorithm
+ if (fBufType<0) {
+ Error("CompressBuffer", "buffer doesn't exist");
+ return;
+ }
+ if (fBufType == bufferType) return;
+ //
+ if (fBufType>0) 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; i<idim;i++)
+ for (Int_t j = 0; j<jdim;j++)
+ {
+ Int_t index = his->GetBin(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; i<fNrows;i++)
+ for (Int_t j = 0; j<fNcols;j++)
+ his->Fill(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 ;i<fNcols;i++,k+=fNrows) (*fIndex)[i]=k;
+ Int_t col=0;
+ Int_t row = 0;
+ Int_t N=fElements->fN;
+ for (i=0;i<N;i++){
+ //oposite signa means how many unwrited (under threshold) values
+ if ((*fElements)[i]<0) row-=fElements->At(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; col<fNcols; col++){
+ index[col]=icurrent+1;//set collumn pointer
+ izero = 0; //reset zer counter at the begining of the column
+ for (Int_t row = 0; row< fNrows;row++){
+ //if under threshold
+ if (GetDigitFast(row,col)<=fThreshold) izero++;
+ else{
+ if (izero>0) {
+ //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; (( i<fNelems) && (fElements->At(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; ( (i<fNelems) && (fElements->At(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; i<fNelems; i++){
+ if (fElements->At(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; i<fNelems;i++){
+ if (fElements->At(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<fNelems) ) return kTRUE;
+ fCurrentRow =-1;
+ fCurrentCol =-1;
+ return kFALSE;
+}
+
+Short_t AliDigits::GetDigit1(Int_t row, Int_t column)
+{
+ //
+ //return digit for given row and column the buffer type 1
+ //no control performed
+
+ Int_t i,n2;
+ if ( (column+1)>=fNcols) n2 = fNelems;
+ else
+ n2 = fIndex->At(column+1);
+ Int_t irow = 0; //current row
+
+ for (i=fIndex->At(column); ( (i<n2) && (irow<row) );i++){
+ if (fElements->At(i) < 0) irow-=fElements->At(i);
+ else
+ irow++;
+ }
+ if ( irow == row ) return fElements->At(i);
+ return -1;
+}
+
--- /dev/null
+#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
+
--- /dev/null
+/**************************************************************************
+ * 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;
+}
--- /dev/null
+#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
--- /dev/null
+/**************************************************************************
+ * 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 ;i<dimx;i++)
+ for (Int_t j = 0 ;j<dimy;j++)
+ {
+ SetCellContent(i,j,0);
+ SetCellError(i,j,0);
+ }
+}
+
+
+void AliH2F::AddNoise(Float_t sn)
+{
+ 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 noise = gRandom->Gaus(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 ;i<dimx;i++)
+ for (Int_t j = 0 ;j<dimy;j++)
+ {
+ Float_t x2 =GetXaxis()->GetBinCenter(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 <threshold)
+ SetCellContent(i,j,0);
+ }
+}
+
+void AliH2F::Round()
+{
+ 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);
+ oldv=(Int_t)oldv;
+ SetCellContent(i,j,oldv);
+ }
+}
+
+
+
+AliH2F *AliH2F::GetSubrange2d(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+="_subrange";
+ t2+="_subrange";
+ const Text_t * tt1 = t1;
+ const Text_t * tt2 = t2;
+
+ AliH2F * sub = new AliH2F(tt1,tt2,nx,xmin,xmax,ny,ymin,ymax);
+
+ 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;i<nx;i++)
+ for (Int_t j=0;j<ny;j++)
+ {
+ Int_t index1 = GetBin(i1+i,i2+j);
+ // Int_t index2 = sub->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;i<nx;i++)
+ for (Int_t j=0;j<ny;j++)
+ {
+ Int_t index1 = GetBin(i1+i,i2+j);
+ Float_t val = GetBinContent(index1);
+ if (val>th) 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;i<nx;i++)
+ for (Int_t j=0;j<ny;j++)
+ {
+ Int_t index1 = GetBin(i1+i,i2+j);
+ Float_t val = GetBinContent(index1);
+ if (val>th) 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;
+}
--- /dev/null
+#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 */
--- /dev/null
+/**************************************************************************
+ * 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 <TROOT.h>
+#include <TTree.h>
+#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; i<nevent; i++){
+ brindix->GetEvent(i);
+ Int_t treeIndex=segment.GetID();
+ if (fTreeIndex->fN<treeIndex) fTreeIndex->Expand(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<<ptreeName;
+ fTree->Write();
+ }
+}
--- /dev/null
+#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
--- /dev/null
+/**************************************************************************
+ * 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)
--- /dev/null
+#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
+
--- /dev/null
+/**************************************************************************
+ * 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 <iostream.h>
+#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;(i<n2);i++){
+ ID = 0;
+ Int_t num = fTracks->At(i);
+ if (num<0) {
+ rownew-=num;
+ rowold = rownew;
+ i++;
+ if (i<n2){
+ num = fTracks->At(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;i<N;i++){
+ //oposite signa means how many unwrited (under threshold) values
+ Int_t num = fTracks->At(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<num; j++,row++) (*buf)[level*all+col*fNrows+row]=ID;
+ }
+ if (row>=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<fNlevel; lev++){ //loop over levels
+ for (Int_t col = 0; col<fNcols; col++){ //loop over columns
+ izero = 0;
+ inum = 0;
+ lastID = 0;
+ (*index)[lev*fNcols+col]=icurrent+1;//set collumn pointer
+ Int_t ID; //current ID
+ for (Int_t row = 0; row< fNrows;row++){ //loop over rows
+ ID = GetTrackIDFast(row,col,lev);
+ if (ID <= 0) {
+ 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] = 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; i<fNrows;i++)
+ for (Int_t j = 0; j<fNcols;j++)
+ his->Fill(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; row<fNrows; row++)
+ for (Int_t col =0; col<fNcols; col++){
+ Int_t amp = GetDigit(row,col);
+ if (amp>GetThreshold()){
+ 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;
+}
+
--- /dev/null
+#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
/*
$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
#include <fstream.h>
#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"
fNsectors = 0;
fNtracks = 0;
fNclusters= 0;
-
- fDigParam= new AliTPCD();
- fDigits = fDigParam->GetArray();
+ //MI changes
+ fDigitsArray = 0;
+ fClustersArray = 0;
+ fTPCParam = 0;
}
//_____________________________________________________________________________
//
// 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;
//
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;
}
//_____________________________________________________________________________
//
// 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)
{
//_____________________________________________________________________________
void AliTPC::BuildGeometry()
{
+
//
// Build TPC ROOT TNode geometry for the event display
//
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();
// inner sectors
- rl = fTPCParam->GetInSecLowEdge();
- ru = fTPCParam->GetInSecUpEdge();
+ rl = fTPCParam->GetInnerRadiusLow();
+ ru = fTPCParam->GetInnerRadiusUp();
for(i=0;i<nLo;i++) {
// Outer sectors
- rl = fTPCParam->GetOuSecLowEdge();
- ru = fTPCParam->GetOuSecUpEdge();
+ rl = fTPCParam->GetOuterRadiusLow();
+ ru = fTPCParam->GetOuterRadiusUp();
for(i=0;i<nHi;i++) {
sprintf(name,"US%2.2d",i);
Node->SetLineColor(kColorTPC);
fNodes->Add(Node);
}
+
+
}
}
//_____________________________________________________________________________
-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;
}
if (row) {
- for (int i=row.Find(y-road); i<row; i++) {
+ for (Int_t i=row.Find(y-road); i<row; i++) {
AliTPCcluster* c=(AliTPCcluster*)(row[i]);
if (c->fY > y+road) break;
if (c->IsUsed()) continue;
}
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;
}
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.
// 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; ns<max_sec; ns++) {
- int nl=sec[(ns-1+max_sec)%max_sec][i2];
- int nm=sec[ns][i2];
- int nu=sec[(ns+1)%max_sec][i2];
+ Double_t alpha=sec->GetAlpha(), shift=sec->GetAlphaShift();
+ Double_t cs=cos(alpha), sn=sin(alpha);
+ for (Int_t ns=0; ns<max_sec; ns++) {
+ Int_t nl=sec[(ns-1+max_sec)%max_sec][i2];
+ Int_t nm=sec[ns][i2];
+ Int_t nu=sec[(ns+1)%max_sec][i2];
const AliTPCRow& r1=sec[ns][i1];
- for (int is=0; is < r1; is++) {
- double x1=sec->GetX(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 (js<nl) {
ks=(ns-1+max_sec)%max_sec;
y2 =x2*sn+y2*cs; x2=tmp;
}
- double d=(x2-x1)*(0.-y2)-(0.-x2)*(y2-y1);
+ Double_t zz=z1 - z1/x1*(x1-x2);
+ if (TMath::Abs(zz-z2)>5) 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;
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;
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);
}
//-----------------------------------------------------------------
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<nis*2) {
ssec[sec%nis][row].InsertCluster(c);
} else {
TObjArray seeds(20000);
- int nrows=nrow_low+nrow_up;
- int gap=int(0.125*nrows), shift=int(0.5*gap);
+ Int_t nrows=nrow_low+nrow_up;
+ Int_t gap=Int_t(0.125*nrows), shift=Int_t(0.5*gap);
MakeSeeds(seeds, lsec, nos, nrow_up-1, nrow_up-1-gap);
MakeSeeds(seeds, lsec, nos, nrow_up-1-shift, nrow_up-1-shift-gap);
seeds.Sort();
-
- int found=0;
- int nseed=seeds.GetEntriesFast();
-
- for (int s=0; s<nseed; s++) {
- AliTPCtrack& t=*((AliTPCtrack*)seeds.UncheckedAt(s));
- double alpha=t.GetAlpha();
+
+ Int_t found=0;
+ Int_t nseed=seeds.GetEntriesFast();
+
+ for (Int_t s=0; s<nseed; s++) {
+ AliTPCtrack *pt=(AliTPCtrack*)seeds.UncheckedAt(s), &t=*pt;
+ Double_t alpha=t.GetAlpha();
if (alpha > 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<<found++<<'\r';
+ if (t >= Int_t(0.4*nrows)) {
+ AddTrack(t);
+ t.UseClusters();
+ cerr<<found++<<'\r';
+ }
+ delete pt;
}
delete[] ssec;
delete[] lsec;
+
}
//_____________________________________________________________________________
AliMedium(12,"CO2",10,0, ISXFLD, SXMGMX, 10., 999.,.1, .001, .001);
-
-
}
//_____________________________________________________________________________
struct Bin {
- const AliTPCdigit *dig;
- int idx;
- Bin() {dig=0; idx=-1;}
+ UShort_t q;
+ UInt_t mask;
+ Bin();
};
+Bin::Bin() {q=0; mask=0xFFFFFFFE;}
-struct PreCluster : public AliTPCcluster {
- const AliTPCdigit* summit; //pointer to the maximum digit of this precluster
- int idx; //index in AliTPC::fClusters
- int npeaks; //number of peaks in this precluster
- int ndigits; //number of digits in this precluster
- PreCluster();
+struct Peak {
+ Int_t k;
+ UInt_t mask;
};
-PreCluster::PreCluster() : AliTPCcluster() {npeaks=ndigits=0;}
+inline Bool_t IsMaximum(Int_t k, Int_t max, const Bin *bins) {
+ UShort_t q=bins[k].q;
+ if (q==1023) return kFALSE;
+ if (bins[k-max].q > 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<<n);
+ n++;
+ }
+ bins[k].mask=0;
+ if (bins[k-max].mask&1) FindPeaks(k-max,max,bins,peaks,n);
+ if (bins[k-1 ].mask&1) FindPeaks(k-1 ,max,bins,peaks,n);
+ if (bins[k+max].mask&1) FindPeaks(k+max,max,bins,peaks,n);
+ if (bins[k+1 ].mask&1) FindPeaks(k+1 ,max,bins,peaks,n);
+}
-//_____________________________________________________________________________
-static void FindPreCluster(int i,int j,int maxj,Bin *bins,PreCluster &c)
-{
- //-----------------------------------------------------------------
- // This function looks for "preclusters".
- //
- // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
- //-----------------------------------------------------------------
- Bin& b=bins[i*maxj+j];
- double q=(double)TMath::Abs(b.dig->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);
}
//_____________________________________________________________________________
//
// 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; n<sectors_by_rows; n++) {
- if (!t->GetEvent(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 ! "<<digarr.GetID()<<endl;
+ continue;
+ }
+
+ Float_t rx=par->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;
}
}
- int ndig;
- for (ndig=0; ndig<ndigits; ndig++) {
- dig=(AliTPCdigit*)fDigits->UncheckedAt(ndig);
- int i=dig->fPad+1, j=dig->fTime+1;
- if (i > npads) {
- cerr<<"AliTPC::Digits2Clusters error: pad number is out of range ! ";
- cerr<<i<<' '<<npads<<endl;
- continue;
- }
- if (j > MAXTBKT) {
- cerr<<"AliTPC::Digits2Clusters error: time bucket is out of range ! ";
- cerr<<j<<' '<<MAXTBKT<<endl;
- continue;
+ const Int_t MAXBIN=MAXZ*(npads+2);
+ Bin *bins=new Bin[MAXBIN];
+
+ digarr.First();
+ do {
+ Short_t dig=digarr.CurrentDigit();
+ if (dig<=par->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; i<MAXBIN; i++) {
+ if ((bins[i].mask&1) == 0) continue;
+ Peak peaks[32]; Int_t npeaks=0;
+ FindPeaks(i, MAXZ, bins, peaks, npeaks);
+
+ if (npeaks>30) continue;
+
+ Int_t k,l;
+ for (k=0; k<npeaks-1; k++){//mark adjacent peaks
+ if (peaks[k].k < 0) continue; //this peak is already removed
+ for (l=k+1; l<npeaks; l++) {
+ if (peaks[l].k < 0) continue; //this peak is already removed
+ Int_t ki=peaks[k].k/MAXZ, kj=peaks[k].k - ki*MAXZ;
+ Int_t li=peaks[l].k/MAXZ, lj=peaks[l].k - li*MAXZ;
+ Int_t di=TMath::Abs(ki - li);
+ Int_t dj=TMath::Abs(kj - lj);
+ if (di>1 || 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; i<MAXY-1; i++) {
- for (j=1; j<MAXZ-1; j++) {
- if (bins[i*MAXZ+j].dig == 0) continue;
- PreCluster c; c.summit=bins[i*MAXZ+j].dig; c.idx=ncls;
- FindPreCluster(i, j, MAXZ, bins, c);
- 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.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; k<npeaks; k++) {
+ MarkPeak(TMath::Abs(peaks[k].k), MAXZ, bins, peaks[k].mask);
}
- }
- for (ndig=0; ndig<ndigits; ndig++) {
- dig=(AliTPCdigit*)fDigits->UncheckedAt(ndig);
- int i=dig->fPad+1, j=dig->fTime+1;
- if (i > npads) {
- cerr<<"AliTPC::Digits2Clusters error: pad number is out of range ! ";
- cerr<<i<<' '<<npads<<endl;
- continue;
- }
- if (j > MAXTBKT) {
- cerr<<"AliTPC::Digits2Clusters error: time bucket is out of range ! ";
- cerr<<j<<' '<<MAXTBKT<<endl;
- continue;
+ for (k=0; k<npeaks; k++) {
+ if (peaks[k].k < 0) continue; //removed peak
+ AliTPCcluster c;
+ MakeCluster(peaks[k].k, MAXZ, bins, peaks[k].mask, c);
+ if (c.fQ < 5) continue; //noise cluster
+ c.fY /= c.fQ;
+ c.fZ /= c.fQ;
+
+ Double_t s2 = c.fSigmaY2/c.fQ - c.fY*c.fY;
+ c.fSigmaY2 = s2 + 1./12.;
+ c.fSigmaY2 *= par->GetPadPitchWidth(sec)*par->GetPadPitchWidth(sec);
+ if (s2 != 0.) {
+ c.fSigmaY2 *= 0.064*1.3*1.3;
+ if (sec<par->GetNInnerSector()) 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 (sec<par->GetNInnerSector()) 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; i<MAXY-1; i++) {
- for (j=1; j<MAXZ-1; j++) {
- if (bins[i*MAXZ+j].dig == 0) continue;
- PreCluster c; c.summit=bins[i*MAXZ+j].dig; c.idx=ncls;
- FindPreCluster(i, j, MAXZ, bins, c);
- if (c.ndigits < 2) continue; //noise cluster
- if (c.npeaks>1) 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: "
- <<sec<<' '<<row<<' '<<ndigits<<' '<<ncl<<" \r";
-
- fDigits->Clear();
-
+ cerr<<"sector, row, compressed digits, clusters: "
+ <<sec<<' '<<row<<' '<<digarr.GetSize()<<' '<<ncl<<" \r";
+
delete[] bins;
}
}
-//_____________________________________________________________________________
-void AliTPC::ElDiff(Float_t *xyz)
-{
- //--------------------------------------------------
- // calculates the diffusion of a single electron
- //--------------------------------------------------
-
- //-----------------------------------------------------------------
- // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
- //-----------------------------------------------------------------
- AliTPCParam * fTPCParam = &(fDigParam->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()
{
// 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
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; isec<Nsectors; isec++){
+
+ for(Int_t isec=0;isec<fTPCParam->GetNSector();isec++){
//MI change
- fTPCParam->AdjustAngles(isec,cph,sph);
+ fTPCParam->AdjustCosSin(isec,cph,sph);
//------------------------------------------------------------
// Loop over tracks
// to the particles
//
nhits=fHits->GetEntriesFast();
+ Particles=gAlice->Particles();
//
// Loop over hits
//
for(Int_t hit=0;hit<nhits;hit++){
tpcHit=(AliTPChit*)fHits->UncheckedAt(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;
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; i<fTPCParam->GetNRow(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;track<ntracks;track++){
+ ResetHits();
+ TH->GetEvent(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;hit<nhits;hit++){
+ tpcHit=(AliTPChit*)fHits->UncheckedAt(hit);
+ if (tpcHit==0) continue;
+ sector=tpcHit->fSector; // sector number
+ if(sector != isec) continue;
+ ipart=tpcHit->fTrack;
+ if (ipart<npart) particle=(TParticle*)Particles->UncheckedAt(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;index<currentIndex;index++){
+ Float_t x,x2,x3,x4;
+ x=x2=x3=x4=xxx(index*4);
+ x2*=x;
+ x3*=x2;
+ x4*=x3;
+ sumx+=x;
+ sumx2+=x2;
+ sumx3+=x3;
+ sumx4+=x4;
+ sumy+=xxx(index*4+1);
+ sumxy+=xxx(index*4+1)*x;
+ sumx2y+=xxx(index*4+1)*x2;
+ sumz+=xxx(index*4+2);
+ sumxz+=xxx(index*4+2)*x;
+ sumx2z+=xxx(index*4+2)*x2;
+ sumq+=xxx(index*4+3);
+ }
+ Float_t CentralPad = (fTPCParam->GetNPads(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; ii<fTPCParam->GetNRow(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;isec<Nsectors;isec++) Hits2DigitsSector(isec);
+ // Loop over all sectors
+ //----------------------------------------------------
+
+ if(fTPCParam == 0){
+ printf("AliTPCParam MUST be created firstly\n");
+ return;
+ }
+
+ for(Int_t isec=0;isec<fTPCParam->GetNSector();isec++) Hits2DigitsSector(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();
// 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);
Int_t i;
- for (i=0;i<nrows;i++){
-
- // Triplets for i = 0 and i=1 are identical!
- // The same for i = nrows-1 and nrows!
+ if (fDigitsArray->GetTree()==0) fDigitsArray->MakeTree();
- if(i != 1 && i != nrows-1){
- MakeTriplet(i,rowTriplet,row);
- }
+ for (i=0;i<nrows;i++){
- DigitizeRow(i,isec,rowTriplet);
+ AliDigits * dig = fDigitsArray->CreateRow(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;i<nrows;i++){
+ row[i]->Delete();
+ }
+
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;i2<nt;i2++){
- pv = (TVector*)prow[i1]->At(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;nel<nElectrons;nel++){
- Int_t idx1 = nel*3;
- Int_t idx2 = nel*4;
- // Avalanche, including fluctuations
- Int_t aval = (Int_t) (-gasgain*TMath::Log(gRandom->Rndm()));
- 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;i1<nTracks[0];i1++){
- pv=(TVector*)rowTriplet[1]->At(i1);
- rowTriplet[0]->Add(pv);
- }
-
- rowTriplet[1]->Clear(); // leave tracks on the heap!!!
-
- for(i1=0;i1<nTracks[1];i1++){
- pv=(TVector*)rowTriplet[2]->At(i1);
- rowTriplet[1]->Add(pv);
- }
-
- rowTriplet[2]->Clear(); // leave tracks on the heap!!!
-
- //---------------------------------------------
- // Create new upper row
- //---------------------------------------------
-
-
-
- for(i1=0;i1<nTracks[2];i1++){
- pv = (TVector*)prow[row+1]->At(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;nel<nElectrons;nel++){
-
- Int_t idx1 = nel*3;
- Int_t idx2 = nel*4;
- // Avalanche, including fluctuations
- Int_t aval = (Int_t)
- (-gasgain*TMath::Log(gRandom->Rndm()));
-
- 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
//-----------------------------------------------------------------
// 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;lp<NofDigits;lp++)pList[lp]=0; // set all pointers to NULL
-
//
- // Straight signal and cross-talk, cross-talk is integrated over all
- // tracks and added to the signal at the very end
- //
-
-
- for (i1=0;i1<nTracks[iFlag];i1++){
-
- m2->Zero(); // 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;i1<nTracks;i1++){
+ fCurrentIndex[2]= row;
+ fCurrentIndex[3]=irow;
+ if (row==irow){
+ m2->Zero(); // 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;ip<n_of_pads[iFlag];ip++){
- for(Int_t it=0;it<MAXTBKT;it++){
+ AliDigits *dig = fDigitsArray->GetRow(isec,irow);
+ for(Int_t ip=0;ip<n_of_pads;ip++){
+ for(Int_t it=0;it<n_of_tbins;it++){
Float_t q = Total(ip,it);
- Int_t gi =it*n_of_pads[iFlag]+ip; // global index
+ Int_t gi =it*n_of_pads+ip; // global index
- q = gRandom->Gaus(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 <zerosup) continue; // do not fill zeros
+ q = (Int_t)q;
+
+ if(q <=zerosup) continue; // do not fill zeros
if(q > adc_sat) q = adc_sat; // saturation
//
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
+/*
+ <A NAME="AliDigits"></A>
+ 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
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)
{
//-----------------------------------------------------------------
// 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; nel<nElectrons; nel++){
- Int_t idx=nel*4;
- Float_t xwire = v(idx+1);
- 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 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 = (absy<range-0.5) ? v(idx+4):v(idx+4)*IneffFactor;
-
-
- Float_t dist = y - (Float_t)(PadNumber-CentralPad)*fTPCParam->GetPadPitchWidth();
- 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; i<n; i++){
+ Int_t *index = fTPCParam->GetResBin(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
}
// 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!
-
}//end of GetList
//___________________________________________________________________
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
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
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){
for(i=0;i<nrows;i++){
if(previousTrack != -1){
if(n_of_electrons[i]>0){
- 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
// 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!
//-----------------------------------------------
// Loop over electrons
//-----------------------------------------------
-
+ Int_t index[3];
+ index[1]=isec;
for(Int_t nel=0;nel<QI;nel++){
// skip if electron lost due to the attachment
if((gRandom->Rndm(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
for(i=0;i<nrows;i++){
if(n_of_electrons[i]>0){
- 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;nt<ntracks;nt++){
- tv=(TVector*)p->At(nt); // pointer to a track
- TVector &v = *tv;
- Int_t nElectrons = (tv->GetNrows()-1)/4;
- // Loop over electrons
- for(Int_t nel=0; nel<nElectrons; nel++){
- Int_t idx=nel*4;
- xwire=v(idx+1);
-
- if (iFlag==0) xwire+=fTPCParam->GetPadPitchLength();
- 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 = (absy<range-0.5) ? v(idx+4):v(idx+4)*IneffFactor;
-
- Float_t dist = y - (Float_t)(PadNumber-CentralPad)*fTPCParam->GetPadPitchWidth();
-
- 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<pmax+1;i3++){
- Int_t TruePad = LeftPad+i3-pmin;
-
- if(TruePad<nPadsDiff || TruePad > 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
//_____________________________________________________________________________
// 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();
}
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)
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);
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;
}
//_____________________________________________________________________________
//
fX=hits[0]; // This is dummy code !
}
+//_________________________________________________________________________
AliTPCtrack::AliTPCtrack(const AliTPCcluster *c,const TVector& xx,
const TMatrix& CC, Double_t xref, Double_t alpha):
fX=t.fX;
fChi2=t.fChi2;
fAlpha=t.fAlpha;
- int n=t.fClusters.GetEntriesFast();
- for (int i=0; i<n; i++) fClusters.AddLast(t.fClusters.UncheckedAt(i));
+ Int_t n=t.fClusters.GetEntriesFast();
+ for (Int_t i=0; i<n; i++) fClusters.AddLast(t.fClusters.UncheckedAt(i));
}
//_____________________________________________________________________________
Int_t AliTPCtrack::Compare(TObject *o) {
//-----------------------------------------------------------------
- // This function compares tracks according to their curvature.
- //
+ // This function compares tracks according to the uncertainty of their
+ // position in Y.
// Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
//-----------------------------------------------------------------
AliTPCtrack *t=(AliTPCtrack*)o;
}
//_____________________________________________________________________________
-int AliTPCtrack::PropagateTo(Double_t xk,Double_t x0,Double_t rho,Double_t pm)
+Int_t AliTPCtrack::PropagateTo(Double_t xk,Double_t x0,Double_t rho,Double_t pm)
{
//-----------------------------------------------------------------
// This function propagates a track to a reference plane x=xk.
return 0;
}
- Double_t x1=fX, x2=x1+0.5*(xk-x1), dx=x2-x1, y1=x(0), z1=x(1);
+ 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);
F(1,4)= dx*cc/cr;
TMatrix tmp(F,TMatrix::kMult,C);
C.Mult(tmp,TMatrix(TMatrix::kTransposed,F));
-
+
fX=x2;
-
+
//Multiple scattering******************
Double_t ey=x(2)*fX - x(3);
Double_t ex=sqrt(1-ey*ey);
Double_t p2=GetPt()*GetPt()*(1.+x(4)*x(4));
Double_t beta2=p2/(p2 + pm*pm);
Double_t d=sqrt((x1-fX)*(x1-fX)+(y1-x(0))*(y1-x(0))+(z1-x(1))*(z1-x(1)));
- d*=2.;
Double_t theta2=14.1*14.1/(beta2*p2*1e6)*d/x0*rho;
Q*=theta2;
C+=Q;
-
+
//Energy losses************************
Double_t dE=0.153e-3/beta2*(log(5940*beta2/(1-beta2)) - beta2)*d*rho;
if (x1 < x2) dE=-dE;
x(2)*=(1.- sqrt(p2+pm*pm)/p2*dE);
//x(3)*=(1.- sqrt(p2+pm*pm)/p2*dE);
-
- x1=fX; x2=xk; y1=x(0); z1=x(1);
- c1=x(2)*x1 - x(3); r1=sqrt(1.- c1*c1);
- 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);
-
- F.UnitMatrix();
- rr=r1+r2; cc=c1+c2; xx=x1+x2;
- F(0,2)= dx*(rr*xx + cc*(c1*x1/r1+c2*x2/r2))/(rr*rr);
- F(0,3)=-dx*(2*rr + cc*(c1/r1 + c2/r2))/(rr*rr);
- cr=c1*r2+c2*r1;
- F(1,2)= dx*x(4)*(cr*xx-cc*(r1*x2-c2*c1*x1/r1+r2*x1-c1*c2*x2/r2))/(cr*cr);
- F(1,3)=-dx*x(4)*(2*cr + cc*(c2*c1/r1-r1 + c1*c2/r2-r2))/(cr*cr);
- F(1,4)= dx*cc/cr;
- tmp.Mult(F,C);
- C.Mult(tmp,TMatrix(TMatrix::kTransposed,F));
-
- fX=x2;
-
+
return 1;
}
TMatrix K(C,TMatrix::kMult,Ht); K*=R;
TVector savex=x;
- x*=H; x-=m; x*=-1; x*=K; x+=savex;
+ x*=H; x-=m;
+
+ x*=-1; x*=K; x+=savex;
if (TMath::Abs(x(2)*fX-x(3)) >= 0.999) {
if (*this>4) cerr<<*this<<" AliTPCtrack warning: Filtering failed !\n";
x=savex;
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.
//
// Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
//-----------------------------------------------------------------
- int num_of_clusters=fClusters.GetEntriesFast();
- for (int i=0; i<num_of_clusters; i++) {
+ Int_t num_of_clusters=fClusters.GetEntriesFast();
+ for (Int_t i=0; i<num_of_clusters; i++) {
//if (i<=14) continue;
AliTPCcluster *c=(AliTPCcluster*)fClusters.UncheckedAt(i);
c->Use();
}
//_____________________________________________________________________________
-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; i<num_of_clusters; i++) s[i].lab=s[i].max=0;
- int lab=123456789;
+ Int_t lab=123456789;
for (i=0; i<num_of_clusters; i++) {
AliTPCcluster *c=(AliTPCcluster*)fClusters.UncheckedAt(i);
lab=TMath::Abs(c->fTracks[0]);
- int j;
+ Int_t j;
for (j=0; j<num_of_clusters; j++)
if (s[j].lab==lab || s[j].max==0) break;
s[j].lab=lab;
s[j].max++;
}
- int max=0;
+ Int_t max=0;
for (i=0; i<num_of_clusters; i++)
if (s[i].max>max) {max=s[i].max; lab=s[i].lab;}
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;
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;
}
//
// 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; i<ncl; i++) {
+ Int_t i;
+ for (i=1; i<ncl; i++) { //Shall I think of this "i=1" ? (I.Belikov)
AliTPCcluster *cl=(AliTPCcluster*)(fClusters.UncheckedAt(i));
- // if (cl->fdEdX > 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; i<n-1; i++) {
}
} while (swap);
- int nl=int(low*n), nu=int(up *n);
+ Int_t nl=Int_t(low*n), nu=Int_t(up *n);
Double_t dedx=0.;
for (i=nl; i<=nu; i++) dedx += q[i];
dedx /= (nu-nl+1);
cerr<<"AliTPCRow::InsertCluster(): Too many clusters !\n"; return;
}
if (num_of_clusters==0) {clusters[num_of_clusters++]=c; return;}
- int i=Find(c->fY);
+ 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
//
//-----------------------------------------------------------------------
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<e; m=(b+e)/2) {
if (y > clusters[m]->fY) b=m+1;
else e=m;
}
return m;
}
+//________________________________________________________________________
////////////////////////////////////////////////
// Manager class for TPC //
////////////////////////////////////////////////
-
#include "AliDetector.h"
#include "AliHit.h"
#include "AliDigit.h"
-#include "AliTPCSecGeo.h"
#include "AliTPCParam.h"
#include <TMatrix.h>
#include <TTree.h>
class AliTPCcluster;
class AliTPCtrack;
class AliTPCParam;
-//MI changes
-class AliTPCD;
+
+class AliTPCDigitsArray;
+class AliTPCClustersArray;
class AliTPC : public AliDetector {
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
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&);
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
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();
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);
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
};
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
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) ;
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 ;
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
};
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 {
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 {
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);
}
};
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);
}
};
--- /dev/null
+/**************************************************************************
+ * 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 (; b<e; m=(b+e)/2) {
+ cl = (AliTPCcluster*)fClusters->UncheckedAt(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());
+}
--- /dev/null
+#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 <TMatrix.h>
+#include <TTree.h>
+#include <TClonesArray.h>
+
+
+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
+
--- /dev/null
+/**************************************************************************
+ * 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;
+}
--- /dev/null
+#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 <TMatrix.h>
+#include <TTree.h>
+#include <TClonesArray.h>
+#include <TClass.h>
+
+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
--- /dev/null
+/**************************************************************************
+ * 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);
+//}
+
--- /dev/null
+#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 <TClonesArray.h>
+
+
+class TClonesArray;
+class TObjArray;
+
+
+class AliTPCClustersRow : public AliClusters{
+public:
+ AliTPCClustersRow();
+
+public:
+
+ ClassDef(AliTPCClustersRow,1)
+};
+#endif //ALITPCCLUSTERROW_H
+++ /dev/null
-/**************************************************************************
- * 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 <TMath.h>
-#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
-/*
-<img src="picts/alitpcd.gif">
-*/
-//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 <<fParam;
- R__b <<fPRF;
- R__b <<fRF;
- if (fTreeD!=0) fTreeD->Write();
- }
-}
+++ /dev/null
-#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 */
--- /dev/null
+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; i<t->GetEntries(); 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<<lab0<<' '<<lab1<<' '<<lab2<<endl;
+ }
+ h->Fill(i,j,dig);
+ } while (digit->Next());
+ if (qmax>0) {cerr<<"Peak (time,pad,q) : "<<imax<<' '<<jmax<<' '<<qmax<<endl;}
+
+ h->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");
+}
+
--- /dev/null
+/**************************************************************************
+ * 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());
+}
--- /dev/null
+#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 <TMatrix.h>
+#include <TTree.h>
+#include <TClonesArray.h>
+
+
+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
+++ /dev/null
-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; n<sectors_by_rows; n++) {
- if (!t->GetEvent(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; ndig<ndigits; ndig++) {
- dig=(AliTPCdigit*)fDigits->UncheckedAt(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");
- }
-}
-
--- /dev/null
+/**************************************************************************
+ * 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 <iostream.h>
+#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
+/*
+<img src="gif/TPCDigitsH.gif">
+*/
+//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; n<sectors_by_rows; n++)
+ {
+ if (!ftree->GetEvent(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; ndig<ndigits; ndig++)
+ {
+ Float_t x,y;
+ dig=(AliTPCdigit*)fDigits->UncheckedAt(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;i<size1;i++)
+ {
+ Int_t mul=Int_t(fHParticles->GetBinContent(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; n<sectors_by_rows; n++) {
+ if (!ftree->GetEvent(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; ndig<ndigits; ndig++) {
+ dig=(AliTPCdigit*)fDigits->UncheckedAt(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;i<fTimeN;i++)
+ {
+ Int_t index = fH2Digit->GetBin(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;i<fOccuN;i++)
+ {
+ Int_t over =0;
+ Int_t all =0;
+ for (int itime = i*(fTimeN/fOccuN); itime<(i+1)*(fTimeN/fOccuN);itime++)
+ {
+ for (Int_t ipad = 0; ipad < n_of_pads; ipad++)
+ {
+ Int_t index = fH2Digit->GetBin(itime,ipad);
+ if ( (ipad>3) && ((ipad+3)<n_of_pads)){
+ all++;
+ if (fH2Digit->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());
+ }
+}
--- /dev/null
+#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 */
-
void AliTPCHits2Digits(const char * name= "pokusD_")
{
}
//names of trees
+
const char * inFile = "galice.root";
// const * char ident= "TreeD1par_";
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);
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
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();
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();
/*
$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 //
// Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk //
// //
///////////////////////////////////////////////////////////////////////////////
+
+
#include "TMath.h"
#include "AliTPCPRF2D.h"
#include "TF2.h"
#include "TH2.h"
#include "TPaveText.h"
#include "TText.h"
+//
extern TStyle * gStyle;
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])));
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.);
return res;
}
-
-///////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
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()
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;
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);
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
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");
}
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);
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);
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");
}
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);
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");
}
void AliTPCPRF2D::Update()
{
- for (Int_t i=0; i<fNYdiv; i++){
- if (fNYdiv == 1) fActualY = fY1;
+ //
+ //update fields with interpolated values for
+ //PRF calculation
+
+ if ( fGRF == 0 ) return;
+ //initialize interpolated values to 0
+ Int_t i;
+ //Float_t x;
+ for (i =0; i<fNPRF*fNYdiv;i++) ffcharge[i] = 0;
+ //firstly calculate total integral of charge
+
+ ////////////////////////////////////////////////////////
+ //I'm waiting for normal integral
+ //in this moment only sum
+ Float_t x2= 4*fOrigSigmaX;
+ Float_t y2= 4*fOrigSigmaY;
+ Float_t dx = fOrigSigmaX/Float_t(fNdiv*6);
+ Float_t dy = fOrigSigmaY/Float_t(fNdiv*6);
+ Int_t nx = Int_t(0.5+x2/dx);
+ Int_t ny = Int_t(0.5+y2/dy);
+ Int_t ix,iy;
+ fInteg = 0;
+ Double_t dInteg =0;
+ for (ix=-nx;ix<=nx;ix++)
+ for ( iy=-ny;iy<=ny;iy++)
+ dInteg+=fGRF->Eval(Float_t(ix)*dx,Float_t(iy)*dy)*dx*dy;
+ /////////////////////////////////////////////////////
+ fInteg =dInteg;
+ if ( fInteg == 0 ) fInteg = 1;
+
+ for (i=0; i<fNYdiv; i++){
+ if (fNYdiv == 1) fCurrentY = fY1;
else
- fActualY = fY1+Float_t(i)*(fY2-fY1)/Float_t(fNYdiv-1);
+ fCurrentY = fY1+Double_t(i)*(fY2-fY1)/Double_t(fNYdiv-1);
fcharge = &(ffcharge[i*fNPRF]);
Update1();
}
+ //calculate conversion coefitient to convert position to virtual wire
+ fDYtoWire=Float_t(fNYdiv-1)/(fY2-fY1);
+ fDStepM1=1/fDStep;
+ UpdateSigma();
}
void AliTPCPRF2D::Update1()
{
- //initialize to 0
-
-
+ //
+ //update fields with interpolated values for
+ //PRF calculation for given charge line
Int_t i;
- Float_t x;
- for (i =0; i<fNPRF;i++) fcharge[i] = 0;
- if ( fGRF == 0 ) return;
- ////////////////////////////////////////////////////////
- //I'm waiting for normal integral
- //in this moment only sum
- Float_t x2= 4*forigsigmaX;
- Float_t y2= 4*forigsigmaY;
- Float_t dx = forigsigmaX/Float_t(fNdiv*6);
- Float_t dy = forigsigmaY/Float_t(fNdiv*6);
- fInteg = 0;
- for (x=0.;x<x2;x+=dx)
- for (Float_t y=0;y<y2;y+=dy) fInteg+=fGRF->Eval(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; i<fNPRF;i++)
- { //x in cm fWidth in cm
+ {
+ //x in cm fWidth in cm
//calculate integral
- Float_t xch = fDStep * (Float_t)(i-fNPRF/2);
- Float_t k=1;
+ Double_t xch = fDStep * (Double_t)(i-fNPRF/2);
+ Double_t k=1;
fcharge[i]=0;
- for (Float_t y=-fHeightFull/2.-fShiftY;
+
+ for (Double_t y=-fHeightFull/2.-fShiftY; //loop over chevron steps
y<fHeightFull/2.;y+=fHeightS){
- Float_t y2=TMath::Min((y+fHeightS),Float_t(fHeightFull/2.));
- Float_t y1=TMath::Max((y),Float_t(-fHeightFull/2.));
- Float_t x1;
+ Double_t y2=TMath::Min((y+fHeightS),Double_t(fHeightFull/2.));
+ Double_t y1=TMath::Max((y),Double_t(-fHeightFull/2.));
+ Double_t x1;
if (k>0)
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<forigsigmaX) dx=(x2-x1);
+ if ((x2-x1)*fNdiv<fOrigSigmaX) dx=(x2-x1);
else{
- dx= forigsigmaX/Float_t(fNdiv);
- dx = (x2-x1)/Float_t(Int_t(3+(x2-x1)/dx));
+ dx= fOrigSigmaX/Double_t(fNdiv);
+ dx = (x2-x1)/Double_t(Int_t(3.5+(x2-x1)/dx));
}
- Float_t dy;
- if ((y2-y1)*fNdiv<forigsigmaY) dy=(y2-y1);
+ Double_t dy;
+ if ((y2-y1)*fNdiv<fOrigSigmaY) dy=(y2-y1);
else{
- dy= forigsigmaY/Float_t(fNdiv);
- dy = (y2-y1)/Float_t(Int_t(3+(y2-y1)/dy));
+ dy= fOrigSigmaY/Double_t(fNdiv);
+ dy = (y2-y1)/Double_t(Int_t(3.5+(y2-y1)/dy));
}
+ //integrate between x1 x2 and y1 y2
+ for (x=x1;x<x2+dx/2.;x+=dx)
+ for (Double_t y=y1;y<y2+dy/2.;y+=dy){
+ if ( (y>(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<x2;x+=dx)
- for (Float_t y=y1;y<y2;y+=dy){
- if ( (y>(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;
}
}
}
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; x<fNPRF*fDStep;x+=fDStep)
- { //x in cm fWidth in cm
- Float_t weight = GetPRFActiv(x);
- fSigmaX+=x*x*weight;
- mean+=x*weight;
- sum+=weight;
+ Int_t i;
+ Float_t x,y;
+
+ for (i=-1; i<=fNYdiv; i++){
+ if (fNYdiv == 1) y = fY1;
+ else
+ y = fY1+Float_t(i)*(fY2-fY1)/Float_t(fNYdiv-1);
+ for (x =-fNPRF*fDStep; x<fNPRF*fDStep;x+=fDStep)
+ {
+ //x in cm fWidth in cm
+ Float_t weight = GetPRF(x,y);
+ fSigmaX+=x*x*weight;
+ fSigmaY+=y*y*weight;
+ fMeanX+=x*weight;
+ fMeanY+=y*weight;
+ sum+=weight;
};
+ }
if (sum>0){
- 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
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){
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;
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;
void AliTPCPRF2D::DrawX(Float_t x1 ,Float_t x2,Float_t y, Bool_t inter)
{
+ //draw pad response function at interval <x1,x2> at given y position
if (fGRF==0) return ;
const Int_t N=100;
char s[100];
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;i<N+1;i++)
{
comment->AddText(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);
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);
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;
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);
* See cxx source for full Copyright notice */
/* $Id$ */
-
////////////////////////////////////////////////
-// Manager class for AliTPCPRF2D //
+// Manager class for AliTPCPRF2D //
////////////////////////////////////////////////
#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,
&