removed obsolete AliTPCDigitsDisplay.C
authorkowal2 <kowal2@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 17 Apr 2000 09:42:27 +0000 (09:42 +0000)
committerkowal2 <kowal2@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 17 Apr 2000 09:42:27 +0000 (09:42 +0000)
80 files changed:
TPC/AliArrayI.cxx [new file with mode: 0644]
TPC/AliArrayI.h [new file with mode: 0644]
TPC/AliArrayS.cxx [new file with mode: 0644]
TPC/AliArrayS.h [new file with mode: 0644]
TPC/AliCluster.cxx [new file with mode: 0644]
TPC/AliCluster.h [new file with mode: 0644]
TPC/AliClusterFinder.cxx [new file with mode: 0644]
TPC/AliClusterFinder.h [new file with mode: 0644]
TPC/AliClusters.cxx [new file with mode: 0644]
TPC/AliClusters.h [new file with mode: 0644]
TPC/AliClustersArray.cxx [new file with mode: 0644]
TPC/AliClustersArray.h [new file with mode: 0644]
TPC/AliDetectorParam.cxx [new file with mode: 0644]
TPC/AliDetectorParam.h [new file with mode: 0644]
TPC/AliDigits.cxx [new file with mode: 0644]
TPC/AliDigits.h [new file with mode: 0644]
TPC/AliDigitsArray.cxx [new file with mode: 0644]
TPC/AliDigitsArray.h [new file with mode: 0644]
TPC/AliH2F.cxx [new file with mode: 0644]
TPC/AliH2F.h [new file with mode: 0644]
TPC/AliSegmentArray.cxx [new file with mode: 0644]
TPC/AliSegmentArray.h [new file with mode: 0644]
TPC/AliSegmentID.cxx [new file with mode: 0644]
TPC/AliSegmentID.h [new file with mode: 0644]
TPC/AliSimDigits.cxx [new file with mode: 0644]
TPC/AliSimDigits.h [new file with mode: 0644]
TPC/AliTPC.cxx
TPC/AliTPC.h
TPC/AliTPCCluster.cxx [new file with mode: 0644]
TPC/AliTPCCluster.h [new file with mode: 0644]
TPC/AliTPCClustersArray.cxx [new file with mode: 0644]
TPC/AliTPCClustersArray.h [new file with mode: 0644]
TPC/AliTPCClustersRow.cxx [new file with mode: 0644]
TPC/AliTPCClustersRow.h [new file with mode: 0644]
TPC/AliTPCD.cxx [deleted file]
TPC/AliTPCD.h [deleted file]
TPC/AliTPCDigitDisplay.C [new file with mode: 0644]
TPC/AliTPCDigitsArray.cxx [new file with mode: 0644]
TPC/AliTPCDigitsArray.h [new file with mode: 0644]
TPC/AliTPCDigitsDisplay.C [deleted file]
TPC/AliTPCDigitsH.cxx [new file with mode: 0644]
TPC/AliTPCDigitsH.h [new file with mode: 0644]
TPC/AliTPCHits2Digits.C
TPC/AliTPCPRF2D.cxx
TPC/AliTPCPRF2D.h
TPC/AliTPCParam.cxx
TPC/AliTPCParam.h
TPC/AliTPCParamCR.cxx [new file with mode: 0644]
TPC/AliTPCParamCR.h [new file with mode: 0644]
TPC/AliTPCParamSR.cxx [new file with mode: 0644]
TPC/AliTPCParamSR.h [new file with mode: 0644]
TPC/AliTPCRF1D.cxx
TPC/AliTPCRF1D.h
TPC/AliTPCSecGeo.h [deleted file]
TPC/AliTPCTestClustering.C
TPC/AliTPCTestTracking.C
TPC/AliTPCprf2d.root [deleted file]
TPC/AliTPCv0.cxx
TPC/AliTPCv0.h
TPC/AliTPCv1.cxx
TPC/AliTPCv1.h
TPC/AliTPCv2.cxx
TPC/AliTPCv2.h
TPC/AliTPCv3.cxx
TPC/AliTPCv3.h
TPC/CLFinderDemo.C [new file with mode: 0644]
TPC/ClassTree.C [new file with mode: 0644]
TPC/Makefile
TPC/ParamTest.C [new file with mode: 0644]
TPC/TPCAnal.C [new file with mode: 0644]
TPC/TPCConfig.C [new file with mode: 0644]
TPC/TPCDigits2Clusters.C [new file with mode: 0644]
TPC/TPCHits2ExactClusters.C [new file with mode: 0644]
TPC/TPCLinkDef.h
TPC/TPCtest.C [new file with mode: 0644]
TPC/TestAliTPCDigitsArray.C [new file with mode: 0644]
TPC/TestSimDigits.C [new file with mode: 0644]
TPC/diganal.C [new file with mode: 0644]
TPC/template.C [new file with mode: 0644]
TPC/template.cxx [new file with mode: 0644]

