Got rid of class template AliFMD<Type> on request of Federico, who
authorcholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 5 Nov 2004 11:58:31 +0000 (11:58 +0000)
committercholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 5 Nov 2004 11:58:31 +0000 (11:58 +0000)
thinks they are evil (sigh!).   Added a lot of (duplicate) code to
cover what was previously done by that class template.

New structure to the reconstruction algorithms.  In essence, the
details of the algorithms areput into separate classes.

Clean-up of some code.

Removed header guards in implementation files _only_ - Peter thinks
they are evil (sigh!).  They are still present in the declaration files
as I believe that is definitely the Right Thing (tm) to do cf. Fons.

The code is in a pretty unstable state, but I had to commit as Federico
and Peter wanted the class template out ASAP.  Apparently there's a
problem on Optreon/Itianium machines where either R__ACCESS_IN_SYMBOL
or R__USE_SHADOW_CLASS is defined, and an assert fails:

   Assert(sizeof(AliFMDMap<float>) == sizeof(::ROOT::Shadow::BlaBla))

This seems to be a problem in (ROOT)CINT - not with templates as such.

37 files changed:
FMD/AliFMD.cxx
FMD/AliFMD1.cxx
FMD/AliFMD2.cxx
FMD/AliFMD3.cxx
FMD/AliFMDDigit.cxx
FMD/AliFMDDigitizer.cxx
FMD/AliFMDDigitizer.h
FMD/AliFMDEdepMap.cxx [new file with mode: 0644]
FMD/AliFMDEdepMap.h [new file with mode: 0644]
FMD/AliFMDHit.cxx
FMD/AliFMDMap.cxx [new file with mode: 0644]
FMD/AliFMDMap.h
FMD/AliFMDNaiiveAlgorithm.cxx [new file with mode: 0644]
FMD/AliFMDParticles.cxx
FMD/AliFMDPoissonAlgorithm.cxx [new file with mode: 0644]
FMD/AliFMDPoissonAlgorithm.h [new file with mode: 0644]
FMD/AliFMDPolygon.cxx
FMD/AliFMDRawReader.cxx [new file with mode: 0644]
FMD/AliFMDRawReader.h [new file with mode: 0644]
FMD/AliFMDRawStream.cxx
FMD/AliFMDRawStream.h
FMD/AliFMDRawWriter.cxx [new file with mode: 0644]
FMD/AliFMDRawWriter.h [new file with mode: 0644]
FMD/AliFMDReconstructionAlgorithm.cxx [new file with mode: 0644]
FMD/AliFMDReconstructionAlgorithm.h [new file with mode: 0644]
FMD/AliFMDReconstructor.cxx
FMD/AliFMDReconstructor.h
FMD/AliFMDRing.cxx
FMD/AliFMDSubDetector.cxx
FMD/AliFMDUShortMap.cxx [new file with mode: 0644]
FMD/AliFMDUShortMap.h [new file with mode: 0644]
FMD/AliFMDv0.cxx
FMD/AliFMDv1.cxx
FMD/FMDrecLinkDef.h
FMD/FMDsimLinkDef.h
FMD/libFMDrec.pkg
FMD/libFMDsim.pkg

index 69a3a7b..57277b7 100644 (file)
@@ -15,7 +15,7 @@
 
 /* $Id$ */
 
-//////////////////////////////////////////////////////////////////////////////
+//____________________________________________________________________
 //                                                                          
 // Forward Multiplicity Detector based on Silicon wafers. This class
 // contains the base procedures for the Forward Multiplicity detector
 // Many modifications by Christian Holm Christensen <cholm@nbi.dk>
 //
 
-#ifndef ROOT_TClonesArray
-#include <TClonesArray.h>
-#endif
-#ifndef ROOT_TGeomtry
-# include <TGeometry.h>
-#endif
-#ifndef ROOT_TNode
-# include <TNode.h>
-#endif
-#ifndef ROOT_TTUBE
-# include <TTUBE.h>
-#endif
-#ifndef ROOT_TTree
-# include <TTree.h>
-#endif
-#ifndef ROOT_TVirtualMC
-# include <TVirtualMC.h>
-#endif
-#ifndef ROOT_TBrowser
-# include <TBrowser.h>
-#endif
-#ifndef ROOT_TMath
-# include <TMath.h>
-#endif
-
-#ifndef ALIRUNDIGITIZER_H
-# include "AliRunDigitizer.h"
-#endif
-#ifndef ALILOADER_H
-# include "AliLoader.h"
-#endif
-#ifndef ALIRUN_H
-# include "AliRun.h"
-#endif
-#ifndef ALIMC_H
-# include "AliMC.h"
-#endif
-#ifndef ALILOG_H
-# include "AliLog.h"
-#endif
-#ifndef ALIMAGF_H
-# include "AliMagF.h"
-#endif
-#ifndef ALIFMD_H
-# include "AliFMD.h"
-#endif
-#ifndef ALIFMDDIGIG_H
-# include "AliFMDDigit.h"
-#endif
-#ifndef ALIFMDHIT_H
-# include "AliFMDHit.h"
-#endif
-#ifndef ALIFMDDIGITIZER_H
-# include "AliFMDDigitizer.h"
-#endif
-#ifndef ALIFMD1_H
-# include "AliFMD1.h"
-#endif
-#ifndef ALIFMD2_H
-# include "AliFMD2.h"
-#endif
-#ifndef ALIFMD3_H
-# include "AliFMD3.h"
-#endif
-#ifndef ALIALTROBUFFER_H
-# include "AliAltroBuffer.h"
-#endif
-#include <Riostream.h>
+#include "TClonesArray.h"      // ROOT_TClonesArray
+#include "TGeometry.h"         // ROOT_TGeomtry
+#include "TNode.h"             // ROOT_TNode
+#include "TTUBE.h"             // ROOT_TTUBE
+#include "TTree.h"             // ROOT_TTree
+#include "TVirtualMC.h"                // ROOT_TVirtualMC
+#include "TBrowser.h"          // ROOT_TBrowser
+#include "TMath.h"             // ROOT_TMath
+
+#include "AliRunDigitizer.h"   // ALIRUNDIGITIZER_H
+#include "AliLoader.h"         // ALILOADER_H
+#include "AliRun.h"            // ALIRUN_H
+#include "AliMC.h"             // ALIMC_H
+#include "AliLog.h"            // ALILOG_H
+#include "AliMagF.h"           // ALIMAGF_H
+#include "AliFMD.h"            // ALIFMD_H
+#include "AliFMDDigit.h"       // ALIFMDDIGIG_H
+#include "AliFMDHit.h"         // ALIFMDHIT_H
+#include "AliFMDDigitizer.h"   // ALIFMDDIGITIZER_H
+#include "AliFMD1.h"           // ALIFMD1_H
+#include "AliFMD2.h"           // ALIFMD2_H
+#include "AliFMD3.h"           // ALIFMD3_H
+#include "AliFMDRawWriter.h"   // ALIFMDRAWWRITER_H
 
 //____________________________________________________________________
 ClassImp(AliFMD);
@@ -1011,6 +966,12 @@ AliFMD::Digits2Raw()
 {
   // Turn digits into raw data. 
   // 
+  // This uses the class AliFMDRawWriter to do the job.   Please refer
+  // to that class for more information. 
+  AliFMDRawWriter writer(this);
+  writer.Exec();
+  
+#if 0
   // Digits are read from the Digit branch, and processed to make
   // three DDL files, one for each of the sub-detectors FMD1, FMD2,
   // and FMD3. 
@@ -1220,6 +1181,7 @@ AliFMD::Digits2Raw()
     }
   }
   fLoader->UnloadDigits();
+#endif
 }
 
 //==================================================================
index 4cae6d2..5da3f1f 100644 (file)
 //
 // This implements the geometry for FMD1 
 //
-#ifndef ALIFMD1_H
-# include "AliFMD1.h"
-#endif 
-#ifndef ALIFMDRING_H
-# include "AliFMDRing.h"
-#endif 
-#ifndef ROOT_TVirtualMC
-# include <TVirtualMC.h>
-#endif
-#ifndef ALILOG_H
-# include "AliLog.h"
-#endif
+#include "AliFMD1.h"           // ALIFMD1_H 
+#include "AliFMDRing.h"                // ALIFMDRING_H 
+#include "TVirtualMC.h"                // ROOT_TVirtualMC
+#include "AliLog.h"            // ALILOG_H
 
 
 //____________________________________________________________________
index 1affdf0..0e72c47 100644 (file)
 //
 // This implements the geometry for FMD2
 //
-#ifndef ALIFMD2_H
-# include "AliFMD2.h"
-#endif 
-#ifndef ROOT_TVirtualMC
-# include <TVirtualMC.h>
-#endif
-#ifndef ALILOG_H
-# include "AliLog.h"
-#endif
-#ifndef ALIFMDRING_H
-# include "AliFMDRing.h"
-#endif 
+#include "AliFMD2.h"           // ALIFMD2_H 
+#include "TVirtualMC.h"                // ROOT_TVirtualMC
+#include "AliLog.h"            // ALILOG_H
+#include "AliFMDRing.h"                // ALIFMDRING_H 
 
 //____________________________________________________________________
 ClassImp(AliFMD2);
index a8912d2..ebc1743 100644 (file)
 //
 // This implements the geometry for FMD3
 //
-#ifndef ROOT_TVirtualMC
-# include <TVirtualMC.h>
-#endif
-#ifndef ROOT_TCONS
-# include <TCONS.h>
-#endif
-#ifndef ROOT_TNode
-# include <TNode.h>
-#endif
-#ifndef ROOT_TList
-# include <TList.h>
-#endif
-#ifndef ALIFMD3_H
-# include "AliFMD3.h"
-#endif 
-#ifndef ALILOG_H
-# include "AliLog.h"
-#endif
-#ifndef ALIFMDRING_H
-# include "AliFMDRing.h"
-#endif 
-#include <Riostream.h>
+#include "TVirtualMC.h"                // ROOT_TVirtualMC
+#include "TCONS.h"             // ROOT_TCONS
+#include "TNode.h"             // ROOT_TNode
+#include "TList.h"             // ROOT_TList
+#include "AliFMD3.h"           // ALIFMD3_H 
+#include "AliLog.h"            // ALILOG_H
+#include "AliFMDRing.h"                // ALIFMDRING_H 
+#include <Riostream.h>         // ROOT_Riostream
 
 //____________________________________________________________________
 ClassImp(AliFMD3);
@@ -165,7 +151,7 @@ AliFMD3::SimpleGeometry(TList* nodes,
                   / (fOuterZ - fInnerZ));
   Double_t bo   = 0;
   if (ao2 > ao1) {
-    cout << "Wafer determinds the size" << endl;
+    // std::cout << "Wafer determinds the size" << std::endl;
     ao  = ao2;
     bo  = fInner->GetHighR() - ao * fInnerZ;
   }
index 2fb5a71..e1127d6 100644 (file)
 //
 //////////////////////////////////////////////////////////////////////
 
-#ifndef ALIFMDDIGIT_H
-# include "AliFMDDigit.h"
-#endif
-# include <Riostream.h>
+#include "AliFMDDigit.h"       // ALIFMDDIGIT_H
+#include "Riostream.h"         // ROOT_Riostream
 
 //====================================================================
 ClassImp(AliFMDBaseDigit);
@@ -102,9 +100,9 @@ AliFMDBaseDigit::Print(Option_t* /* option*/) const
 {
   // Print digit to standard out 
   cout << ClassName() << ": FMD" << fDetector << fRing << "[" 
-           << setw(3) << fSector << ","
-           << setw(3) << fStrip << "]" 
-           << endl;
+       << setw(3) << fSector << ","
+       << setw(3) << fStrip << "]" 
+       << endl;
 }
 
 //====================================================================
index b664af6..67fcbfb 100644 (file)
 //         we'd like have the option, and so it should be reflected in
 //         the code.
 //
-// The shaping function of the VA1_ALICE is given by 
 //
-//      f(x) = A(1 - exp(-Bx))
-//
-// Where A is a normalization constant, tuned so that the integral 
-//
-//      /1
-//      |           A(-1 + B + exp(-B))
-//      | f(x) dx = ------------------- = 1
-//      |                    B
-//      / 0
+// The shaping function of the VA1_ALICE is generally given by 
 //
-// and B is the a parameter defined by the shaping time (fShapingTime).  
-//
-// Solving the above equation, for A gives
-//
-//                 B
-//      A = ----------------
-//          -1 + B + exp(-B)
-//
-// So, if we define the function g: [0,1] -> [0:1] by 
-//
-//               / v
-//               |              Bu + exp(-Bu) - Bv - exp(-Bv) 
-//      g(u,v) = | f(x) dx = -A -----------------------------
-//               |                            B
-//               / u
-//
-// we can evaluate the ALTRO sample of the VA1_ALICE pre-amp between
-// any two times (u, v), by 
-//       
-//
-//                                B        Bu + exp(-Bu) - Bv - exp(-Bv)
-//      C = Q g(u,v) = - Q ---------------- -----------------------------
-//                        -1 + B + exp(-B)              B                  
+//      f(x) = A(1 - exp(-Bx))
 //
-//               Bu + exp(-Bu) - Bv - exp(-Bv) 
-//        = -  Q -----------------------------
-//                    -1 + B + exp(-B)
+// where A is the total charge collected in the pre-amp., and B is a
+// paramter that depends on the shaping time of the VA1_ALICE circut.
+// 
+// When simulating the shaping function of the VA1_ALICe
+// pre-amp. chip, we have to take into account, that the shaping
+// function depends on the previous value of read from the pre-amp. 
+//
+// That results in the following algorithm:
+//
+//    last = 0;
+//    FOR charge IN pre-amp. charge train DO 
+//      IF last < charge THEN 
+//        f(t) = (charge - last) * (1 - exp(-B * t)) + last
+//      ELSE
+//        f(t) = (last - charge) * exp(-B * t) + charge)
+//      ENDIF
+//      FOR i IN # samples DO 
+//        adc_i = f(i / (# samples))
+//      DONE
+//      last = charge
+//   DONE
+//
+// Here, 
+//
+//   pre-amp. charge train 
+//       is a series of 128 charges read from the VA1_ALICE chip
+//
+//   # samples
+//       is the number of times the ALTRO ADC samples each of the 128
+//       charges from the pre-amp. 
 //
 // Where Q is the total charge collected by the VA1_ALICE
 // pre-amplifier.   Q is then given by 
 //
 //////////////////////////////////////////////////////////////////////////////
 