diff --git a/TPC/AliArrayI.cxx b/TPC/AliArrayI.cxx
new file mode 100644 (file)
index 0000000..9d0ec86
--- /dev/null
@@ -0,0 +1,71 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:32:37  kowal2
+
+"ROOT"-based class with some extra functionality
+
+*/
+
+///////////////////////////////////////////////////////////////////////
+//   Added additional functionality  to original TArrayI              //
+//   multiple inheritance from TObject to be possible use automatic   //
+//   branch mechanism for tree
+//   function Expand to be possible expand array without deleting     //
+//   array contents                                                  //
+//                                                                   //
+//  Origin:  Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk // 
+//                                                                   //  
+///////////////////////////////////////////////////////////////////////
+#include "AliArrayI.h"
+ClassImp(AliArrayI)
+void AliArrayI::Expand(Int_t n)
+{
+  //
+  // Set array size of TArrayI object to n integers and copy old array
+  // If n<0 leave array unchanged.
+  // user are responsible for appopiate size of array
+  //
+  if (n < 0) return;  
+  fArray = (Int_t*)  TStorage::ReAlloc(fArray, n * sizeof(Int_t),fN * sizeof(Int_t));
+  if (fArray!=0) fN= n; 
+}
+
+void AliArrayI::Streamer(TBuffer &R__b)
+{
+   // Stream an object of class AliTPC.
+
+   if (R__b.IsReading()) {
+      Version_t R__v = R__b.ReadVersion(); if (R__v) { }
+      TObject::Streamer(R__b);     
+      //read pad parameters
+      R__b >> fN;
+      if (fArray!=0) {
+       delete [] fArray;
+       fArray = 0;
+      }
+      if (fN>0){
+       fArray = new Int_t[fN];
+       R__b.ReadFastArray(fArray,fN); 
+      }
+   } else {
+      R__b.WriteVersion(AliArrayI::IsA());
+      TObject::Streamer(R__b);   
+      R__b << fN;     
+      if (fN>0) R__b.WriteFastArray(fArray,fN); 
+   }
+}
diff --git a/TPC/AliArrayI.h b/TPC/AliArrayI.h
new file mode 100644 (file)
index 0000000..d73c210
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef AliArrayI_H
+#define AliArrayI_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+////////////////////////////////////////////////
+//  Manager class generaol Alice segment 
+//  segment is for example one pad row in TPC //
+////////////////////////////////////////////////
+
+#include "TObject.h"
+#include "TArrayI.h"
+
+class AliArrayI: public TObject ,public TArrayI {
+public:
+  void Expand(Int_t n);
+  ClassDef(AliArrayI,1) 
+};
+
+#endif //ALIARRAY_I
+
diff --git a/TPC/AliArrayS.cxx b/TPC/AliArrayS.cxx
new file mode 100644 (file)
index 0000000..0eb5a74
--- /dev/null
@@ -0,0 +1,75 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:32:37  kowal2
+
+"ROOT"-based class with some extra functionality
+
+*/
+
+///////////////////////////////////////////////////////////////////////
+//   Added additional functionality  to original TArrayS              //
+//   multiple inheritance from TObject to be possible use automatic   //
+//   branch mechanism for tree
+//   function Expand to be possible expand array without deleting     //
+//   array contents                                                  //                  //
+//                                                                   //
+//  Origin:  Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk // 
+//                                                                   //  
+///////////////////////////////////////////////////////////////////////
+#include "AliArrayS.h"
+ClassImp(AliArrayS)
+void AliArrayS::Expand(Int_t n)
+{
+  //
+  // Set array size of TArrayS object to n integers and copy old array
+  // If n<0 leave array unchanged.
+  // user are responsible for apropriate size of array
+  // 
+  if (n < 0) return;  
+  fArray = (Short_t*)  TStorage::ReAlloc(fArray, n * sizeof(UShort_t),fN * sizeof(UShort_t));
+  if (fArray!=0) fN= n; 
+  else fN =0;
+}
+
+
+
+void AliArrayS::Streamer(TBuffer &R__b)
+{
+   // Stream an object of class AliTPC.
+
+   if (R__b.IsReading()) {
+      Version_t R__v = R__b.ReadVersion(); if (R__v) { }
+      TObject::Streamer(R__b);     
+      //read pad parameters
+      R__b >> fN;
+      if (fArray!=0){
+       delete [] fArray;
+       fArray =0;
+      }
+      if (fN>0){
+       fArray = new Short_t[fN];
+       R__b.ReadFastArray(fArray,fN); 
+      }
+   } else {
+      R__b.WriteVersion(AliArrayS::IsA());
+      TObject::Streamer(R__b);   
+      R__b << fN;      
+      if (fN>0) R__b.WriteFastArray(fArray,fN); 
+   }
+}
diff --git a/TPC/AliArrayS.h b/TPC/AliArrayS.h
new file mode 100644 (file)
index 0000000..023271a
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef ALIARRAYS_H
+#define ALIARRAYS_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+////////////////////////////////////////////////
+//  Manager class generaol Alice segment digits
+//  segment is for example one pad row in TPC //
+////////////////////////////////////////////////
+
+#include "TObject.h"
+#include "TArrayS.h"
+
+
+class AliArrayS:  public TObject,public TArrayS {
+public:
+  void Expand(Int_t n);
+  ClassDef(AliArrayS,1) 
+};
+#endif //ALIARRAYS_H
diff --git a/TPC/AliCluster.cxx b/TPC/AliCluster.cxx
new file mode 100644 (file)
index 0000000..f407673
--- /dev/null
@@ -0,0 +1,61 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:34:02  kowal2
+
+Clusters handling in a new data structure
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  Time Projection Chamber clusters objects                                //
+//
+//  Origin: Marian Ivanov , GSI Darmstadt
+//                                                                           //
+//Begin_Html
+/*
+<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)
diff --git a/TPC/AliCluster.h b/TPC/AliCluster.h
new file mode 100644 (file)
index 0000000..3226171
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef ALICLUSTER_H
+#define ALICLUSTER_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+#include "TObject.h"
+
+class AliCluster : public TObject {
+public:
+  Int_t     fTracks[3];//labels of overlapped tracks
+  Float_t   fX ;       //Y of cluster
+  Float_t   fY ;       //Z of cluster
+  Float_t   fQ ;       //Q of cluster (in ADC counts)
+  Float_t   fSigmaX2;  //Sigma Y square of cluster
+  Float_t   fSigmaY2;  //Sigma Z square of cluster
+  Float_t   fSigmaXY;  //      XY moment 
+  Float_t   fArea;     //area of cluster
+  Float_t   fMax;     //amplitude at maximum 
+public:
+  AliCluster() {
+    fTracks[0]=fTracks[1]=fTracks[2]=0; 
+    fX=fY=fQ=fSigmaX2=fSigmaY2=0.;
+  }
+  virtual ~AliCluster() {;}
+  Bool_t    IsSortable() const;
+  Int_t Compare(TObject *o) ;
+  ClassDef(AliCluster,1)  // Tclusters
+};
+
+class AliDigitCluster : public AliCluster {
+public:
+  Int_t fNx; //number of accepted x bins
+  Int_t fNy; //number of accepted y bins
+  Float_t fMaxX; //maximum x bin
+  Float_t fMaxY; //maximum y bin
+public:  
+  ClassDef(AliDigitCluster,1)  // Tclusters
+};
+
+class AliDifCluster : public AliDigitCluster {
+public:
+  Float_t fDx; //delta x 
+  Float_t fDy; //delta y
+  Float_t fAngleX;//x angle
+  Float_t fAngleY;//y angle
+  Float_t fOrigQ; //original charge
+  Int_t fGenerTrack;  //track number of nearest track
+  ClassDef(AliDifCluster,1)  // Tclusters
+};
+
+#endif //ALICLUSTER_H
diff --git a/TPC/AliClusterFinder.cxx b/TPC/AliClusterFinder.cxx
new file mode 100644 (file)
index 0000000..f2fcd3d
--- /dev/null
@@ -0,0 +1,899 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:34:56  kowal2
+
+Experimental cluster finder
+
+*/
+
+//-----------------------------------------------------------------------------
+//
+//  Implementation of class ALICLUSTERFINDER
+// 
+//Class for cluster finding in two dimension.
+//In the present there are implemented two algorithm
+//primitive recursion algorithm. (FindPeaks) 
+//Algorithm is not working in case of overlaping clusters
+//Maximum - minimum in direction algoritm (Find clusters)
+//In this algoritm we suppose that each cluster has local 
+//maximum. From this local maximum I mus see each point 
+//of cluster.
+//From maximum i can accept every point in radial 
+//direction which is before border in direction
+//Border in direction occur if we have next in
+//direction nder threshold or response begin
+//to increase in given radial direction
+//-----------------------------------------------------------------------------
+#include "TMinuit.h"
+#include "AliArrayI.h"
+#include "TClonesArray.h"
+#include "AliTPC.h"
+#include "TRandom.h"
+#include "AliH2F.h"
+#include "TMarker.h"
+#include "AliCluster.h"
+#include "AliClusterFinder.h"
+
+#include "iostream.h" //I.Belikov
+
+//direction constants possible direction in 8 different sectors
+//
+
+
+const Int_t kClStackSize =1000;
+
+
+
+
+static AliClusterFinder * gClusterFinder; //for fitting routine
+
+void gauss(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
+{
+  AliArrayI * points = gClusterFinder->GetStack();
+  const Int_t nbins = gClusterFinder->GetStackIndex();
+  Int_t i;
+  //calculate chisquare
+   Double_t chisq = 0;
+   Double_t delta;
+   for (i=0;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;  
+}
diff --git a/TPC/AliClusterFinder.h b/TPC/AliClusterFinder.h
new file mode 100644 (file)
index 0000000..47a55df
--- /dev/null
@@ -0,0 +1,314 @@
+#ifndef TCLUSTERFINDER_H
+#define TCLUSTERFINDER_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+// include files and class forward declarations
+#include "TObject.h"
+#include "TH2.h"
+class TClonesArray;
+class AliCluster;
+class AliCell;
+class AliArrayI;
+class AliDetectorParam;
+class TMinuit;
+class AliH2F;
+class  AliClusterFinder : public TObject {
+public:      
+  AliClusterFinder(); 
+  // constructor which create cluster finder  object  
+  ~AliClusterFinder();
+  void GetHisto(TH2F * his2);
+  //reset object to include histograms values
+  TClonesArray * FindPeaks1( TClonesArray *arr=0);  
+  TClonesArray * FindPeaks2( TClonesArray *arr=0);  
+  TClonesArray * FindPeaks3( TClonesArray *arr=0);  
+
+  void FindMaxima();
+  // if at point is local maximum return cell with maximum information  (for testing only
+  Int_t & GetNType(){return fNType;}  //return type of neighborow for max determinatio 
+  void SetThreshold(Float_t threshold) { fThreshold = threshold;}
+  void SetNoise(Float_t noise) {fNoiseTh =noise;}
+  void SetDirSigmaFac(Float_t fac) {fDirSigmaFac = fac;}
+  void SetDirAmpFac(Float_t fac) {fDirAmpFac = fac;}
+
+  void SetDetectorParam(AliDetectorParam*param) {fDetectorParam = param;}
+  //set Detector parameters -necesssary to estimate cluster size
+  void SetDetectorIndex(Int_t *index) {fDetectorIndex = index;}
+  //set index of described detector
+  Bool_t  SetSigma2(Int_t i, Int_t j, Float_t & sigmax2, Float_t & sigmay2);
+  //set sigmax and sigma y accordig i and j position of cell 
+  void SetMulSigma(Float_t sigma) {fMulSigma2= sigma*sigma;}
+  AliArrayI * GetStack(){return fStack;}
+  Int_t GetStackIndex(){return fStackIndex;}
+  void SetBFit(Bool_t fit) {fBFit = fit;}
+  TMinuit * GetMinuit() {return fMinuit;}
+  AliH2F *  Draw( const char *option=0,Float_t x1=-1, Float_t x2=-1, Float_t y1=-1, Float_t y2=-1); 
+           //draw digits
+  void DrawCluster(Int_t color=5, Int_t size=5, Int_t style=4);
+  AliH2F *  DrawBorders( const char *option=0,  AliH2F *his=0, Int_t type =0, Float_t x1=-1, Float_t x2=-1, Float_t y1=-1, Float_t y2=-1); 
+  //draw digits
+public:
+  Bool_t   IsMaximum(Int_t i, Int_t  j);
+  Bool_t   IsVirtualMaximum(Float_t x, Float_t  y);
+  
+  void ResetSignal();   //reset signals to 0
+  void ResetStatus();   //reset status of signals to not used
+
+  AliCell  * GetCell(Int_t i, Int_t j);   
+  //return reference to the cell with index i,j 
+  void SetBlockIndex(Int_t *index); //calculate which indexes we must check for border
+public:
+  void AddToStack(Int_t i, Int_t j, Int_t signal);       
+  //add given cell to the stack of particles
+  void GetClusterStatistic(AliDigitCluster & cluster);
+  //go through the cluster and calculate statistic
+  void GetClusterFit(AliDigitCluster & cluster);
+  Bool_t CheckIfDirBorder(Float_t x, Float_t y, Int_t i,Int_t j);
+  //check if given cell is border
+  void   Adjacent(Int_t i, Int_t j);  
+  //recursion procedure 
+  Float_t ItoX(Float_t i) {return (fX1)+(i+0.5)*(fX2-fX1)/fDimX;}
+  Float_t JtoY(Float_t j) {return (fY1)+(j+0.5)*(fY2-fY1)/fDimY;}
+
+  inline Bool_t IsChecked(Int_t index, Int_t i, Int_t j);
+  inline Bool_t IsBorder(Int_t index, Int_t i, Int_t j);
+  inline Bool_t IsThBorder(Int_t index, Int_t i, Int_t j);
+  inline Bool_t IsDirBorder(Int_t index, Int_t i, Int_t j);
+  inline Bool_t IsMaximum(Int_t index, Int_t i, Int_t j);
+  inline void  SetChecked(Int_t index, Int_t i, Int_t j);
+  inline void  SetBorder(Int_t index, Int_t i, Int_t j);
+  inline void  SetThBorder(Int_t index, Int_t i, Int_t j);
+  inline void  SetDirBorder(Int_t index, Int_t i, Int_t j);
+  inline void  SetMaximum(Int_t index, Int_t i, Int_t j);
+
+  
+  
+  inline Int_t  GetSignal(Int_t i, Int_t j); 
+  Float_t  GetVirtualSignal(Float_t ri, Float_t rj); 
+  //create new virtual cell and interpolate signal at  position ri,rj
+
+  void Transform(AliDigitCluster *c);
+private:
+  Int_t fNType;  //type of neighborow for maximum determination
+  Float_t fCurrentMaxX; //!current cluster maximum X index
+  Float_t fCurrentMaxY; //!current cluster maximum X index
+  Float_t fCurrentSigmaX2; //!current sigmax2 according detector (updated by function ...)
+  Float_t fCurrentSigmaY2;//!
+  Float_t fCurrentMaxAmp;//!current cluster maximum amplitude
+  Bool_t fBDistType;  //
+  Bool_t fBFit;  //
+  Float_t  fMulSigma2; //
+  Float_t fDirSigmaFac;  //!for direction border calculation
+  Float_t fDirAmpFac;    //!for direction border calculation
+
+  Float_t fThreshold; //treshold;
+  Float_t  fNoiseTh;  //noise threshoshol to accept maximum    
+  AliCell   * fDigits;  //field with all cell digits   
+  Int_t      fIndex;        //!index of current  cluster
+  AliArrayI  * fStack;      //!stack with digits index
+  Int_t      fStackIndex;   //!stack index
+  TMinuit    *fMinuit;      //!minuit object
+  AliDetectorParam * fDetectorParam; //pointer to detector param  - finder is not owner
+  Int_t *    fDetectorIndex; // detector index -  
+  //original frame 
+  Float_t   fX1;
+  Float_t   fY1;
+  Float_t   fX2;
+  Float_t   fY2;
+  Int_t      fDimX;
+  Int_t      fDimY;
+  Int_t      fOver;     
+
+  //
+  TClonesArray * fClustersArray; //array with current clusters
+  Bool_t     rOK;       
+  //signalize that all fields were initialised 
+  ClassDef(AliClusterFinder,2)
+};  
+
+
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+//objec AliCell 
+
+const Int_t krCheck     = 1;
+const Int_t krBorder    = 2;
+const Int_t krThBorder  = 4;
+const Int_t krDirBorder = 8;
+const Int_t krMaximum = 16;
+const Int_t krIndexNull =0x1F;
+
+class AliCell{
+public :
+  AliCell(Int_t signal =0, Int_t status = 0){fSignal =signal;fStatus = status;}  
+  //at the begining set  
+  void SetSignal(Int_t signal){fSignal = signal;}
+  void SetStatus(Int_t status){fStatus = status;}  
+  void SetChecked(Int_t index) {fStatus &=krIndexNull; fStatus+=(index<<5); fStatus|=krCheck;}
+  void SetChecked() {fStatus|=krCheck;}
+  void SetBorder(Int_t index) {fStatus &=krIndexNull; fStatus |= krBorder;fStatus+=(index<<5);}
+  void SetThBorder(Int_t index) {fStatus &=krIndexNull;fStatus|=krBorder|krThBorder;fStatus+=(index<<5);}
+  void SetDirBorder(Int_t index) {fStatus &=krIndexNull;fStatus|=krBorder|krDirBorder;fStatus+=(index<<5);}
+  void SetMaximum(Int_t index) {fStatus &=krIndexNull;fStatus|=krMaximum;fStatus+=(index<<5);}
+
+
+  void SetUnChecked(){if (fStatus&krCheck) fStatus-=krCheck;}
+  void SetUnBorder(){if (fStatus&krBorder) fStatus-=krBorder;}
+  void SetThUnBorder(){SetUnBorder();if (fStatus&krBorder) fStatus-=krThBorder+krBorder;}
+  void SetDirUnBorder(){SetUnBorder();if (fStatus&krBorder) fStatus-=krDirBorder+krBorder;}
+  
+  Bool_t IsChecked() {return fStatus&&krBorder;}
+  Bool_t IsChecked(Int_t index) {return ((fStatus>>5)==index);}
+  
+  Bool_t  IsBorder() {return ((fStatus&krBorder)!=0);}
+  Bool_t  IsBorder(Int_t index) {return ( ((fStatus&krBorder)!=0) && ((fStatus>>5)==index));}  
+  Bool_t  IsDirBorder() {return ((fStatus&krDirBorder)!=0);}        
+  Bool_t  IsDirBorder(Int_t index) {return ( ((fStatus&krDirBorder)!=0) && ((fStatus>>5)==index));}
+  Bool_t  IsThBorder() {return ((fStatus&krThBorder)!=0);}        
+  Bool_t  IsThBorder(Int_t index) {return ( ((fStatus&krThBorder)!=0) && ((fStatus>>5)==index));}
+
+  Bool_t  IsMaximum() {return ((fStatus&krMaximum)!=0);}
+  Bool_t  IsMaximum(Int_t index) {return ( ((fStatus&krMaximum)!=0) && ((fStatus>>5)==index));}  
+
+  void Reset() { fStatus = 0; fSignal =0;} 
+  Int_t GetSignal() {return fSignal;}
+  Int_t GetStatus() {return fStatus;}
+
+  
+private:
+  Int_t fSignal;
+  Int_t fStatus;
+};
+
+
+
+Int_t AliClusterFinder::GetSignal(Int_t i, Int_t j)
+{
+  AliCell *c = GetCell(i,j);
+  Int_t res;
+  if (c==0) res = -1;
+  else  res = c->GetSignal();
+  return res;
+}
+
+
+
+Bool_t AliClusterFinder::IsBorder(Int_t index, Int_t i, Int_t j)
+{
+  AliCell *c = GetCell(i,j);
+  Bool_t res;
+  if (c==0) res = kFALSE;
+  else {
+    if (index == 0) res = c->IsBorder();
+    else res = c->IsBorder(index);
+  }
+  return res;
+}
+
+
+
+Bool_t AliClusterFinder::IsThBorder(Int_t index, Int_t i, Int_t j)
+{
+  AliCell *c = GetCell(i,j);
+  Bool_t res;
+  if (c==0) res = kFALSE;
+  else {
+    if (index == 0) res = c->IsThBorder();
+    else res = c->IsThBorder(index);
+  }
+  return res;
+}
+
+Bool_t AliClusterFinder::IsDirBorder(Int_t index, Int_t i, Int_t j)
+{
+  AliCell *c = GetCell(i,j);
+  Bool_t res;
+  if (c==0) res = kFALSE;
+  else {
+    if (index == 0) res = c->IsDirBorder();
+    else res = c->IsDirBorder(index);
+  }
+  return res;
+}
+
+Bool_t AliClusterFinder::IsChecked(Int_t index, Int_t i, Int_t j)
+{
+  AliCell *c = GetCell(i,j);
+  Bool_t res;
+  if (c==0) res = kTRUE;
+  else {
+    if (index == 0) res = c->IsChecked();
+    else res = c->IsChecked(index);
+  }
+  return res;
+}
+
+Bool_t AliClusterFinder::IsMaximum(Int_t index, Int_t i, Int_t j)
+{
+  AliCell *c = GetCell(i,j);
+  Bool_t res;
+  if (c==0) res = kTRUE;
+  else {
+    if (index == 0) res = c->IsMaximum();
+    else res = c->IsMaximum(index);
+  }
+  return res;
+}
+
+
+void AliClusterFinder::SetChecked(Int_t index, Int_t i, Int_t j)
+{
+  AliCell *c = GetCell(i,j);
+  if (c!=0) {
+    if (index>0) c->SetChecked(index);
+    else c->SetChecked();
+  }
+}
+void AliClusterFinder::SetBorder(Int_t index, Int_t i, Int_t j)
+{
+  AliCell *c = GetCell(i,j);
+  if (c!=0) {
+    if (index>0) c->SetBorder(index);
+    //    else c->SetBorder();
+  }
+}
+
+
+void AliClusterFinder::SetThBorder(Int_t index, Int_t i, Int_t j)
+{
+  AliCell *c = GetCell(i,j);
+  if (c!=0) {
+    if (index>0) c->SetThBorder(index);
+    else c->SetThBorder(0);
+  }
+}
+
+
+void AliClusterFinder::SetDirBorder(Int_t index, Int_t i, Int_t j)
+{
+  AliCell *c = GetCell(i,j);
+  if (c!=0) {
+    if (index>0) c->SetDirBorder(index);
+    else c->SetDirBorder(0);
+  }
+}
+
+void AliClusterFinder::SetMaximum(Int_t index, Int_t i, Int_t j)
+{
+  AliCell *c = GetCell(i,j);
+  if (c!=0) {
+    if (index>0) c->SetMaximum(index);
+    else c->SetMaximum(0);
+  }
+}
+
+#endif /* TCLUSTERFINDER_H */
diff --git a/TPC/AliClusters.cxx b/TPC/AliClusters.cxx
new file mode 100644 (file)
index 0000000..9c3d830
--- /dev/null
@@ -0,0 +1,173 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:34:02  kowal2
+
+Clusters handling in a new data structure
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  Time Projection Chamber clusters objects                                //
+//
+//  Origin: Marian Ivanov , GSI Darmstadt
+//                                                                           //
+//                                                                           //
+//                                                                          //
+///////////////////////////////////////////////////////////////////////////////
+#include "TError.h"
+#include "TClass.h"
+#include  <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();    
+  }
+}
+
diff --git a/TPC/AliClusters.h b/TPC/AliClusters.h
new file mode 100644 (file)
index 0000000..c042fe5
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef ALICLUSTERS_H
+#define ALICLUSTERS_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+////////////////////////////////////////////////
+//  Manager class for TPC   clusters          //
+////////////////////////////////////////////////
+
+
+#include "AliSegmentID.h"
+class TClonesArray;
+class TObjArray;
+
+
+class AliClusters : public AliSegmentID{
+public:
+  AliClusters(); 
+  virtual AliCluster* InsertCluster(const AliCluster* c ); //insert copy of cluster  
+  const AliCluster* operator[](Int_t i); 
+  virtual Int_t  Find(Double_t y) const;   //find nearest cluster in y direction
+  void Sort();
+  TClonesArray * GetArray(){return fClusters;}
+  void SetArray(Int_t length); //construct clonnes array of objects of type fClass
+  void Draw(Float_t shiftx, Float_t shifty, Int_t color, Int_t size, Int_t style);
+  Bool_t SetClass(const Text_t *classname);
+protected:
+  TClonesArray * fClusters;  
+  Int_t  fNclusters;  
+  TClass * fClass; //!type of cluster class 
+  ClassDef(AliClusters,1) 
+};
+
+
+#endif //ALICLUSTERS_H
diff --git a/TPC/AliClustersArray.cxx b/TPC/AliClustersArray.cxx
new file mode 100644 (file)
index 0000000..1aa56f3
--- /dev/null
@@ -0,0 +1,101 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:34:02  kowal2
+
+Clusters handling in a new data structure
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  AliClustersArray  object                                //
+//
+//  Origin: Marian Ivanov , GSI Darmstadt
+//                                                                           //
+//                                                                          //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "TObject.h"
+#include "TClass.h"
+#include  <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;
+}
diff --git a/TPC/AliClustersArray.h b/TPC/AliClustersArray.h
new file mode 100644 (file)
index 0000000..b9c4ce7
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef ALICLUSTERSARRAY_H
+#define ALICLUSTERSARRAY_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+////////////////////////////////////////////////
+//  Manager class for AliClustersArray        //
+////////////////////////////////////////////////
+class AliDetectorParam;
+class AliClustersFinder;
+
+class AliClustersArray : public AliSegmentArray {
+public:
+  AliClustersArray();
+  virtual   Bool_t Setup(AliDetectorParam *param);  
+  const AliDetectorParam *  GetParam() {return fParam;} 
+  AliClustersFinder *  GetFinder() {return fClFinder;}
+  virtual Bool_t SetParam(AliDetectorParam * param);
+  virtual Bool_t SetFinder(AliClustersFinder * finder);
+  Bool_t  SetClusterType(Text_t *classname );
+  TClass * GetClusterType() {return fClusterType;}
+protected:  
+  AliDetectorParam * fParam;      //pointer to detector parameters 
+  AliClustersFinder * fClFinder; //!pointer to cluster finder object
+  TClass *fClusterType; //!
+  ClassDef(AliClustersArray,1) 
+};
+  
+#endif
diff --git a/TPC/AliDetectorParam.cxx b/TPC/AliDetectorParam.cxx
new file mode 100644 (file)
index 0000000..a663b42
--- /dev/null
@@ -0,0 +1,73 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:36:13  kowal2
+
+New Detector parameters handling class
+
+*/
+
+///////////////////////////////////////////////////////////////////////
+//  Paramter class for AliDetector                                   //
+//                                                                   //
+//  Origin:  Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk // 
+//                                                                   //  
+///////////////////////////////////////////////////////////////////////
+
+#include "TObject.h"
+#include "AliDetectorParam.h"
+
+
+
+
+Float_t * AliDetectorParam::GetAnglesAccMomentum(Float_t *x, Int_t * index, Float_t *momentum, Float_t *angle)
+{
+  //
+  //calculates deflection angle of particle with longitudinal
+  //longitudinal  momentum[0] and transversal momentum momentum[1]
+  //at position (x,y,z) = (x[0],x[1],x[2]) 
+  //angle[0] - deep angle
+  //angle[1] - magnetic deflection angle 
+  if (momentum==0) {
+    Float_t rtotal =TMath::Sqrt(x[0]*x[0]+x[1]*x[1]);
+    if (rtotal==0) angle[0]=0;
+    else    
+      angle[0] = TMath::ATan(x[2]/rtotal);
+    angle[1]=0;
+    return angle;
+  }
+  Float_t mtotal =TMath::Sqrt(momentum[0]*momentum[0]+momentum[1]*momentum[1]);
+  if (mtotal==0) {
+    angle[0]= 0;
+    angle[1]=0;
+    return angle;
+  }
+  angle[0]= TMath::ATan(momentum[2]/mtotal);
+  Float_t radius1 = TMath::Sqrt(x[0]*x[0]+x[1]*x[1]); //axial symetry in z
+  Float_t radius2 = 1000*mtotal/(3*fBField);
+  if (radius1<radius2)
+    angle[1]= TMath::ASin(radius1/radius2);
+  else 
+    angle[1]=0;
+  return angle;
+} 
+
+
+
+
+
+ClassImp(AliDetectorParam)
diff --git a/TPC/AliDetectorParam.h b/TPC/AliDetectorParam.h
new file mode 100644 (file)
index 0000000..1277ad7
--- /dev/null
@@ -0,0 +1,49 @@
+#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
diff --git a/TPC/AliDigits.cxx b/TPC/AliDigits.cxx
new file mode 100644 (file)
index 0000000..d28a4a5
--- /dev/null
@@ -0,0 +1,413 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:37:42  kowal2
+
+Digits handling in a new data structure
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//   Alice  digits array  object  AliDigits                                  //
+//                                                                           //
+//                                                                           //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+
+#include "TClass.h"
+#include <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;
+}
+
diff --git a/TPC/AliDigits.h b/TPC/AliDigits.h
new file mode 100644 (file)
index 0000000..201f887
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef ALIDIGITS_H
+#define ALIDIGITS_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+////////////////////////////////////////////////
+//  Manager class generaol Alice segment digits
+//  segment is for example one pad row in TPC //
+////////////////////////////////////////////////
+
+#include   "AliArrayI.h"
+#include   "AliArrayS.h"
+#include   "AliSegmentID.h"
+class AliH2F;
+
+class AliDigits: public AliSegmentID{ 
+public:
+  AliDigits();
+  ~AliDigits();
+  inline Short_t GetDigitFast(Int_t row, Int_t column);  //return value at given row and collumn
+  inline void  SetDigitFast(Short_t value,Int_t row, Int_t column);  //set value at given row and collumn
+  inline Bool_t BoundsOK(const char *where, Int_t row, Int_t col) ;  //Check If Bound Ok
+  Bool_t OutOfBoundsError(const char *where, Int_t row, Int_t column);
+  virtual void Allocate(Int_t rows, Int_t columns);  //construct empty buffer fDigits with size rows x columns
+  virtual Short_t GetDigit(Int_t row, Int_t column);
+  virtual void ExpandBuffer();  //expand buffer to twodimensional array
+  virtual void CompresBuffer(Int_t bufferType,Int_t threshold); //compres buffer according buffertype algorithm   
+  virtual Bool_t First(); //adjust  first valid current digit
+  virtual Bool_t Next();  //addjust next valid current digit
+  void SetThreshold(Int_t th) {fThreshold = th;}
+  Int_t  GetThreshold() {return fThreshold;}
+  Int_t CurrentRow(){ return fCurrentRow;}  //return current row
+  Int_t CurrentColumn(){ return fCurrentCol;} //return current column
+  Int_t CurrentDigit() {return fElements->At(fCurrentIndex);} //return degit for current row and column
+  void AcceptHisto(AliH2F * his);  //update buffer for - it will content histogram values
+  AliH2F * GenerHisto();           //generate 2 dimensional histogram with digits
+  AliH2F *  Draw( const char *option=0,Float_t x1=-1, Float_t x2=-1, Float_t y1=-1, Float_t y2=-1); //draw digits
+  Int_t GetSize() {return fNelems;} //return main buffer size
+protected:
+  virtual  void Invalidate();  
+  void ExpandBuffer1(); //expand buffer of type to twodimensional array
+  void CompresBuffer1(); //compres buffer according  algorithm 1
+  Bool_t First0();  //first for the buffer type 0
+  Bool_t Next0();  //next for the buffer type 0
+  Bool_t First1(); //first for the buffer type 1
+  Bool_t Next1();//next for the buffer type 1
+  Short_t  GetDigit1(Int_t row, Int_t column); //return digit for given row and column
+  Int_t     fNrows;   //number of rows in Segment
+  Int_t     fNcols; //number of collumns in Segment 
+private:
+  AliArrayS *fElements;  //buffer of 2 bytes integers for digits
+  AliArrayI *fIndex;  //index position of column
+  Int_t     fBufType; //type of the buffer - define compression algorithm  
+  Int_t     fThreshold; //treshold for zero suppresion
+  Int_t     fNelems;  //total number of elements 
+  Int_t fCurrentRow;   //!current row  iteration
+  Int_t fCurrentCol;   //!current column iteration
+  Int_t fCurrentIndex; //!current index in field
+  ClassDef(AliDigits,1) 
+};
+
+
+inline Bool_t AliDigits::BoundsOK(const char *where, Int_t row, Int_t col) 
+{
+  //Check If Bound Ok
+  if ( (col>=fNcols) || (col<0) ) return OutOfBoundsError(where,row,col);
+  Int_t index =(*fIndex).At(col)+row;
+  if ( (index<0) || (index>fNelems)) return OutOfBoundsError(where,row,col);
+  return kTRUE;  
+}
+
+Short_t AliDigits::GetDigitFast(Int_t row, Int_t column)
+{
+  //
+  //return digit from  fDigits array
+  //if out of range return dummy value  ( value at row = 0, collumn = 0)
+  //
+  return fElements->At(fIndex->At(column)+row); 
+}
+
+void  AliDigits::SetDigitFast(Short_t value, Int_t row, Int_t column)
+{
+  //
+  //set  digit 
+  //
+  if ( (row<0) || (row>=fNrows)  || (column<0) || (column>=fNrows) ) 
+       ::Error("AliDigits::SetDigitFast", "row %d  col %d out of bounds (size: %d x %d, this: 0x%08x)", 
+          row, column, fNrows, fNcols, this);
+  (*fElements)[fIndex->At(column)+row]=value; 
+}
+
+#endif
+
diff --git a/TPC/AliDigitsArray.cxx b/TPC/AliDigitsArray.cxx
new file mode 100644 (file)
index 0000000..eeb6e39
--- /dev/null
@@ -0,0 +1,71 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:37:42  kowal2
+
+Digits handling in a new data structure
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  AliDigitsArray  object                                //
+//
+//  Origin: Marian Ivanov , GSI Darmstadt
+//                                                                           //
+//                                                                          //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "TObject.h"
+#include "AliSegmentID.h"
+#include "TObjArray.h"
+#include "AliSegmentArray.h"
+
+#include "TError.h"
+#include "AliDigits.h"
+#include "AliDetectorParam.h"
+#include "AliDigitsArray.h"
+
+
+
+ClassImp(AliDigitsArray)
+//
+
+AliDigitsArray::AliDigitsArray()
+{
+  fParam = 0;
+}
+
+AliDigitsArray::~AliDigitsArray()
+{
+  if (fParam != 0) delete fParam;
+}  
+
+Bool_t AliDigitsArray::Setup(AliDetectorParam *param)
+{
+  //
+  //setup array according parameters
+  SetParam(param);
+  return kTRUE;
+}
+
+
+Bool_t AliDigitsArray::SetParam(AliDetectorParam * param)
+{
+  fParam = param;
+  return kTRUE;
+}
diff --git a/TPC/AliDigitsArray.h b/TPC/AliDigitsArray.h
new file mode 100644 (file)
index 0000000..9200457
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef ALIDIGITSARRAY_H
+#define ALIDIGITSARRAY_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+////////////////////////////////////////////////
+//  Manager class for AliDigitsArray        //
+////////////////////////////////////////////////
+class AliDetectorParam;
+
+class AliDigitsArray : public AliSegmentArray {
+public:
+  AliDigitsArray();
+  ~AliDigitsArray();  
+  virtual   Bool_t Setup(AliDetectorParam *param);  //setup array according parameters
+  const AliDetectorParam *  GetParam() {return fParam;} 
+  virtual Bool_t SetParam(AliDetectorParam * param);
+protected:  
+  AliDetectorParam * fParam;      //pointer to detector parameters 
+  ClassDef(AliDigitsArray,1) 
+};
+  
+#endif //ALIDIGITSARRAY_H
diff --git a/TPC/AliH2F.cxx b/TPC/AliH2F.cxx
new file mode 100644 (file)
index 0000000..da02e6e
--- /dev/null
@@ -0,0 +1,387 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:32:37  kowal2
+
+"ROOT"-based class with some extra functionality
+
+*/
+
+//----------------------------------------------------------------------------
+//  Author:   Marian Ivanov
+//
+//  Implementation of class AliH2F
+//
+//-----------------------------------------------------------------------------
+
+#include "AliH2F.h"
+#include "TClonesArray.h"
+#include "AliTPC.h"
+#include "TRandom.h"
+#include "AliCluster.h"
+#include "AliClusterFinder.h"
+//*KEEP,TMath.
+
+// other include files follow here
+
+
+ClassImp(AliH2F)
+//***********************************************************************
+//***********************************************************************
+//***********************************************************************
+//***********************************************************************
+AliH2F::AliH2F():TH2F() 
+{
+  fSigmaX2 = 1.;
+  fSigmaY2 = 1.;
+  fdx = 1;
+  fdy=1;
+  fFitMatrix.ResizeTo(5,1);  
+}
+AliH2F::AliH2F(const Text_t *name,const Text_t *title,
+                      Int_t nbinsx,Axis_t xlow,Axis_t xup
+                      ,Int_t nbinsy,Axis_t ylow,Axis_t yup):
+  TH2F(name,title,nbinsx,xlow,xup
+       ,nbinsy,ylow,yup)
+{
+  fSigmaX2 = 1.;
+  fSigmaY2 = 1.;
+  fdx = 1;
+  fdy=1; 
+  fFitMatrix.ResizeTo(5,1);  
+}
+     
+AliH2F::~AliH2F() 
+{
+}
+
+AliH2F::AliH2F(const AliH2F &) 
+{
+}
+
+AliH2F & AliH2F::operator = (const AliH2F &) 
+{
+   return *this;
+}
+
+TClonesArray * AliH2F::FindPeaks(Float_t threshold, Float_t noise)
+{
+  //find peaks and write it in form of AliTPCcluster to array
+    
+  //firstly we need to create object for cluster finding
+  //and fill it with contents of histogram
+  AliClusterFinder cfinder;
+  cfinder.SetThreshold(threshold);
+  cfinder.SetNoise(noise);
+  cfinder.GetHisto(this);
+  return cfinder.FindPeaks3();
+}
+
+void AliH2F::ClearSpectrum()
+{
+  Int_t dimx =  fXaxis.GetNbins();
+  Int_t dimy =  fYaxis.GetNbins();
+  for (Int_t i = 0 ;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;
+}
diff --git a/TPC/AliH2F.h b/TPC/AliH2F.h
new file mode 100644 (file)
index 0000000..6ea5ddb
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef TH2FSMOOTH_H
+#define TH2FSMOOTH_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+// include files and class forward declarations
+
+#include "TH2.h"
+#include "TMatrix.h" 
+
+class TMatrix;
+class TH1F;
+class TClonesArray;
+
+class AliH2F : public TH2F {
+public:
+  AliH2F();
+  AliH2F(const Text_t *name,const Text_t *title,Int_t nbinsx,
+            Axis_t xlow,Axis_t xup,Int_t nbinsy,Axis_t ylow,Axis_t yup);
+    ~AliH2F();
+
+public:
+  AliH2F(const AliH2F &);
+  AliH2F & operator = (const AliH2F &);
+  TClonesArray * FindPeaks(Float_t threshold, Float_t noise);  
+    //find peaks and write it in form of AliTPCcluster to array
+  void ClearSpectrum();
+  void AddGauss(Float_t x,Float_t y,Float_t sx, Float_t sy, Float_t max);
+  void AddNoise(Float_t sn);
+  void ClearUnderTh(Int_t threshold);
+  void Round();
+  //round float values to integer values
+  //  void Smooth();
+  AliH2F * GetSubrange2d(Float_t xmin, Float_t xmax, 
+                            Float_t ymin, Float_t ymax); 
+  //create new  2D histogram 
+  Float_t  GetOccupancy(Float_t th=1. , Float_t xmin=0, Float_t xmax=0, 
+                            Float_t ymin=0, Float_t ymax=0);
+  //calculate ration of channel over threshold to all channels
+  TH1F * GetAmplitudes(Float_t zmin, Float_t zmax, Float_t th=1. , Float_t xmin=0, Float_t xmax=0, 
+                            Float_t ymin=0, Float_t ymax=0);
+                      //generate one dim histogram of amplitudes
+  void SetSmoothSigma(Float_t sigmaX, Float_t sigmaY);
+  void SetSmoothRange(Float_t dx,Float_t dy);
+  TMatrix *  GetFitMatrix(Int_t irow, Int_t icolumn);
+public:  
+
+protected:
+
+private:
+  void SmoothCell(Int_t irow, Int_t icolumn) ;
+  Float_t fSigmaX2;   //sigma x  used for weight calculation in smooth proces
+  Float_t fSigmaY2;   //sigma x  used for weight calculation in smooth proces
+  Int_t fdx;        //dx range on which we are smoothing around 1 point
+  Int_t fdy;        //dy  range on which we are smoothing around 1 point
+  TMatrix fFitMatrix; //matrix with fitted parameters 
+  ClassDef(AliH2F,1)
+};
+
+#endif /*TH2FSMOOTH_H */
diff --git a/TPC/AliSegmentArray.cxx b/TPC/AliSegmentArray.cxx
new file mode 100644 (file)
index 0000000..ecea7f8
--- /dev/null
@@ -0,0 +1,342 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:39:36  kowal2
+
+New data structure handling
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  Alice segment manager object                                             //
+//                                
+//  AliSegmentIDArray object  is array of pointers to object derived from 
+//  AliSegmentID object                                                     //
+//  AliSegmentID - object in comparison with TObject enhalt
+//  additional information fSegmentID
+//  
+//                                                                           //
+//                                                                          //
+///////////////////////////////////////////////////////////////////////////////
+
+#include  <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();
+  }
+}
diff --git a/TPC/AliSegmentArray.h b/TPC/AliSegmentArray.h
new file mode 100644 (file)
index 0000000..6ac9caf
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef ALISEGARRAY_H
+#define ALISEGARRAY_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+////////////////////////////////////////////////
+//  Manager class general Alice segment 
+//  segment is for example one pad row in TPC //
+////////////////////////////////////////////////
+
+#include "TNamed.h"
+#include "TError.h"
+//#include "AliSegmentID.h"
+
+class TTree;
+class TBranch;
+class AliArrayI;
+class AliSegmentID;
+class TObjArray;
+class AliSegmentArray: public TNamed{
+public:
+  AliSegmentArray();
+  AliSegmentArray(Text_t *classname, Int_t n);  //
+  Bool_t  SetClass(Text_t *classname);  //set class of stored object
+  ~AliSegmentArray();
+  inline const AliSegmentID * At(Int_t i); //return pointer to segment with index i 
+  inline const AliSegmentID * operator[](Int_t i); //return pointer to segment with index i
+
+  Bool_t AddSegment(AliSegmentID *segment); // add segment to array
+  AliSegmentID * AddSegment(Int_t index);   //create objet and set index
+  Bool_t   MakeArray(Int_t n);       //make array of pointers to Segments
+  void ClearSegment(Int_t index); //remove segment from active   
+  virtual AliSegmentID * NewSegment(); //dynamicaly create new segment 
+  //input output functions
+  TTree * GetTree(){return fTree;}      //return pointer to connected tree
+  
+  virtual void MakeTree();              //Make tree with the name
+  virtual Bool_t ConnectTree(const char * treeName); //connect tree from current directory 
+  virtual AliSegmentID * LoadSegment(Int_t index);//load segment with index to the memory
+  virtual AliSegmentID * LoadEntry(Int_t index); //load segment entry from position index in tree
+  virtual void StoreSegment(Int_t index);//write segmen persistent  
+  Bool_t  MakeDictionary(Int_t size);//create index table for tree
+  TClass * GetClass() {return fClass;}
+  
+public:
+  TObjArray  * fSegment;  //!pointer to array of pointers to segment
+  AliArrayI    * fTreeIndex; //!pointers(index) table in tree
+  Int_t      fNSegment;   
+  TTree    * fTree;   //!tree with segment objects
+  TBranch  * fBranch; //!total branch 
+private: 
+  TClass  *   fClass;    //!class type of included objects 
+  ClassDef(AliSegmentArray,1) 
+};
+
+
+
+const AliSegmentID*  AliSegmentArray::operator[](Int_t i)
+{
+  //
+  //return segment with given index
+  //
+  if ( (i<0) || (i>=fNSegment)) return 0; 
+  return (AliSegmentID *)((*fSegment)[i]);
+}
+const AliSegmentID*  AliSegmentArray::At(Int_t i)
+{
+  //
+  //return segment with given index
+  //
+  if ( (i<0) || (i>=fNSegment)) return 0; 
+  return (AliSegmentID *)((*fSegment)[i]);
+}
+
+#endif //ALISEGARRAY_H
diff --git a/TPC/AliSegmentID.cxx b/TPC/AliSegmentID.cxx
new file mode 100644 (file)
index 0000000..286a83c
--- /dev/null
@@ -0,0 +1,38 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:39:36  kowal2
+
+New data structure handling
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  Alice  AliSementID   object                                             //
+//                                
+//                                                                           //
+//                                                                          //
+///////////////////////////////////////////////////////////////////////////////
+
+
+#include "AliSegmentID.h"
+AliSegmentID::AliSegmentID()
+{
+}
+
+ClassImp(AliSegmentID)
diff --git a/TPC/AliSegmentID.h b/TPC/AliSegmentID.h
new file mode 100644 (file)
index 0000000..3da7ee3
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef ALISEGMENTID_H
+#define ALISEGMENTID_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+////////////////////////////////////////////////
+//  Manager class generaol Alice segment 
+//  segment is for example one pad row in TPC //
+////////////////////////////////////////////////
+
+#include "TObject.h"
+
+class AliSegmentID: public TObject{
+public:
+  AliSegmentID();
+  AliSegmentID(Int_t index){fSegmentID = index;}
+  Int_t GetID() {return fSegmentID;}
+  void  SetID(Int_t index){fSegmentID = index;} 
+protected:
+  Int_t fSegmentID;   //identification number of Segment
+  ClassDef(AliSegmentID,1) 
+};
+   
+#endif //ALISEGMENTID_H
+
diff --git a/TPC/AliSimDigits.cxx b/TPC/AliSimDigits.cxx
new file mode 100644 (file)
index 0000000..32093fa
--- /dev/null
@@ -0,0 +1,394 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:37:42  kowal2
+
+Digits handling in a new data structure
+
+*/
+
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  Alice segment manager object                                             //
+//                                
+//  AliSimDigits object   (derived from AliDigits)                            //
+//  provide additional track information to digit                            //
+//  
+//   Origin: Marian Ivanov  GSI Darmstadt                                     //
+//
+//                                                                           //
+//                                                                          //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "TClass.h"
+#include <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;
+}
+
diff --git a/TPC/AliSimDigits.h b/TPC/AliSimDigits.h
new file mode 100644 (file)
index 0000000..61a3e44
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef ALISIMDIGITS_H
+#define ALISIMDIGITS_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+////////////////////////////////////////////////
+//  Manager class generaol Alice segment digits
+//  segment is for example one pad row in TPC //
+////////////////////////////////////////////////
+#include "TError.h"
+#include   "AliArrayI.h"
+#include   "AliArrayS.h"
+class AliH2F;
+
+
+class AliSimDigits : public AliDigits{
+public: 
+  AliSimDigits();
+  ~AliSimDigits();
+  void AllocateTrack(Int_t length);  //construct empty buffer fTracks with size rows x column x length (number of tracks for one digit)
+  inline Int_t GetTrackIDFast(Int_t row, Int_t column,Int_t level);  //return track ID  at given row and collumn
+  inline void  SetTrackIDFast(Int_t value,Int_t row, Int_t column,Int_t level);  //set ID track at given row and collumn
+  virtual Int_t GetTrackID(Int_t row, Int_t column, Int_t level);
+  virtual void ExpandTrackBuffer();  //expand buffer to twodimensional array
+  virtual void CompresTrackBuffer(Int_t bufType); //compres buffer according buffertype algorithm 
+  AliH2F *  DrawTracks( const char *option=0,Int_t level=0, 
+                 Float_t x1=-1, Float_t x2=-1, Float_t y1=-1, Float_t y2=-1); //draw tracks
+  TClonesArray * GenerTPCClonesArray(TClonesArray * arr); //generate TClonnesArray of digits
+  //only for demonstration purpose
+public:
+  void InvalidateTrack();
+  Int_t GetTrackID1(Int_t row, Int_t column, Int_t level);  //returnb track ID of digits - for buffer compresion 1 
+  void  ExpandTrackBuffer1(); //comress track according algorithm 1 (track ID comression independent to the digit compression) 
+  void  CompresTrackBuffer1(); //comress track according algorithm 1 (track ID comression independent to the digit compression)
+  Int_t GetTrackID2(Int_t row, Int_t column, Int_t level);  //returnb track ID of digits - for buffer compresion 2
+  void  ExpandTrackBuffer2(); //comress track according algorithm 2 (track ID comression according  digit compression)
+  void  CompresTrackBuffer2(); //comress track according algorithm 2 (track ID comression according  digit compression)
+
+  AliArrayI * fTracks;     //buffer of track index 
+  AliArrayI * fTrIndex;    //index position of column
+  Int_t       fNlevel;   //number of tracks etries  for one digit
+  Int_t       fTrBufType;  //buffer type of the tracks
+  // Bool_t      ClassError( ); //signalize class error 
+  ClassDef(AliSimDigits,1) 
+};
+
+
+
+Int_t AliSimDigits::GetTrackIDFast(Int_t row, Int_t column,Int_t level)
+{
+  //
+  //return track ID  at given row and column
+  //  return fTracks[level].At(fTrIndex[level][column]+row); 
+  return fTracks->At(level*fNrows*fNcols+fNrows*column+row); 
+}
+void AliSimDigits::SetTrackIDFast(Int_t value,Int_t row, Int_t column,Int_t level)
+{
+value+=2;
+  //set ID track at given row and collumn
+  //  fTracks[level][fTrIndex[level][column]+row]=value; 
+  if ( (row<0) || (row>=fNrows)  || (column<0) || (column>=fNcols) ) 
+       ::Error("AliSimDigits::SetTrackIDFast", "row %d  col %d out of bounds (size: %d x %d, this: 0x%08x)", 
+          row, column, fNrows, fNcols, this);
+  if ( (level<0) || (level>=fNlevel)) ::Error("AliSimDigits::SetTrackIDFast", "index %d out of bounds", level);
+  (*fTracks)[level*fNrows*fNcols+fNrows*column+row]=value; 
+}
+
+
+
+#endif
index 533e76b..67f3859 100644 (file)
 
 /*
 $Log$
+Revision 1.17.2.2  2000/04/10 08:15:12  kowal2
+
+New, experimental data structure from M. Ivanov
+New tracking algorithm
+Different pad geometry for different sectors
+Digitization rewritten
+
+Revision 1.17.2.1  2000/04/10 07:56:53  kowal2
+Not used anymore - removed
+
+Revision 1.17  2000/01/19 17:17:30  fca
+Introducing a list of lists of hits -- more hits allowed for detector now
+
 Revision 1.16  1999/11/05 09:29:23  fca
 Accept only signals > 0
 
@@ -57,11 +70,18 @@ Introduction of the Copyright and cvs Log
 #include <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"
 
 
 
@@ -81,9 +101,10 @@ AliTPC::AliTPC()
   fNsectors = 0;
   fNtracks  = 0;
   fNclusters= 0;
-
-  fDigParam= new AliTPCD();
-  fDigits = fDigParam->GetArray();
+  //MI changes
+  fDigitsArray = 0;
+  fClustersArray = 0;
+  fTPCParam = 0;
 }
  
 //_____________________________________________________________________________
@@ -97,23 +118,18 @@ AliTPC::AliTPC(const char *name, const char *title)
   //
   // Initialise arrays of hits and digits 
   fHits     = new TClonesArray("AliTPChit",  176);
-  gAlice->AddHitList(fHits);
-  //  fDigits   = new TClonesArray("AliTPCdigit",10000);
-  //MI change
-  fDigParam= new AliTPCD;
-  fDigits = fDigParam->GetArray();
-
-  AliTPCParam  *fTPCParam = &(fDigParam->GetParam());
-
+  //MI change  
+  fDigitsArray = 0;
+  fClustersArray= 0;
+  fTPCParam = 0;
   //
   // Initialise counters
-  //
   fClusters = 0;
   fTracks   = 0;
-  fNsectors = fTPCParam->GetNSector();
+  fNsectors = 0;
   fNtracks  = 0;
   fNclusters= 0;
-  fDigitsIndex = new Int_t[fNsectors+1];
+
   //
   fIshunt     =  0;
   //
@@ -132,8 +148,10 @@ AliTPC::~AliTPC()
   delete fDigits;
   delete fClusters;
   delete fTracks;
-  delete fDigParam;
-  if (fDigitsIndex)   delete [] fDigitsIndex;
+  if (fDigitsArray!=0) delete fDigitsArray;
+  if (fClustersArray!=0) delete fClustersArray;
+
+  if (fTPCParam) delete fTPCParam;
 }
 
 //_____________________________________________________________________________
@@ -153,24 +171,12 @@ void AliTPC::AddCluster(const AliTPCcluster &c)
   //
   // Add a simulated cluster copy to the list
   //
-  if(!fClusters) fClusters=new TClonesArray("AliTPCcluster",10000);
+  if(!fClusters) fClusters=new TClonesArray("AliTPCcluster",900000);
   TClonesArray &lclusters = *fClusters;
   new(lclusters[fNclusters++]) AliTPCcluster(c);
 }
  
 //_____________________________________________________________________________
-void AliTPC::AddDigit(Int_t *tracks, Int_t *digits)
-{
-  //
-  // Add a TPC digit to the list
-  //
-  //  TClonesArray &ldigits = *fDigits;
-  //MI change 
-  TClonesArray &ldigits = *fDigParam->GetArray();
-  new(ldigits[fNdigits++]) AliTPCdigit(tracks,digits);
-}
-//_____________________________________________________________________________
 void AliTPC::AddHit(Int_t track, Int_t *vol, Float_t *hits)
 {
   //
@@ -204,6 +210,7 @@ void AliTPC::AddTrack(const AliTPCtrack& t)
 //_____________________________________________________________________________
 void AliTPC::BuildGeometry()
 {
+
   //
   // Build TPC ROOT TNode geometry for the event display
   //
@@ -215,7 +222,6 @@ void AliTPC::BuildGeometry()
   const Double_t kDegrad=TMath::Pi()/180;
   const Double_t kRaddeg=180./TMath::Pi();
 
-  AliTPCParam * fTPCParam = &(fDigParam->GetParam());
 
   Float_t InnerOpenAngle = fTPCParam->GetInnerAngle();
   Float_t OuterOpenAngle = fTPCParam->GetOuterAngle();
@@ -246,8 +252,8 @@ void AliTPC::BuildGeometry()
 
   //  inner sectors
 
-  rl = fTPCParam->GetInSecLowEdge();
-  ru = fTPCParam->GetInSecUpEdge();
+  rl = fTPCParam->GetInnerRadiusLow();
+  ru = fTPCParam->GetInnerRadiusUp();
  
 
   for(i=0;i<nLo;i++) {
@@ -267,8 +273,8 @@ void AliTPC::BuildGeometry()
 
   // 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);
@@ -283,6 +289,8 @@ void AliTPC::BuildGeometry()
     Node->SetLineColor(kColorTPC);
     fNodes->Add(Node);
   }
+
+
 }  
   
   
@@ -382,21 +390,21 @@ inline Double_t f3(Double_t x1,Double_t y1,
 }
 
 //_____________________________________________________________________________
-static int FindProlongation(AliTPCtrack& t, const AliTPCSector *sec,
-                           int s, int rf=0) 
+static Int_t FindProlongation(AliTPCtrack& t, const AliTPCSector *sec,
+                           Int_t s, Int_t rf=0) 
 {
   //-----------------------------------------------------------------
   // This function tries to find a track prolongation.
   //
   // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
   //-----------------------------------------------------------------
-  const int ROWS_TO_SKIP=int(0.5*sec->GetNRows());
+  const Int_t ROWS_TO_SKIP=(t<10) ? 10 : Int_t(0.5*sec->GetNRows());
   const Float_t MAX_CHI2=12.;
-  int try_again=ROWS_TO_SKIP;
+  Int_t try_again=ROWS_TO_SKIP;
   Double_t alpha=sec->GetAlpha();
-  int ns=int(2*TMath::Pi()/alpha+0.5);
+  Int_t ns=Int_t(2*TMath::Pi()/alpha+0.5);
 
-  for (int nr=sec->GetRowNumber(t.GetX())-1; nr>=rf; nr--) {
+  for (Int_t nr=sec->GetRowNumber(t.GetX())-1; nr>=rf; nr--) {
     Double_t x=sec->GetX(nr), ymax=sec->GetMaxY(nr);
     if (!t.PropagateTo(x)) return 0;
 
@@ -413,7 +421,7 @@ static int FindProlongation(AliTPCtrack& t, const AliTPCSector *sec,
     }
 
     if (row) {
-      for (int i=row.Find(y-road); 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;
@@ -426,9 +434,8 @@ static int FindProlongation(AliTPCtrack& t, const AliTPCSector *sec,
     }
     if (cl) {
       t.Update(cl,max_chi2);
-      Double_t ll=TMath::Sqrt((1+t.GetTgl()*t.GetTgl())/
+      cl->fdEdX=sec->GetPadPitchWidth()*TMath::Sqrt((1+t.GetTgl()*t.GetTgl())/
                (1-(t.GetC()*x-t.GetEta())*(t.GetC()*x-t.GetEta())));
-      cl->fdEdX = cl->fQ/ll;
       try_again=ROWS_TO_SKIP;
     } else {
       if (try_again==0) break;
@@ -444,12 +451,13 @@ static int FindProlongation(AliTPCtrack& t, const AliTPCSector *sec,
   }
 
   return 1;
+
 }
 
 
 //_____________________________________________________________________________
-static void MakeSeeds(TObjArray& seeds,const AliTPCSector *sec, int max_sec,
-int i1, int i2)
+static void MakeSeeds(TObjArray& seeds,const AliTPCSector *sec, Int_t max_sec,
+Int_t i1, Int_t i2)
 {
   //-----------------------------------------------------------------
   // This function creates track seeds.
@@ -457,19 +465,19 @@ int i1, int i2)
   // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
   //-----------------------------------------------------------------
   TMatrix C(5,5); TVector x(5);
-  double alpha=sec->GetAlpha(), shift=sec->GetAlphaShift();
-  double cs=cos(alpha), sn=sin(alpha);
-  for (int ns=0; 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;
@@ -493,13 +501,18 @@ int i1, int i2)
             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;
@@ -508,20 +521,21 @@ int i1, int i2)
 
        Double_t a=asin(x(3));
        Double_t zv=z1 - x(4)/x(2)*(a+asin(x(2)*x1-x(3)));
-       if (TMath::Abs(zv)>33.) continue; 
+       if (TMath::Abs(zv)>10.) continue; 
 
        TMatrix X(6,6); X=0.; 
        X(0,0)=r1[is]->fSigmaY2; X(1,1)=r1[is]->fSigmaZ2;
        X(2,2)=cl->fSigmaY2;     X(3,3)=cl->fSigmaZ2;
-       X(4,4)=3./12.; X(5,5)=3./12.;
+       X(4,4)=cl->fSigmaY2;     X(5,5)=cl->fSigmaZ2;
+       //X(4,4)=3./12.; X(5,5)=3./12.;
        TMatrix F(5,6); F.UnitMatrix();
        Double_t sy=sqrt(X(0,0)), sz=sqrt(X(1,1));
-       F(2,0)=(f1(x1,y1+sy,x2,y2,0.,0.)-x(2))/sy;
-       F(2,2)=(f1(x1,y1,x2,y2+sy,0.,0.)-x(2))/sy;
-       F(2,4)=(f1(x1,y1,x2,y2,0.,0.+sy)-x(2))/sy;
-       F(3,0)=(f2(x1,y1+sy,x2,y2,0.,0.)-x(3))/sy;
-       F(3,2)=(f2(x1,y1,x2,y2+sy,0.,0.)-x(3))/sy;
-       F(3,4)=(f2(x1,y1,x2,y2,0.,0.+sy)-x(3))/sy;
+       F(2,0)=(f1(x1,y1+sy,x2,y2,x3,y3)-x(2))/sy;
+       F(2,2)=(f1(x1,y1,x2,y2+sy,x3,y3)-x(2))/sy;
+       F(2,4)=(f1(x1,y1,x2,y2,x3,y3+sy)-x(2))/sy;
+       F(3,0)=(f2(x1,y1+sy,x2,y2,x3,y3)-x(3))/sy;
+       F(3,2)=(f2(x1,y1,x2,y2+sy,x3,y3)-x(3))/sy;
+       F(3,4)=(f2(x1,y1,x2,y2,x3,y3+sy)-x(3))/sy;
        F(4,0)=(f3(x1,y1+sy,x2,y2,z1,z2)-x(4))/sy;
        F(4,1)=(f3(x1,y1,x2,y2,z1+sz,z2)-x(4))/sz;
        F(4,2)=(f3(x1,y1,x2,y2+sy,z1,z2)-x(4))/sy;
@@ -533,7 +547,7 @@ int i1, int i2)
        C.Mult(t,TMatrix(TMatrix::kTransposed,F));
 
        AliTPCtrack *track=new AliTPCtrack(r1[is], x, C, x1, ns*alpha+shift);
-       int rc=FindProlongation(*track,sec,ns,i2);
+        Int_t rc=FindProlongation(*track,sec,ns,i2);
         if (rc<0 || *track<(i1-i2)/2) delete track;
         else seeds.AddLast(track); 
       }
@@ -552,21 +566,22 @@ void AliTPC::Clusters2Tracks()
   //-----------------------------------------------------------------
   if (!fClusters) return;
 
-  AliTPCParam *p=&fDigParam->GetParam();
+  AliTPCParam *p=fTPCParam;
   AliTPCSector::SetParam(p);
 
-  const int nis=p->GetNInnerSector()/2;
+  const Int_t nis=p->GetNInnerSector()/2;
   AliTPCSSector *ssec=new AliTPCSSector[nis];         
-  int nrow_low=ssec->GetNRows();     
+  Int_t nrow_low=ssec->GetNRows();     
 
-  const int nos=p->GetNOuterSector()/2;
+  const Int_t nos=p->GetNOuterSector()/2;
   AliTPCLSector *lsec=new AliTPCLSector[nos];
-  int nrow_up=lsec->GetNRows();
+  Int_t nrow_up=lsec->GetNRows();
 
-  int ncl=fClusters->GetEntriesFast();
+  Int_t ncl=fClusters->GetEntriesFast();
   while (ncl--) {
     AliTPCcluster *c=(AliTPCcluster*)fClusters->UncheckedAt(ncl);
     Int_t sec=c->fSector, row=c->fPadRow;
+
     if (sec<nis*2) {
       ssec[sec%nis][row].InsertCluster(c);
     } else {
@@ -577,44 +592,46 @@ void AliTPC::Clusters2Tracks()
   
   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;
+
 }
 
 //_____________________________________________________________________________
@@ -897,58 +914,77 @@ void AliTPC::CreateMaterials()
 
   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);
 }
 
 //_____________________________________________________________________________
@@ -959,31 +995,26 @@ void AliTPC::Digits2Clusters()
   //
   // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
   //-----------------------------------------------------------------
-  AliTPCParam *par = &(fDigParam->GetParam());
-  
-  int inp=par->GetNPads(0,                  par->GetNRowLow()-1);
-  int onp=par->GetNPads(par->GetNSector()-1,par->GetNRowUp() -1);
-  const int MAXY=(inp>onp) ? inp+2 : onp+2;
-  const int MAXTBKT=int((z_end+6*par->GetZSigma())/par->GetZWidth())+1;
-  const int MAXZ=MAXTBKT+2;
-  const int THRESHOLD=20;
-  
-  TTree *t=(TTree*)gDirectory->Get("TreeD0_Param1");
-  t->GetBranch("Digits")->SetAddress(&fDigits);
-  Int_t sectors_by_rows=(Int_t)t->GetEntries();
-  
-  int ncls=0;
-  
+  AliTPCParam *par = fTPCParam;
+  const Int_t MAXZ=par->GetMaxTBin()+2;
+
+  TTree *t = (TTree *)gDirectory->Get("TreeD_75x40_100x60");
+  AliSimDigits digarr, *dummy=&digarr;
+  t->GetBranch("Segment")->SetAddress(&dummy);
+  Stat_t sectors_by_rows = t->GetEntries();
   for (Int_t n=0; 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;
@@ -993,174 +1024,108 @@ void AliTPC::Digits2Clusters()
        }
     }
 
-    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()
 {
   //--------------------------------------------------------
@@ -1173,7 +1138,11 @@ void AliTPC::Hits2Clusters()
   // Origin: Marek Kowalski  IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
   //-----------------------------------------------------------------
 
-  AliTPCParam * fTPCParam = &(fDigParam->GetParam());
+   if(fTPCParam == 0){
+     printf("AliTPCParam MUST be created firstly\n");
+     return;
+   }
+
   Float_t sigma_rphi,sigma_z,cl_rphi,cl_z;
   //
   TParticle *particle; // pointer to a given particle
@@ -1191,22 +1160,19 @@ void AliTPC::Hits2Clusters()
   
   TTree *TH = gAlice->TreeH();
   Stat_t ntracks = TH->GetEntries();
-  Particles=gAlice->Particles();
   
   //------------------------------------------------------------
-  // Loop over all sectors (72 sectors)
-  // Sectors 0-35 are lower sectors, 0-17 z>0, 18-35 z<0
+  // Loop over all sectors (72 sectors for 20 deg
+  // segmentation for both lower and upper sectors)
+  // Sectors 0-35 are lower sectors, 0-17 z>0, 17-35 z<0
   // Sectors 36-71 are upper sectors, 36-53 z>0, 54-71 z<0
   //
   // First cluster for sector 0 starts at "0"
   //------------------------------------------------------------
-  
-  
-  //
-  int Nsectors=fDigParam->GetParam().GetNSector();
-  for(Int_t isec=0; 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
@@ -1220,11 +1186,13 @@ void AliTPC::Hits2Clusters()
       //  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;
@@ -1255,45 +1223,202 @@ void AliTPC::Hits2Clusters()
        if(cl_z < 0.) cl_z=2.5e-5;
        
        //
-       // smearing --> rotate sectors firstly,
+       
+       //
+       // smearing --> rotate to the 1 (13) or to the 25 (49) sector,
        // then the inaccuracy in a X-Y plane is only along Y (pad row)!
        //
-       Float_t xprim= tpcHit->fX*cph + tpcHit->fY*sph;
+       //Float_t xprim= tpcHit->fX*cph + tpcHit->fY*sph;
        Float_t yprim=-tpcHit->fX*sph + tpcHit->fY*cph;
        xyz[0]=gRandom->Gaus(yprim,TMath::Sqrt(sigma_rphi));   // y
-        Double_t alpha=(sector < fTPCParam->GetNInnerSector()) ?
-        fTPCParam->GetInnerAngle() : fTPCParam->GetOuterAngle();
-       if (TMath::Abs(xyz[0]/xprim) > TMath::Tan(0.5*alpha)) xyz[0]=yprim;
        xyz[1]=gRandom->Gaus(tpcHit->fZ,TMath::Sqrt(sigma_z)); // z 
-        if (TMath::Abs(xyz[1]) > 250) xyz[1]=tpcHit->fZ;
-       xyz[2]=tpcHit->fQ+1;// q; let it be not equal to zero (Y.Belikov)
+       xyz[2]=tpcHit->fQ;                                     // q
        xyz[3]=sigma_rphi;                                     // fSigmaY2
        xyz[4]=sigma_z;                                        // fSigmaZ2
-               
-       // and finally add the cluster
-       Int_t tracks[5]={tpcHit->fTrack, -1, -1, sector, tpcHit->fPadRow};
+       
+        Int_t tracks[5]={tpcHit->fTrack, -1, -1, sector, tpcHit->fPadRow};
        AddCluster(xyz,tracks);
        
       } // end of loop over hits
-    }   // end of loop over tracks 
+    }   // end of loop over tracks     
     
-    
-  } // end of loop over sectors
+  } // end of loop over sectors  
+  
+} // end of function
+
+//_________________________________________________________________
+void AliTPC::Hits2ExactClustersSector(Int_t isec)
+{
+  //--------------------------------------------------------
+  //calculate exact cross point of track and given pad row
+  //resulting values are expressed in "digit" coordinata
+  //--------------------------------------------------------
+
+  //-----------------------------------------------------------------
+  // Origin: Marian Ivanov  GSI Darmstadt, m.ivanov@gsi.de
+  //-----------------------------------------------------------------
+  //
+  if (fClustersArray==0){    
+    return;
+  }
+  //
+  TParticle *particle; // pointer to a given particle
+  AliTPChit *tpcHit; // pointer to a sigle TPC hit
+  TClonesArray *Particles; //pointer to the particle list
+  Int_t sector,nhits;
+  Int_t ipart;
+  const Int_t cmaxhits=30000;
+  TVector * xxxx = new TVector(cmaxhits*4);
+  TVector & xxx = *xxxx;
+  Int_t maxhits = cmaxhits;
+  //construct array for each padrow
+  for (Int_t i=0; 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);
+
 }
 
 
@@ -1312,7 +1437,7 @@ void AliTPC::Hits2DigitsSector(Int_t isec)
   //  Get the access to the track hits
   //-------------------------------------------------------
 
-  AliTPCParam * fTPCParam = &(fDigParam->GetParam());
+
   TTree *TH = gAlice->TreeH(); // pointer to the hits tree
   Stat_t ntracks = TH->GetEntries();
 
@@ -1322,20 +1447,7 @@ void AliTPC::Hits2DigitsSector(Int_t isec)
   //  Only if there are any tracks...
   //-------------------------------------------
 
-    
-    // TObjArrays for three neighouring pad-rows
-
-    TObjArray **rowTriplet = new TObjArray* [3]; 
-    
-    // TObjArray-s for each pad-row
-
     TObjArray **row;
-      
-    for (Int_t trip=0;trip<3;trip++){  
-      rowTriplet[trip]=new TObjArray;
-    }
-
-
     
       printf("*** Processing sector number %d ***\n",isec);
 
@@ -1354,203 +1466,38 @@ void AliTPC::Hits2DigitsSector(Int_t isec)
 
       Int_t i;
 
-      for (i=0;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
@@ -1559,140 +1506,69 @@ void AliTPC::DigitizeRow(Int_t irow,Int_t isec,TObjArray **rowTriplet)
 
   //-----------------------------------------------------------------
   // Origin: Marek Kowalski  IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
+  // Modified: Marian Ivanov GSI Darmstadt, m.ivanov@gsi.de
   //-----------------------------------------------------------------
  
 
-  AliTPCParam * fTPCParam = &(fDigParam->GetParam());
-  Float_t chipgain= fTPCParam->GetChipGain();
   Float_t zerosup = fTPCParam->GetZeroSup();
   Int_t nrows =fTPCParam->GetNRow(isec);
-  const int MAXTBKT=
-  int((z_end+6*fTPCParam->GetZSigma())/fTPCParam->GetZWidth())+1;
+  fCurrentIndex[1]= isec;
   
-  Int_t nTracks[3];
-  Int_t n_of_pads[3];
-  Int_t IndexRange[4];
-  Int_t i1;
-  Int_t iFlag; 
-
-  //
-  // iFlag = 0 -> inner row, iFlag = 1 -> the middle one, iFlag = 2 -> the outer one
-  //
 
-  nTracks[0]=rowTriplet[0]->GetEntries(); // lower row
-  nTracks[1]=rowTriplet[1]->GetEntries(); // middle row
-  nTracks[2]=rowTriplet[2]->GetEntries(); // upper row
-
-    
-  if(irow == 0){
-    iFlag=0;
-    n_of_pads[0]=fTPCParam->GetNPads(isec,0);
-    n_of_pads[1]=fTPCParam->GetNPads(isec,1);
-  }
-  else if(irow == nrows-1){
-     iFlag=2;
-     n_of_pads[1]=fTPCParam->GetNPads(isec,irow-1);
-     n_of_pads[2]=fTPCParam->GetNPads(isec,irow);
-  }
-  else {
-    iFlag=1;
-    for(i1=0;i1<3;i1++){
-       n_of_pads[i1]=fTPCParam->GetNPads(isec,irow-1+i1);
-    }
-  }
+  Int_t n_of_pads = fTPCParam->GetNPads(isec,irow);
+  Int_t n_of_tbins = fTPCParam->GetMaxTBin();
+  Int_t IndexRange[4];
   //
   //  Integrated signal for this row
   //  and a single track signal
-  // 
-   
-  TMatrix *m1   = new TMatrix(0,n_of_pads[iFlag]-1,0,MAXTBKT-1); // integrated
-  TMatrix *m2   = new TMatrix(0,n_of_pads[iFlag]-1,0,MAXTBKT-1); // single
-
+  //    
+  TMatrix *m1   = new TMatrix(0,n_of_pads,0,n_of_tbins); // integrated
+  TMatrix *m2   = new TMatrix(0,n_of_pads,0,n_of_tbins); // single
   //
-
   TMatrix &Total  = *m1;
 
   //  Array of pointers to the label-signal list
 
-  Int_t NofDigits = n_of_pads[iFlag]*MAXTBKT; // number of digits for this row
-
+  Int_t NofDigits = n_of_pads*n_of_tbins; // number of digits for this row
   Float_t  **pList = new Float_t* [NofDigits]; 
 
   Int_t lp;
-
+  Int_t i1;   
   for(lp=0;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
 
       //
@@ -1703,15 +1579,20 @@ void AliTPC::DigitizeRow(Int_t irow,Int_t isec,TObjArray **rowTriplet)
         tracks[j1] = (pList[gi]) ?(Int_t)(*(pList[gi]+j1)) : -1;
       }
 
-      digits[0]=isec;
-      digits[1]=irow;
-      digits[2]=ip;
-      digits[3]=it;
-      digits[4]= (Int_t)q;
-
-      //  Add this digit
-
-      AddDigit(tracks,digits);
+//Begin_Html
+/*
+  <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 
@@ -1728,11 +1609,13 @@ void AliTPC::DigitizeRow(Int_t irow,Int_t isec,TObjArray **rowTriplet)
 
   delete m1;
   delete m2;
-  delete m3;
+  //  delete m3;
 
 } // end of DigitizeRow
+
 //_____________________________________________________________________________
-Float_t AliTPC::GetSignal(TObjArray *p1, Int_t ntr, Int_t np, TMatrix *m1, TMatrix *m2,
+
+Float_t AliTPC::GetSignal(TObjArray *p1, Int_t ntr, TMatrix *m1, TMatrix *m2,
                           Int_t *IndexRange)
 {
 
@@ -1744,111 +1627,55 @@ Float_t AliTPC::GetSignal(TObjArray *p1, Int_t ntr, Int_t np, TMatrix *m1, TMatr
 
   //-----------------------------------------------------------------
   // Origin: Marek Kowalski  IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
+  // Modified: Marian Ivanov 
   //-----------------------------------------------------------------
 
   TVector *tv;
-  AliTPCParam * fTPCParam = &(fDigParam->GetParam());
-  AliTPCPRF2D * fPRF2D = &(fDigParam->GetPRF2D());
-  AliTPCRF1D  * fRF    = &(fDigParam->GetRF()); 
-  const int MAXTBKT=
-  int((z_end+6*fTPCParam->GetZSigma())/fTPCParam->GetZWidth())+1;
  
-  //to make the code faster we put parameters  to the stack
-
-  Float_t zwidth  = fTPCParam->GetZWidth();
-  Float_t zwidthm1  =1./zwidth;
-
   tv = (TVector*)p1->At(ntr); // pointer to a track
   TVector &v = *tv;
   
   Float_t label = v(0);
+  Int_t CentralPad = (fTPCParam->GetNPads(fCurrentIndex[1],fCurrentIndex[3])-1)/2;
 
-  Int_t CentralPad = (np-1)/2;
-  Int_t PadNumber;
   Int_t nElectrons = (tv->GetNrows()-1)/4;
-  Float_t range=((np-1)/2 + 0.5)*fTPCParam->GetPadPitchWidth(); // pad range
-
-  range -= 0.5; // dead zone, 5mm from the edge, according to H.G. Fischer
-  
-  Float_t IneffFactor = 0.5; // inefficiency in the gain close to the edge, as above
-
-
-  Float_t PadSignal[7]; // signal from a single electron
-
-  TMatrix &signal = *m1;
-  TMatrix &total = *m2;
-
-
   IndexRange[0]=9999; // min pad
   IndexRange[1]=-1; // max pad
   IndexRange[2]=9999; //min time
   IndexRange[3]=-1; // max time
 
+  //  Float_t IneffFactor = 0.5; // inefficiency in the gain close to the edge, as above
+
+  TMatrix &signal = *m1;
+  TMatrix &total = *m2;
   //
   //  Loop over all electrons
   //
-
   for(Int_t nel=0; 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
 }
 
@@ -1874,7 +1701,7 @@ void AliTPC::GetList(Float_t label,Int_t np,TMatrix *m,Int_t *IndexRange,
 
         // accept only the contribution larger than 500 electrons (1/2 s_noise)
 
-        if(signal(ip,it)<500.) continue; 
+        if(signal(ip,it)<0.5) continue; 
 
 
         Int_t GlobalIndex = it*np+ip; // GlobalIndex starts from 0!
@@ -1943,7 +1770,6 @@ void AliTPC::GetList(Float_t label,Int_t np,TMatrix *m,Int_t *IndexRange,
 
 
 
-
 }//end of GetList
 //___________________________________________________________________
 void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
@@ -1960,9 +1786,9 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
   // Origin: Marek Kowalski  IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
   //-----------------------------------------------------------------
 
-  AliTPCParam * fTPCParam = &(fDigParam->GetParam());
+  Float_t gasgain = fTPCParam->GetGasGain();
   Int_t i;
-  Float_t xyz[3]; 
+  Float_t xyz[4]; 
 
   AliTPChit *tpcHit; // pointer to a sigle TPC hit    
  
@@ -1976,7 +1802,7 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
     row[i] = new TObjArray;
   }
   Int_t *n_of_electrons = new Int_t [nrows]; // electron counter for each row
-  TVector **tr = new TVector* [nrows]; //pointers to the track vectors
+  TVector **tracks = new TVector* [nrows]; //pointers to the track vectors
 
   //--------------------------------------------------------------------
   //  Loop over tracks, the "track" contains the full history
@@ -2003,7 +1829,7 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
       tpcHit = (AliTPChit*)fHits->UncheckedAt(hit); // get a pointer to a hit
       
       Int_t sector=tpcHit->fSector; // sector number
-      if(sector != isec) continue; //terminate iteration
+      if(sector != isec) continue; 
 
        currentTrack = tpcHit->fTrack; // track number
         if(currentTrack != previousTrack){
@@ -2013,19 +1839,19 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
           for(i=0;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
               
@@ -2038,7 +1864,9 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
        //  Calculate the electron attachment probability
        //---------------------------------------------------
 
-        Float_t time = 1.e6*(z_end-TMath::Abs(tpcHit->fZ))/fTPCParam->GetDriftV(); 
+
+        Float_t time = 1.e6*(fTPCParam->GetZLength()-TMath::Abs(tpcHit->fZ))
+                                                        /fTPCParam->GetDriftV(); 
        // in microseconds!     
        Float_t AttProb = fTPCParam->GetAttCoef()*
          fTPCParam->GetOxyCont()*time; //  fraction! 
@@ -2046,41 +1874,43 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
        //-----------------------------------------------
        //  Loop over electrons
        //-----------------------------------------------
-
+       Int_t index[3];
+       index[1]=isec;
         for(Int_t nel=0;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
@@ -2092,172 +1922,22 @@ void AliTPC::MakeSector(Int_t isec,Int_t nrows,TTree *TH,
 
      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
 
 
 //_____________________________________________________________________________
@@ -2313,8 +1993,7 @@ void AliTPC::ResetDigits()
   // reset clusters
   //
   fNdigits   = 0;
-  //  if (fDigits)   fDigits->Clear();
-  if (fDigParam->GetArray()!=0)  fDigParam->GetArray()->Clear();
+  if (fDigits)   fDigits->Clear();
   fNclusters = 0;
   if (fClusters) fClusters->Clear();
 }
@@ -2432,6 +2111,42 @@ void AliTPC::SetGasMixt(Int_t nc,Int_t c1,Int_t c2,Int_t c3,Float_t p1,
  
 }
 //_____________________________________________________________________________
+
+void AliTPC::TransportElectron(Float_t *xyz, Int_t *index)
+{
+  //
+  // electron transport taking into account:
+  // 1. diffusion, 
+  // 2.ExB at the wires
+  // 3. nonisochronity
+  //
+  // xyz and index must be already transformed to system 1
+  //
+
+  fTPCParam->Transform1to2(xyz,index);
+  
+  //add diffusion
+  Float_t driftl=xyz[2];
+  if(driftl<0.01) driftl=0.01;
+  driftl=TMath::Sqrt(driftl);
+  Float_t sig_t = driftl*(fTPCParam->GetDiffT());
+  Float_t sig_l = driftl*(fTPCParam->GetDiffL());
+  xyz[0]=gRandom->Gaus(xyz[0],sig_t);
+  xyz[1]=gRandom->Gaus(xyz[1],sig_t);
+  xyz[2]=gRandom->Gaus(xyz[2],sig_l);
+
+  // ExB
+  
+  if (fTPCParam->GetMWPCReadout()==kTRUE){
+    Float_t x1=xyz[0];
+    fTPCParam->Transform2to2NearestWire(xyz,index);
+    Float_t dx=xyz[0]-x1;
+    xyz[1]+=dx*(fTPCParam->GetOmegaTau());
+  }
+  //add nonisochronity (not implemented yet)
+  
+}
+//_____________________________________________________________________________
 void AliTPC::Streamer(TBuffer &R__b)
 {
   //
@@ -2444,7 +2159,7 @@ void AliTPC::Streamer(TBuffer &R__b)
       R__b >> fNsectors;
       R__b >> fNclusters;
       R__b >> fNtracks;
-      fDigitsIndex   = new Int_t[fNsectors+1];
+
    } else {
       R__b.WriteVersion(AliTPC::IsA());
       AliDetector::Streamer(R__b);
@@ -2483,8 +2198,10 @@ void AliTPCcluster::GetXYZ(Float_t *x, const AliTPCParam *par) const
   x[0]=par->GetPadRowRadii(fSector,fPadRow);
   x[1]=fY;
   x[2]=fZ;
-  par->CRXYZtoXYZ(x,fSector,fPadRow,1);
-  x[2]=fZ;
+  Float_t cs, sn, tmp;
+  par->AdjustCosSin(fSector,cs,sn);
+  tmp = x[0]*cs-x[1]*sn;
+  x[1]= x[0]*sn+x[1]*cs; x[0]=tmp;
 }
  
 //_____________________________________________________________________________
@@ -2554,6 +2271,7 @@ AliTPCtrack::AliTPCtrack(Float_t *hits)
   //
   fX=hits[0]; // This is dummy code !
 }
+//_________________________________________________________________________
 
 AliTPCtrack::AliTPCtrack(const AliTPCcluster *c,const TVector& xx,
                         const TMatrix& CC, Double_t xref, Double_t alpha):
@@ -2582,15 +2300,15 @@ AliTPCtrack::AliTPCtrack(const AliTPCtrack& t) : x(t.x), C(t.C),
   fX=t.fX;
   fChi2=t.fChi2;
   fAlpha=t.fAlpha;
-  int n=t.fClusters.GetEntriesFast();
-  for (int i=0; i<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;
@@ -2602,7 +2320,7 @@ Int_t AliTPCtrack::Compare(TObject *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.
@@ -2614,7 +2332,7 @@ int AliTPCtrack::PropagateTo(Double_t xk,Double_t x0,Double_t rho,Double_t pm)
     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);
   
@@ -2631,9 +2349,9 @@ int AliTPCtrack::PropagateTo(Double_t xk,Double_t x0,Double_t rho,Double_t pm)
   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);
@@ -2654,37 +2372,16 @@ int AliTPCtrack::PropagateTo(Double_t xk,Double_t x0,Double_t rho,Double_t pm)
   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;
 }
 
@@ -2729,7 +2426,9 @@ void AliTPCtrack::Update(const AliTPCcluster *c, Double_t chisq)
   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;
@@ -2738,13 +2437,13 @@ void AliTPCtrack::Update(const AliTPCcluster *c, Double_t chisq)
   
   TMatrix saveC=C;
   C.Mult(K,tmp); C-=saveC; C*=-1;
-  
+
   fClusters.AddLast((AliTPCcluster*)c);
   fChi2 += chisq;
 }
 
 //_____________________________________________________________________________
-int AliTPCtrack::Rotate(Double_t alpha)
+Int_t AliTPCtrack::Rotate(Double_t alpha)
 {
   //-----------------------------------------------------------------
   // This function rotates this track.
@@ -2795,8 +2494,8 @@ void AliTPCtrack::UseClusters() const
   //
   // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
   //-----------------------------------------------------------------
-  int num_of_clusters=fClusters.GetEntriesFast();
-  for (int i=0; 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();   
@@ -2835,31 +2534,31 @@ Double_t AliTPCtrack::GetPredictedChi2(const AliTPCcluster *c) const
 }
 
 //_____________________________________________________________________________
-struct S { int lab; int max; };
-int AliTPCtrack::GetLabel(int nrows) const 
+struct S { Int_t lab; Int_t max; };
+Int_t AliTPCtrack::GetLabel(Int_t nrows) const 
 {
   //-----------------------------------------------------------------
   // This function returns the track label. If label<0, this track is fake.
   //
   // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
   //-----------------------------------------------------------------
-  int num_of_clusters=fClusters.GetEntriesFast();
+  Int_t num_of_clusters=fClusters.GetEntriesFast();
   S *s=new S[num_of_clusters];
-  int i;
+  Int_t i;
   for (i=0; 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;}
     
@@ -2871,9 +2570,9 @@ int AliTPCtrack::GetLabel(int nrows) const
         TMath::Abs(c->fTracks[2]) == lab ) max++;
   }
   
-  if (1.-float(max)/num_of_clusters > 0.10) return -lab;
+  if (1.-Float_t(max)/num_of_clusters > 0.10) return -lab;
   
-  int tail=int(0.08*nrows);
+  Int_t tail=Int_t(0.08*nrows);
   if (num_of_clusters < tail) return lab;
   
   max=0;
@@ -2883,7 +2582,7 @@ int AliTPCtrack::GetLabel(int nrows) const
         lab == TMath::Abs(c->fTracks[1]) ||
         lab == TMath::Abs(c->fTracks[2])) max++;
   }
-  if (max < int(0.5*tail)) return -lab;
+  if (max < Int_t(0.5*tail)) return -lab;
   
   return lab;
 }
@@ -2914,19 +2613,18 @@ Double_t AliTPCtrack::GetdEdX(Double_t low, Double_t up) const {
   //
   // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
   //-----------------------------------------------------------------
-  int ncl=fClusters.GetEntriesFast();
-  int n=0;
+  Int_t ncl=fClusters.GetEntriesFast();
+  Int_t n=0;
   Double_t *q=new Double_t[ncl];
-  int i;
-  for (i=0; 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++) {
@@ -2936,7 +2634,7 @@ Double_t AliTPCtrack::GetdEdX(Double_t low, Double_t up) const {
     }
   } 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);
@@ -2957,12 +2655,13 @@ void AliTPCRow::InsertCluster(const AliTPCcluster* c) {
     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 
   //
@@ -2970,11 +2669,12 @@ int AliTPCRow::Find(Double_t y) const {
   //-----------------------------------------------------------------------
   if (y <= clusters[0]->fY) return 0;
   if (y > clusters[num_of_clusters-1]->fY) return num_of_clusters;
-  int b=0, e=num_of_clusters-1, m=(b+e)/2;
+  Int_t b=0, e=num_of_clusters-1, m=(b+e)/2;
   for (; b<e; m=(b+e)/2) {
     if (y > clusters[m]->fY) b=m+1;
     else e=m; 
   }
   return m;
 }
+//________________________________________________________________________
 
index 8dd5b50..fc8c181 100644 (file)
@@ -8,11 +8,9 @@
 ////////////////////////////////////////////////
 //  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>
@@ -21,8 +19,9 @@
 class AliTPCcluster;
 class AliTPCtrack;
 class AliTPCParam;
-//MI changes
-class AliTPCD;
+
+class AliTPCDigitsArray;
+class AliTPCClustersArray;
 
 class AliTPC : public AliDetector {
 protected:
@@ -34,8 +33,12 @@ protected:
   Int_t          fNsectors;         // Number of sectors in TPC
   Int_t          fNclusters;        // Number of clusters in TPC
   Int_t          fNtracks;          // Number of tracks in TPC
-  Int_t          *fClustersIndex;   // Index for each sector in fClusters
-  Int_t          *fDigitsIndex;     // Index for each sector in fDigits
+  TClonesArray   *fClusters;        // List of clusters for all sectors
+  TClonesArray   *fTracks;          // List of reconstructed tracks
+  //MI changes
+  AliTPCDigitsArray * fDigitsArray;              //detector digit object  
+  AliTPCClustersArray * fClustersArray; //detector cluster object
+  AliTPCParam *fTPCParam;
 
   //MK changes
 
@@ -44,19 +47,12 @@ protected:
   Int_t          fMixtComp[3]; // drift gas components
   Float_t        fMixtProp[3]; // mixture proportions
 
-  //   
-
-  TClonesArray   *fClusters;        // List of clusters for all sectors
-  TClonesArray   *fTracks;          // List of reconstructed tracks
-  //MI changes
-  AliTPCD * fDigParam;              //detector parameters  
 public:
   AliTPC();
   AliTPC(const char *name, const char *title);
   virtual      ~AliTPC();
   virtual void  AddCluster(Float_t*, Int_t*);
   /*virtual*/void  AddCluster(const AliTPCcluster&);