-#ifndef ROOT_TTree
-# include <TTree.h>
-#endif
-#ifndef ROOT_TRandom
-# include <TRandom.h>
-#endif
-#ifndef ALILOG_H
-# include "AliLog.h"
-#endif
-#ifndef ALIFMDDIGITIZER_H
-# include "AliFMDDigitizer.h"
-#endif
-#ifndef ALIFMD_H
-# include "AliFMD.h"
-#endif
-#ifndef ALIFMDHIT_H
-# include "AliFMDHit.h"
-#endif
-#ifndef ALIFMDDIGIT_H
-# include "AliFMDDigit.h"
-#endif
-#ifndef ALIFMDDIGIT_H
-# include "AliFMDSDigit.h"
-#endif
-#ifndef ALIRUNDIGITIZER_H
-# include "AliRunDigitizer.h"
-#endif
-#ifndef ALIRUN_H
-# include "AliRun.h"
-#endif
-#ifndef ALILOADER_H
-# include "AliLoader.h"
-#endif
-#ifndef ALIRUNLOADER_H
-# include "AliRunLoader.h"
-#endif
+//      /1
+//      |           A(-1 + B + exp(-B))
+//      | f(x) dx = ------------------- = 1
+//      |                    B
+//      / 0
+//
+// and B is the a parameter defined by the shaping time (fShapingTime).  
+//
+// Solving the above equation, for A gives
+//
+//                 B
+//      A = ----------------
+//          -1 + B + exp(-B)
+//
+// So, if we define the function g: [0,1] -> [0:1] by 
+//
+//               / v
+//               |              Bu + exp(-Bu) - Bv - exp(-Bv) 
+//      g(u,v) = | f(x) dx = -A -----------------------------
+//               |                            B
+//               / u
+//
+// we can evaluate the ALTRO sample of the VA1_ALICE pre-amp between
+// any two times (u, v), by 
+//       
+//
+//                                B        Bu + exp(-Bu) - Bv - exp(-Bv)
+//      C = Q g(u,v) = - Q ---------------- -----------------------------
+//                        -1 + B + exp(-B)              B                  
+//
+//               Bu + exp(-Bu) - Bv - exp(-Bv) 
+//        = -  Q -----------------------------
+//                    -1 + B + exp(-B)
+//
+
+#include "TTree.h"             // ROOT_TTree
+#include "TRandom.h"           // ROOT_TRandom
+#include "AliLog.h"            // ALILOG_H
+#include "AliFMDDigitizer.h"   // ALIFMDDIGITIZER_H
+#include "AliFMD.h"            // ALIFMD_H
+#include "AliFMDHit.h"         // ALIFMDHIT_H
+#include "AliFMDDigit.h"       // ALIFMDDIGIT_H
+#include "AliRunDigitizer.h"   // ALIRUNDIGITIZER_H
+#include "AliRun.h"            // ALIRUN_H
+#include "AliLoader.h"         // ALILOADER_H
+#include "AliRunLoader.h"      // ALIRUNLOADER_H
     
 //____________________________________________________________________
 ClassImp(AliFMDEdepMap);
@@ -215,7 +221,10 @@ AliFMDBaseDigitizer::AliFMDBaseDigitizer()
 AliFMDBaseDigitizer::AliFMDBaseDigitizer(AliRunDigitizer* manager) 
   : AliDigitizer(manager, "AliFMDBaseDigitizer", "FMD Digitizer base class"), 
     fRunLoader(0),
-    fEdep(kMaxDetectors, kMaxRings, kMaxSectors, kMaxStrips)
+    fEdep(AliFMDMap::kMaxDetectors, 
+         AliFMDMap::kMaxRings, 
+         AliFMDMap::kMaxSectors, 
+         AliFMDMap::kMaxStrips)
 {
   // Normal CTOR
   AliDebug(1," processed");
@@ -230,7 +239,10 @@ AliFMDBaseDigitizer::AliFMDBaseDigitizer(const Char_t* name,
                                         const Char_t* title) 
   : AliDigitizer(name, title),
     fRunLoader(0),
-    fEdep(kMaxDetectors, kMaxRings, kMaxSectors, kMaxStrips)
+    fEdep(AliFMDMap::kMaxDetectors, 
+         AliFMDMap::kMaxRings, 
+         AliFMDMap::kMaxSectors, 
+         AliFMDMap::kMaxStrips)
 {
   // Normal CTOR
   AliDebug(1," processed");
@@ -309,12 +321,12 @@ AliFMDBaseDigitizer::SumContributions(AliFMD* fmd)
       UShort_t sector   = fmdHit->Sector();
       UShort_t strip    = fmdHit->Strip();
       Float_t  edep     = fmdHit->Edep();
-      if (fEdep(detector, ring, sector, strip).first != 0)
+      if (fEdep(detector, ring, sector, strip).fEdep != 0)
        AliDebug(1, Form("Double hit in %d%c(%d,%d)", 
                         detector, ring, sector, strip));
       
-      fEdep(detector, ring, sector, strip).first  += edep;
-      fEdep(detector, ring, sector, strip).second += 1;
+      fEdep(detector, ring, sector, strip).fEdep  += edep;
+      fEdep(detector, ring, sector, strip).fN     += 1;
       // Add this to the energy deposited for this strip
     }  // hit loop
   } // track loop
@@ -354,11 +366,18 @@ AliFMDBaseDigitizer::DigitizeHits(AliFMD* fmd) const
        // Get number of strips 
        UShort_t nStrips = r->GetNStrips();
        // Loop over the stips 