-  virtual void  AddDigit(Int_t*, Int_t*);
   virtual void  AddHit(Int_t, Int_t*, Float_t*);
   virtual void  AddTrack(Float_t*);
   /*virtual*/void  AddTrack(const AliTPCtrack&);
@@ -65,6 +61,7 @@ public:
   virtual void  CreateGeometry() {}
   virtual void  CreateMaterials();
   virtual void  Hits2Clusters();
+  virtual void  Hits2ExactClustersSector(Int_t isec); // MI change calculate "exact" cluster position
 
   virtual void  Hits2Digits();   //MI change
   virtual void Hits2DigitsSector(Int_t isec);  //MI change
@@ -74,8 +71,7 @@ public:
   virtual void  Clusters2Tracks();
   TClonesArray  *Clusters() {return fClusters;}
   TClonesArray  *Tracks()   {return fTracks;}
-  Int_t         *GetClustersIndex() {return fClustersIndex;}
-  Int_t         *GetDigitsIndex()   {return fDigitsIndex;}
+
   Int_t         GetNsectors()       {return fNsectors;}
   virtual void  MakeBranch(Option_t *opt=" ");
   virtual void  ResetDigits();
@@ -85,6 +81,9 @@ public:
   virtual void  SetSecUps (Int_t s1,Int_t s2,Int_t s3,Int_t s4,Int_t s5, Int_t s6,
                           Int_t s7,Int_t s8,Int_t s9,Int_t s10, Int_t s11, Int_t s12);
   virtual void  SetSens(Int_t sens);
+
+  //MK changes
+
   //MK changes
 
   virtual void  SetSide(Float_t side);
@@ -93,24 +92,25 @@ public:
 
   virtual void  StepManager()=0;
   virtual void  DrawDetector() {}
-  AliTPCD*  GetDigParam() {return fDigParam;} //MI change8
-  void SetDigParam(AliTPCD* param) {fDigParam=param;}  //MI must think about it
+  AliTPCDigitsArray*  GetDigitsArray() {return fDigitsArray;} //MI change
+  AliTPCClustersArray* GetClustersArray(){return fClustersArray;} //MI change
+  AliTPCParam *GetParam(){return fTPCParam;} // M.K, M.I changes
+  void SetParam(AliTPCParam *param){fTPCParam=param;} // M.K, M.I changes
+  void SetDigitsArray(AliTPCDigitsArray* param) {fDigitsArray=param;}  //MI change
+  void SetClustersArray(AliTPCClustersArray *clusters) {fClustersArray = clusters;} //MI change
 private:
   //
-  void ElDiff(Float_t *xyz);
-  void MakeTriplet(Int_t row,TObjArray **rowTriplet, 
-                   TObjArray **prow);
-
-  void ExB(Float_t *xyz);
   void DigitizeRow(Int_t irow,Int_t isec,TObjArray **rowTriplet);