+       Float_t last = 0;
        for (UShort_t strip = 0; strip < nStrips; strip++) {
+         // Reset the counter array to the invalid value -1 
          counts.Reset(-1);
-         Float_t edep = fEdep(detector, r->GetId(), sector, strip).first;
-         ConvertToCount(edep, r->GetSiThickness(), fmd->GetSiDensity(), 
+         // Reset the last `ADC' value when we've get to the end of a
+         // VA1_ALICE channel. 
+         if (strip % 128 == 0) last = 0;
+         
+         Float_t edep = fEdep(detector, r->GetId(), sector, strip).fEdep;
+         ConvertToCount(edep, last, r->GetSiThickness(), fmd->GetSiDensity(), 
                         counts);
+         last = edep;
          AddDigit(fmd, detector, r->GetId(), sector, strip, 
                   edep, UShort_t(counts[0]), 
                   Short_t(counts[1]), Short_t(counts[2]));
@@ -367,8 +386,8 @@ AliFMDBaseDigitizer::DigitizeHits(AliFMD* fmd) const
          // number of particles when reconstructed, using a naiive
          // approach.  It's here only as a quality check - nothing
          // else. 
-         CheckDigit(fEdep(detector, r->GetId(), sector, strip).first,
-                    fEdep(detector, r->GetId(), sector, strip).second,
+         CheckDigit(fEdep(detector, r->GetId(), sector, strip).fEdep,
+                    fEdep(detector, r->GetId(), sector, strip).fN,
                     counts);
 #endif
        } // Strip
@@ -378,79 +397,69 @@ AliFMDBaseDigitizer::DigitizeHits(AliFMD* fmd) const
 }
 
 //____________________________________________________________________
-Float_t
-AliFMDBaseDigitizer::ShapeIntegral(Float_t u, Float_t v) const
-{
-  // Calculates the integral 
-  // 
-  //      / v
-  //      |               Bu + exp(-Bu) - Bv - exp(-Bv) 
-  //      | f(x) dx = - A -----------------------------
-  //      |                             B
-  //      / u
-  // 
-  // of the shaping function of the VA1_ALICE between times u and v
-  //
-  //      f(x) = A(1 - exp(-Bx))
-  //
-  // where A is a normalization constant, tuned so that the integral 
-  //
-  //      /1
-  //      |                              B         
-  //      | f(x) dx = 1   =>  A = ----------------
-  //      |                      -1 + B + exp(-B)
-  //      / 0
-  //
-  // and B is the a parameter defined by the shaping time (fShapingTime).  
-  // 
-  // That is, the function return the value 
-  // 
-  //        Bu + exp(-Bu) - Bv - exp(-Bv) 
-  //      - -----------------------------
-  //               -1 + B + exp(-B)
-  // 
-  // u,v should lie in the interval [0,1], and u < v
-  if (u == 0 && v == 1) return 1;
-  Float_t B = fShapingTime;
-  
-  // Calculate the integral 
-  Float_t res = - ((B * u + TMath::Exp(-B * u) - B * v - TMath::Exp(-B * v)) /
-                (-1 + B + TMath::Exp(-B)));
-  return res;
-}
-
-//____________________________________________________________________
 void
 AliFMDBaseDigitizer::ConvertToCount(Float_t   edep, 
+                                   Float_t   last,
                                    Float_t   siThickness, 
                                    Float_t   siDensity, 
                                    TArrayI&  counts) const
 {
-  // Put noise and make ADC signal
-  // This is calculated as the product 
+  // Convert the total energy deposited to a (set of) ADC count(s). 
   // 
-  //   DeltaEmip * SiThickness * SiDensity / Number 
-  //
-  // Where 
-  //  
-  //   DeltaEmip     is the energy loss of a MIP 
-  //   SiThickness   is the thickness of the silicon 
-  //   SiDensity     is the Silicon density 
-  //   Number        is # of e^- per MIP
+  // This is done by 
+  // 
+  //               Energy_Deposited      ALTRO_Channel_Size
+  //    ADC = -------------------------- ------------------- + pedestal
+  //          Energy_Deposition_Of_1_MIP VA1_ALICE_MIP_Range
   //
-  // Note: Need to check this is correct. 
+  //               Energy_Deposited             fAltroChannelSize
+  //        = --------------------------------- ----------------- + pedestal 
+  //          1.664 * Si_Thickness * Si_Density   fVA1MipRange  
+  //          
   // 
-  const Float_t mipI = 1.664 * siThickness * siDensity;
-  // const Float_t mipI = 1.664 * 0.04 * 2.33 / 22400; // = 6.923e-6;
-  
+  //        = Energy_Deposited * ConversionFactor + pedestal
+  // 
+  // However, this is modified by the response function of the
+  // VA1_ALICE pre-amp. chip in case we are doing oversampling of the
+  // VA1_ALICE output. 
+  // 
+  // In that case, we get N=fSampleRate values of the ADC, and the
+  // `EnergyDeposited' is a function of which sample where are
+  // calculating the ADC for 
+  // 
+  //     ADC_i = f(EnergyDeposited, i/N, Last) * ConversionFactor + pedestal 
+  // 
+  // where Last is the Energy deposited in the previous strip. 
+  // 
+  // Here, f is the shaping function of the VA1_ALICE.   This is given
+  // by 
+  //                       
+  //                    |   (E - l) * (1 - exp(-B * t) + l   if E > l
+  //       f(E, t, l) = <
+  //                    |   (l - E) * exp(-B * t) + E        otherwise
+  //                       
+  // 
+  //                  = E + (l - E) * ext(-B * t)
+  // 
+  const Float_t mipEnergy = 1.664 * siThickness * siDensity;
+  const Float_t convf     = (1 / mipEnergy * Float_t(fAltroChannelSize) 
+                            / fVA1MipRange);
+  UShort_t ped            = MakePedestal();
+
+  // In case we don't oversample, just return the end value. 
+  if (fSampleRate == 1) {
+    counts[0] = UShort_t(TMath::Min(edep * convf + ped, 
+                                   Float_t(fAltroChannelSize)));
+    return;
+  }
+
   // Create a pedestal 
-  UShort_t ped = MakePedestal();
-  
-  Float_t convf = 1 / mipI * Float_t(fAltroChannelSize) / fVA1MipRange;
-  Int_t n = fSampleRate;
+  Int_t   n = fSampleRate;
+  Float_t B = fShapingTime;
   for (Ssiz_t i = 0; i < n;  i++) {
-    Float_t w = ShapeIntegral(Float_t(i)/n, Float_t(i+1)/n);
-    counts[i] = UShort_t(TMath::Min(w * edep * convf + ped, 
+    Float_t t = Float_t(i) / n;
+    Float_t s = edep + (last - edep) * TMath::Exp(-B * t);
+    counts[i] = UShort_t(TMath::Min(s * convf + ped, 
                                    Float_t(fAltroChannelSize))); 
   }
 }
index 1b350e8..318ee73 100644 (file)
@@ -11,8 +11,8 @@
 #ifndef ALIRUNDIGITIZER_H
 # include <AliRunDigitizer.h>
 #endif
-#ifndef ALIFMDMAP_H
-# include <AliFMDMap.h>
+#ifndef ALIFMDEdepMAP_H
+# include <AliFMDEdepMap.h>
 #endif
 #ifndef __UTILITY__
 # include <utility>
@@ -27,7 +27,6 @@ class AliFMD;
 class AliLoader;
 class AliRunLoader;
 
-typedef AliFMDMap<std::pair<Float_t, UShort_t> > AliFMDEdepMap;
 
 //====================================================================
 class AliFMDBaseDigitizer : public AliDigitizer 
@@ -55,11 +54,11 @@ protected:
   virtual void     SumContributions(AliFMD* fmd);
   virtual void     DigitizeHits(AliFMD* fmd) const;
   virtual void     ConvertToCount(Float_t   edep, 
+                                 Float_t   last,
                                  Float_t   siThickness, 
                                  Float_t   siDensity, 
                                  TArrayI&  counts) const;
   virtual UShort_t MakePedestal() const { return 0; }
-  virtual Float_t  ShapeIntegral(Float_t u, Float_t v) const;
   virtual void     AddNoise(TArrayI&) const {}
   virtual void     AddDigit(AliFMD*  /* fmd      */,
                            UShort_t /* detector */, 
@@ -78,12 +77,6 @@ protected:
   UShort_t      fSampleRate;       // Times the ALTRO samples pre-amp.
   Float_t       fShapingTime;      // Shaping profile parameter
   
-  enum { 
-    kMaxDetectors = 3, 
-    kMaxRings     = 2, 
-    kMaxSectors   = 20, 
-    kMaxStrips    = 512
-  };
   ClassDef(AliFMDBaseDigitizer,0) // Base class for FMD digitizers
 };
 
diff --git a/FMD/AliFMDEdepMap.cxx b/FMD/AliFMDEdepMap.cxx
new file mode 100644 (file)
index 0000000..8f817b1
--- /dev/null
@@ -0,0 +1,122 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
+//____________________________________________________________________
+//                                                                          
+//
+//
+#include "AliFMDEdepMap.h"             // ALIFMDEDEPMAP_H
+
+//____________________________________________________________________
+ClassImp(AliFMDEdepMap);
+
+//____________________________________________________________________
+AliFMDEdepMap::AliFMDEdepMap(const AliFMDEdepMap& other)
+  : AliFMDMap(other.fMaxDetectors, other.fMaxRings, other.fMaxSectors, 
+             other.fMaxStrips), 
+    fData(0)
+{
+  fData = new AliFMDEdepHitPair[fMaxDetectors * fMaxRings * 
+                               fMaxSectors * fMaxStrips];
+  for (size_t i = 0; i < fMaxDetectors * fMaxRings * fMaxSectors * fMaxStrips;
+       i++) fData[i] = other.fData[i];
+}
+
+  
+
+//____________________________________________________________________
+AliFMDEdepMap::AliFMDEdepMap(size_t maxDet, 
+                            size_t maxRing, 
+                            size_t maxSec, 
+                            size_t maxStr)
+  : AliFMDMap(maxDet, maxRing, maxSec, maxStr), 
+    fData(0)
+{
+  // Construct a map
+  //
+  // Parameters:
+  //     maxDet       Maximum # of detectors
+  //     maxRinf      Maximum # of rings
+  //     maxSec       Maximum # of sectors
+  //     maxStr       Maximum # of strips
+  fData = new AliFMDEdepHitPair[fMaxDetectors * fMaxRings * 
+                               fMaxSectors * fMaxStrips];
+}
+
+//____________________________________________________________________
+AliFMDEdepMap&
+AliFMDEdepMap::operator=(const AliFMDEdepMap& other) 
+{
+  fMaxDetectors = other.fMaxDetectors;
+  fMaxRings     = other.fMaxRings;
+  fMaxSectors   = other.fMaxSectors;
+  fMaxStrips    = other.fMaxStrips;
+  if (fData) delete [] fData;
+  fData = new AliFMDEdepHitPair[fMaxDetectors * fMaxRings * 
+                               fMaxSectors * fMaxStrips];
+  for (size_t i = 0; i < fMaxDetectors * fMaxRings * fMaxSectors * fMaxStrips;
+       i++) fData[i] = other.fData[i];
+  return *this;
+}
+
+//____________________________________________________________________
+void
+AliFMDEdepMap::Clear(const AliFMDEdepHitPair& val) 
+{
+  for (size_t i = 0; i < fMaxDetectors * fMaxRings * fMaxSectors * fMaxStrips;
+       i++) fData[i] = val;
+}
+
+//____________________________________________________________________
+AliFMDEdepHitPair& 
+AliFMDEdepMap::operator()(UShort_t det, Char_t ring, UShort_t sec, UShort_t str) 
+{
+  // Get data 
+  // 
+  // Parameters: 
+  //     det       Detector #
+  //     ring      Ring ID
+  //     sec       Sector # 
+  //     str       Strip # 
+  //
+  // Returns appropriate data
+  //
+  return fData[CalcIndex(det, ring, sec, str)];
+}
+
+//____________________________________________________________________
+const AliFMDEdepHitPair& 
+AliFMDEdepMap::operator()(UShort_t det, Char_t ring, UShort_t sec, UShort_t str) const
+{
+  // Get data 
+  // 
+  // Parameters: 
+  //     det       Detector #
+  //     ring      Ring ID
+  //     sec       Sector # 
+  //     str       Strip # 
+  //
+  // Returns appropriate data
+  //
+  return fData[CalcIndex(det, ring, sec, str)];
+}
+
+
+//___________________________________________________________________
+//
+// EOF
+//
diff --git a/FMD/AliFMDEdepMap.h b/FMD/AliFMDEdepMap.h
new file mode 100644 (file)
index 0000000..f34fba1
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef ALIFMDEDEPMAP_H
+#define ALIFMDEDEPMAP_H
+/* Copyright(c) 1998-2000, ALICE Experiment at CERN, All rights
+ * reserved. 
+ *
+ * See cxx source for full Copyright notice                               
+ */
+#ifndef ALIFMDMAP_H
+# include <AliFMDMap.h>
+#endif 
+//____________________________________________________________________
+//
+// Cache of Energy deposited, hit information perr strip
+//
+
+//____________________________________________________________________
+class AliFMDEdepHitPair 
+{
+ public:
+  Float_t  fEdep;
+  UShort_t fN;
+  AliFMDEdepHitPair() : fEdep(0), fN(0) {}
+};
+
+//____________________________________________________________________
+class AliFMDEdepMap : public AliFMDMap
+{
+public:
+  AliFMDEdepMap(const AliFMDEdepMap& other);
+  AliFMDEdepMap(size_t maxDet = kMaxDetectors, 
+               size_t maxRing= kMaxRings, 
+               size_t maxSec = kMaxSectors, 
+               size_t maxStr = kMaxStrips);
+  virtual ~AliFMDEdepMap() { delete [] fData; }
+  AliFMDEdepMap& operator=(const AliFMDEdepMap& other);
+  virtual void Clear(const AliFMDEdepHitPair& val=AliFMDEdepHitPair());
+  virtual AliFMDEdepHitPair& operator()(UShort_t detector, 
+                                    Char_t   ring, 
+                                    UShort_t sector, 
+                                    UShort_t strip);
+  virtual const AliFMDEdepHitPair& operator()(UShort_t detector, 
+                                          Char_t   ring, 
+                                          UShort_t sector, 
+                                          UShort_t strip) const;
+protected:
+  AliFMDEdepHitPair* fData;  // The data 
+  ClassDef(AliFMDEdepMap, 1) // Cache of edep,hit information per strip
+};
+
+#endif 
+//____________________________________________________________________
+//
+// Local Variables:
+//   mode: C++
+// End:
+//
+// EOF
+//
+
+
index 61afbd9..0d15f12 100644 (file)
 
 /* $Id$ */
 
-//////////////////////////////////////////////////////////////////////////////
+//____________________________________________________________________
 //
 //  Hits in the FMD 
 //
 // Latest changes by Christian Holm Christensen
 //
-//////////////////////////////////////////////////////////////////////////////
-#ifndef ALIFMDHIT_H
-# include "AliFMDHit.h"
-#endif
-#ifndef ALILOG_H
-# include "AliLog.h"
-#endif
-# include <Riostream.h>
+#include "AliFMDHit.h"         // ALIFMDHIT_H
+#include "AliLog.h"            // ALILOG_H
+#include "Riostream.h"         // ROOT_Riostream
 
 //____________________________________________________________________
 ClassImp(AliFMDHit);
diff --git a/FMD/AliFMDMap.cxx b/FMD/AliFMDMap.cxx
new file mode 100644 (file)
index 0000000..5a59f67
--- /dev/null
@@ -0,0 +1,80 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
+//____________________________________________________________________
+//                                                                          
+//
+//
+#include "AliFMDMap.h"         // ALIFMDMAP_H
+
+//____________________________________________________________________
+ClassImp(AliFMDMap);
+
+//____________________________________________________________________
+AliFMDMap::AliFMDMap(size_t maxDet, 
+                    size_t maxRing, 
+                    size_t maxSec, 
+                    size_t maxStr)
+  : fMaxDetectors(maxDet), 
+    fMaxRings(maxRing), 
+    fMaxSectors(maxSec), 
+    fMaxStrips(maxStr)
+{
+  // Construct a map
+  //
+  // Parameters:
+  //     maxDet       Maximum # of detectors
+  //     maxRinf      Maximum # of rings
+  //     maxSec       Maximum # of sectors
+  //     maxStr       Maximum # of strips
+}
+
+
+//____________________________________________________________________
+size_t 
+AliFMDMap::CalcIndex(size_t det, Char_t ring, size_t sec, size_t str) const
+{
+  // Calculate index into storage from arguments. 
+  // 
+  // Parameters: 
+  //     det       Detector #
+  //     ring      Ring ID
+  //     sec       Sector # 
+  //     str       Strip # 
+  //
+  // Returns appropriate index into storage 
+  //
+  size_t ringi = (ring == 'I' ||  ring == 'i' ? 0 : 1);
+  size_t idx = 
+    (det + fMaxDetectors * (ringi + fMaxRings * (sec + fMaxSectors * str)));
+  if (idx >= fMaxDetectors * fMaxRings * fMaxSectors * fMaxStrips) {
+    Fatal("CalcIndex", "Index (%d,'%c',%d,%d) out of bounds, "
+         "in particular the %s index", 
+         det, ring, sec, str, 
+         (det >= fMaxDetectors ? "Detector" : 
+          (ringi >= fMaxRings ? "Ring" : 
+           (sec >= fMaxSectors ? "Sector" : "Strip"))));
+    return 0;
+  }
+  return idx;
+}
+
+
+//___________________________________________________________________
+//
+// EOF
+//
index 8487cd7..91fb4e6 100644 (file)
@@ -5,10 +5,55 @@
  *
  * See cxx source for full Copyright notice                               
  */
+#ifndef ROOT_TObject
+# include <TObject.h>
+#endif 
+//____________________________________________________________________
+//
+// Base class for caches of per-strip information.
+//
+
+class AliFMDMap : public TObject 
+{
+public:
+  enum { 
+    kMaxDetectors = 3, 
+    kMaxRings     = 2, 
+    kMaxSectors   = 20, 
+    kMaxStrips    = 512
+  };
+  AliFMDMap(size_t maxDet = kMaxDetectors, 
+           size_t maxRing= kMaxRings, 
+           size_t maxSec = kMaxSectors, 
+           size_t maxStr = kMaxStrips);
+  virtual ~AliFMDMap() {}
+protected:
+  size_t CalcIndex(size_t det, Char_t ring, size_t sec, size_t str) const;
+  size_t fMaxDetectors;             // Maximum # of detectors
+  size_t fMaxRings;                 // Maximum # of rings
+  size_t fMaxSectors;               // Maximum # of sectors
+  size_t fMaxStrips;                // Maximum # of strips
+  ClassDef(AliFMDMap, 1) // Cache of per strip information
+};
+
+#ifdef  MAY_USE_TEMPLATES
 #ifndef __VECTOR__
 # include <vector>
 #endif 
-
+//____________________________________________________________________
+//
+// Class template for classes that cache per strip information.  
+// Access to the data goes via 
+//
+//   Type& AliFMDMap<Type>::operator()(size_t detector,
+//                                     Char_t ring, 
+//                                     size_t sector,
+//                                     size_t strip);
+// 
+// (as well as a const version of this member function). 
+// The elements can be reset to the default value by calling 
+// AliFMDMap<Type>::Clear().  This resets the values to `Type()'. 
+//
 template <typename Type> 
 class AliFMDMap : public TObject 
 {
@@ -16,7 +61,7 @@ public:
   AliFMDMap(size_t maxDet=3, size_t maxRing=2, size_t maxSec=40, 
            size_t maxStr=512);
   virtual ~AliFMDMap() {}
-  void Clear();
+  void Clear(const Type& val=Type());
   Type& operator()(size_t det, Char_t ring, size_t sec, size_t str);
   const Type& operator()(size_t det, Char_t ring, size_t sec, size_t str)const;
 private:
@@ -88,10 +133,10 @@ AliFMDMap<Type>::CalcIndex(size_t det, Char_t ring, size_t sec, size_t str) cons
 //____________________________________________________________________
 template <typename Type>
 inline void
-AliFMDMap<Type>::Clear() 
+AliFMDMap<Type>::Clear(const Type& val) 
 {
   // Resets stored values to the default value for that type 
-  for (size_t i = 0; i < fValues.size(); ++i) fValues[i] = Type();
+  for (size_t i = 0; i < fValues.size(); ++i) fValues[i] = val;
 }
 
 //____________________________________________________________________
@@ -112,7 +157,10 @@ AliFMDMap<Type>::operator()(size_t det, Char_t ring, size_t sec, size_t str)
 //____________________________________________________________________
 template <typename Type>
 inline const Type& 
-AliFMDMap<Type>::operator()(size_t det, Char_t ring, size_t sec, size_t str)const
+AliFMDMap<Type>::operator()(size_t det, 
+                           Char_t ring, 
+                           size_t sec, 
+                           size_t str) const
 {
   // Parameters: 
   //     det       Detector #
@@ -125,7 +173,14 @@ AliFMDMap<Type>::operator()(size_t det, Char_t ring, size_t sec, size_t str)cons
 }
 
 
+//____________________________________________________________________
+// 
+// Some specialisations 
+//
+typedef AliFMDMap<UShort_t> AliFMDAdcMap;
+typedef AliFMDMap<std::pair<Float_t, UShort_t> > AliFMDEdepMap;
 
+#endif
 #endif 
 //____________________________________________________________________
 //
diff --git a/FMD/AliFMDNaiiveAlgorithm.cxx b/FMD/AliFMDNaiiveAlgorithm.cxx
new file mode 100644 (file)
index 0000000..c56b33e
--- /dev/null
@@ -0,0 +1,97 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
+//____________________________________________________________________
+// 
+// Base class for FMD naiive algorithms. 
+//
+// Derived classes will implement various ways of reconstructing the
+// charge particle multiplicity in the FMD.  
+// 
+#include "AliFMDNaiiveAlgorithm.h"     // ALIFMDNAIIVEALGORITHM_H
+#include "AliFMDDigit.h"               // ALIFMDDIGIT_H
+
+//____________________________________________________________________
+ClassImp(AliFMDNaiiveAlgorithm);
+
+//____________________________________________________________________
+AliFMDNaiiveAlgorithm::AliFMDNaiiveAlgorithm()
+  : AliFMDReconstructionAlgorithm("Naiive", "Naiive")
+{}
+
+
+//____________________________________________________________________
+void
+AliFMDNaiiveAlgorithm::Reset() 
+{
+  // Reset internal data 
+  fTotal = 0;
+  fEdep.Clear(0);
+  fMultiplicity.Clear(0);
+}
+
+//____________________________________________________________________
+void
+AliFMDNaiiveAlgorithm::ProcessDigit(AliFMDDigit* digit, 
+                                   Float_t eta, 
+                                   Float_t phi, 
+                                   UShort_t count)
+{
+  // Process one digit. 
+  // 
+  // Parameters: 
+  //    
+  //   digit           Digit to process 
+  //   eta              Pseudo-rapidity of digit
+  //   phi              Azimuthal angle of digit
+  //   count            ADC (corrected for the pedestal)
+  //
+  // This calculates the energy deposited and the number of MIPs that
+  // this energy deposition corresponds to 
+  // 
+  //   EnergyDeposited = cos(theta) * gain * count 
+  //   Multiplicity    = EnergyDeposited / EnergyDepositedPerMIP
+  // 
+  // where gain is a conversion factor from number of counts to an
+  // energy:
+  //          Pre_Amp_MIP_Range           1
+  //   gain = ----------------- * ---------------------
+  //          ADC_channel_size    EnergyDepositedPerMip
+  // 
+  // and theta is the particles incident angle on the strip, given by 
+  //
+  //   theta = 2 * atan  * exp(-eta)
+  //
+  // The cos(theta) factor corrects for the fact that the particle may
+  // traverse the strip at an angle, and therefor have a longer flight
+  // length, leading to a larger energy deposition. 
+  // 
+  if (!digit) return;
+  Double_t theta = 2 * TMath::Tan(TMath::Exp(- eta));
+  Double_t edep  = TMath::Cos(theta) * fGain * count;
+  Double_t mult  = edep / fEdepMip;
+  fEdep(digit->Detector() - 1, digit->Ring(), 
+       digit->Setctor(), digit->Strip()) = edep;
+  fMultiplicity(digit->Detector() - 1, digit->Ring(), 
+               digit->Setctor(), digit->Strip()) = mult;
+}
+
+
+//____________________________________________________________________
+// 
+// EOF
+//
index 9cffbc3..88e5e74 100644 (file)
@@ -1,15 +1,29 @@
-//////////////////////////////////////////////////////////////////////
+/**************************************************************************
+ * Copyright(c) 2004, 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.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
+//____________________________________________________________________
 //
 //  Forward Multiplicity Detector have to be reconstructed number of
 //  particles in fixed pseudorapidity interval from fNumOfMinRing
 //  to fNumOfMaxRing and phi interval from fNumOfMinSector to
 //  fNumOfMaxSector
 //
-//////////////////////////////////////////////////////////////////////
-#ifndef ALIFMDPARTICLES_H
-# include "AliFMDParticles.h"
-#endif
-# include <Riostream.h>
+#include "AliFMDParticles.h"   // ALIFMDPARTICLES_H
+#include "Riostream.h"         // ROOT_Riostream
 
 //____________________________________________________________________
 ClassImp(AliFMDParticles)
diff --git a/FMD/AliFMDPoissonAlgorithm.cxx b/FMD/AliFMDPoissonAlgorithm.cxx
new file mode 100644 (file)
index 0000000..be89bea
--- /dev/null
@@ -0,0 +1,72 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
+//____________________________________________________________________
+// 
+// Base class for FMD poisson algorithms. 
+//
+// Derived classes will implement various ways of reconstructing the
+// charge particle multiplicity in the FMD.  
+// 
+#include "AliFMDPoissonAlgorithm.h"    // ALIFMDPOISSONALGORITHM_H
+#include "AliFMDDigit.h"               // ALIFMDDIGIT_H
+
+//____________________________________________________________________
+ClassImp(AliFMDPoissonAlgorithm);
+
+//____________________________________________________________________
+AliFMDPoissonAlgorithm::AliFMDPoissonAlgorithm()
+  : AliFMDReconstructionAlgorithm("Poisson", "Poisson")
+{}
+
+
+//____________________________________________________________________
+void
+AliFMDPoissonAlgorithm::Reset() 
+{
+  // Reset internal data 
+  fTotal = 0;
+  fEmpty.Reset(kFALSE);
+}
+
+//____________________________________________________________________
+void
+AliFMDPoissonAlgorithm::ProcessDigit(AliFMDDigit* digit, 
+                                    Float_t eta, Float_t phi, 
+                                    UShort_t count)
+{
+  // Process one digit. 
+  // 
+  // Parameters: 
+  //    
+  //   digit           Digit to process 
+  //   ipZ             Z--coordinate of the primary interaction
+  //                    vertex of this event 
+  //
+  if (!digit) return;
+  fTotal++;
+  if (charge < threshold) fEmpty(digit->Detector() - 1, 
+                                digit->Ring(), 
+                                digit->Setctor(), 
+                                digit->Strip()) = kTRUE;
+}
+
+
+//____________________________________________________________________
+// 
+// EOF
+//
diff --git a/FMD/AliFMDPoissonAlgorithm.h b/FMD/AliFMDPoissonAlgorithm.h
new file mode 100644 (file)
index 0000000..265f950
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef ALIFMDPOISSONALGORITHM_H
+#define ALIFMDPOISSONALGORITHM_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+ * reserved. 
+ *
+ * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
+ *
+ * See cxx source for full Copyright notice                               
+ */
+/* $Id$ */
+//____________________________________________________________________
+// 
+// Class to do multiplicity reconstruction using the Poisson method.
+// That is, we count the number of empty strips in a region, and
+// derive the charge particle multiplicity from that number. 
+// 
+
+#ifndef ROOT_TTask
+# include <TTask.h>
+#endif
+
+//____________________________________________________________________
+class AliFMDDigit;
+
+//____________________________________________________________________
+class AliFMDPoissonAlgorithm : public TNamed
+{
+public:
+  AliFMDPoissonAlgorithm();
+  virtual ~AliFMDPoissonAlgorithm() {}
+  
+  virtual void Reset();
+  virtual void ProcessDigit(AliFMDDigit* digit, Float_t ipZ);
+  
+protected:
+  ClassDef(AliFMDPoissonAlgorithm, 0) // Poisson algorithm
+};
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+//   mode: C++
+// End:
+//
+// EOF
+//
index a3f6649..9af5abf 100644 (file)
 // Latest changes by Christian Holm Christensen
 //
 //////////////////////////////////////////////////////////////////////////////
-#ifndef ALIFMDPOLYGON_H
-# include "AliFMDPolygon.h"
-#endif
-#ifndef ALILOG_H
-# include "AliLog.h"
-#endif
-#ifndef ROOT_TString
-# include <TString.h>
-#endif
-#ifndef ROOT_TVector2
-# include <TVector2.h>
-#endif
-#ifndef ROOT_TCanvas
-# include <TCanvas.h>
-#endif
-#ifndef ROOT_TText
-# include <TText.h>
-#endif
-#ifndef ROOT_TGraph
-# include <TGraph.h>
-#endif
-#ifndef ROOT_TError
-# include <TError.h>
-#endif
+#include "AliFMDPolygon.h"     // ALIFMDPOLYGON_H
+#include "AliLog.h"            // ALILOG_H
+#include "TString.h"           // ROOT_TString
+#include "TVector2.h"          // ROOT_TVector2
+#include "TCanvas.h"           // ROOT_TCanvas
+#include "TText.h"             // ROOT_TText
+#include "TGraph.h"            // ROOT_TGraph
+#include "TError.h"            // ROOT_TError
 
 //____________________________________________________________________
 ClassImp(AliFMDPolygon);
diff --git a/FMD/AliFMDRawReader.cxx b/FMD/AliFMDRawReader.cxx
new file mode 100644 (file)
index 0000000..36ea8b9
--- /dev/null
@@ -0,0 +1,151 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
+//____________________________________________________________________
+//
+// Class to read ADC values from a AliRawReader object. 
+//
+#include "AliLog.h"            // ALILOG_H
+#include "AliFMD.h"            // ALIFMD_H
+#include "AliFMDDigit.h"       // ALIFMDDIGIT_H
+#include "AliFMDRawStream.h"   // ALIFMDRAWSTREAM_H 
+#include "AliRawReader.h"      // ALIRAWREADER_H 
+#include "AliFMDRawReader.h"   // ALIFMDRAWREADER_H 
+#include "TArrayI.h"           // ROOT_TArrayI
+// #include <TClonesArray.h>   // ROOT_TClonesArray
+
+//____________________________________________________________________
+ClassImp(AliFMDRawReader);
+
+//____________________________________________________________________
+AliFMDRawReader::AliFMDRawReader(AliFMD* fmd, AliRawReader* reader) 
+  : TTask("FMDRawReader", "Reader of Raw ADC values from the FMD"),
+    fFMD(fmd),
+    fReader(reader)
+{
+  SetSampleRate();
+}
+
+
+//____________________________________________________________________
+void
+AliFMDRawReader::Exec(Option_t*) 
+{
+  if (!fReader->ReadHeader()) {
+    Error("ReadAdcs", "Couldn't read header");
+    return;
+  }
+
+  // Use AliAltroRawStream to read the ALTRO format.  No need to
+  // reinvent the wheel :-) 
+  AliFMDRawStream input(fReader, fSampleRate);
+  // Select FMD DDL's 
+  fReader->Select(AliFMD::kBaseDDL >> 8);
+  
+  Int_t    oldDDL      = -1;
+  Int_t    count       = 0;
+  UShort_t detector    = 1; // Must be one here
+  UShort_t oldDetector = 0;
+  Bool_t   next        = kTRUE;
+
+  // local Cache 
+  TArrayI counts(10);
+  counts.Reset(-1);
+  
+  // Loop over data in file 
+  while (next) {
+    next = input.Next();
+
+    count++; 
+    Int_t ddl = fReader->GetDDLID();
+    if (ddl != oldDDL || input.IsNewStrip() || !next) {
+      // Make a new digit, if we have some data (oldDetector == 0,
+      // means that we haven't really read anything yet - that is,
+      // it's the first time we get here). 
+      if (oldDetector > 0) {
+       // Got a new strip. 
+       AliDebug(10, Form("Add a new strip: FMD%d%c[%2d,%3d] "
+                         "(current: FMD%d%c[%2d,%3d])", 
+                         oldDetector, input.PrevRing(), 
+                         input.PrevSector() , input.PrevStrip(),
+                         detector , input.Ring(), input.Sector(), 
+                         input.Strip()));
+       fFMD->AddDigit(oldDetector, 
+                      input.PrevRing(), 
+                      input.PrevSector(), 
+                      input.PrevStrip(), 
+                      counts[0], counts[1], counts[2]);
+#if 0
+       AliFMDDigit* digit = 
+         static_cast<AliFMDDigit*>(fFMD->Digits()->
+                                   UncheckedAt(fFMD->GetNdigits()-1));
+#endif 
+      }
+       
+      if (!next) { 
+       AliDebug(10, Form("Read %d channels for FMD%d", 
+                         count + 1, detector));
+       break;
+      }
+    
+    
+      // If we got a new DDL, it means we have a new detector. 
+      if (ddl != oldDDL) {
+       if (detector != 0) 
+         AliDebug(10, Form("Read %d channels for FMD%d", 
+                           count + 1, detector));
+       // Reset counts, and update the DDL cache 
+       count       = 0;
+       oldDDL      = ddl;
+       // Check that we're processing a FMD detector 
+       Int_t detId = fReader->GetDetectorID();
+       if (detId != (AliFMD::kBaseDDL >> 8)) {
+         Error("ReadAdcs", "Detector ID %d != %d",
+               detId, (AliFMD::kBaseDDL >> 8));
+         break;
+       }
+       // Figure out what detector we're deling with 
+       oldDetector = detector;
+       switch (ddl) {
+       case 0: detector = 1; break;
+       case 1: detector = 2; break;
+       case 2: detector = 3; break;
+       default:
+         Error("ReadAdcs", "Unknown DDL 0x%x for FMD", ddl);
+         return;
+       }
+       AliDebug(10, Form("Reading ADCs for 0x%x  - That is FMD%d",
+                         fReader->GetEquipmentId(), detector));
+      }
+      counts.Reset(-1);
+    }
+    
+    counts[input.Sample()] = input.Count();
+    
+    AliDebug(10, Form("ADC of FMD%d%c[%2d,%3d] += %d",
+                     detector, input.Ring(), input.Sector(), 
+                     input.Strip(), input.Count()));
+    oldDetector = detector;
+  }
+  return;
+
+}
+
+//____________________________________________________________________
+// 
+// EOF
+//
diff --git a/FMD/AliFMDRawReader.h b/FMD/AliFMDRawReader.h
new file mode 100644 (file)
index 0000000..d2a086c
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef ALIFMDRAWREADER_H
+#define ALIFMDRAWREADER_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+ * reserved. 
+ *
+ * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
+ *
+ * See cxx source for full Copyright notice                               
+ */
+/* $Id$ */
+//____________________________________________________________________
+// 
+// Class to read ADC values from a AliRawReader object. 
+// 
+
+#ifndef ROOT_TTask
+# include <TTask.h>
+#endif
+
+//____________________________________________________________________
+class AliRawReader;
+class AliFMD;
+
+
+//____________________________________________________________________
+class AliFMDRawReader : public TTask 
+{
+public:
+  AliFMDRawReader(AliFMD* fmd, AliRawReader* reader);
+
+  virtual void Exec(Option_t* option="");
+  void SetSampleRate(UShort_t sampleRate=1) { fSampleRate = sampleRate; }
+protected:
+  AliFMD*       fFMD;        //! Pointer to detector description 
+  AliRawReader* fReader;     //! Pointer to raw reader 
+  UShort_t      fSampleRate; // The sample rate (if 0, inferred from data)
+  ClassDef(AliFMDRawReader, 0) // Read FMD raw data into a cache 
+};
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+//   mode: C++
+// End:
+//
+// EOF
+//
index b9233e2..0a57d33 100644 (file)
 
 /* $Id$ */
 
-//////////////////////////////////////////////////////////////////////
+//____________________________________________________________________
 //                                                                          
 // Buffer to read RAW ALTRO FMD format from a AliRawReader 
 // 
-// Currently, I had to overload the Next member function and introduce
-// my own members fMyData, fMyPosition, fMyCount, and fMyBunchLength.
-// The reason is, that we can use the fMyCount to determine the
-// sampling rate used in the ALTRO.   However,
-// AliAltroBuffer::fCount is private, so we can not access it. 
-//
-// If it wasn't I'd implement Next as 
 //
-//     Bool_t
-//     AliFMDRawStreamer::Next()
-//     {
-//        if (AliAltroRawStreamer::Next()) {
-//          if (fPrevPad != fPad) 
-//             fSampleRate = (fCount - 2) / 128;
-//          return kTRUE;
-//        }
-//        return kFALSE;
-//     } 
-//
-//////////////////////////////////////////////////////////////////////
-#ifndef ALIFMDRAWSTREAM_H
-# include "AliFMDRawStream.h"
-#endif
-#ifndef ALIRAWREADER_H
-# include "AliRawReader.h"
-#endif
-#ifndef __IOSTREAM__
-# include <iostream>
-#endif
+#include "AliFMDRawStream.h"           // ALIFMDRAWSTREAM_H
+#include "AliRawReader.h"              // ALIRAWREADER_H
 
 //____________________________________________________________________
 ClassImp(AliFMDRawStream);
 
 //____________________________________________________________________
-AliFMDRawStream::AliFMDRawStream(AliRawReader* reader) 
+AliFMDRawStream::AliFMDRawStream(AliRawReader* reader, UShort_t sampleRate) 
   : AliAltroRawStream(reader), 
-    // fMyData(0), 
-    // fMyPosition(0), 
-    // fMyCount(0),
-    //    fMyBunchLength(0), 
-    fPrevTime(-1)
-{}
-
-
+    fSampleRate(sampleRate),
+    fPrevTime(-1), 
+    fExplicitSampleRate(kFALSE)
+{
+  if (fSampleRate > 0) fExplicitSampleRate = kTRUE;
+}
 
 //_____________________________________________________________________________
 Bool_t 
@@ -72,115 +44,13 @@ AliFMDRawStream::Next()
   // returns kFALSE if there is no digit left
   fPrevTime = fTime;
   if (AliAltroRawStream::Next()) {
-    if (fPrevPad != fPad) {
+    if (!fExplicitSampleRate && fPrevPad != fPad) 
       fSampleRate = fTimeBunch / 128;
-#if 0
-      std::cout << "Setting Sample rate to (" << fTimeBunch << "/" 
-               << 128 << "=" << fSampleRate << std::endl;
-#endif
-    }
     return kTRUE;
   }
   return kFALSE;
 }
 
-#if 0
-//_____________________________________________________________________________
-Bool_t 
-AliFMDRawStream::Next()
-{
-  // read the next raw digit
-  // returns kFALSE if there is no digit left
-  fPrevSector = fSector;
-  fPrevRow    = fRow;
-  fPrevPad    = fPad;
-  fPrevTime   = fTime;
-  
-  while (fMyCount == 0) {  // next trailer
-    if (fMyPosition <= 0) {  // next payload
-      do {
-        if (!fRawReader->ReadNextData(fMyData)) return kFALSE;
-      } while (fRawReader->GetDataSize() == 0);
-
-      fMyPosition = (fRawReader->GetDataSize() * 8) / 10;
-      while (Get10BitWord(fMyData, fMyPosition-1) == 0x2AA) fMyPosition--;
-    }
-
-    if (fMyPosition > 0) {
-      // read the trailer
-      if (fMyPosition <= 4) {
-        Error("Next", "could not read trailer");
-        return kFALSE;
-      }
-      fSector   = Get10BitWord(fMyData, --fMyPosition);
-      fRow      = Get10BitWord(fMyData, --fMyPosition);
-      fPad      = Get10BitWord(fMyData, --fMyPosition);
-      fMyCount  = Get10BitWord(fMyData, --fMyPosition);
-
-      fMyPosition -= (4 - (fMyCount % 4)) % 4;  // skip fill words
-      fMyBunchLength = 0;
-
-      // Set the sample rate, based on the number of samples in the
-      // channel. 
-      fSampleRate = (fMyCount - 2) / 128;
-#if 0
-      std::cout << "Setting Sample rate to (" << fMyCount << " - 2)/" 
-               << 128 << "=" << fSampleRate << std::endl;
-#endif
-    }
-  }
-
-  if (fMyBunchLength == 0) {
-    if (fMyPosition <= 0) {
-      Error("Next", "could not read bunch length");
-      return kFALSE;
-    }
-    fMyBunchLength = Get10BitWord(fMyData, --fMyPosition) - 2;
-    fMyCount--;
-    
-
-    if (fMyPosition <= 0) {
-      Error("Next", "could not read time bin");
-      return kFALSE;
-    }
-    fTime = Get10BitWord(fMyData, --fMyPosition);
-    fMyCount--;
-  } else {
-    fTime--;
-  }
-
-  if (fMyPosition <= 0) {
-    Error("Next", "could not read sample amplitude");
-    return kFALSE;
-  }
-  fSignal = Get10BitWord(fMyData, --fMyPosition);
-  fMyCount--;
-  fMyBunchLength--;
-
-  return kTRUE;
-}
-
-//_____________________________________________________________________________
-UShort_t 
-AliFMDRawStream::Get10BitWord(UChar_t* buffer, Int_t position) const
-{
-// return a word in a 10 bit array as an UShort_t
-
-  Int_t iBit = position * 10;
-  Int_t iByte = iBit / 8;
-  Int_t shift = iBit % 8;
-//  return ((buffer[iByte+1] * 256 + buffer[iByte]) >> shift) & 0x03FF;
-
-  // recalculate the byte numbers and the shift because
-  // the raw data is written as integers where the high bits are filled first
-  // -> little endian is assumed here !
-  Int_t iByteHigh = 4 * (iByte / 4) + 3 - (iByte % 4);
-  iByte++;
-  Int_t iByteLow  = 4 * (iByte / 4) + 3 - (iByte % 4);
-  shift = 6 - shift;
-  return ((buffer[iByteHigh] * 256 + buffer[iByteLow]) >> shift) & 0x03FF;
-}
-#endif 
 //_____________________________________________________________________________
 //
 // EOF
index ad62694..ae891e3 100644 (file)
 class AliFMDRawStream : public AliAltroRawStream 
 {
 public:
-  AliFMDRawStream(AliRawReader* reader);
+  AliFMDRawStream(AliRawReader* reader, UShort_t sampleRate=0);
 
   Short_t Sector()      const { return fRow; }
   Char_t  Ring()        const { return (fSector == 0 ? 'I' : 'O'); }
   Short_t Strip()       const { return fPad + fTime / fSampleRate; }
+  Short_t Sample()      const { return fTime % fSampleRate; }
   Short_t PrevSector()  const { return fPrevRow; }
   Char_t  PrevRing()    const { return (fPrevSector == 0 ? 'I' : 'O'); }
   Short_t PrevStrip()   const { return fPrevPad + fPrevTime/fSampleRate; }
-
+    
   Bool_t  IsNewRing()   const { return (fSector != fPrevSector); }
   Bool_t  IsNewSector() const { return (fRow != fPrevRow) || IsNewRing(); }
   Bool_t  IsNewStrip()  const { return(Strip() != PrevStrip())||IsNewSector();}
     
-  Short_t Count()      const { return fSignal; }
-  Short_t SampleRate() const { return fSampleRate; }
+  Short_t Count()       const { return fSignal; }
+  Short_t SampleRate()  const { return fSampleRate; }
   
   virtual Bool_t   Next();
   
 private:
-  UShort_t fSampleRate; // # of ALTRO samples per VA1_ALICE clock
-  Int_t    fPrevTime;   // Last time bin
-
+  UShort_t fSampleRate;         // # of ALTRO samples per VA1_ALICE clock
+  Int_t    fPrevTime;           // Last time bin
+  Bool_t   fExplicitSampleRate; // True if the sample rate was set externally
+  
   ClassDef(AliFMDRawStream, 0) // Read raw FMD Altro data 
 };
 
diff --git a/FMD/AliFMDRawWriter.cxx b/FMD/AliFMDRawWriter.cxx
new file mode 100644 (file)
index 0000000..3c6222c
--- /dev/null
@@ -0,0 +1,266 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
+//____________________________________________________________________
+//
+// Class to write ADC values to a raw data file
+//
+#include "AliLog.h"            // ALILOG_H
+#include "AliFMD.h"            // ALIFMD_H
+#include "AliFMDDigit.h"       // ALIFMDDIGIT_H
+#include "AliFMDRawWriter.h"   // ALIFMDRAWREADER_H 
+#include "AliAltroBuffer.h"     // ALIALTROBUFFER_H
+#include "AliLoader.h"         // ALILOADER_H
+#include "TArrayI.h"           // ROOT_TArrayI
+#include <TClonesArray.h>      // ROOT_TClonesArray
+
+//____________________________________________________________________
+ClassImp(AliFMDRawWriter);
+
+//____________________________________________________________________
+AliFMDRawWriter::AliFMDRawWriter(AliFMD* fmd) 
+  : TTask("FMDRawWriter", "Writer of Raw ADC values from the FMD"),
+    fFMD(fmd)
+{
+  SetSampleRate();
+}
+
+
+//____________________________________________________________________
+void
+AliFMDRawWriter::Exec(Option_t*) 
+{
+  // Turn digits into raw data. 
+  // 
+  // Digits are read from the Digit branch, and processed to make
+  // three DDL files, one for each of the sub-detectors FMD1, FMD2,
+  // and FMD3. 
+  //
+  // The raw data files consists of a header, followed by ALTRO
+  // formatted blocks.  
+  // 
+  //          +-------------+
+  //          | Header      |
+  //          +-------------+
+  //          | ALTRO Block |
+  //          | ...         |
+  //          +-------------+
+  //          DDL file 
+  // 
+  // An ALTRO formatted block, in the FMD context, consists of a
+  // number of counts followed by a trailer. 
+  // 
+  //          +------------------+
+  //          | Count            |
+  //          | ...              |
+  //          | possible fillers |
+  //          +------------------+
+  //          | Trailer          |
+  //          +------------------+
+  //          ALTRO block 
+  // 
+  // The counts are listed backwards, that is, starting with the
+  // latest count, and ending in the first. 
+  // 
+  // Each count consist of 1 or more ADC samples of the VA1_ALICE
+  // pre-amp. signal.  Just how many samples are used depends on
+  // whether the ALTRO over samples the pre-amp.  Each sample is a
+  // 10-bit word, and the samples are grouped into 40-bit blocks 
+  //
+  //          +------------------------------------+
+  //          |  S(n)   | S(n-1) | S(n-2) | S(n-3) |
+  //          |  ...    | ...    | ...    | ...    |
+  //          |  S(2)   | S(1)   | AA     | AA     |
+  //          +------------------------------------+
+  //          Counts + possible filler 
+  //
+  // The trailer of the number of words of signales, the starting
+  // strip number, the sector number, and the ring ID; each 10-bit
+  // words,  packed into 40-bits. 
+  // 
+  //          +------------------------------------+
+  //          | # words | start  | sector | ring   |
+  //          +------------------------------------+
+  //          Trailer
+  // 
+  // Note, that this method assumes that the digits are ordered. 
+  // 
+  AliLoader* loader = fFMD->GetLoader();
+  loader->LoadDigits();
+  TTree* digitTree = loader->TreeD();
+  if (!digitTree) {
+    Error("Digits2Raw", "no digit tree");
+    return;
+  }
+  
+  TClonesArray* digits = new TClonesArray("AliFMDDigit", 1000);
+  fFMD->SetTreeAddress();
+  TBranch* digitBranch = digitTree->GetBranch(fFMD->GetName());
+  if (!digitBranch) {
+    Error("Digits2Raw", "no branch for %s", fFMD->GetName());
+    return;
+  }
+  digitBranch->SetAddress(&digits);
+  
+  Int_t nEvents = Int_t(digitTree->GetEntries());
+  for (Int_t event = 0; event < nEvents; event++) {
+    fFMD->ResetDigits();
+    digitTree->GetEvent(event);
+    
+    Int_t nDigits = digits->GetEntries();
+    if (nDigits < 1) continue;
+
+
+    UShort_t prevDetector = 0;
+    Char_t   prevRing     = '\0';
+    UShort_t prevSector   = 0;
+    // UShort_t prevStrip    = 0;
+
+    // The first seen strip number for a channel 
+    UShort_t startStrip   = 0;
+    
+    // Which channel number in the ALTRO channel we're at 
+    UShort_t offset       = 0;
+
+    // How many times the ALTRO Samples one VA1_ALICE channel 
+    Int_t sampleRate = 1;
+
+    // A buffer to hold 1 ALTRO channel - Normally, one ALTRO channel
+    // holds 128 VA1_ALICE channels, sampled at a rate of `sampleRate' 
+    TArrayI channel(128 * sampleRate);
+    
+    // The Altro buffer 
+    AliAltroBuffer* altro = 0;
+    
+    // Loop over the digits in the event.  Note, that we assume the
+    // the digits are in order in the branch.   If they were not, we'd
+    // have to cache all channels before we could write the data to
+    // the ALTRO buffer, or we'd have to set up a map of the digits. 
+    for (Int_t i = 0; i < nDigits; i++) {
+      // Get the digit
+      AliFMDDigit* digit = static_cast<AliFMDDigit*>(digits->At(i));
+
+      UShort_t det    = digit->Detector();
+      Char_t   ring   = digit->Ring();
+      UShort_t sector = digit->Sector();
+      UShort_t strip  = digit->Strip();
+      if (det != prevDetector) {
+       AliDebug(10, Form("FMD: New DDL, was %d, now %d",
+                         AliFMD::kBaseDDL + prevDetector - 1,
+                         AliFMD::kBaseDDL + det - 1));
+       // If an altro exists, delete the object, flushing the data to
+       // disk, and closing the file. 
+       if (altro) { 
+         // When the first argument is false, we write the real
+         // header. 
+         AliDebug(10, Form("New altro: Write channel at %d Strip: %d "
+                           "Sector: %d  Ring: %d", 
+                           i, startStrip, prevSector, prevRing));
+         // TPC to FMD translations 
+         // 
+         //    TPC                FMD
+         //    ----------+-----------
+         //    pad       |      strip
+         //    row       |     sector
+         //    sector    |       ring
+         // 
+         altro->WriteChannel(Int_t(startStrip), 
+                             Int_t(prevSector), 
+                             Int_t((prevRing == 'I' ? 0 : 1)), 
+                             channel.fN, channel.fArray, 0);
+         altro->Flush();
+         altro->WriteDataHeader(kFALSE, kFALSE);
+         delete altro;
+         altro = 0;
+       }
+
+       prevDetector = det;
+       // Need to open a new DDL! 
+       Int_t ddlId = AliFMD::kBaseDDL + det - 1;
+       TString filename(Form("%s_%d.ddl", fFMD->GetName(),  ddlId));
+
+       AliDebug(10, Form("New altro buffer with DDL file %s", 
+                         filename.Data()));
+       AliDebug(10, Form("New altro at %d", i));
+       // Create a new altro buffer - a `1' as the second argument
+       // means `write mode' 
+       altro = new AliAltroBuffer(filename.Data(), 1);
+       
+       // Write a dummy (first argument is true) header to the DDL
+       // file - later on, when we close the file, we write the real
+       // header
+       altro->WriteDataHeader(kTRUE, kFALSE);
+
+       // Figure out the sample rate 
+       if (fSampleRate > 0) sampleRate = fSampleRate;
+       else {
+         if (digit->Count2() >= 0) sampleRate = 2;
+         if (digit->Count3() >= 0) sampleRate = 3;
+       }
+
+       channel.Set(128 * sampleRate);
+       offset     = 0;
+       prevRing   = ring;
+       prevSector = sector;
+       startStrip = strip;
+      }
+      else if (offset == 128                        
+              || digit->Ring() != prevRing 
+              || digit->Sector() != prevSector) {
+       // Force a new Altro channel
+       AliDebug(10, Form("Flushing channel to disk because %s",
+                         (offset == 128 ? "channel is full" :
+                          (ring != prevRing ? "new ring up" :
+                           "new sector up"))));
+       AliDebug(10, Form("New Channel: Write channel at %d Strip: %d "
+                         "Sector: %d  Ring: %d", 
+                         i, startStrip, prevSector, prevRing));
+       altro->WriteChannel(Int_t(startStrip), 
+                           Int_t(prevSector), 
+                           Int_t((prevRing == 'I' ? 0 : 1)), 
+                           channel.fN, channel.fArray, 0);
+       // Reset and update channel variables 
+       channel.Reset(0);
+       offset     = 0; 
+       startStrip = strip;
+       prevRing   = ring;
+       prevSector = sector;
+      }
+
+      // Store the counts of the ADC in the channel buffer 
+      channel[offset * sampleRate] = digit->Count1();
+      if (sampleRate > 1) 
+       channel[offset * sampleRate + 1] = digit->Count2();
+      if (sampleRate > 2) 
+       channel[offset * sampleRate + 2] = digit->Count3();
+      offset++;
+    }
+    // Finally, we need to close the final ALTRO buffer if it wasn't
+    // already 
+    if (altro) {
+      altro->Flush();
+      altro->WriteDataHeader(kFALSE, kFALSE);
+      delete altro;
+    }
+  }
+  loader->UnloadDigits();
+}
+
+//____________________________________________________________________
+// 
+// EOF
+//
diff --git a/FMD/AliFMDRawWriter.h b/FMD/AliFMDRawWriter.h
new file mode 100644 (file)
index 0000000..2e0d4cb
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef ALIFMDRAWWRITER_H
+#define ALIFMDRAWWRITER_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+ * reserved. 
+ *
+ * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
+ *
+ * See cxx source for full Copyright notice                               
+ */
+/* $Id$ */
+//____________________________________________________________________
+// 
+// Class to writer ADC values to a Raw File
+//
+#ifndef ROOT_TTask
+# include <TTask.h>
+#endif
+
+//____________________________________________________________________
+class AliFMD;
+
+
+//____________________________________________________________________
+class AliFMDRawWriter : public TTask 
+{
+public:
+  AliFMDRawWriter(AliFMD* fmd);
+
+  virtual void Exec(Option_t* option="");
+  void SetSampleRate(UShort_t sampleRate=1) { fSampleRate = sampleRate; }
+  void SetChannelsPerAltro(UShort_t size=128) { fChannelsPerAltro = size; }
+protected:
+  AliFMD*       fFMD;        //! Pointer to detector description 
+  UShort_t      fSampleRate; // The sample rate (if 0, inferred from data)
+  UShort_t      fChannelsPerAltro;
+  ClassDef(AliFMDRawWriter, 0) // Write FMD raw data to a DDL file
+};
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+//   mode: C++
+// End:
+//
+// EOF
+//
diff --git a/FMD/AliFMDReconstructionAlgorithm.cxx b/FMD/AliFMDReconstructionAlgorithm.cxx
new file mode 100644 (file)
index 0000000..10d3ea1
--- /dev/null
@@ -0,0 +1,42 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
+//____________________________________________________________________
+// 
+// Base class for FMD reconstruction algorithms. 
+//
+// Derived classes will implement various ways of reconstructing the
+// charge particle multiplicity in the FMD.  
+// 
+#include "AliFMDReconstructionAlgorithm.h"     // ALIFMDRECONSTRUCTIONALGORITHM_H
+#include "AliFMDDigit.h"                       // ALIFMDDIGIT_H
+
+//____________________________________________________________________
+ClassImp(AliFMDReconstructionAlgorithm);
+
+//____________________________________________________________________
+AliFMDReconstructionAlgorithm::AliFMDReconstructionAlgorithm(const char* name, 
+                                                            const char* title)
+  : TNamed(name, title)
+{}
+
+
+
+//____________________________________________________________________
+// 
+// EOF
+//
diff --git a/FMD/AliFMDReconstructionAlgorithm.h b/FMD/AliFMDReconstructionAlgorithm.h
new file mode 100644 (file)
index 0000000..fd2759e
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef ALIFMDRECONSTRUCTIONALGORITHM_H
+#define ALIFMDRECONSTRUCTIONALGORITHM_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+ * reserved. 
+ *
+ * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
+ *
+ * See cxx source for full Copyright notice                               
+ */
+/* $Id$ */
+//____________________________________________________________________
+// 
+// Base class for FMD reconstruction algorithms. 
+//
+// Derived classes will implement various ways of reconstructing the
+// charge particle multiplicity in the FMD.  
+// 
+
+#ifndef ROOT_TTask
+# include <TTask.h>
+#endif
+
+//____________________________________________________________________
+class AliFMDDigit;
+
+//____________________________________________________________________
+class AliFMDReconstructionAlgorithm : public TNamed
+{
+public:
+  AliFMDReconstructionAlgorithm(const char* name, const char* title);
+  virtual ~AliFMDReconstructionAlgorithm() {}
+  
+  virtual void PreEvent() {};
+  virtual void ProcessDigit(AliFMDDigit* digit, 
+                           Float_t eta, 
+                           Float_t phi, 
+                           UShort_t counts) = 0;
+  virtual void PostEvent() {};
+protected:
+  ClassDef(AliFMDReconstructionAlgorithm, 0) // Base class for algorithms
+};
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+//   mode: C++
+// End:
+//
+// EOF
+//
index 0468f0b..b634193 100644 (file)
 //
 //____________________________________________________________________
 
-#include "AliFMD.h"
-#include "AliFMDDigit.h"
-#include "AliFMDParticles.h"
-#include "AliFMDReconstructor.h"
-#include "AliAltroBuffer.h"
-#include "AliLog.h"
-#include "AliRun.h"
-#include "AliRunLoader.h"
-#include "AliLoader.h"
-#include "AliHeader.h"
-#include "AliGenEventHeader.h"
-#include "AliFMDRawStream.h"
-#include "AliRawReader.h"
+#include "AliFMD.h"                            // ALIFMD_H
+#include "AliFMDDigit.h"                       // ALIFMDDIGIT_H
+#include "AliFMDParticles.h"                   // ALIFMDPARTICLES_H
+#include "AliFMDReconstructor.h"               // ALIFMDRECONSTRUCTOR_H
+#include "AliAltroBuffer.h"                    // ALIALTROBUFFER_H
+#include "AliLog.h"                            // ALILOG_H
+#include "AliRun.h"                            // ALIRUN_H
+#include "AliRunLoader.h"                      // ALIRUNLOADER_H
+#include "AliLoader.h"                         // ALILOADER_H
+#include "AliHeader.h"                         // ALIHEADER_H
+#include "AliGenEventHeader.h"                 // ALIGENEVENTHEADER_H
+#include "AliFMDRawStream.h"                   // ALIFMDRAWSTREAM_H
+#include "AliFMDRawReader.h"                   // ALIFMDRAWREADER_H
+#include "AliRawReader.h"                      // ALIRAWREADER_H
+#include "AliFMDReconstructionAlgorithm.h"     // ALIFMDRECONSTRUCTIONALGORITHM_H
 
 //____________________________________________________________________
 ClassImp(AliFMDReconstructor);
@@ -63,12 +65,12 @@ ClassImp(AliFMDReconstructor);
 //____________________________________________________________________
 AliFMDReconstructor::AliFMDReconstructor() 
   : AliReconstructor(),
-    fAdcs(kMaxDetectors, kMaxRings, kMaxSectors, kMaxStrips),
     fDeltaEta(0), 
     fDeltaPhi(0), 
     fThreshold(0),
     fPedestal(0), 
-    fPedestalWidth(0)
+    fPedestalWidth(0),
+    fPedestalFactor(0)
 {
   // Make a new FMD reconstructor object - default CTOR.
   SetDeltaEta();
@@ -86,18 +88,18 @@ AliFMDReconstructor::AliFMDReconstructor()
 //____________________________________________________________________
 AliFMDReconstructor::AliFMDReconstructor(const AliFMDReconstructor& other) 
   : AliReconstructor(),
-    fAdcs(kMaxDetectors, kMaxRings, kMaxSectors, kMaxStrips),
     fDeltaEta(0), 
     fDeltaPhi(0), 
     fThreshold(0),
     fPedestal(0), 
-    fPedestalWidth(0)
+    fPedestalWidth(0),
+    fPedestalFactor(0)
 {
   // Make a new FMD reconstructor object - default CTOR.
   SetDeltaEta(other.fDeltaEta);
   SetDeltaPhi(other.fDeltaPhi);
   SetThreshold(other.fThreshold);
-  SetPedestal(other.fPedestal, other.fPedestalWidth);
+  SetPedestal(other.fPedestal, other.fPedestalWidth, other.fPedestalFactor);
 
   // fParticles = new TClonesArray("AliFMDParticles", 1000);
   fFMDLoader = other.fFMDLoader;
@@ -126,11 +128,12 @@ AliFMDReconstructor::operator=(const AliFMDReconstructor& other)
   
 //____________________________________________________________________
 void 
-AliFMDReconstructor::SetPedestal(Float_t mean, Float_t width) 
+AliFMDReconstructor::SetPedestal(Float_t mean, Float_t width, Float_t factor) 
 {
   // Set the pedestal, and pedestal width 
-  fPedestal      = mean;
-  fPedestalWidth = width;
+  fPedestal       = mean;
+  fPedestalWidth  = width;
+  fPedestalFactor = factor;
 }
 
 //____________________________________________________________________
@@ -172,18 +175,17 @@ AliFMDReconstructor::Reconstruct(AliRunLoader* runLoader,
 
   if (!fRunLoader->TreeE())     fRunLoader->LoadHeader();
 
-  TClonesArray* digits = fFMD->Digits();
   if (rawReader) {
     Int_t event = 0;
     while (rawReader->NextEvent()) {
-      ProcessEvent(event, rawReader, digits);
+      ProcessEvent(event, rawReader);
       event++;
     }
   }
   else {
     Int_t nEvents= Int_t(fRunLoader->TreeE()->GetEntries()); 
     for(Int_t event = 0; event < nEvents; event++) 
-      ProcessEvent(event, 0, digits);
+      ProcessEvent(event, 0);
   }
 
 
@@ -214,22 +216,21 @@ AliFMDReconstructor::Reconstruct(AliRunLoader* runLoader) const
 //____________________________________________________________________
 void 
 AliFMDReconstructor::ProcessEvent(Int_t event, 
-                                 AliRawReader* reader, 
-                                 TClonesArray* digits) const
+                                 AliRawReader* reader) const
 {
   // Process one event read from either a clones array or from a a raw
   // data reader. 
   fRunLoader->GetEvent(event) ;
   //event z-vertex for correction eta-rad dependence      
   AliHeader *header            = fRunLoader->GetHeader();
-  if (!header) 
-    Warning("ProcessEvent", "no AliHeader found!");
+  if (!header) Warning("ProcessEvent", "no AliHeader found!");
   AliGenEventHeader* genHeader = (header ? header->GenEventHeader() : 0);
 
   // Get the Z--coordinate from the event header 
   TArrayF o(3); 
   if (genHeader) genHeader->PrimaryVertex(o);
-  Float_t zVertex = o.At(2);
+  else           Warning("ProcessEvent", "No GenEventHeader Found");
+  fCurrentVertex = o.At(2);
 
   // If the recontruction tree isn't loaded, load it
   if(fFMDLoader->TreeR()==0) fFMDLoader->MakeTree("R");
@@ -244,7 +245,6 @@ AliFMDReconstructor::ProcessEvent(Int_t event,
       Error("Exec","Error occured while loading digits. Exiting.");
       return;
     }
-    
   }
   // Get the digits tree 
   TTree* digitTree = fFMDLoader->TreeD();
@@ -260,6 +260,7 @@ AliFMDReconstructor::ProcessEvent(Int_t event,
   }
   // Get the FMD branch holding the digits. 
   TBranch *digitBranch = digitTree->GetBranch("FMD");
+  TClonesArray* digits = fFMD->Digits();
   if (!digitBranch) {
     if (!reader) {
       Error("Exec", "No digit branch for the FMD found");
@@ -269,15 +270,30 @@ AliFMDReconstructor::ProcessEvent(Int_t event,
   }
   if (!reader) digitBranch->SetAddress(&digits);
 
-  fEmptyStrips = 0;
-  fTotalStrips = 0;
-  Bool_t ok = kFALSE;
-  if      (reader) ok = ReadAdcs(reader);
-  else if (digits) ok = ReadAdcs(digits);
-  if (!ok) return;
+  if  (reader) {
+    AliFMDRawReader rawRead(fFMD, reader);
+    // rawRead->SetSampleRate(fSampleRate);
+    rawRead.Exec();
+  }
+  else {
+    // Read the ADC values from a clones array. 
+    AliDebug(10, "Reading ADCs from Digits array");
+    // read Digits, and reconstruct the particles
+    if (!fFMDLoader->TreeD()->GetEvent(0)) return;
+  }
   
-  ReconstructFromCache(zVertex);
+  TIter next(&fAlgorithms);
+  AliFMDReconstructionAlgorithm* algorithm = 0;
+  while ((algorithm = static_cast<AliFMDReconstructionAlgorithm*>(next()))) 
+    algorithm->PreEvent();
 
+  ProcessDigits(digits);
+
+  next.Reset();
+  algorithm = 0;
+  while ((algorithm = static_cast<AliFMDReconstructionAlgorithm*>(next()))) 
+    algorithm->PostEvent();
+  
   if (reader) {
     digitTree->Fill();
     fFMDLoader->WriteDigits("OVERWRITE");
@@ -289,189 +305,81 @@ AliFMDReconstructor::ProcessEvent(Int_t event,
 }
 
 //____________________________________________________________________
-Bool_t
-AliFMDReconstructor::ReadAdcs(TClonesArray* digits) const
+UShort_t
+AliFMDReconstructor::SubtractPedestal(AliFMDDigit* digit) const
 {
-  // Read the ADC values from a clones array. 
-  AliDebug(10, "Reading ADCs from Digits array");
-  // read Digits, and reconstruct the particles
-  if (!fFMDLoader->TreeD()->GetEvent(0)) return kFALSE;
+  // Member function to subtract the pedestal from a digit
+  // This implementation does nothing, but a derived class could over
+  // load this to subtract a pedestal that was given in a database or
+  // something like that. 
 
-  // Reads the digits from the array, and fills up the cache (fAdcs) 
-  fAdcs.Clear();
-  Int_t nDigits = digits->GetEntries();
-  for (Int_t digit = 0; digit < nDigits; digit++) {
-    AliFMDDigit* fmdDigit = 
-      static_cast<AliFMDDigit*>(digits->UncheckedAt(digit));    
-    
-    ProcessDigit(fmdDigit);
-  } //digit loop
-  return kTRUE;
+  Int_t counts = 0;
+  Float_t ped = fPedestal * fPedestalFactor * fPedestalWidth;
+  if (digit->Count3() >= 0)      counts = digit->Count3();
+  else if (digit->Count2() >= 0) counts = digit->Count2();
+  else                           counts = digit->Count2();
+  counts = TMath::Max(Int_t(counts - ped), 0);
+  return  UShort_t(counts);
 }
 
 //____________________________________________________________________
-Bool_t
-AliFMDReconstructor::ReadAdcs(AliRawReader* reader) const
+void
+AliFMDReconstructor::ProcessDigits(TClonesArray* digits) const
 {
-  // Read the ADC values from a raw data reader. 
-  AliDebug(10, "Reading ADCs from RawReader");
-  // Reads the digits from a RAW data 
-  fAdcs.Clear();
-  // reader->Reset();
-
-  if (!reader->ReadHeader()) {
-    Error("ReadAdcs", "Couldn't read header");
-    return kFALSE;
-  }
-
-  // Use AliAltroRawStream to read the ALTRO format.  No need to
-  // reinvent the wheel :-) 
-  AliFMDRawStream input(reader);
-  // Select FMD DDL's 
-  reader->Select(AliFMD::kBaseDDL >> 8);
-  
-  Int_t    oldDDL      = -1;
-  Int_t    count       = 0;
-  UShort_t detector    = 1; // Must be one here
-  UShort_t oldDetector = 0;
-  // Loop over data in file 
-  Bool_t   next       = kTRUE;
-
-  // local Cache 
-  TArrayI counts(10);
-  counts.Reset(-1);
-  Int_t offset = 0;
-  
-  while (next) {
-    next = input.Next();
-
-
-    count++; 
-    Int_t ddl = reader->GetDDLID();
-    if (ddl != oldDDL 
-       || input.IsNewStrip()
-       || !next) {
-      // Make a new digit, if we have some data! 
-      if (counts[0] >= 0) {
-       // Got a new strip. 
-       AliDebug(10, Form("Add a new strip: FMD%d%c[%2d,%3d] "
-                         "(current: FMD%d%c[%2d,%3d])", 
-                         oldDetector, input.PrevRing(), 
-                         input.PrevSector() , input.PrevStrip(),
-                         detector , input.Ring(), input.Sector(), 
-                         input.Strip()));
-       fFMD->AddDigit(oldDetector, 
-                      input.PrevRing(), 
-                      input.PrevSector(), 
-                      input.PrevStrip(), 
-                      counts[0], counts[1], counts[2]);
-       AliFMDDigit* digit = 
-         static_cast<AliFMDDigit*>(fFMD->Digits()->
-                                   UncheckedAt(fFMD->GetNdigits()-1));
-       ProcessDigit(digit);
-      }
-       
-      if (!next) { 
-       AliDebug(10, Form("Read %d channels for FMD%d", 
-                         count + 1, detector));
-       break;
-      }
-    
+  Int_t nDigits = digits->GetEntries();
+  for (Int_t i = 0; i < nDigits; i++) {
+    AliFMDDigit* digit = static_cast<AliFMDDigit*>(digits->At(i));
+    AliFMDSubDetector* subDetector = 0;
+    switch (digit->Detector()) {
+    case 1: subDetector = fFMD->GetFMD1(); break;
+    case 2: subDetector = fFMD->GetFMD2(); break;
+    case 3: subDetector = fFMD->GetFMD3(); break;
+    }
+    if (!subDetector) { 
+      Warning("ProcessDigits", "Unknown detector: FMD%d" , digit->Detector());
+      continue;
+    }
     
-      // If we got a new DDL, it means we have a new detector. 
-      if (ddl != oldDDL) {
-       if (detector != 0) 
-         AliDebug(10, Form("Read %d channels for FMD%d", 
-                           count + 1, detector));
-       // Reset counts, and update the DDL cache 
-       count       = 0;
-       oldDDL      = ddl;
-       // Check that we're processing a FMD detector 
-       Int_t detId = reader->GetDetectorID();
-       if (detId != (AliFMD::kBaseDDL >> 8)) {
-         Error("ReadAdcs", "Detector ID %d != %d",
-               detId, (AliFMD::kBaseDDL >> 8));
-         break;
-       }
-       // Figure out what detector we're deling with 
-       oldDetector = detector;
-       switch (ddl) {
-       case 0: detector = 1; break;
-       case 1: detector = 2; break;
-       case 2: detector = 3; break;
-       default:
-         Error("ReadAdcs", "Unknown DDL 0x%x for FMD", ddl);
-         return kFALSE;
-       }
-       AliDebug(10, Form("Reading ADCs for 0x%x  - That is FMD%d",
-                         reader->GetEquipmentId(), detector));
-      }
-      counts.Reset(-1);
-      offset = 0;
+    AliFMDRing* ring  = 0;
+    Float_t     ringZ = 0;
+    switch(digit->Ring()) {
+    case 'i':
+    case 'I':  
+      ring  = subDetector->GetInner(); 
+      ringZ = subDetector->GetInnerZ();
+      break;
+    case 'o':
+    case 'O':  
+      ring  = subDetector->GetOuter(); 
+      ringZ = subDetector->GetOuterZ();
+      break;
+    }
+    if (!ring) {
+      Warning("ProcessDigits", "Unknown ring: FMD%d%c", digit->Detector(), 
+             digit->Ring());
+      break;
     }
     
-    counts[offset] = input.Count();
-    offset++;
+    Float_t  realZ    = fCurrentVertex + ringZ;
+    Float_t  stripR   = ((ring->GetHighR() - ring->GetLowR()) / ring->GetNStrips() 
+                        * (digit->Strip() + .5) + ring->GetLowR());
+    Float_t  theta    = TMath::ATan2(stripR, realZ);
+    Float_t  phi      = (2 * TMath::Pi() / ring->GetNSectors() 
+                        * (digit->Sector() + .5));
+    Float_t  eta      = -TMath::Log(TMath::Tan(theta / 2));
+    UShort_t counts   = SubtractPedestal(digit);
     
-    AliDebug(10, Form("ADC of FMD%d%c[%2d,%3d] += %d",
-                     detector, input.Ring(), input.Sector(), 
-                     input.Strip(), input.Count()));
-    oldDetector = detector;
+    TIter next(&fAlgorithms);
+    AliFMDReconstructionAlgorithm* algorithm = 0;
+    while ((algorithm = static_cast<AliFMDReconstructionAlgorithm*>(next()))) 
+      algorithm->ProcessDigit(digit, eta, phi, counts);
   }
-  return kTRUE;
-}
-
-//____________________________________________________________________
-void
-AliFMDReconstructor::ProcessDigit(AliFMDDigit* digit) const
-{
-  // Process a digit.  Derived classes can overload this member
-  // function to do stuff to the digit.  However, it should write the
-  // ADC count to the internal cache 
-  //
-  //    fAdcs(detector - 1, ring, sector, strip) = counts;
-  //
-  // In this implementation, we count the number of strips below
-  // threshold.   This we do to later choose what kind of
-  // reconstruction algorithm we'd like to use. 
-  // 
-  UShort_t detector = digit->Detector();
-  Char_t   ring     = digit->Ring();
-  UShort_t sector   = digit->Sector();
-  UShort_t strip    = digit->Strip();    
-  
-  UShort_t counts  = SubtractPedestal(digit);
-  
-  fAdcs(detector - 1, ring, sector, strip) = counts;
-  if (counts < fThreshold) fEmptyStrips++;
-  fTotalStrips++;
 }
 
-//____________________________________________________________________
-UShort_t
-AliFMDReconstructor::SubtractPedestal(AliFMDDigit* digit) const
-{
-  // Member function to subtract the pedestal from a digit
-  // This implementation does nothing, but a derived class could over
-  // load this to subtract a pedestal that was given in a database or
-  // something like that. 
-
-  Int_t counts = 
-    TMath::Max(Int_t(digit->Count1() - fPedestal - 3 * fPedestalWidth), 0);
-  if (digit->Count2() >= 0) 
-    counts += 
-      TMath::Max(Int_t(digit->Count2() - fPedestal - 3 * fPedestalWidth), 0);
-  if (digit->Count3() >= 0) 
-    counts += 
-      TMath::Max(Int_t(digit->Count3() - fPedestal - 3 * fPedestalWidth), 0);
       
-  if (counts < 0) counts = 0;
-  return  UShort_t(counts);
-}
-
 //____________________________________________________________________
 void
-AliFMDReconstructor::ReconstructFromCache(Float_t zVertex) const
+AliFMDReconstructor::ReconstructFromCache() const
 {
   // Based on the information in the cache, do the reconstruction. 
   Int_t nRecon = 0;
@@ -497,7 +405,7 @@ AliFMDReconstructor::ReconstructFromCache(Float_t zVertex) const
       
       // Calculate low/high theta and eta 
       // FIXME: Is this right? 
-      Float_t realZ    = zVertex + rZ;
+      Float_t realZ    = fCurrentVertex + rZ;
       Float_t thetaOut = TMath::ATan2(r->GetHighR(), realZ);
       Float_t thetaIn  = TMath::ATan2(r->GetLowR(), realZ);
       Float_t etaOut   = - TMath::Log(TMath::Tan(thetaOut / 2));
@@ -552,9 +460,9 @@ AliFMDReconstructor::ReconstructFromCache(Float_t zVertex) const
          // Count number of empty strips
          Int_t   emptyStrips = 0;
          for (Int_t sector = minSector; sector < maxSector; sector++) 
-           for (Int_t strip = minStrip; strip < maxStrip; strip++) 
-             if (fAdcs(sub->GetId() - 1, r->GetId(), sector, strip) 
-                 < fThreshold) emptyStrips++;
+           for (Int_t strip = minStrip; strip < maxStrip; strip++) emptyStrips++;
+         // if (fAdcs(sub->GetId() - 1, r->GetId(), sector, strip) 
+         //     < fThreshold) emptyStrips++;
          
          // The total number of strips 
          Float_t nTotal = (maxSector - minSector) * (maxStrip - minStrip);
index 57ac30a..a36e7cb 100644 (file)
 #ifndef ALIRECONSTRUCTOR_H
 # include <AliReconstructor.h>
 #endif
-#ifndef ALIFMDMAP_H
-# include <AliFMDMap.h>
+#ifndef ROOT_TObjArray
+# include <TObjArray.h>
 #endif
+// #ifndef ALIFMDUSHORTMAP_H
+// # include <AliFMDUShortMap.h>
+// #endif
 
 //____________________________________________________________________
 class TClonesArray;
@@ -43,7 +46,8 @@ class AliLoader;
 class AliRunLoader;
 class AliFMDDigit;
 class AliRawReader;
-typedef AliFMDMap<UShort_t> AliFMDAdcMap;
+
+// typedef AliFMDUShortMap AliFMDAdcMap;
 
 
 //____________________________________________________________________
@@ -58,7 +62,7 @@ public:
   void         SetDeltaEta(Float_t deta=.1)  { fDeltaEta = deta;  }
   void         SetDeltaPhi(Float_t dphi=360) { fDeltaPhi = dphi;  } 
   void         SetThreshold(UShort_t t=6)    { fThreshold = t; }
-  void         SetPedestal(Float_t mean=10, Float_t width=1);
+  void         SetPedestal(Float_t mean=10, Float_t width=1, Float_t f=3);
      
   virtual void Reconstruct(AliRunLoader* runLoader) const;
   virtual void Reconstruct(AliRunLoader* runLoader,  
@@ -67,27 +71,26 @@ public:
   
 protected:
   virtual void     ProcessEvent(Int_t event, 
-                               AliRawReader* rawReader, 
-                               TClonesArray* digits) const;
-  virtual Bool_t   ReadAdcs(TClonesArray* digits) const;
-  virtual Bool_t   ReadAdcs(AliRawReader* rawReader) const;
-  virtual void     ProcessDigit(AliFMDDigit* digit) const;
+                               AliRawReader* rawReader) const;
+  virtual void     ProcessDigits(TClonesArray* digits) const;
   virtual UShort_t SubtractPedestal(AliFMDDigit* digit) const;
-  virtual void     ReconstructFromCache(Float_t zVertex) const;
+  virtual void     ReconstructFromCache() const;
 
-  mutable AliFMDAdcMap  fAdcs;       // Cached ADC values
   mutable AliRunLoader* fRunLoader;  // Run loader 
   mutable AliLoader*    fFMDLoader;  // FMD specific loader 
   mutable TClonesArray* fParticles;  // Array of particles 
   mutable AliFMD*       fFMD;        // Pointer to FMD manager 
   
+  TObjArray            fAlgorithms;    // Array of algorithms
   Float_t               fDeltaEta;      // Bin size in eta
   Float_t               fDeltaPhi;      // Bin size in phi
   UShort_t              fThreshold;     // Threshold for Poisson recon.
   Float_t               fPedestal;      // Pedestal to subtract
   Float_t               fPedestalWidth; // Width of pedestal
+  Float_t               fPedestalFactor;// Number of pedestal widths 
   mutable Int_t         fEmptyStrips;   // Number of empty strips
   mutable Int_t         fTotalStrips;   // Total number of strips 
+  mutable Float_t       fCurrentVertex; // Z-coordinate of primary vertex
   
   enum { 
     kMaxDetectors = 3,                  // Maximum number of sub-det.
index 9f94ba7..5530fae 100644 (file)
 //
 // Latest changes by Christian Holm Christensen
 //
-#ifndef ALIFMDRING_H
-# include "AliFMDRing.h"
-#endif
-#ifndef ALILOG_H
-# include "AliLog.h"
-#endif
-#ifndef ROOT_TMath
-# include <TMath.h>
-#endif
-#ifndef ROOT_TH2
-# include <TH2.h>
-#endif
-#ifndef ROOT_TVirtualMC
-# include <TVirtualMC.h>
-#endif
-#ifndef ROOT_TVector2
-# include <TVector2.h>
-#endif
-#ifndef ROOT_TBrowser
-# include <TBrowser.h>
-#endif
-#ifndef ROOT_TString
-# include <TString.h>
-#endif
-#ifndef ROOT_TArc
-# include <TArc.h>
-#endif
-#ifndef ROOT_TObjArray
-# include <TObjArray.h>
-#endif
-#ifndef ROOT_TXTRU
-# include <TXTRU.h>
-#endif
-#ifndef ROOT_TNode
-# include <TNode.h>
-#endif
-#ifndef ROOT_TRotMatrix
-# include <TRotMatrix.h>
-#endif
-#ifndef ROOT_TList
-# include <TList.h>
-#endif
-#ifndef __IOSTREAM__
-# include <iostream>
-#endif
-#include <math.h>
+#include "AliFMDRing.h"                // ALIFMDRING_H
+#include "AliLog.h"            // ALILOG_H
+#include "TMath.h"             // ROOT_TMath
+#include "TH2.h"               // ROOT_TH2
+#include "TVirtualMC.h"                // ROOT_TVirtualMC
+#include "TVector2.h"          // ROOT_TVector2
+#include "TBrowser.h"          // ROOT_TBrowser
+#include "TString.h"           // ROOT_TString
+#include "TArc.h"              // ROOT_TArc
+#include "TObjArray.h"         // ROOT_TObjArray
+#include "TXTRU.h"             // ROOT_TXTRU
+#include "TNode.h"             // ROOT_TNode
+#include "TRotMatrix.h"                // ROOT_TRotMatrix
+#include "TList.h"             // ROOT_TList
 
 const Char_t* AliFMDRing::fgkRingFormat         = "FRG%c";
 const Char_t* AliFMDRing::fgkVirtualFormat      = "FV%c%c";
index 498e3f2..bc87f76 100644 (file)
 //
 //////////////////////////////////////////////////////////////////////////////
 
-#ifndef ALIFMDSUBDETECTOR_H
-# include "AliFMDSubDetector.h"
-#endif
-#ifndef ALIFMDRING_H
-# include <AliFMDRing.h>
-#endif
-#ifndef ALILOG_H
-# include "AliLog.h"
-#endif
-#ifndef ROOT_TVirtualMC
-# include <TVirtualMC.h>
-#endif
-#ifndef ROOT_TList
-# include <TList.h>
-#endif
-#ifndef ROOT_TString
-# include <TString.h>
-#endif
-#ifndef __IOSTREAM__
-# include <iostream>
-#endif
+#include "AliFMDSubDetector.h" // ALIFMDSUBDETECTOR_H
+#include "AliFMDRing.h"                // ALIFMDRING_H
+#include "AliLog.h"            // ALILOG_H
+#include "TVirtualMC.h"                // ROOT_TVirtualMC
+#include "TList.h"             // ROOT_TList
+#include "TString.h"           // ROOT_TString
 
 ClassImp(AliFMDSubDetector);
 
diff --git a/FMD/AliFMDUShortMap.cxx b/FMD/AliFMDUShortMap.cxx
new file mode 100644 (file)
index 0000000..daba529
--- /dev/null
@@ -0,0 +1,119 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
+//____________________________________________________________________
+//                                                                          
+//
+//
+#include "AliFMDUShortMap.h"           // ALIFMDUSHORTMAP_H
+
+//____________________________________________________________________
+ClassImp(AliFMDUShortMap);
+
+//____________________________________________________________________
+AliFMDUShortMap::AliFMDUShortMap(const AliFMDUShortMap& other)
+  : AliFMDMap(other.fMaxDetectors, other.fMaxRings, other.fMaxSectors, 
+             other.fMaxStrips), 
+    fData(0)
+{
+  fData = new UShort_t[fMaxDetectors * fMaxRings * fMaxSectors * fMaxStrips];
+  for (size_t i = 0; i < fMaxDetectors * fMaxRings * fMaxSectors * fMaxStrips;
+       i++) fData[i] = other.fData[i];
+}
+
+  
+
+//____________________________________________________________________
+AliFMDUShortMap::AliFMDUShortMap(size_t maxDet, 
+                                size_t maxRing, 
+                                size_t maxSec, 
+                                size_t maxStr)
+  : AliFMDMap(maxDet, maxRing, maxSec, maxStr), 
+    fData(0)
+{
+  // Construct a map
+  //
+  // Parameters:
+  //     maxDet       Maximum # of detectors
+  //     maxRinf      Maximum # of rings
+  //     maxSec       Maximum # of sectors
+  //     maxStr       Maximum # of strips
+  fData = new UShort_t[fMaxDetectors * fMaxRings * fMaxSectors * fMaxStrips];
+}
+
+//____________________________________________________________________
+AliFMDUShortMap&
+AliFMDUShortMap::operator=(const AliFMDUShortMap& other) 
+{
+  fMaxDetectors = other.fMaxDetectors;
+  fMaxRings     = other.fMaxRings;
+  fMaxSectors   = other.fMaxSectors;
+  fMaxStrips    = other.fMaxStrips;
+  if (fData) delete [] fData;
+  fData = new UShort_t[fMaxDetectors * fMaxRings * fMaxSectors * fMaxStrips];
+  for (size_t i = 0; i < fMaxDetectors * fMaxRings * fMaxSectors * fMaxStrips;
+       i++) fData[i] = other.fData[i];
+  return *this;
+}
+
+//____________________________________________________________________
+void
+AliFMDUShortMap::Clear(const UShort_t& val) 
+{
+  for (size_t i = 0; i < fMaxDetectors * fMaxRings * fMaxSectors * fMaxStrips;
+       i++) fData[i] = val;
+}
+
+//____________________________________________________________________
+UShort_t& 
+AliFMDUShortMap::operator()(UShort_t det, Char_t ring, UShort_t sec, UShort_t str) 
+{
+  // Get data 
+  // 
+  // Parameters: 
+  //     det       Detector #
+  //     ring      Ring ID
+  //     sec       Sector # 
+  //     str       Strip # 
+  //
+  // Returns appropriate data
+  //
+  return fData[CalcIndex(det, ring, sec, str)];
+}
+
+//____________________________________________________________________
+const UShort_t& 
+AliFMDUShortMap::operator()(UShort_t det, Char_t ring, UShort_t sec, UShort_t str) const
+{
+  // Get data 
+  // 
+  // Parameters: 
+  //     det       Detector #
+  //     ring      Ring ID
+  //     sec       Sector # 
+  //     str       Strip # 
+  //
+  // Returns appropriate data
+  //
+  return fData[CalcIndex(det, ring, sec, str)];
+}
+
+
+//___________________________________________________________________
+//
+// EOF
+//
diff --git a/FMD/AliFMDUShortMap.h b/FMD/AliFMDUShortMap.h
new file mode 100644 (file)
index 0000000..664484a
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef ALIFMDEDEPMAP_H
+#define ALIFMDEDEPMAP_H
+/* Copyright(c) 1998-2000, ALICE Experiment at CERN, All rights
+ * reserved. 
+ *
+ * See cxx source for full Copyright notice                               
+ */
+#ifndef ALIFMDMAP_H
+# include <AliFMDMap.h>
+#endif 
+//____________________________________________________________________
+//
+// Cache of Energy deposited, hit information perr strip
+//
+
+//____________________________________________________________________
+class AliFMDUShortMap : public AliFMDMap
+{
+public:
+  AliFMDUShortMap(const AliFMDUShortMap& other);
+  AliFMDUShortMap(size_t maxDet = kMaxDetectors, 
+                 size_t maxRing= kMaxRings, 
+                 size_t maxSec = kMaxSectors, 
+                 size_t maxStr = kMaxStrips);
+  virtual ~AliFMDUShortMap() { delete [] fData; }
+  AliFMDUShortMap& operator=(const AliFMDUShortMap& other);
+  virtual void Clear(const UShort_t& val=UShort_t());
+  virtual UShort_t& operator()(UShort_t detector, 
+                              Char_t   ring, 
+                              UShort_t sector, 
+                              UShort_t strip);
+  virtual const UShort_t& operator()(UShort_t detector, 
+                                    Char_t   ring, 
+                                    UShort_t sector, 
+                                    UShort_t strip) const;
+ protected:
+  UShort_t* fData;  // The data 
+  ClassDef(AliFMDUShortMap, 1) // Cache of edep,hit information per strip
+};
+
+#endif 
+//____________________________________________________________________
+//
+// Local Variables:
+//   mode: C++
+// End:
+//
+// EOF
+//
+
+
index b4719fc..e4682a0 100644 (file)
@@ -58,9 +58,7 @@
 // various components. 
 //
 
-#ifndef ALIFMDV0_H
-# include "AliFMDv0.h"
-#endif
+#include "AliFMDv0.h"          // ALIFMDV0_H
 
 //____________________________________________________________________
 ClassImp(AliFMDv0);
index 2e9436a..f7149ac 100644 (file)
 //
 // See also the class AliFMD for a more detailed explanation of the
 // various componets. 
-#ifndef ROOT_TVirtualMC
-# include <TVirtualMC.h>
-#endif
-#ifndef ALIFMDV1_H
-# include "AliFMDv1.h"
-#endif
-#ifndef ALIRUN_H
-# include "AliRun.h"
-#endif
-#ifndef ALIMC_H
-# include "AliMC.h"
-#endif
-#ifndef ALILOG_H
-# include "AliLog.h"
-#endif
+#include "TVirtualMC.h"                // ROOT_TVirtualMC
+#include "AliFMDv1.h"          // ALIFMDV1_H
+#include "AliRun.h"            // ALIRUN_H
+#include "AliMC.h"             // ALIMC_H
+#include "AliLog.h"            // ALILOG_H
 
 //____________________________________________________________________
 ClassImp(AliFMDv1);
index 5efba2f..2f993e7 100644 (file)
 #pragma link off all classes;
 #pragma link off all functions;
  
-#pragma link C++ class  AliFMDMap<UShort_t>;
-#pragma link C++ typedef AliFMDAdcMap;
+// #pragma link C++ class  AliFMDMap<UShort_t>;
+// #pragma link C++ typedef AliFMDAdcMap;
+#pragma link C++ class  AliFMDUShortMap+;
+// #pragma link C++ typedef  AliFMDAdcMap;
 #pragma link C++ class  AliFMDReconstructor+;
+#pragma link C++ class  AliFMDReconstructionAlgorithm+;
 #pragma link C++ class  AliFMDParticles+;
 #pragma link C++ class  AliFMDRawStream+;
+#pragma link C++ class  AliFMDRawReader+;
 
 #else
 # error Not for compilation 
index c76f8c9..df17f45 100644 (file)
 #pragma link off all classes;
 #pragma link off all functions;
 
-#pragma link C++ class  std::pair<Float_t,UShort_t>;
-#pragma link C++ class  AliFMDMap<std::pair<Float_t,UShort_t> >;
-#pragma link C++ typedef  AliFMDEdepMap;
+// #pragma link C++ class  std::pair<Float_t,UShort_t>;
+// #pragma link C++ class  AliFMDMap<std::pair<Float_t,UShort_t> >;
+// #pragma link C++ typedef  AliFMDEdepMap;
+#pragma link C++ class  AliFMDMap+;
+#pragma link C++ class  AliFMDEdepMap+;
 #pragma link C++ class  AliFMDHit+;
 #pragma link C++ class  AliFMD+;
 #pragma link C++ class  AliFMDv0+;
@@ -28,6 +30,7 @@
 #pragma link C++ class  AliFMDBaseDigitizer+;
 #pragma link C++ class  AliFMDDigitizer+;
 #pragma link C++ class  AliFMDSDigitizer+;
+#pragma link C++ class  AliFMDRawWriter+;
 
 #else
 # error Not for compilation 
index ce2a293..ad83dc6 100644 (file)
@@ -3,8 +3,11 @@
 # $Id$
 
 SRCS           =  AliFMDReconstructor.cxx \
+                  AliFMDReconstructionAlgorithm.cxx \
                   AliFMDRawStream.cxx  \
-                  AliFMDParticles.cxx
+                  AliFMDRawReader.cxx  \
+                  AliFMDParticles.cxx  \
+                  AliFMDUShortMap.cxx
 HDRS           =  $(SRCS:.cxx=.h)
 DHDR           := FMDrecLinkDef.h
 EINCLUDE       := $(ALICE)/RAW
index 92477f0..8867b23 100644 (file)
@@ -12,8 +12,11 @@ SRCS         =  AliFMD.cxx                   \
                   AliFMDRing.cxx               \
                   AliFMDPolygon.cxx            \
                   AliFMDHit.cxx                \
-                  AliFMDDigitizer.cxx
-HDRS           =  $(SRCS:.cxx=.h) AliFMDMap.h
+                  AliFMDDigitizer.cxx          \
+                  AliFMDMap.cxx                \
+                  AliFMDEdepMap.cxx            \
+                  AliFMDRawWriter.cxx
+HDRS           =  $(SRCS:.cxx=.h) 
 DHDR           := FMDsimLinkDef.h
 EINCLUDE       := $(ALICE)/RAW