-  Float_t GetSignal(TObjArray *p1, Int_t ntr, Int_t np, TMatrix *m1, TMatrix *m2,
+  Float_t GetSignal(TObjArray *p1, Int_t ntr, TMatrix *m1, TMatrix *m2,
                     Int_t *IndexRange);
   void GetList (Float_t label,Int_t np,TMatrix *m,Int_t *IndexRange,
                 Float_t **pList);
   void MakeSector(Int_t isec,Int_t nrows,TTree *TH,Stat_t ntracks,TObjArray **row);
-  void GetCrossTalk (Int_t iFlag,TObjArray *p,Int_t ntracks,Int_t *npads,
-                     TMatrix *m);
-
+  void TransportElectron(Float_t *xyz, Int_t *index);
+  Int_t fCurrentIndex[4];// index[0] indicates coordinate system, 
+                         // index[1] sector number, 
+                         // index[2] pad row number  
+                         // index[3] pad row number for which signal is calculated
   
   ClassDef(AliTPC,2)  // Time Projection Chamber class
 };
@@ -122,9 +122,9 @@ public:
   Int_t     fTracks[3];//labels of overlapped tracks
   Int_t     fSector;   //sector number
   Int_t     fPadRow;   //PadRow number
-  Float_t   fY;        //Y of cluster
-  Float_t   fZ;        //Z of cluster
-  Float_t   fQ;        //Q of cluster (in ADC counts)
+  Float_t   fY ;       //Y of cluster
+  Float_t   fZ ;       //Z of cluster
+  Float_t   fQ ;       //Q of cluster (in ADC counts)
   Float_t   fdEdX;     //dE/dX inside this cluster
   Float_t   fSigmaY2;  //Sigma Y square of cluster
   Float_t   fSigmaZ2;  //Sigma Z square of cluster
@@ -138,7 +138,7 @@ public:
   AliTPCcluster(Float_t *hits, Int_t*);
   virtual ~AliTPCcluster() {;}
   void Use() {fQ=-fQ;} //if fQ<0 cluster is already associated with a track
-  int IsUsed() const {return (fQ<0) ? 1 : 0;}
+  Int_t IsUsed() const {return (fQ<0) ? 1 : 0;}
   void GetXYZ(Float_t *x, const AliTPCParam *) const; //Get global x,y,z
   Bool_t IsSortable() const;
   Int_t Compare(TObject *o) ;
@@ -194,22 +194,23 @@ class AliTPCtrack : public TObject {
    TObjArray fClusters;      // clusters belonging to this track
    Double_t fChi2;           // total chi2 value for this track
 public:
+   AliTPCtrack(): x(5), C(5,5), fClusters(200) {fAlpha=fX=fChi2=0.;}
    AliTPCtrack(Float_t *hits);
    AliTPCtrack(const AliTPCcluster *c, const TVector& xx, const TMatrix& CC,
                Double_t xr, Double_t alpha); 
    AliTPCtrack(const AliTPCtrack& t);
    Int_t Compare(TObject *o);
-   int PropagateTo(Double_t xr,
-                   Double_t x0=28.94,Double_t rho=0.9e-3,Double_t pm=0.139);
+   Int_t PropagateTo(Double_t xr,
+                     Double_t x0=28.94,Double_t rho=0.9e-3,Double_t pm=0.139);
    void PropagateToVertex(
                    Double_t x0=36.66,Double_t rho=1.2e-3,Double_t pm=0.139);
    void Update(const AliTPCcluster* c, Double_t chi2);
-   int Rotate(Double_t angle);
+   Int_t Rotate(Double_t angle);
 
    Bool_t IsSortable() const {return kTRUE;}
    void UseClusters() const ;
    Double_t GetPredictedChi2(const AliTPCcluster*) const ;
-   int GetLabel(int nrows) const ;
+   Int_t GetLabel(Int_t nrows) const ;
    void GetPxPyPz(Double_t&, Double_t&, Double_t&) const ;
    Double_t GetdEdX(Double_t low, Double_t up) const ;
 
@@ -229,7 +230,10 @@ public:
    Double_t GetSigmaTgl2() const {return C(4,4);}
    Double_t GetAlpha() const {return fAlpha;}
    Double_t GetChi2() const {return fChi2;}
-   operator int() const {return fClusters.GetEntriesFast();}
+   operator Int_t() const {return fClusters.GetEntriesFast();}
+   const AliTPCcluster *GetCluster(Int_t i) const {
+      return (const AliTPCcluster *)fClusters.UncheckedAt(i);
+   }
  
    ClassDef(AliTPCtrack,1)  // Time Projection Chamber reconstructed tracks
 };
@@ -251,9 +255,9 @@ public:
    AliTPCRow() {num_of_clusters=0;}
    void InsertCluster(const AliTPCcluster*);
 
-   operator int() const {return num_of_clusters;}
-   const AliTPCcluster* operator[](int i) const {return clusters[i];}
-   int Find(Double_t y) const; 
+   operator Int_t() const {return num_of_clusters;}
+   const AliTPCcluster* operator[](Int_t i) const {return clusters[i];}
+   Int_t Find(Double_t y) const; 
 };
 
 class AliTPCSector {
@@ -268,13 +272,14 @@ public:
    AliTPCSector() { row = 0; num_of_rows=0; }
    virtual ~AliTPCSector() { delete[] row; }
    static void SetParam(AliTPCParam *p) { param=p; }
-   AliTPCRow& operator[](int i) const { return *(row+i); }
-   int GetNRows() const { return num_of_rows; }
-   virtual Double_t GetX(int l) const = 0;
-   virtual Double_t GetMaxY(int l) const = 0;
+   AliTPCRow& operator[](Int_t i) const { return *(row+i); }
+   Int_t GetNRows() const { return num_of_rows; }
+   virtual Double_t GetX(Int_t l) const = 0;
+   virtual Double_t GetMaxY(Int_t l) const = 0;
    virtual Double_t GetAlpha() const = 0;
    virtual Double_t GetAlphaShift() const = 0;
    virtual Int_t GetRowNumber(Double_t x) const = 0;
+   virtual Double_t GetPadPitchWidth() const = 0;
 };
 
 class AliTPCSSector : public AliTPCSector {
@@ -291,16 +296,19 @@ public:
      row=new AliTPCRow[num_of_rows];
    }
    virtual ~AliTPCSSector() {}
-   Double_t GetX(int l) const { return param->GetPadRowRadiiLow(l); }
-   Double_t GetMaxY(int l) const { return GetX(l)*tan(0.5*GetAlpha()); }
+   Double_t GetX(Int_t l) const { return param->GetPadRowRadiiLow(l); }
+   Double_t GetMaxY(Int_t l) const { return GetX(l)*tan(0.5*GetAlpha()); }
    Double_t GetAlpha() const {return param->GetInnerAngle();}
    Double_t GetAlphaShift() const {return param->GetInnerAngleShift();}
+   Double_t GetPadPitchWidth() const {
+      return param->GetInnerPadPitchWidth();
+   }
    Int_t GetRowNumber(Double_t x) const {
-      Double_t r=param->GetInnerRadiusUp();
+      Double_t r=param->GetPadRowRadiiLow(param->GetNRowLow()-1);
       if (x > r) return param->GetNRowLow();
-      r=param->GetInnerRadiusLow();
+      r=param->GetPadRowRadiiLow(0);
       if (x < r) return -1;
-      return int((x-r)/param->GetPadPitchLength() + 0.5);
+      return Int_t((x-r)/param->GetInnerPadPitchLength() + 0.5);
    }
 };
 
@@ -318,16 +326,19 @@ public:
      row=new AliTPCRow[num_of_rows];
    }
    virtual ~AliTPCLSector() {}
-   Double_t GetX(int l) const { return param->GetPadRowRadiiUp(l); }
-   Double_t GetMaxY(int l) const { return GetX(l)*tan(0.5*GetAlpha()); }
+   Double_t GetX(Int_t l) const { return param->GetPadRowRadiiUp(l); }
+   Double_t GetMaxY(Int_t l) const { return GetX(l)*tan(0.5*GetAlpha()); }
    Double_t GetAlpha() const {return param->GetOuterAngle();}
    Double_t GetAlphaShift() const {return param->GetOuterAngleShift();}
+   Double_t GetPadPitchWidth() const {
+      return param->GetOuterPadPitchWidth();
+   }
    Int_t GetRowNumber(Double_t x) const {
-      Double_t r=param->GetOuterRadiusUp();
+      Double_t r=param->GetPadRowRadiiUp(param->GetNRowUp()-1);
       if (x > r) return param->GetNRowUp();
-      r=param->GetOuterRadiusLow();
+      r=param->GetPadRowRadiiUp(0);
       if (x < r) return -1;
-      return int((x-r)/param->GetPadPitchLength() + 0.5);
+      return Int_t((x-r)/param->GetOuterPadPitchLength() + 0.5);
    }
 };
 
diff --git a/TPC/AliTPCCluster.cxx b/TPC/AliTPCCluster.cxx
new file mode 100644 (file)
index 0000000..b337034
--- /dev/null
@@ -0,0 +1,175 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:34:02  kowal2
+
+Clusters handling in a new data structure
+
+*/
+
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  Time Projection Chamber clusters objects                                //
+//
+//  Origin: Marian Ivanov , GSI Darmstadt
+//                                                                           //
+//                                                                           //
+//                                                                          //
+///////////////////////////////////////////////////////////////////////////////
+#include "AliTPC.h"
+#include "AliTPCCluster.h"
+#include "TClonesArray.h"
+#include "TDirectory.h"
+
+
+const Int_t kDefSize = 1;  //defalut size
+
+
+ClassImp(AliTPCClustersRow) 
+
+
+//*****************************************************************************
+//
+//_____________________________________________________________________________
+AliTPCClustersRow::AliTPCClustersRow() 
+{  
+  //
+  //default constructor
+  fNclusters=0;
+  fClusters =  new TClonesArray("AliTPCcluster",kDefSize); 
+}
+//_____________________________________________________________________________
+AliTPCClustersRow::AliTPCClustersRow(Int_t size) 
+{  
+  fNclusters=0;
+  fClusters = new TClonesArray("AliTPCcluster",size);
+}
+
+//_____________________________________________________________________________
+const  AliTPCcluster* AliTPCClustersRow::operator[](Int_t i)
+{
+  //
+  // return cluster at internal position i
+  //
+  if (fClusters==0) return 0;
+  void * cl = fClusters->UncheckedAt(i);
+  if (cl==0) return 0;
+  return  (AliTPCcluster*)cl;
+}
+//_____________________________________________________________________________
+void  AliTPCClustersRow::Sort()
+{
+  // sort cluster 
+  if (fClusters) fClusters->Sort();
+}
+
+//_____________________________________________________________________________
+void AliTPCClustersRow::InsertCluster(const AliTPCcluster * c) 
+{ 
+  //
+  // Add a simulated cluster copy to the list
+  //
+  if(!fClusters) fClusters=new TClonesArray("AliTPCcluster",1000);
+  TClonesArray &lclusters = *fClusters;
+  new(lclusters[fNclusters++]) AliTPCcluster(*c);
+}
+
+//_____________________________________________________________________________
+Int_t AliTPCClustersRow::Find(Double_t y) const 
+{
+  //
+  // return index of cluster nearest to given y position
+  //
+  AliTPCcluster* cl;
+  cl=(AliTPCcluster*)fClusters->UncheckedAt(0);
+  if (y <= cl->fY) return 0;  
+  cl=(AliTPCcluster*)fClusters->UncheckedAt(fNclusters-1);
+  if (y > cl->fY) return fNclusters; 
+  //if (y <= clusters[0]->fY) return 0;
+  //if (y > clusters[num_of_clusters-1]->fY) return num_of_clusters;  
+  Int_t b=0, e=fNclusters-1, m=(b+e)/2;
+  //  Int_t b=0, e=num_of_clusters-1, m=(b+e)/2;
+  for (; 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());
+}
diff --git a/TPC/AliTPCCluster.h b/TPC/AliTPCCluster.h
new file mode 100644 (file)
index 0000000..7cd2172
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef TPCClusters_H
+#define TPCClusters_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+////////////////////////////////////////////////
+//  Manager class for TPC   clusters                   //
+////////////////////////////////////////////////
+
+#include "AliDetector.h"
+#include "AliHit.h" 
+#include "AliDigit.h" 
+#include "AliSegmentArray.h"
+#include "AliTPCParam.h" 
+
+#include <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
+
diff --git a/TPC/AliTPCClustersArray.cxx b/TPC/AliTPCClustersArray.cxx
new file mode 100644 (file)
index 0000000..d9c38c8
--- /dev/null
@@ -0,0 +1,178 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:34:02  kowal2
+
+Clusters handling in a new data structure
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  Time Projection Chamber clusters objects                                //
+//
+//  Origin: Marian Ivanov , GSI Darmstadt
+//                                                                           //
+//                                                                           //
+//                                                                          //
+///////////////////////////////////////////////////////////////////////////////
+#include "AliTPC.h"
+#include "AliTPCParam.h" 
+#include "AliSegmentArray.h" 
+#include "AliCluster.h"
+#include "AliClusters.h"
+#include "AliClustersArray.h" 
+#include "AliTPCClustersRow.h" 
+
+#include "AliTPCClustersArray.h"
+#include "TClonesArray.h"
+#include "TDirectory.h"
+
+
+
+//_____________________________________________________________________________
+
+ClassImp(AliTPCClustersArray) 
+
+AliTPCClustersArray::AliTPCClustersArray()
+{
+  fParam = 0;
+  SetClass("AliTPCClustersRow");
+}
+
+AliTPCClustersArray::~AliTPCClustersArray()
+{
+  //
+  //object is only owner of fParam
+  //
+  if (fParam) delete fParam;
+}
+
+
+
+AliTPCClustersRow * AliTPCClustersArray::GetRow(Int_t sector,Int_t row) 
+{
+  //
+  //return clusters ((AliTPCClustersRow *) per given sector and padrow
+  //
+  if (fParam==0) return 0;
+  Int_t index = ((AliTPCParam*)fParam)->GetIndex(sector,row);  
+  return (AliTPCClustersRow *)(*this)[index];
+}
+
+AliTPCClustersRow *  AliTPCClustersArray::CreateRow(Int_t sector, Int_t row)
+{
+  //
+  //create digits row  
+  //
+  //if row just exist - delete it
+  AliTPCParam * param = (AliTPCParam*)fParam;
+  Int_t index = param->GetIndex(sector,row);  
+  AliTPCClustersRow * clusters = (AliTPCClustersRow *)(*this)[index];
+  if (clusters !=0) delete clusters;
+
+  clusters = (AliTPCClustersRow *) AddSegment(index);
+  if (clusters == 0) return 0;
+  return clusters;
+}
+
+AliTPCClustersRow * AliTPCClustersArray::LoadRow(Int_t sector,Int_t row)
+{
+  //
+  //return clusters ((AliTPCClustersRow *) per given sector and padrow
+  //
+  if (fParam==0) return 0;
+  Int_t index = ((AliTPCParam*)fParam)->GetIndex(sector,row);  
+  return (  AliTPCClustersRow *) LoadSegment(index);
+}
+
+Bool_t  AliTPCClustersArray::StoreRow(Int_t sector,Int_t row)
+{
+  //
+  //return clusters ((AliTPCClustersRow *) per given sector and padrow
+  //
+  if (fParam==0) return 0;
+  Int_t index = ((AliTPCParam*)fParam)->GetIndex(sector,row);  
+  StoreSegment(index);
+  return kTRUE;
+}
+
+Bool_t  AliTPCClustersArray::ClearRow(Int_t sector,Int_t row)
+{
+  //
+  //return clusters ((AliTPCDigitsRow *) per given sector and padrow
+  //
+  if (fParam==0) return 0;
+  Int_t index = ((AliTPCParam*)fParam)->GetIndex(sector,row);  
+  ClearSegment(index);
+  return kTRUE;
+}
+
+
+
+Bool_t AliTPCClustersArray::Setup(AliDetectorParam *param)
+{
+  //
+  //setup  function to adjust array parameters
+  //
+  if (param==0) return kFALSE;
+  fParam = param;
+  return MakeArray(((AliTPCParam*)fParam)->GetNRowsTotal());
+
+}
+Bool_t AliTPCClustersArray::Update()
+{
+  //
+  //setup  function to adjust array parameters
+  //
+  if (fParam ==0 ) return kFALSE;
+  if (fTree!=0) return MakeDictionary( ((AliTPCParam*)fParam)->GetNRowsTotal()) ;
+  ((AliTPCParam*)fParam)->Update();
+  return MakeArray(((AliTPCParam*)fParam)->GetNRowsTotal());
+}
+
+
+/*
+void AliTPCClustersArray::MakeTree()
+{
+  //  AliSegmentID  segment;
+  if (fClusterType==0) {
+    Error("AliTPCCLustersArray", "cluster type isn't adjusted");
+    return;
+  }
+  AliClusters * psegment = (AliClusters *)NewSegment();  
+  psegment->SetClass(fClusterType->GetName());  
+  psegment->SetArray(100);
+  if (fTree) delete fTree;
+  fTree = new TTree("Segment Tree","Tree with segments");
+  fBranch = fTree->Branch("Segment",psegment->IsA()->GetName(),&psegment,64000,1);
+  delete psegment;
+}              
+*/
+AliSegmentID * AliTPCClustersArray::NewSegment()
+{
+  //
+  //create object according class information 
+  if (fClusterType==0) {
+    Error("AliTPCCLustersArray", "cluster type isn't adjusted");
+    return 0;
+  }
+  AliSegmentID *segment=AliSegmentArray::NewSegment();
+  ((AliTPCClustersRow*)segment)->SetClass(fClusterType->GetName()); 
+  ((AliTPCClustersRow*)segment)->SetArray(100);
+  return segment;
+}
diff --git a/TPC/AliTPCClustersArray.h b/TPC/AliTPCClustersArray.h
new file mode 100644 (file)
index 0000000..08f891a
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef ALITPCCLUSTERSARRAY_H
+#define ALITPCCLUSTERSARRAY_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+////////////////////////////////////////////////
+//  Manager class for TPC   clusters                   //
+////////////////////////////////////////////////
+
+#include "AliDetector.h"
+#include "AliHit.h" 
+#include "AliDigit.h" 
+#include "AliSegmentArray.h"
+#include "AliClustersArray.h"
+#include "AliTPCParam.h" 
+
+#include <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
diff --git a/TPC/AliTPCClustersRow.cxx b/TPC/AliTPCClustersRow.cxx
new file mode 100644 (file)
index 0000000..f44e6f9
--- /dev/null
@@ -0,0 +1,54 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  Time Projection Chamber AliTPCClusterRow  objects
+//  -   clusters for given segment of TPC                                //
+//
+//  Origin: Marian Ivanov , GSI Darmstadt
+//                                                                           //
+//                                                                          //
+///////////////////////////////////////////////////////////////////////////////
+#include "AliTPC.h"
+#include "AliCluster.h"
+#include "AliClusters.h"
+#include "AliTPCClustersRow.h"
+#include "TDirectory.h"
+
+
+const Int_t kDefSize = 1;  //defalut size
+
+
+ClassImp(AliTPCClustersRow) 
+
+
+//*****************************************************************************
+//
+//_____________________________________________________________________________
+AliTPCClustersRow::AliTPCClustersRow() 
+{  
+  //
+  //default constructor
+  fNclusters=0;
+}
+
+//_____________________________________________________________________________
+//AliTPCClustersRow::AliTPCClustersRow(Int_t size) 
+//{    
+//  fNclusters=0;
+//  fClusters = new TClonesArray("AliTPCcluster",size);
+//}
+
diff --git a/TPC/AliTPCClustersRow.h b/TPC/AliTPCClustersRow.h
new file mode 100644 (file)
index 0000000..c7a5bd7
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef ALITPCCLUSTERROW_H
+#define ALITPCCLUSTERROW_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+////////////////////////////////////////////////
+//  Manager class for TPC   clusters                   //
+////////////////////////////////////////////////
+
+#include "AliDetector.h"
+#include "AliSegmentArray.h"
+#include "AliClusters.h"
+
+
+#include <TClonesArray.h>
+
+
+class TClonesArray;
+class TObjArray;
+
+
+class AliTPCClustersRow : public AliClusters{
+public:
+  AliTPCClustersRow();
+
+public:
+  
+  ClassDef(AliTPCClustersRow,1) 
+};  
+#endif //ALITPCCLUSTERROW_H
diff --git a/TPC/AliTPCD.cxx b/TPC/AliTPCD.cxx
deleted file mode 100644 (file)
index 3df93fe..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- *                                                                        *
- * Author: The ALICE Off-line Project.                                    *
- * Contributors are mentioned in the code where appropriate.              *
- *                                                                        *
- * Permission to use, copy, modify and distribute this software and its   *
- * documentation strictly for non-commercial purposes is hereby granted   *
- * without fee, provided that the above copyright notice appears in all   *
- * copies and that both the copyright notice and this permission notice   *
- * appear in the supporting documentation. The authors make no claims     *
- * about the suitability of this software for any purpose. It is          *
- * provided "as is" without express or implied warranty.                  *
- **************************************************************************/
-
-/*
-$Log$
-*/
-
-//-----------------------------------------------------------------------------
-// 
-//  Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk
-//
-//  Implementation of class AliTPCD
-//
-//-----------------------------------------------------------------------------
-
-#include <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();         
-  } 
-}
diff --git a/TPC/AliTPCD.h b/TPC/AliTPCD.h
deleted file mode 100644 (file)
index 104c1bd..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef ALITPCD_H
-#define ALITPCD_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice                               */
-
-/* $Id$ */
-
-// include files and class forward declarations
-
-
-// Documentation
-/**
-  *   Object with the  TPC parameters 
-  *   
-  *
-  *
-  */
-#include "TNamed.h"
-#include "TTree.h"
-class AliTPCPRF2D;
-class AliTPCRF1D;
-class AliTPCParam;
-class TClonesArray;
-class TTree;
-class TDirectory;
-R__EXTERN TDirectory *  gDirectory;
-//class TBranch;
-
-class AliTPCD : public TNamed{
-
-public:
-  AliTPCD(
-         Text_t *  name ="DIGIT",
-         AliTPCParam *param=0, 
-         AliTPCPRF2D *prf=0, 
-         AliTPCRF1D *prfz=0);
-  ~AliTPCD();
-  
-public: 
-  AliTPCParam & GetParam() {return *fParam;}
-  //give us reference to the parameters
-  AliTPCPRF2D &  GetPRF2D() {return *fPRF;}
-  //give us reference to 2-dimensional pad response function object
-  //this is responsible for respnse in x and y dimension
-  AliTPCRF1D  &  GetRF() {return *fRF;}
-  //give us reference to 1 dimensionl response
-  //this is responsible for z-direction
-  TClonesArray * GetArray() {return fDigits;}
-  //return reference for digits array
-
-  TTree * GetTree() { return fTreeD;}
-  //return refeence to actual tree 
-  Bool_t  SetTree(Int_t nevent=0, TDirectory *dir = gDirectory);
-  //map tree from given directory
-  Bool_t  MakeTree(Int_t nevent=0);
-  //map tree from given directory
-   void Fill();
-protected:
-  
-public:
-  AliTPCParam * fParam;     //geometry and gas parameters object 
-  AliTPCPRF2D * fPRF;            //x and y pad response function object
-  AliTPCRF1D * fRF;             //z (time) response function object
-  TClonesArray *fDigits;    //aray of tpc Digits
-  TTree   *fTreeD;        //tree 
-private:
-  AliTPCD *fpthis;  //pointer to object
-  ClassDef(AliTPCD,2) 
-};
-
-
-#endif /* ALITPCD_H */
diff --git a/TPC/AliTPCDigitDisplay.C b/TPC/AliTPCDigitDisplay.C
new file mode 100644 (file)
index 0000000..a5ea315
--- /dev/null
@@ -0,0 +1,64 @@
+void AliTPCDigitDisplay(int sec, int row, int lab=-1,
+                 int max_t_chan=500, float min_t=0., float max_t=500.,
+                 int max_p_chan=150, float min_p=0., float max_p=150.)
+{
+// Dynamically link some shared libs
+   if (gClassTable->GetID("AliRun") < 0) {
+      gROOT->LoadMacro("loadlibs.C");
+      loadlibs();
+   }
+
+// Connect the Root Galice file containing Geometry, Kine and Hits
+   TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root");
+   if (f) f->Close();
+   //f = new TFile("galice.root");
+   f = TFile::Open("rfio:galice.root");
+
+   AliTPCParam *par=(AliTPCParam *)f.Get("75x40_100x60");
+
+   char s[80];
+   sprintf(s,"Sector %d   Row %d\n",sec,row);
+   TH2F *h = new TH2F("h",s,max_t_chan,min_t,max_t,max_p_chan,min_p,max_p);
+
+   TTree *t=(TTree*)f.Get("TreeD_75x40_100x60");
+   AliSimDigits dummy, *digit=&dummy;
+   t->GetBranch("Segment")->SetAddress(&digit);
+   for (int i=0; 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");
+}
+
diff --git a/TPC/AliTPCDigitsArray.cxx b/TPC/AliTPCDigitsArray.cxx
new file mode 100644 (file)
index 0000000..6a5991a
--- /dev/null
@@ -0,0 +1,169 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:37:42  kowal2
+
+Digits handling in a new data structure
+
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  Time Projection Chamber clusters objects                                //
+//
+//  Origin: Marian Ivanov , GSI Darmstadt
+//                                                                           //
+//                                                                           //
+//                                                                          //
+///////////////////////////////////////////////////////////////////////////////
+#include "AliTPCParam.h" 
+#include "AliTPCParam.h"
+#include "AliTPCRF1D.h"
+#include "AliTPCPRF2D.h"
+
+#include "TObjArray.h"
+#include "AliSegmentID.h" 
+#include "AliSegmentArray.h" 
+
+#include "AliArrayI.h"
+#include "AliArrayS.h"
+
+
+#include "AliDigits.h"
+#include "AliSimDigits.h"
+#include "AliDigitsArray.h" 
+#include "AliTPCDigitsArray.h"
+//#include "TClonesArray.h"
+#include "TDirectory.h"
+
+
+
+//_____________________________________________________________________________
+
+ClassImp(AliTPCDigitsArray) 
+
+AliTPCDigitsArray::AliTPCDigitsArray(Bool_t sim)
+{
+  //
+  //default constructor
+  fParam = 0;
+  fBSim = sim;
+  if ( sim == kTRUE) SetClass("AliSimDigits");
+  else
+    SetClass("AliDigits");
+  fParam = 0;
+  //  fPRF   = 0;
+  //fRF    = 0;  
+  fCompression = 1;
+  fTrackLevel = 3;
+}
+
+AliTPCDigitsArray::~AliTPCDigitsArray()
+{
+  //
+  
+  //
+}
+
+AliDigits *  AliTPCDigitsArray::CreateRow(Int_t sector, Int_t row)
+{
+  //
+  //create digits row  
+  //
+  //if row just exist - delete it
+  AliTPCParam * param = (AliTPCParam*)fParam;
+  Int_t index = param->GetIndex(sector,row);  
+  AliDigits * dig = (AliDigits *)(*this)[index];
+  if (dig !=0) delete dig;
+
+  dig = (AliDigits *) AddSegment(index);
+  if (dig == 0) return 0;
+  dig->Allocate(param->GetMaxTBin(),param->GetNPads(sector,row));  
+  if (fBSim == kTRUE) ((AliSimDigits*) dig)->AllocateTrack(fTrackLevel);
+  return dig;
+}
+
+
+AliDigits * AliTPCDigitsArray::GetRow(Int_t sector,Int_t row)
+{
+  //
+  //return clusters ((AliTPCDigitsRow *) per given sector and padrow
+  //
+  if (fParam==0) return 0;
+  Int_t index = ((AliTPCParam*)fParam)->GetIndex(sector,row);  
+  return (AliDigits *)(*this)[index];
+}
+
+AliDigits * AliTPCDigitsArray::LoadRow(Int_t sector,Int_t row)
+{
+  //
+  //return clusters ((AliTPCDigitsRow *) per given sector and padrow
+  //
+  if (fParam==0) return 0;
+  Int_t index = ((AliTPCParam*)fParam)->GetIndex(sector,row);  
+  return (AliDigits *)LoadSegment(index);
+}
+
+Bool_t  AliTPCDigitsArray::StoreRow(Int_t sector,Int_t row)
+{
+  //
+  //return clusters ((AliTPCDigitsRow *) per given sector and padrow
+  //
+  AliTPCParam * param = (AliTPCParam*)fParam;
+  if (fParam==0) return 0;
+  Int_t index = param->GetIndex(sector,row);  
+  ( (AliDigits *)At(index))->CompresBuffer(fCompression,param->GetZeroSup());
+  if (fBSim == kTRUE) ( (AliSimDigits *)At(index))->CompresTrackBuffer(1);
+  StoreSegment(index);
+  return kTRUE;
+}
+
+Bool_t  AliTPCDigitsArray::ClearRow(Int_t sector,Int_t row)
+{
+  //
+  //return clusters ((AliTPCDigitsRow *) per given sector and padrow
+  //
+  if (fParam==0) return 0;
+  Int_t index = ((AliTPCParam*)fParam)->GetIndex(sector,row);  
+  ClearSegment(index);
+  return kTRUE;
+}
+
+
+
+Bool_t AliTPCDigitsArray::Setup(AliDetectorParam *param)
+{
+  //
+  //setup  function to adjust array parameters
+  //
+  if (param==0) return kFALSE;
+  if (fParam !=0) delete fParam;
+  //  fParam = new AliTPCParam((AliTPCParam&)(*param));
+  fParam = param;
+  return MakeArray(((AliTPCParam*)fParam)->GetNRowsTotal());
+}
+
+Bool_t AliTPCDigitsArray::Update()
+{
+  //
+  //setup  function to adjust array parameters
+  //
+  if (fParam ==0 ) return kFALSE;
+  if (fTree!=0) return MakeDictionary( ((AliTPCParam*)fParam)->GetNRowsTotal()) ;
+  ((AliTPCParam*)fParam)->Update();
+  return MakeArray(((AliTPCParam*)fParam)->GetNRowsTotal());
+}
diff --git a/TPC/AliTPCDigitsArray.h b/TPC/AliTPCDigitsArray.h
new file mode 100644 (file)
index 0000000..ba39fe5
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef ALITPCDIGITSARRAY_H
+#define ALITPCDIGITSARRAY_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+////////////////////////////////////////////////
+//  Manager class for TPC   clusters                   //
+////////////////////////////////////////////////
+
+#include "AliDetector.h"
+#include "AliHit.h" 
+#include "AliDigits.h" 
+#include "AliSegmentArray.h"
+#include "AliDigitsArray.h"
+#include "AliTPCParam.h" 
+
+#include <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
diff --git a/TPC/AliTPCDigitsDisplay.C b/TPC/AliTPCDigitsDisplay.C
deleted file mode 100644 (file)
index a6e6455..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-void AliTPCDigitsDisplay(int sec, int row,
-                 int max_t_chan=500, float min_t=0., float max_t=500.,
-                 int max_p_chan=200, float min_p=0., float max_p=200.)
-{
-// Dynamically link some shared libs
-   if (gClassTable->GetID("AliRun") < 0) {
-      gROOT->LoadMacro("loadlibs.C");
-      loadlibs();
-   } else {
-      delete gAlice;
-      gAlice=0;
-   }
-
-// Connect the Root Galice file containing Geometry, Kine and Hits
-   TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root");
-   if (f) f->Close();
-   f = new TFile("galice.root");
-
-   TClonesArray *fDigits=new TClonesArray("AliTPCdigit",10000);
-   TTree *t=(TTree*)f->Get("TreeD0_Param1");
-   t->GetBranch("Digits")->SetAddress(&fDigits);
-   Int_t sectors_by_rows=(Int_t)t->GetEntries();
-   for (Int_t n=0; 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");
-   }
-}
-
diff --git a/TPC/AliTPCDigitsH.cxx b/TPC/AliTPCDigitsH.cxx
new file mode 100644 (file)
index 0000000..d101d7d
--- /dev/null
@@ -0,0 +1,644 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.4.2  2000/04/10 11:37:42  kowal2
+
+Digits handling in a new data structure
+
+*/
+
+//-----------------------------------------------------------------------------
+//
+//
+//  Author:   Marian Ivanov
+//
+//  Implementation of class TTPCDigitsH
+//
+//-----------------------------------------------------------------------------
+////////////////////////////////////////////////
+//  Manager class for AliTPCDigitsH             //
+////////////////////////////////////////////////
+#include <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());    
+   } 
+}
diff --git a/TPC/AliTPCDigitsH.h b/TPC/AliTPCDigitsH.h
new file mode 100644 (file)
index 0000000..c29beb6
--- /dev/null
@@ -0,0 +1,114 @@
+#ifndef TTPCDIGITSH_H
+#define TTPCDIGITSH_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+////////////////////////////////////////////////
+//  Manager class for AliTPCDigitsH             //
+////////////////////////////////////////////////
+
+// include files and class forward declarations
+
+class TFile;   
+class TH2F;
+class AliH2F;
+class TH1F;
+class TPaveText;
+class TPad;
+class TCanvas;
+class AliTPCParam;
+class AliTPCD;
+class TClonesArray;
+class TTree;
+#include "TObject.h"
+#include "TUnixSystem.h"
+
+class AliTPCDigitsH :public TObject{
+public:   
+  ~AliTPCDigitsH();
+  AliTPCDigitsH(const AliTPCDigitsH &);
+  AliTPCDigitsH();
+  AliTPCDigitsH & operator = (const AliTPCDigitsH &);
+  AliTPCD * GetDParam() {return fDParam;}
+  void   SetDParam(AliTPCD * dig);
+  AliTPCParam *&   GetParam();
+  //get tpc parameters
+  TFile * GetIn() {return fin;}  
+  TFile * GetOut() {return fout;}
+  void Anal();   //get two dimensional histogram time*pad*amplitude for given
+  void SetSecRowTime(Int_t sec , Int_t row = 1, 
+                  Int_t TimeN = 500 , 
+                  Float_t TimeStart = 0, Float_t TimeStop = 500); 
+  //set section row and timing histogram 
+  //ranges and calculate histograms 
+  void SetHisto( Int_t pad = 1 ); 
+  virtual void Draw(Option_t * opt1 ="cont1"  , Option_t * opt2 = "error",
+                       Option_t * opt3 = "L" );
+  
+  void CloseFiles();  //close input and output file
+  void DeleteHisto(const Text_t *namecycle);  //
+  Bool_t  SetIO(const char *  inFile, const char* outFile);  
+  Bool_t  SetTree(Int_t eventn =0 );
+  void  SetParticles(Int_t sec = -1, Int_t row = -1 ,
+                  Int_t size1 = 30000,Int_t size2=300,
+                  Bool_t all=1 );
+  Bool_t SetEventN(Int_t EventN=0);  //set event number connected to analisys
+  
+  void SetbDelHisto(Bool_t bDelHisto) { fbDelHisto = bDelHisto;} //
+  void SetThreshold(Int_t threshold = 10 ) { fThreshold = threshold ;} //
+  /////////////  
+  AliH2F &  GetHis1() { return  *fH2Digit;}
+  AliH2F & GetHisBW() { return  *fH2DigitBW;}
+  TH1F &  GetHis2() { return  *fH1Digit;}
+  TH1F &  GetHis3() { return  *fH1Occu;}
+  TPad & GetPad1() {return *fpad1;}   
+  TPad & GetPad2() {return *fpad2;}   
+  TPad & GetPad3() {return *fpad3;}  
+  TCanvas &GetCanvas(){return *fcanvas;}
+protected:
+
+private:
+  TFile *fin;   //input TTRE file with digits
+  TFile *fout; //output file
+  TPad * fpad1;
+  TPad * fpad2;
+  TPad * fpad3;
+  TCanvas * fcanvas;
+  AliTPCParam * fTPCParam;
+  AliTPCD *fDParam;
+  Bool_t fbIOState;  
+  //state of Input and Output file : kTRUE if all is OK
+  Bool_t fbDigState; 
+  //state of Input digits tree kTRUE if ftree point to valid digit tree
+  TClonesArray  *fDigits;  //pointer to digits object used inanal 
+  TClonesArray  *fParticles; //pointer to particles array 
+  TTree   *ftree;  //pointer to tree with digits
+  Int_t fsec;  //actual sector of TPC  
+  Int_t frow;  //actual row of TPC 
+  Int_t fpad;  //actual pad
+  Int_t fEventN; //event number connected to
+  Int_t fTimeN;  //division number of the time
+  Float_t fTimeStart,fTimeStop;  //start and stop time for histograms
+  Int_t fOccuN;  //time division for occupancy calculating
+  TPaveText *  fTitle;  //  
+  Int_t fThreshold;   //treshold for the ocupancy definition
+  Bool_t fbDelHisto;   //swith which tell if we want to delete produced histogram
+  
+  AliH2F *fH2Digit; //two dimensional histogram - sector row
+  AliH2F *fH2DigitBW; //black and white histogram over treshold
+  TH1F *fH1Digit; //one dimensional histogram sector row pad
+  TH1F *fH1Occu; //occupancy graph  
+  TH1F *fHParticles; //histogram of particles contributing to digits  
+  TH1F *fHPartMultiplicity; 
+  //histogram of particles multiplicity
+  TH1F *fHAllP;  //histogram with accepted time bin for all  particles  
+  TH1F *fHSecondaryP;
+  //histogram with accepted time bin for secondary particles  
+  
+ ClassDef(AliTPCDigitsH,1)
+};
+#endif /* TTPCDIGITSH_H */
index c47f93a..54c2d02 100644 (file)
@@ -1,4 +1,3 @@
-
 void AliTPCHits2Digits(const  char * name= "pokusD_")
 {
  
@@ -9,6 +8,7 @@ void AliTPCHits2Digits(const  char * name= "pokusD_")
      }
   
    //names of trees
+
    const char * inFile = "galice.root";
    //   const * char ident= "TreeD1par_";
 
@@ -42,8 +42,8 @@ void AliTPCHits2Digits(const  char * name= "pokusD_")
   AliTPCPRF2D &prf = paramd->GetPRF2D();
   AliTPCRF1D  & rf  = paramd->GetRF();
   
-  param.SetPadLength(2.0);
-  param.SetPadWidth(0.3);
+  param.SetPadLength(2.05);
+  param.SetPadWidth(0.35);
   param.SetPadPitchLength(2.05);
   param.SetPadPitchWidth(0.35);
   param.SetNWires(5);
@@ -53,19 +53,11 @@ void AliTPCHits2Digits(const  char * name= "pokusD_")
   param.SetNoise(500);
   param.SetGasGain(1.e4);
   param.SetChipGain(24); 
-  param.SetSectorAngles(20.,0.,20.,0.);
-  param.SetInnerRadiusLow(83.9);
-  param.SetInnerRadiusUp(141.3);
+  param.SetSectorAngles(40.,0.,20.,10.);
+  param.SetInnerRadiusLow(83.7);
+  param.SetInnerRadiusUp(132.9);
   param.SetOuterRadiusLow(146.9);
   param.SetOuterRadiusUp(249.4);     
-  param.SetTSample(1.9e-7);
-  param.SetTSigma(1.5e-7/2.35);
-  param.SetInSecLowEdge(81.6);
-  param.SetInSecUpEdge(143.6);
-  param.SetOuSecLowEdge(144.2);
-  param.SetOuSecUpEdge(252.1);
-  param.SetEdge(1.5);
-  param.SetDeadZone(1.15);
   param.Update();
 
     //Set z (time) response function
@@ -74,7 +66,7 @@ void AliTPCHits2Digits(const  char * name= "pokusD_")
   rf.SetGauss(param.GetZSigma(),param.GetZWidth(),0.4);
   rf.Update();
   //Set two dimensional pad response function
-  TFile f("$(ALICE_ROOT)/TPC/AliTPCprf2d.root");
+  TFile f("TPC/AliTPCprf2d.root");
   //  prf.Read("prf_205035_Gati_062074_d03");
   prf.Read("prf_205035_Gati_062074_d03");
   f.Close();
@@ -89,18 +81,7 @@ void AliTPCHits2Digits(const  char * name= "pokusD_")
   prf.Dump();
   printf("**********Digit object dump end********************\n");
 
-   TPC->Hits2DigitsSector(1);     
-   TPC->Hits2DigitsSector(2);     
-   TPC->Hits2DigitsSector(3);     
-   TPC->Hits2DigitsSector(1+18);     
-   TPC->Hits2DigitsSector(2+18);     
-   TPC->Hits2DigitsSector(3+18);     
-   TPC->Hits2DigitsSector(1+36);     
-   TPC->Hits2DigitsSector(2+36);     
-   TPC->Hits2DigitsSector(3+36);     
-   TPC->Hits2DigitsSector(1+36+18);     
-   TPC->Hits2DigitsSector(2+36+18);     
-   TPC->Hits2DigitsSector(3+36+18);     
+   TPC->Hits2DigitsSector(0);     
          
  
    file->cd();
index 57b073b..bf0df1e 100644 (file)
 
 /*
 $Log$
+Revision 1.3.8.2  2000/04/10 08:40:46  kowal2
+
+Small changes by M. Ivanov, improvements of algorithms
+
+Revision 1.3.8.1  2000/04/10 07:56:53  kowal2
+Not used anymore - removed
+
+Revision 1.3  1999/10/05 17:15:46  fca
+Minor syntax for the Alpha OSF
+
 Revision 1.2  1999/09/29 09:24:34  fca
 Introduction of the Copyright and cvs Log
 
 */
 
 ///////////////////////////////////////////////////////////////////////////////
-//  AliTPCPRF2D -                                                                         //
+//  AliTPCPRF2D -                                                              //
 //  Pad response function object in two dimesions                            //
 //  This class contains the basic functions for the                          //
 //  calculation of PRF according generic charge distribution                 //
@@ -33,6 +43,8 @@ Introduction of the Copyright and cvs Log
 //  Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk          //
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
+
+
 #include "TMath.h"
 #include "AliTPCPRF2D.h"
 #include "TF2.h"
@@ -45,6 +57,7 @@ Introduction of the Copyright and cvs Log
 #include "TH2.h"
 #include "TPaveText.h"
 #include "TText.h"
+//
 
 extern TStyle * gStyle;
 
@@ -54,6 +67,7 @@ static const Int_t   NPRF = 100;
 
 static Double_t funGauss2D(Double_t *x, Double_t * par)
 { 
+//Gauss function  -needde by the generic function object 
   return ( TMath::Exp(-(x[0]*x[0])/(2*par[0]*par[0]))*
           TMath::Exp(-(x[1]*x[1])/(2*par[1]*par[1])));
 
@@ -61,14 +75,14 @@ static Double_t funGauss2D(Double_t *x, Double_t * par)
 
 static Double_t funCosh2D(Double_t *x, Double_t * par)
 {
+ //Cosh function  -needde by the generic function object 
   return ( 1/(TMath::CosH(3.14159*x[0]/(2*par[0]))*
           TMath::CosH(3.14159*x[1]/(2*par[1]))));
 }    
 
 static Double_t funGati2D(Double_t *x, Double_t * par)
 {
-  //par[1] = is equal to k3X
-  //par[0] is equal to pad wire distance
+  //Gati function  -needde by the generic function object 
   Float_t K3=par[1];
   Float_t K3R=TMath::Sqrt(K3);
   Float_t K2=(TMath::Pi()/2)*(1-K3R/2.);
@@ -89,9 +103,6 @@ static Double_t funGati2D(Double_t *x, Double_t * par)
   return res;  
 }   
 
-
-///////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////
 
@@ -99,20 +110,24 @@ ClassImp(AliTPCPRF2D)
 
 AliTPCPRF2D::AliTPCPRF2D()
 {
+  //default constructor for response function object
   ffcharge = 0;
   fNPRF =NPRF ;
   fSigmaX = 0;
+  fSigmaY = 0;
 
   fGRF = 0;
   fkNorm = 1;
-  forigsigmaY=0;
-  forigsigmaX=0;
+  fOrigSigmaY=0;
+  fOrigSigmaX=0;
   fNdiv = 5;
+  //set daault angels
+  fChargeAngle = 0;
+  fCosAngle = 0;
   //chewron default values   
   SetPad(0.8,0.8);
   SetChevron(0.2,0.0,1.0);
   SetY(-0.2,0.2,2);
-  // SetGauss(0.22,0.22,1);  
 }
 
 AliTPCPRF2D::~AliTPCPRF2D()
@@ -159,8 +174,10 @@ void AliTPCPRF2D::SetChParam(Float_t width, Float_t height,
 
 Float_t AliTPCPRF2D::GetPRF(Float_t xin, Float_t yin, Bool_t inter)
 {
-  if (ffcharge==0) return 0;
-  //  Float_t y=Float_t(fNYdiv-1)*(yin-fY1)/(fY2-fY1);
+  //function which return pad response
+  //for the charge in distance xin 
+  //return  cubic aproximation of PRF or PRF at nearest virtual wire
+   if (ffcharge==0) return 0;
   //transform position to "wire position"
   Float_t y=fDYtoWire*(yin-fY1);
   if (fNYdiv == 1) y=fY1;
@@ -203,16 +220,16 @@ Float_t AliTPCPRF2D::GetPRF(Float_t xin, Float_t yin, Bool_t inter)
     c=K-d;
     Float_t dy=y-Float_t(i);
         Float_t res = a+b*dy+c*dy*dy+d*dy*dy*dy;  
-       //Float_t res = z1*(1-dy)+z2*dy;
     return res;            
   }        
+  return 0.;
 } 
 
 
 Float_t AliTPCPRF2D::GetPRFActiv(Float_t xin)
 {
-  //x xin DStep unit
-  //return splaine aproximaton 
+  //GEt response function on given charege line 
+  //return spline aproximaton 
   Float_t x = (xin*fDStepM1)+fNPRF/2;
   Int_t i = Int_t(x);
   
@@ -234,6 +251,8 @@ Float_t AliTPCPRF2D::GetPRFActiv(Float_t xin)
 
 Float_t  AliTPCPRF2D::GetGRF(Float_t xin, Float_t yin)
 {  
+  //function which returnoriginal charge distribution
+  //this function is just normalised for fKnorm
   if (fGRF != 0 ) 
     return fkNorm*fGRF->Eval(xin,yin)/fInteg;
       else
@@ -244,15 +263,16 @@ Float_t  AliTPCPRF2D::GetGRF(Float_t xin, Float_t yin)
 void AliTPCPRF2D::SetParam( TF2 * GRF,  Float_t kNorm, 
                       Float_t sigmaX, Float_t sigmaY)
 {
+  //adjust parameters of the original charge distribution
+  //and pad size parameters
    if (fGRF !=0 ) fGRF->Delete();
    fGRF = GRF;
    fkNorm = kNorm;
    if (sigmaX ==0) sigmaX=(fWidth+fK*fHeightS)/sqrt12;
    if (sigmaY ==0) sigmaY=(fWidth+fK*fHeightS)/sqrt12;
-   forigsigmaX=sigmaX; 
-   forigsigmaY=sigmaY; 
+   fOrigSigmaX=sigmaX; 
+   fOrigSigmaY=sigmaY; 
    fDStep = TMath::Sqrt(sigmaX*sigmaX+fWidth*fWidth/6.)/10.; 
-   //   Update();   
   sprintf(fType,"User");
 }
   
@@ -260,6 +280,9 @@ void AliTPCPRF2D::SetParam( TF2 * GRF,  Float_t kNorm,
 void AliTPCPRF2D::SetGauss(Float_t sigmaX, Float_t sigmaY,
                      Float_t kNorm)
 {
+  // 
+  // set parameters for Gauss generic charge distribution
+  //
   fkNorm = kNorm;
   if (fGRF !=0 ) fGRF->Delete();
   fGRF = new TF2("fun",funGauss2D,-5.,5.,-5.,5.,4);
@@ -267,18 +290,19 @@ void AliTPCPRF2D::SetGauss(Float_t sigmaX, Float_t sigmaY,
   funParam[1]=sigmaY;  
   funParam[2]=fK;
   funParam[3]=fHeightS;    
-  forigsigmaX=sigmaX;
-  forigsigmaY=sigmaY;
+  fOrigSigmaX=sigmaX;
+  fOrigSigmaY=sigmaY;
   fGRF->SetParameters(funParam);
   fDStep = TMath::Sqrt(sigmaX*sigmaX+fWidth*fWidth/6.)/10.; 
   //by default I set the step as one tenth of sigma
-  //Update();
   sprintf(fType,"Gauss");
 }
 
 void AliTPCPRF2D::SetCosh(Float_t sigmaX, Float_t sigmaY,
                     Float_t kNorm)
-{
+{ 
+  // set parameters for Cosh generic charge distribution
+  //
   fkNorm = kNorm;
   if (fGRF !=0 ) fGRF->Delete();
   fGRF = new TF2("fun",        funCosh2D,-5.,5.,-5.,5.,4);   
@@ -287,11 +311,10 @@ void AliTPCPRF2D::SetCosh(Float_t sigmaX, Float_t sigmaY,
   funParam[2]=fK;  
   funParam[3]=fHeightS;
   fGRF->SetParameters(funParam);
-  forigsigmaX=sigmaX;
-  forigsigmaY=sigmaY;
+  fOrigSigmaX=sigmaX;
+  fOrigSigmaY=sigmaY;
   fDStep = TMath::Sqrt(sigmaX*sigmaX+fWidth*fWidth/6.)/10.; 
   //by default I set the step as one tenth of sigma
-  //Update();
   sprintf(fType,"Cosh");
 }
 
@@ -299,6 +322,8 @@ void AliTPCPRF2D::SetGati(Float_t K3X, Float_t K3Y,
                     Float_t padDistance,
                     Float_t kNorm)
 {
+  // set parameters for Gati generic charge distribution
+  //
   fkNorm = kNorm;
   if (fGRF !=0 ) fGRF->Delete();
   fGRF = new TF2("fun",        funGati2D,-5.,5.,-5.,5.,5);  
@@ -311,11 +336,10 @@ void AliTPCPRF2D::SetGati(Float_t K3X, Float_t K3Y,
   funParam[3]=fHeightS;
   funParam[4]=K3Y;
   fGRF->SetParameters(funParam);
-  forigsigmaX=padDistance;
-  forigsigmaY=padDistance;
+  fOrigSigmaX=padDistance;
+  fOrigSigmaY=padDistance;
   fDStep = TMath::Sqrt(padDistance*padDistance+fWidth*fWidth/6.)/10.; 
   //by default I set the step as one tenth of sigma
-  //Update();
   sprintf(fType,"Gati");
 }
 
@@ -323,102 +347,144 @@ void AliTPCPRF2D::SetGati(Float_t K3X, Float_t K3Y,
 
 void AliTPCPRF2D::Update()
 {
-  for (Int_t i=0; 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;              
                  }
                }
              }
@@ -426,27 +492,47 @@ void AliTPCPRF2D::Update1()
          k*=-1;
        }
       };   
-  
-  fSigmaX = 0; 
+    
+}
+
+void AliTPCPRF2D::UpdateSigma()
+{
+  //
+  //calulate effective sigma X and sigma y of PRF
+  fMeanX = 0;
+  fMeanY = 0;
+  fSigmaX = 0;
+  fSigmaY = 0;
   Float_t sum =0;
-  Float_t mean=0;
-  for (x =-fNPRF*fDStep; 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
@@ -455,30 +541,27 @@ void AliTPCPRF2D::Streamer(TBuffer &R__b)
       Version_t R__v = R__b.ReadVersion(); if (R__v) { }
       TObject::Streamer(R__b);     
       //read chewron parameters
-      R__b >> fSigmaX;
       R__b >> fHeightFull;
       R__b >> fHeightS;
       R__b >> fShiftY;
       R__b >> fWidth;
       R__b >> fK;
-      R__b >> fActualY;
-      //read charge parameters
-      R__b >> fType[0];
-      R__b >> fType[1];
-      R__b >> fType[2];
-      R__b >> fType[3];
-      R__b >> fType[4];
-      R__b >> forigsigmaX;
-      R__b >> forigsigmaY;
+      R__b >> fSigmaX;
+      R__b >> fSigmaY;
+      R__b >> fMeanX;
+      R__b >> fMeanY;
+      //read charge parameters     
+      R__b.ReadFastArray(fType,5);
+      R__b >> fOrigSigmaX;
+      R__b >> fOrigSigmaY;
       R__b >> fkNorm;
       R__b >> fK3X;
       R__b >> fK3Y;
       R__b >> fPadDistance;
-      R__b >> fInteg;
-      
+      R__b >> fInteg;      
       //read functions
       if (fGRF!=0) { 
-       delete [] fGRF;  
+       fGRF->Delete();  
        fGRF=0;
       }
       if (strncmp(fType,"User",3)==0){
@@ -490,8 +573,7 @@ void AliTPCPRF2D::Streamer(TBuffer &R__b)
       if (strncmp(fType,"Cosh",3)==0) 
        fGRF = new TF2("fun",funCosh2D,-5.,5.,-5.,5.,4);
        if (strncmp(fType,"Gati",3)==0) 
-       fGRF = new TF2("fun",funGati2D,-5.,5.,-5.,5.,5);
-      
+       fGRF = new TF2("fun",funGati2D,-5.,5.,-5.,5.,5);      
       //read interpolation parameters
       R__b >>fY1;
       R__b >>fY2;
@@ -510,22 +592,19 @@ void AliTPCPRF2D::Streamer(TBuffer &R__b)
       R__b.WriteVersion(AliTPCPRF2D::IsA());
       TObject::Streamer(R__b);      
       //write chewron parameters
-      R__b << fSigmaX;
       R__b << fHeightFull;
       R__b << fHeightS;
       R__b << fShiftY;
       R__b << fWidth;
       R__b << fK;
-      R__b << fActualY;
+      R__b << fSigmaX;
+      R__b << fSigmaY;
+      R__b << fMeanX;
+      R__b << fMeanY;
       //write charge parameters
-      R__b << fType[0];
-      R__b << fType[1];
-      R__b << fType[2];
-      R__b << fType[3];
-      R__b << fType[4];
-
-      R__b << forigsigmaX;
-      R__b << forigsigmaY;
+      R__b.WriteFastArray(fType,5);
+      R__b << fOrigSigmaX;
+      R__b << fOrigSigmaY;
       R__b << fkNorm;
       R__b << fK3X;
       R__b << fK3Y;
@@ -549,6 +628,7 @@ void AliTPCPRF2D::Streamer(TBuffer &R__b)
 
 void AliTPCPRF2D::DrawX(Float_t x1 ,Float_t x2,Float_t y, Bool_t inter)
 { 
+  //draw pad response function at interval <x1,x2> at  given y position
   if (fGRF==0) return ;
   const Int_t N=100;
   char s[100];
@@ -559,15 +639,12 @@ void AliTPCPRF2D::DrawX(Float_t x1 ,Float_t x2,Float_t y, Bool_t inter)
   TPad * pad2 = new TPad("pad2PRF","",0.05,0.22,0.95,0.60,21);
   pad2->Draw();
 
-  //  pad1->cd();  
-  //pad2->cd();
   gStyle->SetOptFit(1);
   gStyle->SetOptStat(0); 
   sprintf(s,"PRF response function for chevron pad");  
   TH1F * hPRFc = new TH1F("hPRFc",s,N+1,x1,x2);
   Float_t x=x1;
   Float_t y1;
-  //  Float_t y2;
 
   for (Float_t i = 0;i<N+1;i++)
     {
@@ -601,9 +678,9 @@ void AliTPCPRF2D::DrawX(Float_t x1 ,Float_t x2,Float_t y, Bool_t inter)
   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); 
@@ -664,9 +741,9 @@ void AliTPCPRF2D::Draw(Float_t x1 ,Float_t x2,Float_t y1, Float_t y2,
   comment->AddText(s);
   sprintf(s,"Overlap factor:  %2.2f",fK*fHeightS/fWidth);
   comment->AddText(s); 
-  sprintf(s,"Sigma x of original distribution: %2.2f ",forigsigmaX);
+  sprintf(s,"Sigma x of original distribution: %2.2f ",fOrigSigmaX);
   comment->AddText(s);  
-  sprintf(s,"Sigma y of original distribution: %2.2f ",forigsigmaY);
+  sprintf(s,"Sigma y of original distribution: %2.2f ",fOrigSigmaY);
   comment->AddText(s);    
   sprintf(s,"Type of original distribution: %s ",fType);
   comment->AddText(s); 
@@ -697,14 +774,16 @@ void AliTPCPRF2D::DrawDist(Float_t x1 ,Float_t x2,Float_t y1, Float_t y2,
   Float_t dy=(y2-y1)/Float_t(Ny) ;
   Float_t x,y,z,ddx;
   //  Float_t y2;
-  for ( x = x1;x<(x2+dx/2.);x+=dx)
-    for(y = y1;y<=(y2+dx/2.);y+=dy)
+  for ( x = x1;x<(x2+3.1*dx);x+=dx)
+    for(y = y1;y<(y2+3.1*dx);y+=dy)
       {
        Float_t sumx=0;
        Float_t sum=0;
-       for (Float_t padx=-fWidth;padx<(fWidth*1.1);padx+=fWidth)
+       for (Int_t i=-3;i<=3;i++)
+       //      for (Float_t padx=-fWidth;padx<(fWidth*1.1);padx+=fWidth)
          {         
-           z = GetPRF(x-padx,y,inter);
+           Float_t padx=Float_t(i)*fWidth;
+           z = GetPRF(x-padx,y,inter); 
            if (z>thr){
              sum+=z;
              sumx+=z*padx;
@@ -743,9 +822,9 @@ void AliTPCPRF2D::DrawDist(Float_t x1 ,Float_t x2,Float_t y1, Float_t y2,
   comment->AddText(s);
   sprintf(s,"Overlap factor:  %2.2f",fK*fHeightS/fWidth);
   comment->AddText(s); 
-  sprintf(s,"Sigma x of original distribution: %2.2f ",forigsigmaX);
+  sprintf(s,"Sigma x of original distribution: %2.2f ",fOrigSigmaX);
   comment->AddText(s);  
-  sprintf(s,"Sigma y of original distribution: %2.2f ",forigsigmaY);
+  sprintf(s,"Sigma y of original distribution: %2.2f ",fOrigSigmaY);
   comment->AddText(s);    
   sprintf(s,"Type of original distribution: %s ",fType);
   comment->AddText(s); 
index 3646f77..64aec84 100644 (file)
@@ -4,9 +4,8 @@
  * 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,
            Bool_t inter=kFALSE, Int_t Nx=20, Int_t Ny=20);
   //draw two dimensional PRF
@@ -45,7 +42,17 @@ public :
                Float_t  thr=0);
   //draw distortion of COG method
   //we suppose threshold equal to thr
-   
+
+  void SetPad(Float_t width, Float_t height);
+  //set base chevron parameters
+  void SetChevron(Float_t hstep, Float_t shifty, Float_t fac);
+  //set chevron parameters   
+  void SetChParam(Float_t width, Float_t height,
+                 Float_t hstep, Float_t shifty, Float_t fac);
+  //set all geometrical parameters     
+  void SetY(Float_t y1, Float_t y2, Int_t nYdiv) ;
+  void SetChargeAngle(Float_t angle){fChargeAngle = angle;} //set angle of pad and charge distribution
+                                                            //axes
   void SetGauss(Float_t sigmaX,Float_t sigmaY , Float_t kNorm=1);
   //adjust PRF with GAUSIAN as generic GRF 
   //if  direct = kTRUE then it does't convolute distribution
@@ -56,25 +63,30 @@ public :
                     Float_t kNorm=1);
   void SetParam(TF2 * GRF,Float_t kNorm, 
                Float_t sigmaX=0, Float_t sigmaY=0);
-  void SetPad(Float_t width, Float_t height);
-  //set base chevron parameters
-  void SetChevron(Float_t hstep, Float_t shifty, Float_t fac);
-  //set chevron parameters   
-  void SetChParam(Float_t width, Float_t height,
-                 Float_t hstep, Float_t shifty, Float_t fac);
-  //set all geometrical parameters  
   void SetNdiv(Int_t Ndiv){fNdiv=Ndiv;}
-  void Update();  
+  Float_t GetSigmaX() const {return fSigmaX;}
+  Float_t GetSigmaY() const {return fSigmaY;}
+  
+  
 protected:
-  void Update1();  
+  void Update1(); 
+  void UpdateSigma();  //recalculate sigma of PRF
   Float_t GetPRFActiv(Float_t xin); //return PRF in point xin and actual y
-  Float_t  * fcharge; // field with PRF 
-  Float_t fY1;
-  Float_t fY2;
-  Int_t fNYdiv;  
+  Float_t  * fcharge; //field with PRF 
+  Float_t fY1;        //position of first "virtual" vire 
+  Float_t fY2;        //position of last virtual vire
+  Int_t fNYdiv;       //number of wires
   Float_t * ffcharge;  //pointer to array of arrays
 
 private: 
+
+  //chevron parameters
+  Float_t fHeightFull;  //height of the full pad
+  Float_t fHeightS;     //height of the one step
+  Float_t fShiftY;      //shift of the step
+  Float_t fWidth;       //width of the pad
+  Float_t fK;           //k factor of the chewron
+
   Double_t funParam[5];//parameters of used charge function
   Int_t  fNPRF;      //number of interpolations point
   Int_t  fNdiv;      //number of division to calculate integral
@@ -83,27 +95,27 @@ private:
   Float_t fInteg;     //integral of GRF on +- infinity
   TF2 *  fGRF;        //charge distribution function
 
-  Float_t fK3X;
-  Float_t fK3Y;
-  Float_t fPadDistance;
+  Float_t fK3X;       //KX parameter (only for Gati parametrization)
+  Float_t fK3Y;       //KY parameter (only for Gati parametrisation)
+  Float_t fPadDistance; //pad anode distnce (only for Gati parametrisation)
+
+  Float_t  fOrigSigmaX; //sigma of original distribution;  
+  Float_t  fOrigSigmaY; //sigma of original distribution;  
+  Float_t  fChargeAngle;//'angle' of charge distribution refernce system to pad reference system
+  Float_t  fCosAngle;   //'angle' of the pad assymetry
 
-  Float_t  forigsigmaX;//sigma of original distribution;  
-  Float_t  forigsigmaY;//sigma of original distribution;  
-  Float_t fSigmaX;     //sigma of PAD response function
+  Float_t  fSigmaX;    //sigma X of PAD response function
+  Float_t  fSigmaY;    //sigma Y of PAD response function
+  Float_t  fMeanX;     //mean X value
+  Float_t  fMeanY;     //mean Y value
   //calculated during update
 
-  //chewron parameters
-  Float_t fHeightFull;  //height of the full pad
-  Float_t fHeightS;     //height of the one step
-  Float_t fShiftY;  //shift of the step
-  Float_t fWidth;       //width of the pad
-  Float_t fK;           //k factor of the chewron
-  Float_t fActualY;          //in reality we calculate PRF only for 
-  //one fixed y
-  char  fType[5];  //charge type
-  //to make calculation faster we reduce  division
-  Float_t fDYtoWire;    //used to make PRF calculation faster in GetPRF
-  Float_t fDStepM1;     //used in GetPRFActiv
+   
+
+  char  fType[5];       //charge type
+  Float_t fCurrentY;    //in reality we calculate PRF only for one fixed y 
+  Float_t fDYtoWire;    //! used to make PRF calculation faster in GetPRF
+  Float_t fDStepM1;     //! used in GetPRFActiv to make calculation faster
   ClassDef(AliTPCPRF2D,1) 
 }; 
 
index 33c6e38..4f398d6 100644 (file)
 
 /*
 $Log$
+Revision 1.7.8.2  2000/04/10 08:44:51  kowal2
+
+New transformations added
+Different pad and pad-rows geometries for different sectors
+
+Revision 1.7.8.1  2000/04/10 07:56:53  kowal2
+Not used anymore - removed
+
+Revision 1.7  1999/10/08 13:10:35  fca
+Values in SetDefault are in radiants
+
 Revision 1.6  1999/10/08 06:27:59  fca
 Defaults updated
 
@@ -41,242 +52,266 @@ Introduction of the Copyright and cvs Log
 #include <iostream.h>
 #include <TMath.h>
 #include <TObject.h>
-#include "AliTPCSecGeo.h"
+#include <TRandom.h>
 #include <AliTPCParam.h>
 
 
 ClassImp(AliTPCParam)
 
-const static  Int_t kMaxRows=600;
-
-
-// default values  
-const static   Int_t kMaxTBin =512; 
-
-
-const static  Float_t kInnerRadiusLow = 83.9;
-const static  Float_t kOuterRadiusLow = 146.9;
-const static  Float_t kInnerRadiusUp  = 141.3;
-const static  Float_t kOuterRadiusUp  = 249.4;
-
-const static  Float_t kInnerAngle = 0.34906585; // 20 degrees
-const static  Float_t kInnerAngleShift = 0;
-const static  Float_t kOuterAngle = 0.34906585; //  20 degrees
-const static  Float_t kOuterAngleShift = 0;
-
-const static Float_t kPadPitchLength = 2.05;
-const static Float_t kPadPitchWidth = 0.35;
-const static Float_t kPadLength = 2.05;
-const static Float_t kPadWidth = 0.35;
-
-//  Number of wires per pad and wire-wire pitch
-const static Int_t knWires = 5;
+const static  Int_t kMaxRows=600; 
+//
+//sector default parameters
+//
+const static  Float_t kInnerRadiusLow = 81.6;
+const static  Float_t kOuterRadiusLow = 144.2;
+const static  Float_t kInnerRadiusUp  = 143.6;
+const static  Float_t kOuterRadiusUp  = 252.1;
+const static  Float_t