Updated reconstruction to (optionally) make angle correction.
authorcholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 19 Dec 2006 10:49:48 +0000 (10:49 +0000)
committercholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 19 Dec 2006 10:49:48 +0000 (10:49 +0000)
Updated reconstruction to (optionally) suppress noise.
Updated ESD data to have this information.
Updated ALTRO mapping to reflect real configuration (2 RCU branches)
Updated Display with newer and better code.
Added the pattern and fancy viewers.
Fixed ADC range in digitizer.
Put more realistic noise characteristics in AliFMDCalibFaker.
Added some more scripts for display and illustration.
Added script to make Dummy AliModule for all but the FMD.
Added newer calibrations (fixes ushort problem in AliFMDMap).

44 files changed:
FMD/AliFMDAltroMapping.cxx
FMD/AliFMDBaseDigitizer.cxx
FMD/AliFMDCalibFaker.cxx
FMD/AliFMDCalibFaker.h
FMD/AliFMDCalibGain.h
FMD/AliFMDDisplay.cxx
FMD/AliFMDDisplay.h
FMD/AliFMDFancy.cxx [new file with mode: 0644]
FMD/AliFMDFancy.h [new file with mode: 0644]
FMD/AliFMDInput.cxx
FMD/AliFMDInput.h
FMD/AliFMDParameters.cxx
FMD/AliFMDParameters.h
FMD/AliFMDPattern.cxx [new file with mode: 0644]
FMD/AliFMDPattern.h [new file with mode: 0644]
FMD/AliFMDReconstructor.cxx
FMD/AliFMDReconstructor.h
FMD/Calib/AltroMap/Run0_0_v0_s1.root [new file with mode: 0644]
FMD/Calib/Dead/Run0_0_v0_s1.root [new file with mode: 0644]
FMD/Calib/Pedestal/Run0_0_v0_s1.root [new file with mode: 0644]
FMD/Calib/PulseGain/Run0_0_v0_s1.root [new file with mode: 0644]
FMD/Calib/SampleRate/Run0_0_v0_s1.root [new file with mode: 0644]
FMD/Calib/StripRange/Run0_0_v0_s1.root [new file with mode: 0644]
FMD/Calib/ZeroSuppression/Run0_0_v0_s1.root [new file with mode: 0644]
FMD/FMDutilLinkDef.h
FMD/libFMDutil.pkg
FMD/scripts/Compile.C
FMD/scripts/DrawDigitsRecs.C
FMD/scripts/DrawHits.C
FMD/scripts/DrawHitsDigits.C
FMD/scripts/DrawXsection.C
FMD/scripts/Dummy.C [new file with mode: 0644]
FMD/scripts/DummyConfig.C [new file with mode: 0644]
FMD/scripts/FancyDigits.C [new file with mode: 0644]
FMD/scripts/FancyHits.C [new file with mode: 0644]
FMD/scripts/LoadDummy.C [new file with mode: 0644]
FMD/scripts/MakeCalibration.C
FMD/scripts/PatternDigits.C [new file with mode: 0644]
FMD/scripts/PatternESD.C [new file with mode: 0644]
FMD/scripts/PatternHits.C [new file with mode: 0644]
FMD/scripts/PatternRecs.C [new file with mode: 0644]
FMD/scripts/PrintCalibration.C
FMD/scripts/TestAltroMapping.C
FMD/scripts/TestMap.C [new file with mode: 0644]

index 883ec08..11048dc 100644 (file)
@@ -86,8 +86,8 @@ AliFMDAltroMapping::Hardware2Detector(UInt_t    ddl, UInt_t    addr,
   //   +-------------+----------+----------+
   // 
   // The board number identifier among other things the ring.  There's
-  // up to 4 boards per DDL, and the two first (0 and 1) corresponds
-  // to the inner rings, while the two last (2 and 3) corresponds to
+  // up to 4 boards per DDL, and the two first (0 and 16) corresponds
+  // to the inner rings, while the two last (1 and 17) corresponds to
   // the outer rings. 
   // 
   // The board number and ALTRO number together identifies the sensor,
@@ -145,24 +145,21 @@ AliFMDAltroMapping::Hardware2Detector(UInt_t    ddl, UInt_t    addr,
   UInt_t board =  (addr >> 7) & 0x1F;
   UInt_t altro =  (addr >> 4) & 0x7;
   UInt_t chan  =  (addr & 0xf);
-  if (board > 3) {
-    AliError(Form("Invalid board address %d for the FMD", board));
-    return kFALSE;
+  ring         =  (board % 2) == 0 ? 'I' : 'O';
+  switch (ring) {
+  case 'i':
+  case 'I':
+    sec = ((board / 16) * 10 + (altro < 1 ? 0 : altro < 2 ? 4 : 6) 
+          + 2 * (chan / 8) + chan % 2);
+    str = ((chan % 8) / 2) * 128;
+    break;
+  case 'o':
+  case 'O': 
+    sec = ((board / 16) * 20 + (altro < 1 ? 0 : altro < 2 ? 8 : 12) 
+          + 2 * (chan / 4) + chan % 2);
+    str = ((chan % 4) / 2) * 128;
+    break;
   }
-  if (altro > 2) {
-    AliError(Form("Invalid ALTRO address %d for the FMD digitizer %d", 
-                 altro, board));
-    return kFALSE;
-  }
-  ring         =  (board > 1 ? 'O' : 'I');
-  UInt_t nsen  =  (ring == 'I' ? 10 : 20);
-  UInt_t nsa   =  (ring == 'I' ? 2 : 4);   // Sensors per ALTRO
-  UInt_t ncs   =  (ring == 'I' ? 8 : 4);   // Channels per sensor 
-  UInt_t sen   =  (board % 2) * nsen / 2;  // Base for half-ring
-  sen          += chan / ncs + (altro == 0 ? 0   : 
-                               altro == 1 ? nsa : UInt_t(1.5 * nsa));
-  sec          =  2 * sen + (chan % 2);
-  str          =  (chan % ncs) / 2 * 128;
   return kTRUE;
 }
 
@@ -187,13 +184,13 @@ AliFMDAltroMapping::Detector2Hardware(UShort_t  det, Char_t    ring,
   //   +-------------+----------+----------+
   // 
   // The board number is given by the ring and sector.  The inner
-  // rings board 0 and 1, while the outer are 2 and 3.  Which of these
+  // rings board 0 and 16, while the outer are 1 and 17.  Which of these
   // depends on the sector.  The map is 
   // 
   //    Ring I, sector  0- 9       ->   board 0 
-  //    Ring I, sector 10-19       ->   board 1
-  //    Ring O, sector  0-19       ->   board 2 
-  //    Ring O, sector 20-39       ->   board 3
+  //    Ring I, sector 10-19       ->   board 16
+  //    Ring O, sector  0-19       ->   board 1 
+  //    Ring O, sector 20-39       ->   board 17
   // 
   // There are 3 ALTRO's per board.  The ALTRO number is given by the
   // sector number.  For the inner rings, these are given by
@@ -253,21 +250,26 @@ AliFMDAltroMapping::Detector2Hardware(UShort_t  det, Char_t    ring,
   // give us a unique hardware address 
   //
   ddl          =  (det - 1);
-  UInt_t nsen  =  (ring == 'I' ? 10 : 20);
-  UInt_t nsa   =  (ring == 'I' ? 2 : 4);   // Sensors per ALTRO
-  UInt_t ncs   =  (ring == 'I' ? 8 : 4);   // Channels per sensor 
-  UInt_t bbase =  (ring == 'I' ? 0 : 2);
-  UInt_t board =  bbase + sec / nsen;
-  UInt_t lsec  =  (sec - (board - bbase) * nsen); // Local sec in half-ring
-  UInt_t altro =  (lsec < 2 * nsa ? 0 : (lsec < 3 * nsa ? 1       : 2));
-  UInt_t sbase =  (altro == 0     ? 0 : altro == 1      ? 2 * nsa : 3 * nsa);
-  UInt_t chan  =  (sec % 2) + (lsec-sbase) / 2 * ncs + 2 * (str / 128);
-  AliDebug(40, Form("\n"
-                   "  chan = (%d %% 2) + (%d-%d) / %d * %d + 2 * %d / 128\n"
-                   "       = %d + %d + %d = %d", 
-                   sec, lsec, sbase, 2, ncs, str, 
-                   (sec % 2), (lsec - sbase) / 2 * ncs, 
-                   2 * (str / 128), chan));
+  UInt_t board = 0;
+  UInt_t altro = 0;
+  UInt_t chan  = 0;
+  UInt_t tmp   = 0;
+  switch (ring) {
+  case 'I':
+  case 'i':
+    board += (sec / 10) * 16;
+    altro =  (sec % 10) < 4 ? 0 : (sec % 10) < 6 ? 1 : 2;
+    tmp   =  (sec % 10) - (altro == 0 ? 0 : altro == 1 ? 4 : 6);
+    chan  =  2  * (str / 128) + (sec % 2) + ((tmp / 2) % 2) * 8;
+    break;
+  case 'O':
+  case 'o':
+    board += (sec / 20) * 20 + 1;
+    altro =  (sec % 20) < 8 ? 0 : (sec % 20) < 12 ? 1 : 2;
+    tmp   =  (sec % 20) - (altro == 0 ? 0 : altro == 1 ? 8 : 12);
+    chan  =  2 * (str / 128) + (sec % 2) + ((tmp / 2) % 4) * 4;
+    break;
+  }
   addr         =  chan + (altro << 4) + (board << 7);
   
   return kTRUE;
index 0b14ead..a04cd4f 100644 (file)
@@ -477,25 +477,35 @@ AliFMDBaseDigitizer::ConvertToCount(Float_t   edep,
   //                  = E + (l - E) * ext(-B * t)
   // 
   AliFMDParameters* param = AliFMDParameters::Instance();
-  Float_t  convF          = 1/param->GetPulseGain(detector,ring,sector,strip);
-  UShort_t ped            = MakePedestal(detector,ring,sector,strip);
-  UInt_t   maxAdc         = param->GetAltroChannelSize()-1;
+  Float_t  convF          = 1./param->GetPulseGain(detector,ring,sector,strip);
+  Int_t    ped            = MakePedestal(detector,ring,sector,strip);
+  Int_t    maxAdc         = param->GetAltroChannelSize()-1;
+  if (maxAdc < 0) {
+    AliWarning(Form("Maximum ADC is %d < 0, forcing it to 1023", maxAdc));
+    maxAdc = 1023;
+  }
   UShort_t rate           = param->GetSampleRate(detector,ring,sector,strip);
+  if (rate < 1 || rate > 3) rate = 1;
   
   // In case we don't oversample, just return the end value. 
   if (rate == 1) {
-    counts[0] = UShort_t(TMath::Min(edep * convF + ped, Float_t(maxAdc)));
-    AliDebug(2, Form("FMD%d%c[%2d,%3d]: converting ELoss %f to ADC %d (%f)", 
-                    detector,ring,sector,strip,edep,counts[0],convF));
+    Float_t    a = edep * convF + ped;
+    if (a < 0) a = 0;
+    counts[0]    = UShort_t(TMath::Min(a, Float_t(maxAdc)));
+    AliDebug(2, Form("FMD%d%c[%2d,%3d]: converting ELoss %f to "
+                    "ADC %4d (%f,%d)",
+                    detector,ring,sector,strip,edep,counts[0],convF,ped));
     return;
   }
   
   // Create a pedestal 
   Float_t b = fShapingTime;
   for (Ssiz_t i = 0; i < rate;  i++) {
-    Float_t t = Float_t(i) / rate;
-    Float_t s = edep + (last - edep) * TMath::Exp(-b * t);
-    counts[i] = UShort_t(TMath::Min(s * convF + ped, Float_t(maxAdc)));
+    Float_t t  = Float_t(i) / rate;
+    Float_t s  = edep + (last - edep) * TMath::Exp(-b * t);
+    Float_t a  = Int_t(s * convF + ped);
+    if (a < 0) a = 0;
+    counts[i]  = UShort_t(TMath::Min(a, Float_t(maxAdc)));
   }
 }
 
index 3693be6..604a10f 100644 (file)
@@ -45,6 +45,7 @@
 // #include <TMath.h>
 #include <TROOT.h>
 #include <TRandom.h>
+#include <TF1.h>
 
 //====================================================================
 ClassImp(AliFMDCalibFaker)
@@ -208,21 +209,51 @@ AliFMDCalibFaker::MakePulseGain() const
 }
 
 //__________________________________________________________________
+Float_t 
+AliFMDCalibFaker::MakeNoise(Char_t ring, UShort_t str) const
+{
+  const UShort_t innerN    = 512;
+  const UShort_t outerN    = 256;
+  const UShort_t innerCut  = 350;
+  const UShort_t outerCut  = 190;
+  const Float_t  innerBase =   1.2;
+  const Float_t  outerBase =   2.1;
+  const Float_t  innerInc  =   0.5;
+  const Float_t  outerInc  =   0.8;
+  Float_t cut, base, inc, n;
+  switch (ring) {
+  case 'I': 
+    cut = innerCut; base = innerBase; inc = innerInc; n = innerN; break;
+  case 'O': 
+    cut = outerCut; base = outerBase; inc = outerInc; n = outerN; break;
+  default:
+    return -1;
+  }
+  Float_t bare = base + (str < cut ? 
+                        str / cut * inc : 
+                        inc  - (str - cut) / (n - cut) * inc);
+  return bare + gRandom->Uniform(-.07, .07);
+}
+  
+//__________________________________________________________________
 AliFMDCalibPedestal*
 AliFMDCalibFaker::MakePedestal() const
 {
   // Make the actual data
   AliFMDCalibPedestal*  pedestal  = new AliFMDCalibPedestal;
+  
   for (UShort_t det = 1; det <= 3; det++) {
-    Char_t rings[] = { 'I', (det == 1 ? '\0' : 'O'), '\0' };
+    Char_t rings[] = { 'I', 'O', '\0' };
     for (Char_t* ring = rings; *ring != '\0'; ring++) {
+      if (*ring == 'O' && det == 1) continue;
       UShort_t nSec = ( *ring == 'I' ? 20  :  40 );
       UShort_t nStr = ( *ring == 'I' ? 512 : 256 );
       for (UShort_t sec = 0; sec < nSec; sec++) {
         for (UShort_t str = 0; str < nStr; str++) {
-          pedestal->Set(det, *ring, sec, str,
-                       gRandom->Uniform(fPedestalMin, fPedestalMax), 1.5);
-        }
+         Float_t noise = MakeNoise(*ring, str);
+         Float_t ped   = gRandom->Uniform(fPedestalMin, fPedestalMax);
+          pedestal->Set(det, *ring, sec, str, ped, noise);
+       }
       }
     }
   }
index 72a664c..25c6776 100644 (file)
@@ -144,7 +144,8 @@ protected:
   /** Make a strip range
       @return strip range map */
   virtual AliFMDCalibStripRange*      MakeStripRange() const;
-
+  virtual Float_t MakeNoise(Char_t ring, UShort_t str) const;
+  
   Long_t   fMask;            // What to write 
   Float_t  fGain;            // Gain
   Float_t  fThresholdFactor; // Threshold factor
index e01ad78..fb8209d 100644 (file)
@@ -53,6 +53,7 @@ public:
   Float_t Value(UShort_t det, Char_t ring, UShort_t sec, UShort_t str);
   /** @return threshold */
   Float_t Threshold() const { return fThreshold; }
+  const AliFMDFloatMap& Values() const { return fValue; }
 private:
   AliFMDFloatMap fValue;       // Map
   Float_t        fThreshold;   // Global threshold
index bbde8fb..9270dde 100644 (file)
@@ -47,6 +47,8 @@
 #include <TCanvas.h>
 #include <TView.h>
 #include <TVirtualX.h>
+#include <TSlider.h>
+#include <TH1D.h>
 
 //____________________________________________________________________
 ClassImp(AliFMDDisplay)
@@ -66,16 +68,31 @@ AliFMDDisplay::Instance()
 }
 
 //____________________________________________________________________
-AliFMDDisplay::AliFMDDisplay(const char* gAliceFile)
+AliFMDDisplay::~AliFMDDisplay()
+{
+  if (fMarkers) {
+    fMarkers->Delete();
+    delete fMarkers;
+  }
+  if (fHits) {
+    fHits->Clear();
+    delete fHits;
+  }
+  if (fPad)     delete fPad;
+  fButtons.Delete();
+  if (fSlider)  delete fSlider;
+  if (fCanvas)  delete fCanvas;
+}
+  
+//____________________________________________________________________
+AliFMDDisplay::AliFMDDisplay(Bool_t onlyFMD, const char* gAliceFile)
   : AliFMDInput(gAliceFile),
     fWait(kFALSE),
     fMarkers(0),
     fHits(0),
     fCanvas(0), 
     fPad(0), 
-    fButton(0), 
-    fZoom(0),
-    fPick(0),
+    fSlider(0),
     fZoomMode(kFALSE),
     fX0(0),
     fY0(0),
@@ -87,14 +104,12 @@ AliFMDDisplay::AliFMDDisplay(const char* gAliceFile)
     fYPixel(0),
     fOldXPixel(0),
     fOldYPixel(0),
-    fLineDrawn(0)
+    fLineDrawn(0),
+    fOnlyFMD(onlyFMD)
 {
   // Constructor of an FMD display object. 
   AddLoad(kGeometry);
-  fMarkers = new TObjArray;
-  fHits    = new TObjArray;
-  fMarkers->SetOwner(kTRUE);
-  fHits->SetOwner(kFALSE);
+  if (fgInstance) delete fgInstance;
   fgInstance = this;
   SetMultiplicityCut();
   SetPedestalFactor();
@@ -102,6 +117,106 @@ AliFMDDisplay::AliFMDDisplay(const char* gAliceFile)
 
 //____________________________________________________________________
 void           
+AliFMDDisplay::MakeCanvas(const char** which)
+{
+  gStyle->SetPalette(1);
+  Double_t y1 = .10;
+  Int_t    w  = 700;
+  fCanvas = new TCanvas("display", "Display", w, Int_t(w / (1-y1)));
+  fCanvas->SetFillColor(1);
+  fCanvas->ToggleEventStatus();
+  fCanvas->cd();
+  fPad = new TPad("view", "3DView", 0.0, y1, 1.0, 1.0, 1, 0, 0);
+  fPad->Draw();
+
+  Double_t yb = 0;
+  fCanvas->cd();
+  if (TESTBIT(fTreeMask, kESD) || 
+      TESTBIT(fTreeMask, kDigits) || 
+      TESTBIT(fTreeMask, kRaw)) {
+    yb = .05;
+    fSlider = new TSlider("multCut", "Multiplicity cut", 0, 0, 1, yb);
+    fSlider->SetMethod("AliFMDDisplay::Instance()->ChangeCut()");
+    fSlider->SetMinimum(TESTBIT(fTreeMask, kESD) ? fMultCut :
+                       fPedestalFactor * 10);
+    fSlider->Draw();
+  }
+  const char** p = which;
+  const char*  m;
+  Int_t        n  = 0;
+  Int_t        j  = 0;
+  while (*(p++)) n++;
+  AliInfo(Form("Got %d buttons", n));
+  Float_t      x0 = 0;
+  Float_t      dx = 1. / n;
+  p               = which;
+  while ((m = *(p++))) {
+    fCanvas->cd();
+    AliInfo(Form("Adding button %s", m));
+    TButton* b = new TButton(m, Form("AliFMDDisplay::Instance()->%s()", m),
+                            x0, yb, x0 + dx, y1);
+    b->Draw();
+    fButtons.Add(b);
+    x0 += dx;
+    j++;
+  }
+}
+
+//____________________________________________________________________
+void           
+AliFMDDisplay::ShowOnlyFMD()
+{
+  if (!fGeoManager) return;
+  static bool once = false;
+  if (once) return;
+  once = true;
+  AliInfo("Will only show the FMD");
+  TGeoVolume* top = gGeoManager->GetTopVolume();
+  top->InvisibleAll(kTRUE);
+  TGeoIterator next(top);
+  TGeoNode* node;
+  TGeoVolume* v = 0;
+  Bool_t hasFMD1 = kFALSE;
+  Bool_t hasFMD2 = kFALSE;
+  Bool_t hasFMD3 = kFALSE;
+  TObjArray toshow;
+  while ((node = static_cast<TGeoNode*>(next()))) {
+    const char* name = node->GetName();
+    if (!name) continue;
+    if (!(v = node->GetVolume())) continue;
+
+    if (name[0] == 'F') {
+      if (name[2] == 'M' && (name[3] == 'T' || name[3] == 'B')) {
+       // Virtual Master half-ring volume - top-level
+       Int_t det = node->GetNumber();
+       switch (det) {
+       case 1: hasFMD1 = true; break;
+       case 2: hasFMD2 = true; break;
+       case 3: hasFMD3 = true; break;
+       default: continue;
+       }
+       toshow.Add(v);
+      }
+      else if (name[3] == 'V' && (name[2] == 'T' || name[2] == 'B')) 
+       toshow.Add(v); // Virtual Half-ring, bare detectors
+      // else if (name[3] == 'H' && (name[2] == 'F' || name[2] == 'B')) 
+      //  toshow.Add(v); // Virtual Hybrid container 
+    }
+    v->SetVisibility(kFALSE);
+    v->SetVisDaughters(kFALSE);
+    v->InvisibleAll(kTRUE);
+  }
+  TIter i(&toshow);
+  while ((v = static_cast<TGeoVolume*>(i()))) {
+    v->SetVisibility(kTRUE);
+    v->SetVisDaughters(kTRUE);
+    v->InvisibleAll(kFALSE);
+  }  
+}
+
+    
+//____________________________________________________________________
+void           
 AliFMDDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py) 
 {
   // AliInfo(Form("Event %d, at (%d,%d)", px, py));
@@ -165,37 +280,65 @@ AliFMDDisplay::Init()
   AliFMDGeometry* geom = AliFMDGeometry::Instance();
   geom->Init();
   geom->InitTransformations();
-  // AliFMDParameters* parm = AliFMDParameters::Instance();
-  // parm->Init();
+  fMarkers = new TObjArray;
+  fHits    = new TObjArray;
+  fMarkers->SetOwner(kTRUE);
+  fHits->SetOwner(kFALSE);
   return kTRUE;
 }
+
+//____________________________________________________________________
+void
+AliFMDDisplay::MakeAux()
+{
+  if ((TESTBIT(fTreeMask, kESD) || 
+       TESTBIT(fTreeMask, kDigits) || 
+       TESTBIT(fTreeMask, kRaw))) {
+    if (!fAux) {
+      fAux = new TCanvas("aux", "Aux");
+      fAux->SetLogy();
+      if (TESTBIT(fTreeMask, kESD)) 
+       fSpec = new TH1D("spec", "Mult spectra", 150, 0, 3);
+      else 
+       fSpec = new TH1D("spec", "Adc spectra", 1024, -.5, 1023.5);
+      fSpecCut = static_cast<TH1*>(fSpec->Clone("specCut"));
+      fSpec->SetFillColor(2);
+      fSpec->SetFillStyle(3001);
+      fSpecCut->SetFillColor(4);
+      fSpecCut->SetFillStyle(3001);
+    }
+    else {
+      fSpec->Reset();
+      fSpecCut->Reset();
+    }
+  }
+}
+
+//____________________________________________________________________
+void
+AliFMDDisplay::DrawAux()
+{
+  if (!fAux) return;
+  fAux->cd();
+  fAux->Clear();
+  fSpec->Draw();
+  fSpecCut->Draw("same");
+  fAux->Modified();
+  fAux->Update();
+  fAux->cd();
+}
+
 //____________________________________________________________________
 Bool_t 
 AliFMDDisplay::Begin(Int_t event) 
 {
   // Begin of event.  Make canvas is not already done 
   if (!fCanvas) {
-    gStyle->SetPalette(1);
-    fCanvas = new TCanvas("display", "Display", 700, 700);
-    fCanvas->SetFillColor(1);
-    fCanvas->ToggleEventStatus();
-    fPad = new TPad("view3D", "3DView", 0.0, 0.05, 1.0, 1.0, 1, 0, 0);
-    fCanvas->cd();
-    fPad->Draw();
-  }
-  if (!fButton) {
-    fCanvas->cd();
-    fButton = new TButton("Continue", "AliFMDDisplay::Instance()->Continue()",
-                         0, 0, .5, .05);
-    fButton->Draw();
-    fZoom = new TButton("Zoom", "AliFMDDisplay::Instance()->Zoom()",
-                       .5, 0, .75, .05);
-    fZoom->Draw();
-    fPick = new TButton("Pick", "AliFMDDisplay::Instance()->Pick()",
-                       .75, 0, 1, .05);
-    fPick->Draw();
+    const char* m[] = { "Continue", "Zoom", "Pick", "Redisplay", 0 }; 
+    MakeCanvas(m);
+    MakeAux();
   }
-  AliInfo("Clearing canvas");
+  // AliInfo("Clearing canvas");
   // fCanvas->Clear();
   if (!fGeoManager) {
     Warning("End", "No geometry manager");
@@ -204,6 +347,7 @@ AliFMDDisplay::Begin(Int_t event)
   AliInfo("Drawing geometry");
   fPad->cd();
   fGeoManager->GetTopVolume()->Draw();
+  if (fOnlyFMD) ShowOnlyFMD();
   AliInfo("Adjusting view");
   Int_t irep;
   if (fPad->GetView()) {
@@ -216,20 +360,21 @@ AliFMDDisplay::Begin(Int_t event)
 }
 
 //____________________________________________________________________
-Bool_t 
-AliFMDDisplay::End()
+void
+AliFMDDisplay::AtEnd() 
 {
-  // End of event.  Draw everything 
   fPad->cd();
   fMarkers->Draw();
   fPad->cd();
   AppendPad();
-  // fPad->Update();
   fPad->cd();
-  // fCanvas->Modified(kTRUE);
-  //fCanvas->Update();
-  // fCanvas->cd();
-  // fPad->cd();
+  DrawAux();
+}
+
+//____________________________________________________________________
+void
+AliFMDDisplay::Idle() 
+{
   fWait = kTRUE;
   while (fWait) {
     gApplication->StartIdleing();
@@ -237,9 +382,18 @@ AliFMDDisplay::End()
     gApplication->StopIdleing();
   }
   AliInfo("After idle loop");
-  fMarkers->Delete();
-  fHits->Clear();
+  if (fMarkers) fMarkers->Delete();
+  if (fHits)    fHits->Clear();
   AliInfo("After clearing caches");
+}
+
+//____________________________________________________________________
+Bool_t 
+AliFMDDisplay::End()
+{
+  // End of event.  Draw everything 
+  AtEnd();
+  Idle();
   return AliFMDInput::End();
 }
 
@@ -254,6 +408,29 @@ AliFMDDisplay::LookupColor(Float_t x, Float_t max) const
 
 //____________________________________________________________________
 void
+AliFMDDisplay::ChangeCut() 
+{
+  fMultCut        = fSlider->GetMinimum();
+  fPedestalFactor = fSlider->GetMinimum() * 10;
+  AliInfo(Form("Multiplicity cut: %7.5f, Pedestal factor: %7.4f (%6.5f)", 
+              fMultCut, fPedestalFactor, fSlider->GetMinimum()));
+  Redisplay();
+}
+
+//____________________________________________________________________
+void
+AliFMDDisplay::Redisplay()
+{
+  if (fMarkers) fMarkers->Delete();
+  if (fHits)    fHits->Clear();
+  if (fSpec)    fSpec->Reset();
+  if (fSpecCut) fSpecCut->Reset();
+  Event();
+  AtEnd();
+}
+
+//____________________________________________________________________
+void
 AliFMDDisplay::AddMarker(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
                         TObject* o, Float_t s, Float_t max)
 {
@@ -285,15 +462,15 @@ AliFMDDisplay::AddMarker(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
 
 //____________________________________________________________________
 Bool_t 
-AliFMDDisplay::ProcessHit(AliFMDHit* hit, TParticle* p) 
+AliFMDDisplay::ProcessHit(AliFMDHit* hit, TParticle* /* p */) 
 {
   // Process a hit 
   if (!hit) { AliError("No hit");   return kFALSE; }
-  if (!p)   { AliError("No track"); return kFALSE; }
+  // if (!p)   { AliError("No track"); return kFALSE; }
 
-  fHits->Add(hit);
+  if (fHits) fHits->Add(hit);
   Float_t  size  = .1;
-  Float_t  zsize = hit->Edep() * 10;
+  Float_t  zsize = TMath::Sqrt(hit->Edep() * 20);
   Float_t  z     = hit->Z() + (hit->Z() < 0 ? 1 : -1) * zsize; 
   Float_t  pt    = TMath::Sqrt(hit->Py()*hit->Py()+hit->Px()*hit->Px());
   Float_t  theta = TMath::ATan2(pt, hit->Pz());
@@ -322,8 +499,10 @@ AliFMDDisplay::ProcessDigit(AliFMDDigit* digit)
   Double_t pedW          =  parm->GetPedestalWidth(det,ring, sec, str);
   Double_t threshold     =  ped * fPedestalFactor * pedW;
   Float_t  counts        = digit->Counts();
+  if (fSpec) fSpec->Fill(counts);
   if (counts < threshold) return kTRUE;
-  fHits->Add(digit);
+  if (fHits) fHits->Add(digit);
+  if (fSpecCut) fSpecCut->Fill(counts);
 
   AddMarker(det, ring, sec, str, digit, counts, 1024);
   return kTRUE;
@@ -344,7 +523,7 @@ AliFMDDisplay::ProcessRecPoint(AliFMDRecPoint* recpoint)
   // Process reconstructed point 
   if (!recpoint) { AliError("No recpoint");   return kFALSE; }
   if (recpoint->Particles() < fMultCut) return kTRUE;
-  fHits->Add(recpoint);
+  if (fHits) fHits->Add(recpoint);
   AddMarker(recpoint->Detector(), recpoint->Ring(), recpoint->Sector(),  
            recpoint->Strip(), recpoint, recpoint->Particles(), 20);
   return kTRUE;
@@ -352,23 +531,15 @@ AliFMDDisplay::ProcessRecPoint(AliFMDRecPoint* recpoint)
 
 //____________________________________________________________________
 Bool_t 
-AliFMDDisplay::ProcessESD(AliESDFMD* esd)
+AliFMDDisplay::ProcessESD(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
+                         Float_t eta, Float_t mult)
 {
-  // Process event summary data
-  for (UShort_t det = 1; det <= 3; det++) {
-    Char_t rings[] = { 'I', (det == 1 ? '\0' : 'O'), '\0' };
-    for (Char_t* rng = rings; *rng != '\0'; rng++) {
-      UShort_t nsec = (*rng == 'I' ?  20 :  40);
-      UShort_t nstr = (*rng == 'O' ? 512 : 256);
-      for (UShort_t sec = 0; sec < nsec; sec++) {
-       for (UShort_t str = 0; str < nstr; str++) {
-         Float_t mult = esd->Multiplicity(det,*rng,sec,str);
-         if (mult < fMultCut) continue;
-         AddMarker(det,*rng,sec,str, 0, mult, 20);
-       }
-      }
-    }
-  }
+  Double_t cmult = (mult * 
+                   TMath::Abs(TMath::Cos(2.*TMath::ATan(TMath::Exp(-eta)))));
+  if (fSpec) fSpec->Fill(cmult);
+  if (cmult < fMultCut || cmult == AliESDFMD::kInvalidMult) return kTRUE;
+  AddMarker(det,rng,sec,str, 0, cmult, 20);
+  if (fSpecCut) fSpecCut->Fill(cmult);
   return kTRUE;
 }
 
index 7ba2565..159a04e 100644 (file)
 // various types of data produced by the FMD. 
 //
 #include "AliFMDInput.h"
-class TObjArray;
+#include <TObjArray.h>
 class TCanvas;
 class TPad;
 class TButton;
+class TSlider;
+class TH1;
 
 //___________________________________________________________________
 /** @class AliFMDDisplay 
@@ -33,10 +35,11 @@ class AliFMDDisplay : public AliFMDInput
 {
 public:
   /** Constructor
+      @param onlyFMD Only show the FMD
       @param gAliceFile galice file*/
-  AliFMDDisplay(const char* gAliceFile="galice.root");
+  AliFMDDisplay(Bool_t onlyFMD=kTRUE, const char* gAliceFile="galice.root");
   /** DTOR */
-  virtual ~AliFMDDisplay() {}
+  virtual ~AliFMDDisplay();
   /** Singleton access function
       @return Singleton object. */
   static AliFMDDisplay* Instance();
@@ -47,19 +50,23 @@ public:
   void  Zoom() { fZoomMode = kTRUE; }
   /** Pick mode */
   void  Pick() { fZoomMode = kFALSE; }
+  /** Redisplay the event */ 
+  virtual void Redisplay(); // *MENU*
+  /** Change cut */
+  virtual void ChangeCut();
   /** Called when a mouse or similar event happens in the display. 
       @param event Event type
       @param px    where the event happened in pixels along X
       @param py    where the event happened in pixels along Y */
-  void  ExecuteEvent(Int_t event, Int_t px, Int_t py);
+  virtual void  ExecuteEvent(Int_t event, Int_t px, Int_t py);
   /** Calculate distance from point @f$ (p_x,p_y)@f$ to this object. 
       @param px Pixel X coordinate 
       @param py Pixel Y coordinate 
       @return distance. */
-  Int_t DistancetoPrimitive(Int_t px, Int_t py);
+  virtual Int_t DistancetoPrimitive(Int_t px, Int_t py);
   /** Paint into canvas 
       @param option Not used */
-  void  Paint(Option_t* option="") { (void)option; }
+  virtual void  Paint(Option_t* option="") { (void)option; }
 
   /** Initialize
       @return  @c false on error */
@@ -88,10 +95,17 @@ public:
       @param recpoint Reconstructed point
       @return @c false on error  */
   virtual Bool_t ProcessRecPoint(AliFMDRecPoint* recpoint);
-  /** Visualize data in ESD 
-      @param esd FMD ESD data 
-      @return  Always @c true */
-  virtual Bool_t ProcessESD(AliESDFMD* esd);
+  /** Process ESD data for the FMD.  Users should overload this to
+      deal with ESD data. 
+      @param d    Detector number (1-3)
+      @param r    Ring identifier ('I' or 'O')
+      @param s    Sector number (0-19, or 0-39)
+      @param t    Strip number (0-511, or 0-255)
+      @param eta  Psuedo-rapidity 
+      @param mult Psuedo-multiplicity 
+      @return  @c false on error  */
+  virtual Bool_t ProcessESD(UShort_t d, Char_t r, UShort_t s, UShort_t t, 
+                           Float_t eta, Float_t mult);
   /** Look up a color index, based on the value @a x and the maximum
       value of @a x
       @param x   Value 
@@ -114,9 +128,7 @@ protected:
       fHits(0),
       fCanvas(0),
       fPad(0),
-      fButton(0),
-      fZoom(0),
-      fPick(0),
+      fSlider(0),
       fZoomMode(0),
       fX0(0),
       fY0(0),
@@ -141,8 +153,17 @@ protected:
       @param o   Object to refer to
       @param s   Signal 
       @param max Maximum of signal */
-  void AddMarker(UShort_t det, Char_t rng, UShort_t sec, UShort_t str, 
-                TObject* o, Float_t s, Float_t max);
+  virtual void AddMarker(UShort_t det, Char_t rng, UShort_t sec, UShort_t str, 
+                        TObject* o, Float_t s, Float_t max);
+  
+  /** Show only the FMD detectors. */
+  void ShowOnlyFMD();
+  /** Make base canvas */ 
+  virtual void MakeCanvas(const char** which);
+  virtual void MakeAux();
+  virtual void DrawAux();
+  virtual void Idle();
+  virtual void AtEnd();
   
   static AliFMDDisplay* fgInstance; // Static instance 
   Bool_t                fWait;      // Wait until user presses `Continue'
@@ -150,9 +171,8 @@ protected:
   TObjArray*            fHits;      // Cache of `hits'
   TCanvas*              fCanvas;    // Canvas to draw in 
   TPad*                 fPad;       // View pad. 
-  TButton*              fButton;    // Continue button
-  TButton*              fZoom;      // Zoom button
-  TButton*              fPick;      // Pick button
+  TObjArray             fButtons;   // Continue button
+  TSlider*              fSlider;    // Cut slider
   Bool_t                fZoomMode;  // Whether we're in Zoom mode
   Float_t               fX0;        // X at lower left corner or range 
   Float_t               fY0;        // Y at lower left corner or range 
@@ -165,6 +185,10 @@ protected:
   Int_t                 fOldXPixel; // Old x pixel of mark
   Int_t                 fOldYPixel; // Old y pixel of mark
   Bool_t                fLineDrawn; // Whether we're drawing a box
+  Bool_t                fOnlyFMD;
+  TH1*                  fSpec;
+  TH1*                  fSpecCut;
+  TCanvas*              fAux;
   ClassDef(AliFMDDisplay,0)  // FMD specialised event display
 };
 
diff --git a/FMD/AliFMDFancy.cxx b/FMD/AliFMDFancy.cxx
new file mode 100644 (file)
index 0000000..e92fe24
--- /dev/null
@@ -0,0 +1,409 @@
+/**************************************************************************
+ * 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$ */
+/** @file    AliFMDFancy.cxx
+    @author  Christian Holm Christensen <cholm@nbi.dk>
+    @date    Mon Mar 27 12:39:09 2006
+    @brief   FMD 2D Event display 
+*/
+//___________________________________________________________________
+//
+// The classes defined here, are utility classes for reading in data
+// for the FMD.  They are  put in a seperate library to not polute the
+// normal libraries.  The classes are intended to be used as base
+// classes for customized class that do some sort of analysis on the
+// various types of data produced by the FMD. 
+//
+// Latest changes by Christian Holm Christensen
+//
+#include "AliFMDFancy.h"       // ALIFMDDISPLAY_H
+#include "AliFMDGeometry.h"    // ALIFMDGEOMETRY_H
+#include "AliFMDParameters.h"  // ALIFMDPARAMETERS_H
+#include <AliLog.h>
+#include <TStyle.h>
+#include <TApplication.h>
+#include <TButton.h>
+#include <TCanvas.h>
+#include <TView.h>
+#include <TH2F.h>
+#include <TH3F.h>
+#include <TSystem.h>
+#include <TVector2.h>
+#include "AliFMDRing.h"
+#include "AliFMDDetector.h"
+#include "AliFMDHit.h"
+#include <TRandom.h>
+#include <TLatex.h>
+#include <TLine.h>
+#include <iostream>
+#include <iomanip>
+
+//____________________________________________________________________
+ClassImp(AliFMDFancy)
+#if 0
+  ; // This is here to keep Emacs for indenting the next line
+#endif
+
+//____________________________________________________________________
+AliFMDFancy::AliFMDFancy(const char* gAliceFile)
+  : AliFMDDisplay(kTRUE, gAliceFile),
+    fFMD1Pad(0),
+    fFMD1(1),
+    fFMD2Pad(0),
+    fFMD2(2),
+    fFMD3Pad(0),
+    fFMD3(3),
+    fEvent(.1, .8, "Event #"),
+    fFMD1IHits(.2, .7, "# in FMD1I: "),
+    fFMD2IHits(.2, .6, "# in FMD2I: "),
+    fFMD2OHits(.2, .5, "# in FMD2O: "),
+    fFMD3IHits(.2, .4, "# in FMD3I: "),
+    fFMD3OHits(.2, .3, "# in FMD3O: "),
+    fLine(.15, .27, .85, .27),
+    fTotal(.2, .15, "Total:   ")
+{
+  fEvent.SetBit(TLatex::kTextNDC);
+  fFMD1IHits.SetBit(TLatex::kTextNDC);
+  fFMD2IHits.SetBit(TLatex::kTextNDC);
+  fFMD2OHits.SetBit(TLatex::kTextNDC);
+  fFMD3IHits.SetBit(TLatex::kTextNDC);
+  fFMD3OHits.SetBit(TLatex::kTextNDC);
+  fLine.SetBit(TLine::kLineNDC);
+  fTotal.SetBit(TLatex::kTextNDC);
+}
+
+//____________________________________________________________________
+AliFMDFancy::Detector::Detector(UShort_t id)
+  : fId(id)
+{
+  fInnerHits.SetName(Form("FMD%dI", id));
+  fInnerHits.SetMarkerStyle(1); // 20);
+  fInnerHits.SetMarkerSize(.2);
+  fInnerHits.SetMarkerColor(50); // 12);
+  fOuterHits.SetName(Form("FMD%dO", id));
+  fOuterHits.SetMarkerStyle(1); // 20);
+  fOuterHits.SetMarkerSize(.2);
+  fOuterHits.SetMarkerColor(50); // 12);
+}
+
+//____________________________________________________________________
+AliFMDFancy::Detector::~Detector()
+{
+  fShapes.Delete();
+  if (fFrame) delete fFrame;
+}
+
+//____________________________________________________________________
+AliFMDFancy::~AliFMDFancy()
+{}
+
+//____________________________________________________________________
+void
+AliFMDFancy::Detector::AddHistogram(TGraph2D& g, const char* opt)
+{
+  TH2* h = g.GetHistogram(opt);
+  if (!h) return;
+  h->SetBins(1, -fMaxR, fMaxR, 1, -fMaxR, fMaxR);
+  h->GetZaxis()->SetRangeUser(fMinZ, fMaxZ);
+}
+
+  
+
+//____________________________________________________________________
+void
+AliFMDFancy::Detector::Init()
+{
+  AliFMDGeometry* geom = AliFMDGeometry::Instance();
+  AliFMDDetector* det  = geom->GetDetector(fId);
+  if (!det) return;
+  Char_t   rs[]   = { 'I' , 'O', '\0' };
+  Char_t*  rp     = rs;
+  Char_t   r;
+  Double_t maxR = 0;
+  Double_t minZ = 10000;
+  Double_t maxZ = -10000;
+  Int_t    ns   = 0;
+  while ((r = *(rp++))) {
+    AliFMDRing* ring = det->GetRing(r);
+    if (!ring) continue;
+    // if (r == 'O') continue;
+    const TObjArray& vs = ring->GetVerticies();
+    Int_t            nm = ring->GetNModules();
+    Double_t         zd = (r == 'I' ? det->GetInnerZ() : det->GetOuterZ());
+    for (Int_t m = 0; m < nm; m++) {
+      Int_t          nv = vs.GetEntries();
+      Double_t       a  = TMath::Pi() / 180 * (m * 2 + 1) * ring->GetTheta();
+      TGraph2D*      g  = new TGraph2D(nv);
+      Double_t       x0 = 0, y0 = 0, z0 = 0;
+      Double_t       z  = zd + (m % 2==0 ? 0 : 
+                               TMath::Sign(ring->GetModuleSpacing(), zd));
+      minZ              = TMath::Min(minZ, z);
+      maxZ              = TMath::Max(maxZ, z);
+      g->SetName(Form("FMD%d%cM%02d", fId, r, m));
+      fShapes.AddAtAndExpand(g, ns++);
+      for (Int_t c = 0; c < nv; c++) {
+       TVector2* v = static_cast<TVector2*>(vs.At(nv - 1 - c));
+       TVector2  w(v->Rotate(a));
+       if (c == 0) { x0 = w.X(); y0 = w.Y(); z0 = z; }
+       g->SetPoint(c, w.X(), w.Y(), z);
+       maxR        = TMath::Max(maxR, v->Mod());
+      }
+      //g->SetPoint(nv, x0, y0, z0);
+      g->SetFillColor(2);
+      g->SetFillStyle(3002);
+      g->SetLineColor(2);
+      g->SetLineWidth(1);
+    }
+  }
+  fMaxR = 1.05 * maxR;
+  fMinZ = (minZ  > 0 ? 0.95 * minZ : 1.05 * minZ);
+  fMaxZ = (maxZ  > 0 ? 1.05 * maxZ : 0.95 * maxZ);
+
+  TIter next(&fShapes);
+  TGraph2D* g = 0;
+  while ((g = static_cast<TGraph2D*>(next()))) AddHistogram(*g);
+  if (det->GetInner()) AddHistogram(fInnerHits);
+  if (det->GetOuter()) AddHistogram(fOuterHits);
+
+  fFrame = new TH2F(Form("FMD%d", fId), Form("FMD%d", fId), 
+                   1, -fMaxR, fMaxR, 1, -fMaxR, fMaxR);
+  fFrame->SetStats(kFALSE);
+  fFrame->GetXaxis()->SetTitle("x [cm]");
+  fFrame->GetYaxis()->SetTitle("y [cm]");
+  fFrame->GetZaxis()->SetTitle("z [cm]");
+  fFrame->SetDirectory(0);
+}
+
+  
+//____________________________________________________________________
+Bool_t 
+AliFMDFancy::Init()
+{
+  // Initialize.  GEt transforms and such, 
+  if (!AliFMDInput::Init()) return kFALSE;
+  AliFMDGeometry* geom = AliFMDGeometry::Instance();
+  geom->Init();
+  geom->InitTransformations();
+  
+  fFMD1.Init();
+  fFMD2.Init();
+  fFMD3.Init();
+  return kTRUE;
+}
+
+//____________________________________________________________________
+void
+AliFMDFancy::Detector::Begin(Int_t /* event */)
+{
+  TIter next(&fShapes);
+  TGraph2D* g = 0;
+  fFrame->Draw("surf fb");
+  fFrame->GetZaxis()->SetRangeUser(fMinZ, fMaxZ);
+  while ((g = static_cast<TGraph2D*>(next()))) g->Draw("tri2 FB same");
+}
+
+//____________________________________________________________________
+void
+AliFMDFancy::Detector::Clear(Int_t /* event */)
+{
+  fNInnerHits = 0;
+  fNOuterHits = 0;
+}
+
+  
+//____________________________________________________________________
+Bool_t 
+AliFMDFancy::Begin(Int_t event) 
+{
+  if (!fCanvas) {
+    const char* which[] = { "Continue", "Redisplay", 0 };
+    MakeCanvas(which);
+
+    AliFMDGeometry* geom = AliFMDGeometry::Instance();
+    AliFMDDetector* det;
+    if ((det = geom->GetDetector(1))) {
+      fPad->cd();
+      fFMD1Pad = new TPad("FMD1", "FMD1", 0.0, 0.50, 0.5, 1.0, 0, 0);
+      fFMD1Pad->Draw();
+      fFMD1Pad->cd();
+      fFMD1.Begin(event);
+    }
+    if ((det = geom->GetDetector(2))) {
+      fPad->cd();
+      fFMD2Pad = new TPad("FMD2", "FMD2", 0.5, 0.50, 1.0, 1.0, 0, 0);
+      fFMD2Pad->Draw();
+      fFMD2Pad->cd();
+      fFMD2.Begin(event);
+    }
+    if ((det = geom->GetDetector(3))) {
+      fPad->cd();
+      fFMD3Pad = new TPad("FMD3", "FMD3", 0.0, 0.05, .5, .5, 0, 0);
+      fFMD3Pad->Draw();
+      fFMD3Pad->cd();
+      fFMD3.Begin(event);
+    }
+    fPad->cd();
+    fSummary = new TPad("display", "Display", 0.5, 0.05, 1.0, 0.5, 0, 0);
+    fSummary->Draw();
+    fSummary->cd();
+    fEvent.Draw();
+    fFMD1IHits.Draw();
+    fFMD2IHits.Draw();
+    fFMD2OHits.Draw();
+    fFMD3IHits.Draw();
+    fFMD3OHits.Draw();
+    fLine.Draw();
+    fTotal.Draw();
+  }
+  fEvent.SetTitle(Form("Event # %6d", event));
+  // fEvent.Modify();
+  fCanvas->Modified();
+  fCanvas->Update();
+  fCanvas->cd();
+  fFMD1.Clear(event);
+  fFMD2.Clear(event);
+  fFMD3.Clear(event);
+  return AliFMDInput::Begin(event);
+}
+
+//____________________________________________________________________
+void
+AliFMDFancy::Detector::End()
+{
+  Char_t  rs[] = { 'I', 'O', '\0' };
+  Char_t* rp   = rs;
+  Char_t  r;
+  while ((r = *(rp++))) {
+    TGraph2D& g = (r == 'I' ? fInnerHits : fOuterHits);
+    Int_t&    n = (r == 'I' ? fNInnerHits : fNOuterHits);
+    Int_t     m = (r == 'I' ? 512 * 10 * 2 : 256 * 20 * 2);
+    if (n == 0) continue;
+    for (Int_t i = n; i < g.GetN(); i++)  g.RemovePoint(i);
+    std::cout << g.GetName() << " has " << std::setw(4) << n << "/" 
+             << std::setw(5) << m << " points" << std::endl;
+    g.Draw("same fb p");
+    AddHistogram(g, "empty");
+  }
+}
+
+//____________________________________________________________________
+Bool_t 
+AliFMDFancy::End() 
+{
+  AliFMDGeometry* geom = AliFMDGeometry::Instance();
+  AliFMDDetector* det;
+  Int_t total = 0;
+  if ((det = geom->GetDetector(1))) {
+    fFMD1Pad->cd();
+    fFMD1.End();
+    fFMD1Pad->Modified();
+    fFMD1IHits.SetTitle(Form("# hits in FMD1I:  %5d", fFMD1.fNInnerHits));
+    total += fFMD1.fNInnerHits;
+  }
+  if ((det = geom->GetDetector(2))) {
+    fFMD2Pad->cd();
+    fFMD2.End();
+    fFMD2Pad->Modified();
+    fFMD2IHits.SetTitle(Form("# hits in FMD2I:  %5d", fFMD2.fNInnerHits));
+    fFMD2OHits.SetTitle(Form("# hits in FMD2O: %5d", fFMD2.fNOuterHits));
+    total += fFMD2.fNInnerHits;
+    total += fFMD2.fNOuterHits;    
+  }
+  if ((det = geom->GetDetector(3))) {
+    fFMD3Pad->cd();
+    fFMD3.End();
+    fFMD3Pad->Modified();
+    fFMD3IHits.SetTitle(Form("# hits in FMD3I:  %5d", fFMD3.fNInnerHits));
+    fFMD3OHits.SetTitle(Form("# hits in FMD3O: %5d", fFMD3.fNOuterHits));
+    total += fFMD3.fNInnerHits;
+    total += fFMD3.fNOuterHits;    
+  }
+  fTotal.SetTitle(Form("Total:    %5d/51200 (%3d%%)", 
+                     total, Int_t(100. / 51200 * total)));
+  fSummary->Modified();
+  fCanvas->Modified();
+  fCanvas->Update();
+  fCanvas->cd();
+  fWait = kTRUE;
+  while (fWait) {
+    gApplication->StartIdleing();
+    gSystem->InnerLoop();
+    gApplication->StopIdleing();
+  }
+  return AliFMDInput::End();
+}
+
+//____________________________________________________________________
+Bool_t 
+AliFMDFancy::ProcessHit(AliFMDHit* hit, TParticle*) 
+{
+  AddMarker(hit->Detector(), hit->Ring(), hit->Sector(), hit->Strip(), 
+           hit, hit->Edep(), 0);
+  return kTRUE;
+}
+//____________________________________________________________________
+void
+AliFMDFancy::Detector::AddMarker(Char_t rng, UShort_t sec, UShort_t str,
+                                Float_t, Float_t)
+{
+  AliFMDGeometry*   geom = AliFMDGeometry::Instance();
+  Double_t x, y, z;
+  geom->Detector2XYZ(fId, rng, sec, str, x, y, z);
+  if (true) {
+    AliFMDRing* r  = geom->GetRing(rng);
+    Double_t    t  = .9 * r->GetTheta() / 2;
+    Double_t    a  = gRandom->Uniform(-t,t) * TMath::Pi() / 180;
+    Double_t    x1 = x * TMath::Cos(a) - y * TMath::Sin(a);
+    Double_t    y1 = x * TMath::Sin(a) + y * TMath::Cos(a);
+    x = x1;
+    y = y1;
+  }
+  switch (rng) {
+  case 'I':
+  case 'i': fInnerHits.SetPoint(fNInnerHits++, x, y, z); break;
+  case 'O': 
+  case 'o': fOuterHits.SetPoint(fNOuterHits++, x, y, z); break;
+  default:  return;
+  }
+}
+
+    
+
+//____________________________________________________________________
+void
+AliFMDFancy::AddMarker(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
+                      TObject*, Float_t, Float_t)
+{
+  // Add a marker to the display
+  //
+  //    det    Detector
+  //    rng    Ring
+  //    sec    Sector 
+  //    str    Strip
+  //    o      Object to refer to
+  //    s      Signal 
+  //    max    Maximum of signal 
+  //
+  switch (det) {
+  case 1: fFMD1.AddMarker(rng,sec,str,0,0); break;
+  case 2: fFMD2.AddMarker(rng,sec,str,0,0); break;
+  case 3: fFMD3.AddMarker(rng,sec,str,0,0); break;
+  }
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
diff --git a/FMD/AliFMDFancy.h b/FMD/AliFMDFancy.h
new file mode 100644 (file)
index 0000000..a563e6a
--- /dev/null
@@ -0,0 +1,135 @@
+#ifndef AliFMDFANCY_H
+#define AliFMDFANCY_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+ * reserved. 
+ *
+ * See cxx source for full Copyright notice                               
+ */
+/** @file    AliFMDFancy.h
+    @author  Christian Holm Christensen <cholm@nbi.dk>
+    @date    Mon Mar 27 12:39:09 2006
+    @brief   FMD Event display (as fancys)
+*/
+//___________________________________________________________________
+//
+// The classes defined here, are utility classes for reading in data
+// for the FMD.  They are  put in a seperate library to not polute the
+// normal libraries.  The classes are intended to be used as base
+// classes for customized class that do some sort of analysis on the
+// various types of data produced by the FMD. 
+//
+#include "AliFMDDisplay.h"
+#include <TObjArray.h>
+#include <TGraph2D.h>
+#include <TLatex.h>
+#include <TLine.h>
+class TCanvas;
+class TPad;
+class TH1;
+class TH2;
+class TH3;
+
+
+//___________________________________________________________________
+/** @class AliFMDFancy 
+    @brief Utility class to visualize FMD data in 2D. 
+    @ingroup FMD_util
+ */
+class AliFMDFancy : public AliFMDDisplay
+{
+public:
+  struct Detector 
+  {
+    Detector(UShort_t id);
+    ~Detector();
+    
+    void Init();
+    void Begin(Int_t event=0);
+    void Clear(Int_t event=0);
+    void End();
+    void AddMarker(Char_t rng, UShort_t sec, UShort_t str, 
+                  Float_t v, Float_t max);
+    TH1*      fFrame;
+    Int_t     fId;
+    TObjArray fShapes;
+    Int_t     fNInnerHits;
+    TGraph2D  fInnerHits;
+    Int_t     fNOuterHits;
+    TGraph2D  fOuterHits;
+    Double_t  fMaxR;
+    Double_t  fMinZ;
+    Double_t  fMaxZ;
+  private:
+    void AddHistogram(TGraph2D& g, const char* opt="");
+    Detector(const Detector& );
+    Detector& operator=(const Detector& ) { return *this; }
+  };
+    
+  /** Constructor
+      @param gAliceFile galice file*/
+  AliFMDFancy(const char* gAliceFile="galice.root");
+  /** DTOR */
+  virtual ~AliFMDFancy();
+
+  /** Initialize
+      @return  @c false on error */
+  virtual Bool_t Init();
+  /** Called at beginning of an event 
+      @param event Event number
+      @return @c false on error  */
+  virtual Bool_t Begin(Int_t event);
+  /** Called at end of an event 
+      @return @c false on error  */
+  virtual Bool_t End();
+ protected:
+  AliFMDFancy(const AliFMDFancy& );
+  AliFMDFancy& operator=(const AliFMDFancy& ) { return *this; }
+  /** Add a marker to the display
+      @param det Detector
+      @param rng Ring
+      @param sec Sector 
+      @param str Strip
+      @param o   Object to refer to
+      @param s   Signal 
+      @param max Maximum of signal */
+  virtual void AddMarker(UShort_t det, Char_t rng, UShort_t sec, UShort_t str, 
+                        TObject* o, Float_t s, Float_t max);
+
+  virtual Bool_t ProcessHit(AliFMDHit* hit, TParticle*);
+  /** FMD1 Pad */
+  TPad*  fFMD1Pad;
+  /** FMD1 Frame */ 
+  Detector fFMD1;
+  /** FMD2 Pad  */
+  TPad*  fFMD2Pad;
+  /** FMD2 Frame */ 
+  Detector fFMD2;
+  /** FMD3 Pad */
+  TPad*  fFMD3Pad;
+  /** FMD3 Frame */ 
+  Detector fFMD3;
+  /** Summary pad */
+  TPad*    fSummary;
+  /** Text fields */
+  TLatex fEvent;
+  TLatex fFMD1IHits;
+  TLatex fFMD2IHits;
+  TLatex fFMD2OHits;
+  TLatex fFMD3IHits;
+  TLatex fFMD3OHits;
+  TLine  fLine;
+  TLatex fTotal;
+  
+  ClassDef(AliFMDFancy,0)
+};
+
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+//   mode: C++
+// End:
+//
+// EOF
+//
index f4c561a..281efaa 100644 (file)
@@ -284,7 +284,13 @@ AliFMDInput::Begin(Int_t event)
     AliInfo("Getting FMD digits");
     if (fFMDLoader->LoadDigits()) return kFALSE;
     fTreeD = fFMDLoader->TreeD();
-    if (!fArrayD) fArrayD = fFMD->Digits();
+    if (fTreeD) {
+      if (!fArrayD) fArrayD = fFMD->Digits();
+    }
+    else {
+      fArrayD = 0;
+      AliWarning(Form("Failed to load FMD Digits"));
+    } 
   }
   // Possibly load FMD Sdigit information 
   if (TESTBIT(fTreeMask, kSDigits)) {
@@ -307,6 +313,7 @@ AliFMDInput::Begin(Int_t event)
     if (read <= 0) return kFALSE;
     fESD = fMainESD->GetFMDData();
     if (!fESD) return kFALSE;
+    fESD->CheckNeedUShort(fChainE->GetFile());
   }
   // Possibly load FMD Digit information 
   if (TESTBIT(fTreeMask, kRaw)) {
@@ -344,7 +351,7 @@ AliFMDInput::Event()
   if (TESTBIT(fTreeMask, kRecPoints)) 
     if (!ProcessRecPoints()) return kFALSE;
   if (TESTBIT(fTreeMask, kESD))
-    if (!ProcessESD(fESD)) return kFALSE;
+    if (!ProcessESDs()) return kFALSE;
   
   return kTRUE;
 }
@@ -462,6 +469,29 @@ AliFMDInput::ProcessRecPoints()
 }
 
 //____________________________________________________________________
+Bool_t 
+AliFMDInput::ProcessESDs()
+{
+  // Process event summary data
+  if (!fESD) return kFALSE;
+  for (UShort_t det = 1; det <= 3; det++) {
+    Char_t rings[] = { 'I', (det == 1 ? '\0' : 'O'), '\0' };
+    for (Char_t* rng = rings; *rng != '\0'; rng++) {
+      UShort_t nsec = (*rng == 'I' ?  20 :  40);
+      UShort_t nstr = (*rng == 'I' ? 512 : 256);
+      for (UShort_t sec = 0; sec < nsec; sec++) {
+       for (UShort_t str = 0; str < nstr; str++) {
+         Float_t eta  = fESD->Eta(det,*rng,sec,str);
+         Float_t mult = fESD->Multiplicity(det,*rng,sec,str);
+         if (!ProcessESD(det, *rng, sec, str, eta, mult)) continue;
+       }
+      }
+    }
+  }
+  return kTRUE;
+}
+
+//____________________________________________________________________
 Bool_t
 AliFMDInput::End()
 {
index 2983b8a..996587a 100644 (file)
@@ -170,30 +170,47 @@ public:
       each reconstructed point. 
       @return @c false on error  */
   virtual Bool_t ProcessRecPoints();
+  /** Loop over all ESD data, and call ProcessESD for each entry.
+      @return  @c false on error  */
+  virtual Bool_t ProcessESDs();
 
   /** Process one hit, and optionally it's corresponding kinematics
       track.  Users should over this to process each hit. 
+      @param h Hit 
+      @param p Associated track
       @return  @c false on error   */
-  virtual Bool_t ProcessHit(AliFMDHit*, TParticle*)  { return kTRUE; }
-  /** Process one digit.  Users should over this to process each digit. 
+  virtual Bool_t ProcessHit(AliFMDHit* h, TParticle* p);
+  /** Process one digit.  Users should over this to process each
+      digit. 
+      @param digit Digit
       @return  @c false on error   */
-  virtual Bool_t ProcessDigit(AliFMDDigit*)          { return kTRUE; }
+  virtual Bool_t ProcessDigit(AliFMDDigit* digit);
   /** Process one summable digit.  Users should over this to process
       each summable digit.  
+      @param sdigit Summable digit
       @return  @c false on error   */
-  virtual Bool_t ProcessSDigit(AliFMDSDigit*)        { return kTRUE; }
+  virtual Bool_t ProcessSDigit(AliFMDSDigit* sdigit);
   /** Process one digit from raw data files.  Users should over this
       to process each raw digit.  
+      @param digit Raw digit
       @return  @c false on error   */
-  virtual Bool_t ProcessRawDigit(AliFMDDigit*)       { return kTRUE; }
+  virtual Bool_t ProcessRawDigit(AliFMDDigit* digit);
   /** Process one reconstructed point.  Users should over this to
       process each reconstructed point.  
+      @param point Reconstructed point 
       @return  @c false on error   */
-  virtual Bool_t ProcessRecPoint(AliFMDRecPoint*)    { return kTRUE; }
+  virtual Bool_t ProcessRecPoint(AliFMDRecPoint* point);
   /** Process ESD data for the FMD.  Users should overload this to
       deal with ESD data. 
+      @param d    Detector number (1-3)
+      @param r    Ring identifier ('I' or 'O')
+      @param s    Sector number (0-19, or 0-39)
+      @param t    Strip number (0-511, or 0-255)
+      @param eta  Psuedo-rapidity 
+      @param mult Psuedo-multiplicity 
       @return  @c false on error  */
-  virtual Bool_t ProcessESD(AliESDFMD*)              { return kTRUE; }
+  virtual Bool_t ProcessESD(UShort_t, Char_t, UShort_t, UShort_t, 
+                           Float_t, Float_t);
   
 protected:
   /** Copy ctor 
@@ -258,6 +275,14 @@ protected:
   ClassDef(AliFMDInput,0)  //Hits for detector FMD
 };
 
+inline Bool_t AliFMDInput::ProcessHit(AliFMDHit*,TParticle*) { return kTRUE; }
+inline Bool_t AliFMDInput::ProcessDigit(AliFMDDigit*) { return kTRUE; }
+inline Bool_t AliFMDInput::ProcessSDigit(AliFMDSDigit*) { return kTRUE; }
+inline Bool_t AliFMDInput::ProcessRawDigit(AliFMDDigit*) { return kTRUE; }
+inline Bool_t AliFMDInput::ProcessRecPoint(AliFMDRecPoint*) { return kTRUE; }
+inline Bool_t AliFMDInput::ProcessESD(UShort_t,Char_t,UShort_t,UShort_t,
+                                     Float_t,Float_t) { return kTRUE; }
+
 
 #endif
 //____________________________________________________________________
index e637a15..e8133a4 100644 (file)
@@ -113,10 +113,11 @@ AliFMDParameters::AliFMDParameters()
 
 //__________________________________________________________________
 void
-AliFMDParameters::Init()
+AliFMDParameters::Init(Bool_t forceReInit)
 {
   // Initialize the parameters manager.  We need to get stuff from the
   // CDB here. 
+  if (forceReInit) fIsInit = kFALSE;
   if (fIsInit) return;
   InitPulseGain();
   InitPedestal();
@@ -130,7 +131,7 @@ AliFMDParameters::Init()
 
 //__________________________________________________________________
 #define DET2IDX(det,ring,sec,str) \
-  (det * 10000 + (ring == 'I' ? 0 : 1000) + str)  
+  (det * 1000 + (ring == 'I' ? 0 : 512) + str)  
   
 //__________________________________________________________________
 void
@@ -188,7 +189,11 @@ AliFMDParameters::Draw(Option_t* option)
       UShort_t nStrip  = (iring == 0 ? 512 : 256);
       Char_t   ring    = (iring == 0 ? 'I' : 'O');
       for (UShort_t str = 0; str < nStrip; str++) {
+       // UShort_t nSec    = (iring == 0 ? 20  : 40);
+       // Char_t   ring    = (iring == 0 ? 'I' : 'O');
+       // for (UShort_t sec = 0; sec < nSec; sec++) {
        Int_t idx = DET2IDX(det, ring, 0, str);
+       // Int_t idx = DET2IDX(det, ring, sec, 0);
        if (skip) {
          xbins[i-1] = idx - .5;
          skip  = kFALSE;
@@ -201,11 +206,13 @@ AliFMDParameters::Draw(Option_t* option)
     }
   }
   TArrayD ybins(41);
-  for (Int_t i = 0; i < 41; i++) ybins[i] = Float_t(i - .5);
+  for (Int_t i = 0; i < ybins.fN; i++) ybins[i] = Float_t(i - .5);
   TH2D* hist = new TH2D("calib", Form("Calibration %s", option), 
                        xbins.fN-1, xbins.fArray,  
                        ybins.fN-1, ybins.fArray);
-
+  hist->GetXaxis()->SetTitle("1000 #times detector + 512 #times ring + strip");
+  hist->GetYaxis()->SetTitle("sector");
+  
   // hist->Draw("Lego");
   // return;
   
@@ -244,6 +251,7 @@ AliFMDParameters::Draw(Option_t* option)
             val = GetMaxStrip(det,ring,sec,str); break;
          }
          hist->Fill(idx,sec,val);
+         // hist->Fill(idx,str,val);
        }
       }
     }
@@ -257,76 +265,164 @@ AliFMDParameters::Print(Option_t* option) const
 {
   // Print information. 
   // If option contains an 'A' then everything is printed. 
+  // If the option contains the string "FMD" the function will search 
+  // for detector, ring, sector, and strip numbers to print, in the
+  // format 
+  // 
+  //    FMD<detector><ring>[<sector>,<string>] 
+  // 
+  // The wild card '*' means all of <detector>, <ring>, <sector>, or 
+  // <strip>. 
   TString opt(option);
-  Bool_t showStrips = opt.Contains("a", TString::kIgnoreCase);
+  Bool_t showStrips  = opt.Contains("a", TString::kIgnoreCase);
+  UShort_t ds[]      = { 1, 2, 3, 0 };
+  Char_t   rs[]      = { 'I', 'O', '\0' };
+  UShort_t minStrip  = 0;
+  UShort_t maxStrip  = 512;
+  UShort_t minSector = 0;
+  UShort_t maxSector = 40;
+  
+  
   if (opt.Contains("fmd",TString::kIgnoreCase)) {
-    size_t   i   = opt.Index("fmd",TString::kIgnoreCase);
-    size_t   j   = opt.Index("]",TString::kIgnoreCase);
-    UShort_t det, sec, str;
-    Char_t ring, lbrack, rbrack, comma;
-    UInt_t ddl, addr;
+    showStrips    = kTRUE;
+    size_t   i    = opt.Index("fmd",TString::kIgnoreCase);
+    size_t   j    = opt.Index("]",TString::kIgnoreCase);
+    enum {
+      read_det, 
+      read_ring, 
+      read_lbrack,
+      read_sector,
+      read_comma,
+      read_strip,
+      read_rbrack, 
+      end
+    } state = read_det;
     std::stringstream s(opt(i+4, j-i-3).Data());
-    s >> det >> ring >> lbrack >> sec >> comma >> str >> rbrack;
-    Detector2Hardware(det, ring, sec, str, ddl, addr);
-    std::cout 
-      << "     Strip    |     Pedestal      |    Gain    | ZS thr. | Address\n"
-      << "--------------+-------------------+------------+---------+---------" 
-      << "\nFMD" << det << ring << "[" << std::setw(2) << sec << "," 
-      << std::setw(3) << str << "] | " 
-      << std::setw(7) << GetPedestal(det, ring, sec, str) 
-      << "+/-" << std::setw(7) 
-      << GetPedestalWidth(det, ring, sec, str) 
-      << " | " << std::setw(10) 
-      << GetPulseGain(det, ring, sec, str) 
-      << " | " << std::setw(7) 
-      << GetZeroSuppression(det, ring, sec, str) 
-      << " | 0x" << std::hex << std::setw(4) 
-      << std::setfill('0') << ddl << ",0x" << std::setw(3) 
-      << addr << std::dec << std::setfill(' ') << std::endl;
-    return;
+    while (state != end) {
+      Char_t tmp = s.peek();
+      if (tmp == ' ' || tmp == '\t') {
+       s.get();
+       continue;
+      }
+      switch (state) {
+      case read_det: { // First, try to read the detector 
+       if (tmp == '*') s.get();
+       else { 
+         UShort_t det;
+         s >> det;
+         if (!s.bad()) {
+           ds[0] = det;
+           ds[1] = 0;
+         }
+       }
+       state = (s.bad() ? end : read_ring);
+      } break;
+      case read_ring: { // Then try to read the ring;
+       Char_t ring;
+       s >> ring;
+       if (ring != '*' && !s.bad()) {
+         rs[0] = ring;
+         rs[1] = '\0';
+       }
+       state = (s.bad() ? end : read_lbrack);
+      } break;
+      case read_lbrack: { // Try to read a left bracket 
+       Char_t lbrack;
+       s >> lbrack;
+       state = (s.bad() ? end : read_sector);
+      } break;
+      case read_sector: { // Try to read a sector 
+       if (tmp == '*') s.get();
+       else {
+         UShort_t sec;
+         s >> sec;
+         if (!s.bad()) {
+           minSector = sec;
+           maxSector = sec + 1;
+         }
+       }
+       state = (s.bad() ? end : read_comma);
+      } break;
+      case read_comma: { // Try to read a left bracket 
+       Char_t comma;
+       s >> comma;
+       state = (s.bad() ? end : read_strip);
+      } break;
+      case read_strip: { // Try to read a strip 
+       if (tmp == '*') s.get();
+       else {
+         UShort_t str;
+         s >> str;
+         if (!s.bad()) {
+           minStrip = str;
+           maxStrip = str + 1;
+         }
+       }
+       state = (s.bad() ? end : read_rbrack);
+      } break;
+      case read_rbrack: { // Try to read a left bracket 
+       Char_t rbrack;
+       s >> rbrack;
+       state = end;
+      } break;
+      case end: 
+       break;
+      }
+    }
   }
-  for (UShort_t det=1 ; det <= 3; det++) {
-    std::cout << "FMD" << det << std::endl;
-    Char_t rings[] = { 'I', (det == 1 ? '\0' : 'O'), '\0' };
-    for (Char_t* ring = rings; *ring != '\0'; ring++) {
-      std::cout << " Ring " << *ring << std::endl;
-      UShort_t nSec = ( *ring == 'I' ? 20  :  40 );
-      UShort_t nStr = ( *ring == 'I' ? 512 : 256 );
-      for (UShort_t sec = 0; sec < nSec; sec++) {
-       UShort_t min  = GetMinStrip(det, *ring, sec, 0);
-       UShort_t max  = GetMaxStrip(det, *ring, sec, 0);
-       UShort_t rate = GetSampleRate(det, *ring, sec, 0);
-       std::cout << "  Sector " << std::setw(2) << sec 
-                 << "  Strip range: " << std::setw(3) << min << "," 
-                 << std::setw(3) << max << "  Rate: " << std::setw(2) 
-                 << rate << std::endl;
-       if (!showStrips) continue;
+  UShort_t* dp = ds;
+  UShort_t  det;
+  while ((det = *(dp++))) {
+
+    Char_t* rp = rs;
+    Char_t  ring;
+    while ((ring = *(rp++))) {
+      if (det == 1 && ring == 'O') continue;
+      UShort_t min  = GetMinStrip(det, ring, 0, 0);
+      UShort_t max  = GetMaxStrip(det, ring, 0, 0);
+      UShort_t rate = GetSampleRate(det, ring, 0, 0);
+      std::cout << "FMD" << det << ring 
+               << "  Strip range: " 
+               << std::setw(3) << min << "," 
+               << std::setw(3) << max << "  Rate: " 
+               << std::setw(2) << rate << std::endl;
+
+      if (!showStrips) continue;
+      UShort_t nSec = ( ring == 'I' ? 20  :  40 );
+      UShort_t nStr = ( ring == 'I' ? 512 : 256 );
+      for (UShort_t sec = minSector; sec < maxSector && sec < nSec; sec++) {
        std::cout 
          << "  Strip |     Pedestal      |    Gain    | ZS thr. | Address\n" 
          << "--------+-------------------+------------+---------+---------" 
          << std::endl;
-        for (UShort_t str = 0; str < nStr; str++) {
-         std::cout << "    " << std::setw(3) << str << " | ";
-         if (IsDead(det, *ring, sec, str)) {
+        for (UShort_t str = minStrip; str < nStr && str < maxStrip; str++) {
+         if (str == minStrip) std::cout << std::setw(3) << sec << ",";
+         else std::cout << "    ";
+         std::cout << std::setw(3) << str << " | ";
+         if (IsDead(det, ring, sec, str)) {
            std::cout << "dead" << std::endl;
            continue;
          }
          UInt_t ddl, addr;
-         Detector2Hardware(det, *ring, sec, str, ddl, addr);
-         std::cout << std::setw(7) << GetPedestal(det, *ring, sec, str) 
+         Detector2Hardware(det, ring, sec, str, ddl, addr);
+         std::cout << std::setw(7) << GetPedestal(det, ring, sec, str) 
                    << "+/-" << std::setw(7) 
-                   << GetPedestalWidth(det, *ring, sec, str) 
+                   << GetPedestalWidth(det, ring, sec, str) 
                    << " | " << std::setw(10) 
-                   << GetPulseGain(det, *ring, sec, str) 
-                   << " | " << std::setw(5) 
-                   << GetZeroSuppression(det, *ring, sec, str) 
+                   << GetPulseGain(det, ring, sec, str) 
+                   << " | " << std::setw(7) 
+                   << GetZeroSuppression(det, ring, sec, str) 
                    << " | 0x" << std::hex << std::setw(4) 
                    << std::setfill('0') << ddl << ",0x" << std::setw(3) 
                    << addr << std::dec << std::setfill(' ') << std::endl;
-        }
-      }
-    }
-  }
+        } // for (strip)
+      } // for (sector)
+      std::cout
+       << "=============================================================" 
+       << std::endl;
+    } // while (ring)
+  } // while (det)
+  
 }
 
 //__________________________________________________________________
index 26898a8..21ed1f5 100644 (file)
@@ -82,7 +82,7 @@ public:
   /** Initialize the manager.  This tries to read the parameters from
       CDB.  If that fails, the class uses the hard-coded parameters. 
    */
-  void Init();
+  void Init(Bool_t forceReInit=kFALSE);
   /** Print all parameters. 
       @param option Option string */
   void Print(Option_t* option="A") const;
diff --git a/FMD/AliFMDPattern.cxx b/FMD/AliFMDPattern.cxx
new file mode 100644 (file)
index 0000000..c5a7afd
--- /dev/null
@@ -0,0 +1,373 @@
+/**************************************************************************
+ * 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$ */
+/** @file    AliFMDPattern.cxx
+    @author  Christian Holm Christensen <cholm@nbi.dk>
+    @date    Mon Mar 27 12:39:09 2006
+    @brief   FMD 2D Event display 
+*/
+//___________________________________________________________________
+//
+// The classes defined here, are utility classes for reading in data
+// for the FMD.  They are  put in a seperate library to not polute the
+// normal libraries.  The classes are intended to be used as base
+// classes for customized class that do some sort of analysis on the
+// various types of data produced by the FMD. 
+//
+// Latest changes by Christian Holm Christensen
+//
+#include "AliFMDPattern.h"     // ALIFMDDISPLAY_H
+#include "AliFMDGeometry.h"    // ALIFMDGEOMETRY_H
+#include "AliFMDParameters.h"  // ALIFMDPARAMETERS_H
+#include "AliFMDRing.h"
+#include "AliFMDDetector.h"
+#include "AliFMDHit.h"
+#include <AliLog.h>
+#include <TStyle.h>
+#include <TApplication.h>
+#include <TButton.h>
+#include <TCanvas.h>
+#include <TView.h>
+#include <TH2F.h>
+#include <TSystem.h>
+#include <TVector2.h>
+#include <TRandom.h>
+#include <TSlider.h>
+#include <TPad.h>
+#include <iostream>
+
+//____________________________________________________________________
+ClassImp(AliFMDPattern)
+#if 0
+  ; // This is here to keep Emacs for indenting the next line
+#endif
+
+//____________________________________________________________________
+AliFMDPattern::Detector::Detector(UShort_t id) 
+  : fId(id),
+    fCounts(0), 
+    fGraphs(0), 
+    fFrame(0)
+{}
+
+//____________________________________________________________________
+AliFMDPattern::Detector::~Detector()
+{
+  if (fFrame) delete fFrame;
+}
+
+//____________________________________________________________________
+void
+AliFMDPattern::Detector::DrawShape(TObjArray& a) 
+{
+  TIter next(&a);
+  TGraph* g = 0;
+  while ((g = static_cast<TGraph*>(next()))) {
+    g->DrawClone("f same");
+    g->DrawClone("l same");
+  }
+}
+
+//____________________________________________________________________
+void
+AliFMDPattern::Detector::Begin(Int_t nlevel, Double_t r, 
+                              TObjArray& inners, TObjArray& outers)
+{
+  fCounts.Set(nlevel);
+  if (!fFrame) {
+    fFrame = new TH2F(Form("fmd%dFrame", fId), Form("FMD%d", fId), 
+                     10, -r, r, 10, -r, r);
+    fFrame->SetStats(kFALSE);
+    fFrame->Draw();
+  }
+  DrawShape(inners);
+  if (fId != 1) DrawShape(outers);
+  for (Int_t i = 0; i < nlevel; i++) { 
+    TGraph* g = new TGraph;
+    Int_t idx = Int_t(Float_t(i) / nlevel * gStyle->GetNumberOfColors());
+    Int_t col = gStyle->GetColorPalette(idx);
+    g->SetName(Form("FMD%d_L%02d", fId, i));
+    g->SetMarkerColor(col);
+    g->SetLineColor(col);
+    g->SetFillColor(col);
+    g->SetMarkerSize(i * .2 + .2);
+    g->SetMarkerStyle(2);
+    g->Draw("same p");
+    fGraphs.AddAtAndExpand(g, i);
+  }
+  TIter   next(&fGraphs);
+}
+
+//____________________________________________________________________
+void
+AliFMDPattern::Detector::Clear() 
+{
+  fCounts.Reset(0);
+}
+
+//____________________________________________________________________
+void
+AliFMDPattern::Detector::End()
+{
+  TIter   next(&fGraphs);
+  TGraph* g = 0;
+  Int_t   i = 0;
+  while ((g = static_cast<TGraph*>(next()))) g->Set(fCounts[i++]);
+}
+//____________________________________________________________________
+void
+AliFMDPattern::Detector::AddMarker(Double_t x, Double_t y, Float_t s, 
+                                  Float_t max)
+{
+  Int_t i = TMath::Min(Int_t(fCounts.fN * s / max), 
+                      Int_t(fGraphs.GetEntries()-1));
+  TGraph* g = static_cast<TGraph*>(fGraphs.At(i));
+  if (!g) return;
+  g->SetPoint(fCounts[i]++, x, y);
+}
+
+
+//____________________________________________________________________
+AliFMDPattern::AliFMDPattern(const char* gAliceFile)
+  : AliFMDDisplay(kTRUE, gAliceFile),
+    fInnerMax(0), 
+    fOuterMax(0),
+    fFMD1Pad(0),
+    fFMD1(1),
+    fFMD2Pad(0),
+    fFMD2(2),
+    fFMD3Pad(0),
+    fFMD3(3),
+    fEvent(.1, .8, "Event #"),
+    fFMD1Sum(.2, .7, "# in FMD1: "),
+    fFMD2Sum(.2, .6, "# in FMD2: "),
+    fFMD3Sum(.2, .5, "# in FMD3: "),
+    fLine(.15, .47, .85, .47),
+    fTotal(.2, .35, "Total:   ")
+{
+  // RemoveLoad(kGeometry);
+  fEvent.SetBit(TLatex::kTextNDC);
+  fFMD1Sum.SetBit(TLatex::kTextNDC);
+  fFMD2Sum.SetBit(TLatex::kTextNDC);
+  fFMD3Sum.SetBit(TLatex::kTextNDC);
+  fLine.SetBit(TLine::kLineNDC);
+  fTotal.SetBit(TLatex::kTextNDC);
+}
+
+//____________________________________________________________________
+AliFMDPattern::~AliFMDPattern()
+{
+  fInners.Delete();
+  fOuters.Delete();
+}
+
+    
+//____________________________________________________________________
+Bool_t 
+AliFMDPattern::Init()
+{
+  // Initialize.  GEt transforms and such, 
+  if (!AliFMDInput::Init()) return kFALSE;
+  AliFMDGeometry* geom = AliFMDGeometry::Instance();
+  geom->Init();
+  geom->InitTransformations();
+  
+  Char_t rs[] = { 'I' , 'O', '\0' };
+  Char_t *r   = rs;
+  do {
+    AliFMDRing* ring = geom->GetRing(*r);
+    if (!ring) continue;
+    const TObjArray& vs = ring->GetVerticies();
+    TObjArray&       gs = (*r == 'I' ? fInners   : fOuters);
+    Float_t&         mr = (*r == 'I' ? fInnerMax : fOuterMax);
+    Int_t            nm = ring->GetNModules();
+    AliInfo(Form("Making %d modules for %c", nm, *r));
+    for (Int_t m = 0; m < nm; m++) {
+      Int_t          nv = vs.GetEntries();
+      Double_t       a  = TMath::Pi() / 180 * (m * 2 + 1) * ring->GetTheta();
+      TGraph*        g  = new TGraph(nv+1);
+      Double_t       x0 = 0, y0 = 0;
+      gs.AddAtAndExpand(g, m);
+      for (Int_t c = 0; c < nv; c++) {
+       TVector2* v = static_cast<TVector2*>(vs.At(c));
+       mr          = TMath::Max(mr, Float_t(v->Mod()));
+       TVector2  w(v->Rotate(a));
+       if (c == 0) { x0 = w.X(); y0 = w.Y(); }
+       g->SetPoint(c, w.X(), w.Y());
+      }
+      g->SetName(Form("FMDX%c_%02d", *r, m));
+      g->SetPoint(nv, x0, y0);
+      g->SetFillColor((*rs == 'I' ? 
+                      (m % 2 == 0 ? 18 : 17) :
+                      (m % 2 == 0 ? 20 : 23)));
+      g->SetFillStyle(3001);
+      g->SetLineColor(1);
+      g->SetLineWidth(1);
+      g->SetLineStyle(2);
+    }
+  } while (*(++r));
+    
+  return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t 
+AliFMDPattern::Begin(Int_t event) 
+{
+  if (!fCanvas) {
+    const char* which[] = { "Continue", "Redisplay", 0 };
+    MakeCanvas(which);
+    MakeAux();
+    
+    AliFMDGeometry* geom = AliFMDGeometry::Instance();
+    AliFMDDetector* det;
+    if ((det = geom->GetDetector(1))) {
+      fPad->cd();
+      fFMD1Pad = new TPad("FMD1", "FMD1", 0.0, 0.50, 0.5, 1.0, 0, 0);
+      fFMD1Pad->Draw();
+      fFMD1Pad->cd();
+      fFMD1.Begin(10, fInnerMax, fInners, fOuters);
+    }
+    if ((det = geom->GetDetector(2))) {
+      fPad->cd();
+      fFMD2Pad = new TPad("FMD2", "FMD2", 0.5, 0.50, 1.0, 1.0, 0, 0);
+      fFMD2Pad->Draw();
+      fFMD2Pad->cd();
+      fFMD2.Begin(10, fOuterMax, fInners, fOuters);
+    }
+    if ((det = geom->GetDetector(3))) {
+      fPad->cd();
+      fFMD3Pad = new TPad("FMD3", "FMD3", 0.0, 0.0, .5, .5, 0, 0);
+      fFMD3Pad->Draw();
+      fFMD3Pad->cd();
+      fFMD3.Begin(10, fOuterMax, fInners, fOuters);
+    }
+    fPad->cd();
+    fSummary = new TPad("display", "Display", 0.5, 0.0, 1.0, 0.5, 0, 0);
+    fSummary->Draw();
+    fSummary->cd();
+    fEvent.Draw();
+    fFMD1Sum.Draw();
+    fFMD2Sum.Draw();
+    fFMD3Sum.Draw();
+    fLine.Draw();
+    fTotal.Draw();
+  }
+  fEvent.SetTitle(Form("Event # %6d", event));
+
+  fCanvas->Modified();
+  fCanvas->Update();
+  fCanvas->cd();
+  fFMD1.Clear();
+  fFMD2.Clear();
+  fFMD3.Clear();
+  return AliFMDInput::Begin(event);
+}
+
+//____________________________________________________________________
+void
+AliFMDPattern::Redisplay()
+{
+  fFMD1.Clear();
+  fFMD2.Clear();
+  fFMD3.Clear();
+  AliFMDDisplay::Redisplay();
+}
+
+//____________________________________________________________________
+void
+AliFMDPattern::AtEnd()
+{
+  DrawAux();
+  
+  Int_t total = 0;
+  
+  fFMD1.End();
+  fFMD1Pad->Modified();
+  fFMD1Sum.SetTitle(Form("# hits in FMD1: %5d", fFMD1.Total()));
+  total += fFMD1.Total();
+
+  fFMD2.End();
+  fFMD2Pad->Modified();
+  fFMD2Sum.SetTitle(Form("# hits in FMD2: %5d", fFMD2.Total()));
+  total += fFMD2.Total();
+
+  fFMD3.End();
+  fFMD3Pad->Modified();
+  fFMD3Sum.SetTitle(Form("# hits in FMD3: %5d", fFMD3.Total()));
+  total += fFMD3.Total();
+
+  fTotal.SetTitle(Form("Total:    %5d/51200 (%3d%%)", 
+                     total, Int_t(100. / 51200 * total)));
+  fSummary->Modified();
+  fCanvas->Modified();
+  fCanvas->Update();
+  fCanvas->cd();
+}
+
+//____________________________________________________________________
+Bool_t 
+AliFMDPattern::ProcessHit(AliFMDHit* hit, TParticle*) 
+{
+  switch (hit->Detector()) {
+  case 1: fFMD1.AddMarker(hit->X(), hit->Y(), hit->Edep(), 1); break;
+  case 2: fFMD2.AddMarker(hit->X(), hit->Y(), hit->Edep(), 1); break;
+  case 3: fFMD3.AddMarker(hit->X(), hit->Y(), hit->Edep(), 1); break;
+  }
+  return kTRUE;
+}
+
+
+//____________________________________________________________________
+void
+AliFMDPattern::AddMarker(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
+                        TObject*, Float_t s, Float_t max)
+{
+  // Add a marker to the display
+  //
+  //    det    Detector
+  //    rng    Ring
+  //    sec    Sector 
+  //    str    Strip
+  //    o      Object to refer to
+  //    s      Signal 
+  //    max    Maximum of signal 
+  //
+  Detector* d = 0;
+  switch (det) {
+  case 1: d = &fFMD1; break;
+  case 2: d = &fFMD2; break;
+  case 3: d = &fFMD3; break;
+  }
+  if (!d) return;
+  AliFMDGeometry*   geom = AliFMDGeometry::Instance();
+  Double_t x, y, z;
+  geom->Detector2XYZ(det, rng, sec, str, x, y, z);
+  if (true) {
+    AliFMDRing* r  = geom->GetRing(rng);
+    Double_t    t  = .9 * r->GetTheta() / 2;
+    Double_t    a  = gRandom->Uniform(-t,t) * TMath::Pi() / 180;
+    Double_t    x1 = x * TMath::Cos(a) - y * TMath::Sin(a);
+    Double_t    y1 = x * TMath::Sin(a) + y * TMath::Cos(a);
+    x = x1;
+    y = y1;
+  }
+  d->AddMarker(x, y, s, max);
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
diff --git a/FMD/AliFMDPattern.h b/FMD/AliFMDPattern.h
new file mode 100644 (file)
index 0000000..d94f6a9
--- /dev/null
@@ -0,0 +1,125 @@
+#ifndef AliFMDPATTERN_H
+#define AliFMDPATTERN_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+ * reserved. 
+ *
+ * See cxx source for full Copyright notice                               
+ */
+/** @file    AliFMDPattern.h
+    @author  Christian Holm Christensen <cholm@nbi.dk>
+    @date    Mon Mar 27 12:39:09 2006
+    @brief   FMD Event display (as patterns)
+*/
+//___________________________________________________________________
+//
+// The classes defined here, are utility classes for reading in data
+// for the FMD.  They are  put in a seperate library to not polute the
+// normal libraries.  The classes are intended to be used as base
+// classes for customized class that do some sort of analysis on the
+// various types of data produced by the FMD. 
+//
+#include "AliFMDDisplay.h"
+#include <TObjArray.h>
+#include <TGraph.h>
+#include <TLatex.h>
+#include <TLine.h>
+class TCanvas;
+class TPad;
+class TH2;
+
+
+//___________________________________________________________________
+/** @class AliFMDPattern 
+    @brief Utility class to visualize FMD data in 2D. 
+    @ingroup FMD_util
+ */
+class AliFMDPattern : public AliFMDDisplay
+{
+public:
+  struct Detector 
+  {
+    Detector(UShort_t id);
+    ~Detector();
+    void  Clear();
+    Int_t Total() const { return Int_t(fCounts.GetSum()); }
+    void  End();
+    void  Begin(Int_t nlvl, Double_t r, TObjArray& inners, TObjArray& outers);
+    void  DrawShape(TObjArray& a);
+    void  AddMarker(Double_t x, Double_t y, Float_t s, Float_t max);
+    Int_t     fId;
+    TArrayI   fCounts;
+    TObjArray fGraphs;
+    TH2*      fFrame;
+  };
+  
+  
+  /** Constructor
+      @param gAliceFile galice file*/
+  AliFMDPattern(const char* gAliceFile="galice.root");
+  /** DTOR */
+  virtual ~AliFMDPattern();
+
+  /** Initialize
+      @return  @c false on error */
+  virtual Bool_t Init();
+  /** Called at beginning of an event 
+      @param event Event number
+      @return @c false on error  */
+  virtual Bool_t Begin(Int_t event);
+ protected:
+  /** Add a marker to the display
+      @param det Detector
+      @param rng Ring
+      @param sec Sector 
+      @param str Strip
+      @param o   Object to refer to
+      @param s   Signal 
+      @param max Maximum of signal */
+  virtual void AddMarker(UShort_t det, Char_t rng, UShort_t sec, UShort_t str, 
+                        TObject* o, Float_t s, Float_t max);
+  virtual Bool_t ProcessHit(AliFMDHit* hit, TParticle*);
+  virtual void Redisplay();
+  virtual void AtEnd();
+  /** Graph to show shape of inner sensor */
+  TObjArray fInners;
+  /** Graph to show shape of outer sensor */
+  TObjArray fOuters;
+  /** Max inner radius */
+  Float_t fInnerMax;
+  /** Max outer radius */
+  Float_t fOuterMax;
+  /** FMD1 Pad */
+  TPad*  fFMD1Pad;
+  /** FMD1 Frame */ 
+  Detector fFMD1;
+  /** FMD2 Pad  */
+  TPad*  fFMD2Pad;
+  /** FMD2 Frame */ 
+  Detector fFMD2;
+  /** FMD3 Pad */
+  TPad*  fFMD3Pad;
+  /** FMD3 Frame */ 
+  Detector fFMD3;
+  /** Summary pad */
+  TPad* fSummary;
+  /** Text fields */
+  TLatex fEvent;
+  TLatex fFMD1Sum;
+  TLatex fFMD2Sum;
+  TLatex fFMD3Sum;
+  TLine  fLine;
+  TLatex fTotal;
+
+  ClassDef(AliFMDPattern,0)
+};
+
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+//   mode: C++
+// End:
+//
+// EOF
+//
index 987e819..3029905 100644 (file)
@@ -64,6 +64,8 @@ AliFMDReconstructor::AliFMDReconstructor()
     fESD(0x0)
 {
   // Make a new FMD reconstructor object - default CTOR.  
+  SetNoiseFactor();
+  SetAngleCorrect();
 }
   
 
@@ -75,7 +77,9 @@ AliFMDReconstructor::AliFMDReconstructor(const AliFMDReconstructor& other)
     fTreeR(other.fTreeR),
     fCurrentVertex(other.fCurrentVertex),
     fESDObj(other.fESDObj),
-    fESD(other.fESD)
+    fESD(other.fESD), 
+    fNoiseFactor(other.fNoiseFactor),
+    fAngleCorrect(other.fAngleCorrect)
 {
   // Copy constructor 
 }
@@ -86,12 +90,15 @@ AliFMDReconstructor&
 AliFMDReconstructor::operator=(const AliFMDReconstructor& other) 
 {
   // Assignment operator
-  fMult   = other.fMult;
-  fNMult = other.fNMult;
-  fTreeR = other.fTreeR;
+  fMult          = other.fMult;
+  fNMult         = other.fNMult;
+  fTreeR         = other.fTreeR;
   fCurrentVertex = other.fCurrentVertex;
-  fESDObj = other.fESDObj;
-  fESD = other.fESD;
+  fESDObj        = other.fESDObj;
+  fESD           = other.fESD;
+  fNoiseFactor   = other.fNoiseFactor;
+  fAngleCorrect  = other.fAngleCorrect;
+   
   return *this;
 }
 
@@ -223,6 +230,8 @@ AliFMDReconstructor::ProcessDigits(TClonesArray* digits) const
   // used. 
   Int_t nDigits = digits->GetEntries();
   AliDebug(1, Form("Got %d digits", nDigits));
+  fESDObj->SetNoiseFactor(fNoiseFactor);
+  fESDObj->SetAngleCorrected(fAngleCorrect);
   for (Int_t i = 0; i < nDigits; i++) {
     AliFMDDigit* digit = static_cast<AliFMDDigit*>(digits->At(i));
     AliFMDParameters* param  = AliFMDParameters::Instance();
@@ -282,16 +291,21 @@ AliFMDReconstructor::SubtractPedestal(AliFMDDigit* digit) const
 
   Int_t             counts = 0;
   AliFMDParameters* param  = AliFMDParameters::Instance();
-  Float_t           pedM   = param->GetPedestal(digit->Detector(), 
+  Float_t           ped    = param->GetPedestal(digit->Detector(), 
                                                digit->Ring(), 
                                                digit->Sector(), 
                                                digit->Strip());
+  Float_t           noise  = param->GetPedestalWidth(digit->Detector(), 
+                                                    digit->Ring(), 
+                                                    digit->Sector(), 
+                                                    digit->Strip());
   AliDebug(15, Form("Subtracting pedestal %f from signal %d", 
-                  pedM, digit->Counts()));
+                  ped, digit->Counts()));
   if (digit->Count3() > 0)      counts = digit->Count3();
   else if (digit->Count2() > 0) counts = digit->Count2();
   else                          counts = digit->Count1();
-  counts = TMath::Max(Int_t(counts - pedM), 0);
+  counts = TMath::Max(Int_t(counts - ped), 0);
+  if (counts < noise * fNoiseFactor) counts = 0;
   if (counts > 0) AliDebug(15, "Got a hit strip");
   
   return  UShort_t(counts);
@@ -300,7 +314,7 @@ AliFMDReconstructor::SubtractPedestal(AliFMDDigit* digit) const
 //____________________________________________________________________
 Float_t
 AliFMDReconstructor::Adc2Energy(AliFMDDigit* digit, 
-                               Float_t      /* eta */, 
+                               Float_t      eta, 
                                UShort_t     count) const
 {
   // Converts number of ADC counts to energy deposited. 
@@ -320,16 +334,20 @@ AliFMDReconstructor::Adc2Energy(AliFMDDigit* digit,
   // 
   // is constant and the same for all strips.
 
-  // Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
-  // Double_t edep  = TMath::Abs(TMath::Cos(theta)) * fGain * count;
+  if (count <= 0) return 0;
   AliFMDParameters* param = AliFMDParameters::Instance();
   Float_t           gain  = param->GetPulseGain(digit->Detector(), 
                                                digit->Ring(), 
                                                digit->Sector(), 
                                                digit->Strip());
-  Double_t          edep  = count * gain;
   AliDebug(15, Form("Converting counts %d to energy via factor %f", 
                    count, gain));
+
+  Double_t edep  = count * gain;
+  if (fAngleCorrect) {
+    Double_t theta =  2 * TMath::ATan(TMath::Exp(-eta));
+    edep           *= TMath::Abs(TMath::Cos(theta));
+  }
   return edep;
 }
 
index 22b3b1e..3108abc 100644 (file)
@@ -93,7 +93,12 @@ public:
                         AliESD* esd) const;
   /** Not used */
   virtual void   SetESD(AliESD* esd) { fESD = esd; }
-     
+  /** Set the noise factor 
+      @param f Factor to use */
+  virtual void SetNoiseFactor(Float_t f=3) { fNoiseFactor = f; }
+  /** Set whether we should do angle correction or nor 
+      @param use If true, do angle correction */
+  virtual void SetAngleCorrect(Bool_t use=kTRUE) { fAngleCorrect = use; }
 protected:
   /** Copy CTOR 
       @param other Object to copy from. */
@@ -153,6 +158,8 @@ protected:
   mutable TTree*        fTreeR;         // Output tree 
   mutable Float_t       fCurrentVertex; // Z-coordinate of primary vertex
   mutable AliESDFMD*    fESDObj;        // ESD output object
+  mutable Float_t       fNoiseFactor;   // Factor of noise to check
+  mutable Bool_t        fAngleCorrect;  // Whether to angle correct
   AliESD*               fESD;           // ESD object(?)
   
 private:
diff --git a/FMD/Calib/AltroMap/Run0_0_v0_s1.root b/FMD/Calib/AltroMap/Run0_0_v0_s1.root
new file mode 100644 (file)
index 0000000..9eb38bd
Binary files /dev/null and b/FMD/Calib/AltroMap/Run0_0_v0_s1.root differ
diff --git a/FMD/Calib/Dead/Run0_0_v0_s1.root b/FMD/Calib/Dead/Run0_0_v0_s1.root
new file mode 100644 (file)
index 0000000..f83b334
Binary files /dev/null and b/FMD/Calib/Dead/Run0_0_v0_s1.root differ
diff --git a/FMD/Calib/Pedestal/Run0_0_v0_s1.root b/FMD/Calib/Pedestal/Run0_0_v0_s1.root
new file mode 100644 (file)
index 0000000..f59be14
Binary files /dev/null and b/FMD/Calib/Pedestal/Run0_0_v0_s1.root differ
diff --git a/FMD/Calib/PulseGain/Run0_0_v0_s1.root b/FMD/Calib/PulseGain/Run0_0_v0_s1.root
new file mode 100644 (file)
index 0000000..ea93617
Binary files /dev/null and b/FMD/Calib/PulseGain/Run0_0_v0_s1.root differ
diff --git a/FMD/Calib/SampleRate/Run0_0_v0_s1.root b/FMD/Calib/SampleRate/Run0_0_v0_s1.root
new file mode 100644 (file)
index 0000000..b58a5bd
Binary files /dev/null and b/FMD/Calib/SampleRate/Run0_0_v0_s1.root differ
diff --git a/FMD/Calib/StripRange/Run0_0_v0_s1.root b/FMD/Calib/StripRange/Run0_0_v0_s1.root
new file mode 100644 (file)
index 0000000..a1d6a04
Binary files /dev/null and b/FMD/Calib/StripRange/Run0_0_v0_s1.root differ
diff --git a/FMD/Calib/ZeroSuppression/Run0_0_v0_s1.root b/FMD/Calib/ZeroSuppression/Run0_0_v0_s1.root
new file mode 100644 (file)
index 0000000..0235731
Binary files /dev/null and b/FMD/Calib/ZeroSuppression/Run0_0_v0_s1.root differ
index 2b9967a..1a14ec4 100644 (file)
@@ -21,6 +21,8 @@
 // #pragma link C++ typedef  AliFMDEdepMap;
 #pragma link C++ class  AliFMDInput;
 #pragma link C++ class  AliFMDDisplay;
+#pragma link C++ class  AliFMDPattern;
+#pragma link C++ class  AliFMDFancy;
 #pragma link C++ class  AliFMDCalibFaker;
 #pragma link C++ class  AliFMDAlignFaker;
 
index bdf9b78..20312f2 100644 (file)
@@ -4,6 +4,8 @@
 
 SRCS           =  AliFMDInput.cxx              \
                   AliFMDDisplay.cxx            \
+                  AliFMDPattern.cxx            \
+                  AliFMDFancy.cxx              \
                   AliFMDCalibFaker.cxx         \
                   AliFMDAlignFaker.cxx         
 HDRS           =  $(SRCS:.cxx=.h) 
index 0ce263b..6c9d43e 100644 (file)
@@ -22,6 +22,7 @@ Compile(const char* script, Option_t* option="g")
 {
   gSystem->Load("libFMDutil.so");
   gSystem->SetIncludePath("-I`root-config --incdir` "
+                         "-I${ALICE_ROOT} " 
                          "-I${ALICE_ROOT}/include " 
                          "-I${ALICE_ROOT}/FMD "
                          "-I${ALICE_ROOT}/geant3/TGeant3");
index b053cfe..a2b6d9f 100644 (file)
@@ -17,8 +17,9 @@
 #include <AliFMDInput.h>
 #include <AliFMDUShortMap.h>
 #include <AliFMDFloatMap.h>
-#include <AliFMDMultStrip.h>
-#include <AliFMDMultRegion.h>
+#include <AliFMDRecPoint.h>
+#include <AliESDFMD.h>
+#include <AliLog.h>
 #include <iostream>
 #include <TStyle.h>
 #include <TArrayF.h>
@@ -71,7 +72,7 @@ public:
   Bool_t Begin(Int_t ev) 
   {
     fMap.Reset();
-    return AliFMDInputDigits::Begin(ev);
+    return AliFMDInput::Begin(ev);
   }
   //__________________________________________________________________
   Bool_t ProcessDigit(AliFMDDigit* digit) 
@@ -92,14 +93,14 @@ public:
   //__________________________________________________________________
   Bool_t ProcessRecPoint(AliFMDRecPoint* single)
   {
-    if (!single) continue;
+    if (!single) return kFALSE;
     UShort_t det = single->Detector();
     Char_t   rng = single->Ring();
     UShort_t sec = single->Sector();
     UShort_t str = single->Strip();
     if (str > 511) {
       AliWarning(Form("Bad strip number %d in single", str));
-      continue;
+      return kFALSE;
     }
     fAdcVsSingle->Fill(fMap(det, rng, sec, str), single->Particles());
     return kTRUE;
index af07e62..98e3a39 100644 (file)
@@ -18,6 +18,8 @@
 #include <TStyle.h>
 #include <TArrayF.h>
 #include <TParticle.h>
+#include <TCanvas.h>
+#include <TGraphErrors.h>
 
 /** @class DrawHits
     @brief Draw hit energy loss
@@ -102,6 +104,9 @@ public:
   //__________________________________________________________________
   Bool_t Finish()
   {
+    TCanvas* c = new TCanvas("c", "C");
+    c->SetLogy();
+    c->SetLogx();
     gStyle->SetPalette(1);
     gStyle->SetOptTitle(0);
     gStyle->SetCanvasColor(0);
@@ -110,8 +115,209 @@ public:
     gStyle->SetPadBorderSize(0);
     fElossVsPMQ->SetStats(kFALSE);
     fElossVsPMQ->Draw("COLZ box");
+    c->Modified();
+    c->Update();
+    c->cd();
     return kTRUE;
   }
+  void SuperImposeBetheBloc() 
+  {
+    // This is for pi+, made with MakeXsection.C and DrawXsection.C
+    TGraphErrors *gre = new TGraphErrors(91);
+    gre->SetName("BetheBlocPi");
+    gre->SetTitle("BetheBlocPi");
+    gre->SetFillColor(6);
+    gre->SetFillStyle(3001);
+    gre->SetLineWidth(2);
+    gre->SetPoint(0,7.16486e-05,1218.84);
+    gre->SetPointError(0,0,609.418);
+    gre->SetPoint(1,9.25378e-05,1221.38);
+    gre->SetPointError(1,0,610.689);
+    gre->SetPoint(2,0.000119517,1180.12);
+    gre->SetPointError(2,0,590.058);
+    gre->SetPoint(3,0.000154362,1100.31);
+    gre->SetPointError(3,0,550.156);
+    gre->SetPoint(4,0.000199367,996.621);
+    gre->SetPointError(4,0,498.31);
+    gre->SetPoint(5,0.000257492,886.005);
+    gre->SetPointError(5,0,443.003);
+    gre->SetPoint(6,0.000332563,780.483);
+    gre->SetPointError(6,0,390.241);
+    gre->SetPoint(7,0.000429522,684.927);
+    gre->SetPointError(7,0,342.463);
+    gre->SetPoint(8,0.000554749,599.407);
+    gre->SetPointError(8,0,299.703);
+    gre->SetPoint(9,0.000716486,522.375);
+    gre->SetPointError(9,0,261.187);
+    gre->SetPoint(10,0.000925378,452.497);
+    gre->SetPointError(10,0,226.249);
+    gre->SetPoint(11,0.00119517,389.101);
+    gre->SetPointError(11,0,194.551);
+    gre->SetPoint(12,0.00154362,331.974);
+    gre->SetPointError(12,0,165.987);
+    gre->SetPoint(13,0.00199367,280.969);
+    gre->SetPointError(13,0,140.485);
+    gre->SetPoint(14,0.00257492,235.689);
+    gre->SetPointError(14,0,117.844);
+    gre->SetPoint(15,0.00332564,196.156);
+    gre->SetPointError(15,0,98.078);
+    gre->SetPoint(16,0.00429522,162.402);
+    gre->SetPointError(16,0,81.2012);
+    gre->SetPoint(17,0.00554749,133.87);
+    gre->SetPointError(17,0,66.9351);
+    gre->SetPoint(18,0.00716486,109.959);
+    gre->SetPointError(18,0,54.9797);
+    gre->SetPoint(19,0.00925378,90.2035);
+    gre->SetPointError(19,0,45.1017);
+    gre->SetPoint(20,0.0119517,74.1317);
+    gre->SetPointError(20,0,37.0658);
+    gre->SetPoint(21,0.0154362,60.8988);
+    gre->SetPointError(21,0,30.4494);
+    gre->SetPoint(22,0.0199367,49.9915);
+    gre->SetPointError(22,0,24.9957);
+    gre->SetPoint(23,0.0257492,40.9812);
+    gre->SetPointError(23,0,20.4906);
+    gre->SetPoint(24,0.0332564,33.5739);
+    gre->SetPointError(24,0,16.7869);
+    gre->SetPoint(25,0.0429522,27.5127);
+    gre->SetPointError(25,0,13.7563);
+    gre->SetPoint(26,0.0554749,22.5744);
+    gre->SetPointError(26,0,11.2872);
+    gre->SetPoint(27,0.0716486,18.5674);
+    gre->SetPointError(27,0,9.28372);
+    gre->SetPoint(28,0.0925378,15.3292);
+    gre->SetPointError(28,0,7.66462);
+    gre->SetPoint(29,0.119517,12.7231);
+    gre->SetPointError(29,0,6.36156);
+    gre->SetPoint(30,0.154362,10.6352);
+    gre->SetPointError(30,0,5.31759);
+    gre->SetPoint(31,0.199367,8.97115);
+    gre->SetPointError(31,0,4.48558);
+    gre->SetPoint(32,0.257492,7.65358);
+    gre->SetPointError(32,0,3.82679);
+    gre->SetPoint(33,0.332564,6.61909);
+    gre->SetPointError(33,0,3.30955);
+    gre->SetPoint(34,0.429522,5.81614);
+    gre->SetPointError(34,0,2.90807);
+    gre->SetPoint(35,0.554749,5.20286);
+    gre->SetPointError(35,0,2.60143);
+    gre->SetPoint(36,0.716486,4.74533);
+    gre->SetPointError(36,0,2.37267);
+    gre->SetPoint(37,0.925378,4.40987);
+    gre->SetPointError(37,0,2.20494);
+    gre->SetPoint(38,1.19517,4.17077);
+    gre->SetPointError(38,0,2.08538);
+    gre->SetPoint(39,1.54362,4.014);
+    gre->SetPointError(39,0,2.007);
+    gre->SetPoint(40,1.99367,3.92577);
+    gre->SetPointError(40,0,1.96288);
+    gre->SetPoint(41,2.57492,3.89199);
+    gre->SetPointError(41,0,1.946);
+    gre->SetPoint(42,3.32564,3.90063);
+    gre->SetPointError(42,0,1.95032);
+    gre->SetPoint(43,4.29522,3.94146);
+    gre->SetPointError(43,0,1.97073);
+    gre->SetPoint(44,5.54749,4.00597);
+    gre->SetPointError(44,0,2.00299);
+    gre->SetPoint(45,7.16486,4.08725);
+    gre->SetPointError(45,0,2.04362);
+    gre->SetPoint(46,9.25378,4.17985);
+    gre->SetPointError(46,0,2.08993);
+    gre->SetPoint(47,11.9517,4.27962);
+    gre->SetPointError(47,0,2.13981);
+    gre->SetPoint(48,15.4362,4.38347);
+    gre->SetPointError(48,0,2.19174);
+    gre->SetPoint(49,19.9367,4.48919);
+    gre->SetPointError(49,0,2.2446);
+    gre->SetPoint(50,25.7492,4.59523);
+    gre->SetPointError(50,0,2.29762);
+    gre->SetPoint(51,33.2564,4.70052);
+    gre->SetPointError(51,0,2.35026);
+    gre->SetPoint(52,42.9522,4.80435);
+    gre->SetPointError(52,0,2.40218);
+    gre->SetPoint(53,55.4749,4.90625);
+    gre->SetPointError(53,0,2.45312);
+    gre->SetPoint(54,71.6486,5.00589);
+    gre->SetPointError(54,0,2.50295);
+    gre->SetPoint(55,92.5378,5.10279);
+    gre->SetPointError(55,0,2.55139);
+    gre->SetPoint(56,119.517,5.19654);
+    gre->SetPointError(56,0,2.59827);
+    gre->SetPoint(57,154.362,5.28758);
+    gre->SetPointError(57,0,2.64379);
+    gre->SetPoint(58,199.367,5.37581);
+    gre->SetPointError(58,0,2.6879);
+    gre->SetPoint(59,257.492,5.46109);
+    gre->SetPointError(59,0,2.73055);
+    gre->SetPoint(60,332.564,5.54335);
+    gre->SetPointError(60,0,2.77167);
+    gre->SetPoint(61,429.522,5.62248);
+    gre->SetPointError(61,0,2.81124);
+    gre->SetPoint(62,554.749,5.69843);
+    gre->SetPointError(62,0,2.84922);
+    gre->SetPoint(63,716.486,5.77122);
+    gre->SetPointError(63,0,2.88561);
+    gre->SetPoint(64,925.378,5.84093);
+    gre->SetPointError(64,0,2.92046);
+    gre->SetPoint(65,1195.17,5.9077);
+    gre->SetPointError(65,0,2.95385);
+    gre->SetPoint(66,1543.62,5.97165);
+    gre->SetPointError(66,0,2.98582);
+    gre->SetPoint(67,1993.67,6.03292);
+    gre->SetPointError(67,0,3.01646);
+    gre->SetPoint(68,2574.92,6.09171);
+    gre->SetPointError(68,0,3.04586);
+    gre->SetPoint(69,3325.64,6.14827);
+    gre->SetPointError(69,0,3.07413);
+    gre->SetPoint(70,4295.22,6.20286);
+    gre->SetPointError(70,0,3.10143);
+    gre->SetPoint(71,5547.49,6.25577);
+    gre->SetPointError(71,0,3.12788);
+    gre->SetPoint(72,7164.86,6.30725);
+    gre->SetPointError(72,0,3.15363);
+    gre->SetPoint(73,9253.78,6.35757);
+    gre->SetPointError(73,0,3.17878);
+    gre->SetPoint(74,11951.7,6.38446);
+    gre->SetPointError(74,0,3.19223);
+    gre->SetPoint(75,15436.2,6.38446);
+    gre->SetPointError(75,0,3.19223);
+    gre->SetPoint(76,19936.7,6.38446);
+    gre->SetPointError(76,0,3.19223);
+    gre->SetPoint(77,25749.2,6.38446);
+    gre->SetPointError(77,0,3.19223);
+    gre->SetPoint(78,33256.4,6.38446);
+    gre->SetPointError(78,0,3.19223);
+    gre->SetPoint(79,42952.2,6.38446);
+    gre->SetPointError(79,0,3.19223);
+    gre->SetPoint(80,55474.9,6.38446);
+    gre->SetPointError(80,0,3.19223);
+    gre->SetPoint(81,71648.6,6.38446);
+    gre->SetPointError(81,0,3.19223);
+    gre->SetPoint(82,92537.8,6.38446);
+    gre->SetPointError(82,0,3.19223);
+    gre->SetPoint(83,119517,6.38446);
+    gre->SetPointError(83,0,3.19223);
+    gre->SetPoint(84,154362,6.38446);
+    gre->SetPointError(84,0,3.19223);
+    gre->SetPoint(85,199367,6.38446);
+    gre->SetPointError(85,0,3.19223);
+    gre->SetPoint(86,257492,6.38446);
+    gre->SetPointError(86,0,3.19223);
+    gre->SetPoint(87,332563,6.38446);
+    gre->SetPointError(87,0,3.19223);
+    gre->SetPoint(88,429522,6.38446);
+    gre->SetPointError(88,0,3.19223);
+    gre->SetPoint(89,554749,6.38446);
+    gre->SetPointError(89,0,3.19223);
+    gre->SetPoint(90,716486,6.38446);
+    gre->SetPointError(90,0,3.19223);
+    gre->Draw("l same");
+    gre->DrawClone("l3 same");
+    gPad->Modified();
+    gPad->Update();
+    gPad->cd();
+  }
+  
   ClassDef(DrawHits,0);
 };
 
index 05d286f..52f8da6 100644 (file)
@@ -101,7 +101,7 @@ public:
     UShort_t str = digit->Strip();
     if (str > 511) {
       AliWarning(Form("Bad strip number %d in digit", str));
-      continue;
+      return kFALSE;
     }
     fElossVsAdc->Fill(fMap(det, rng, sec, str).fEdep, digit->Counts());
     return kTRUE;
index 7a02da7..ca45398 100644 (file)
@@ -60,10 +60,19 @@ DrawXsection(Bool_t scale=kFALSE,
     // 5 sigma
     graph->SetPointError(i, 0, 5 * .1 * y);
   }
+  TCanvas* c = new TCanvas("c","c");
+  c->SetLogx();
+  c->SetLogy();
   graph->SetLineWidth(2);
   graph->SetFillStyle(3001);
   graph->SetFillColor(6);
-  graph->Draw("L3 same");
+  graph->Draw("L");
+  graph->DrawClone("AL3");
+  c->Modified();
+  c->Update();
+  c->cd();
+  c->SaveAs("xsec.C");
+  
 }
 
 //____________________________________________________________________
diff --git a/FMD/scripts/Dummy.C b/FMD/scripts/Dummy.C
new file mode 100644 (file)
index 0000000..a16fbe4
--- /dev/null
@@ -0,0 +1,48 @@
+#ifdef COMPILING
+#include "ITS/AliITSvPPRasymmFMD.h"    // ITS
+#include "STRUCT/AliDIPOv2.h"          // DIPO
+#include "STRUCT/AliFRAMEv2.h"         // FRAME
+#include "STRUCT/AliSHILv2.h"          // SHIL
+#include "TPC/AliTPCv2.h"              // TPC
+#include "TOF/AliTOFv4T0.h"            // TOF
+#include "HMPID/AliHMPIDv1.h"          // HMPID
+#include "ZDC/AliZDCv2.h"              // ZDC
+#include "TRD/AliTRDv1.h"              // TRD
+#include "MUON/AliMUONv1.h"            // MUON
+#include "PHOS/AliPHOSv1.h"            // PHOS
+#include "PMD/AliPMDv1.h"              // PMD
+#include "T0/AliT0v1.h"                        // T0
+#include "EMCAL/AliEMCALv1.h"          // EMCAL
+#include "VZERO/AliVZEROv3.h"          // VZERO
+
+template <typename T>
+struct Dummy : public T 
+{
+  Dummy() : T() {}
+  Dummy(const char* n) : T(n, Form("%s dummy", n)) {}
+  void StepManager() {}
+  ClassDef(Dummy, 1);
+};
+
+typedef Dummy<AliDIPOv2>          DummyDIPO;
+typedef Dummy<AliFRAMEv2>         DummyFRAME;
+typedef Dummy<AliSHILv2>          DummySHIL;
+typedef Dummy<AliITSvPPRasymmFMD> DummyITS;
+typedef Dummy<AliTPCv2>           DummyTPC;
+typedef Dummy<AliTOFv4T0>        DummyTOF;
+typedef Dummy<AliHMPIDv1>         DummyHMPID;
+typedef Dummy<AliZDCv2>           DummyZDC;
+typedef Dummy<AliTRDv1>           DummyTRD;
+typedef Dummy<AliMUONv1>          DummyMUON;
+typedef Dummy<AliPHOSv1>          DummyPHOS;
+typedef Dummy<AliPMDv1>           DummyPMD;
+typedef Dummy<AliT0v1>            DummyT0;
+typedef Dummy<AliEMCALv1>         DummyEMCAL;
+typedef Dummy<AliVZEROv3>         DummyVZERO;
+#endif
+
+
+  
+//
+// EOF
+//
diff --git a/FMD/scripts/DummyConfig.C b/FMD/scripts/DummyConfig.C
new file mode 100644 (file)
index 0000000..de3fb0f
--- /dev/null
@@ -0,0 +1,1639 @@
+//____________________________________________________________________
+//
+// $Id$
+//
+// One can use the configuration macro in compiled mode by
+// root [0] gSystem->Load("libgeant321");
+// root [0] gSystem->SetIncludePath("-I$ROOTSYS/include -I$ALICE_ROOT/include\
+//                   -I$ALICE_ROOT -I$ALICE/geant3/TGeant3");
+// root [0] .x grun.C(1,"ConfigPPR.C++")
+//
+/** @file    Config.C
+    @author  Christian Holm Christensen <cholm@nbi.dk>
+    @date    Mon Mar 27 12:50:29 2006
+    @brief   Simulation configuration script
+*/
+//____________________________________________________________________
+// 
+// Generator types 
+//
+enum EG_t {
+  test50,
+  kParam_8000,                 //
+  kParam_4000,                 //
+  kParam_2000,                 //
+  kParam_fmd,                  //
+  kHijing_cent1,               //
+  kHijing_cent2,               //
+  kHijing_per1,                        //
+  kHijing_per2,                        //
+  kHijing_per3,                        //
+  kHijing_per4,                        //
+  kHijing_per5,                        //
+  kHijing_jj25,                        //
+  kHijing_jj50,                        //
+  kHijing_jj75,                        //
+  kHijing_jj100,               //
+  kHijing_jj200,               //
+  kHijing_gj25,                        //
+  kHijing_gj50,                        //
+  kHijing_gj75,                        //
+  kHijing_gj100,               //
+  kHijing_gj200,               //
+  kHijing_pA,                  //
+  kPythia6,                    //
+  kPythia6Jets20_24,           //
+  kPythia6Jets24_29,           //
+  kPythia6Jets29_35,           //
+  kPythia6Jets35_42,           //
+  kPythia6Jets42_50,           //
+  kPythia6Jets50_60,           //
+  kPythia6Jets60_72,           //
+  kPythia6Jets72_86,           //
+  kPythia6Jets86_104,          //
+  kPythia6Jets104_125,         //
+  kPythia6Jets125_150,         //
+  kPythia6Jets150_180,         //
+  kD0PbPb5500,                 //
+  kCharmSemiElPbPb5500,                //
+  kBeautySemiElPbPb5500,       //
+  kCocktailTRD,                        //
+  kPyJJ,                       //
+  kPyGJ,                       //
+  kMuonCocktailCent1,          //
+  kMuonCocktailPer1,           //
+  kMuonCocktailPer4,           //
+  kMuonCocktailCent1HighPt,    //
+  kMuonCocktailPer1HighPt,     //
+  kMuonCocktailPer4HighPt,     //
+  kMuonCocktailCent1Single,    //
+  kMuonCocktailPer1Single,     //
+  kMuonCocktailPer4Single,
+  kFMD1Flat, 
+  kFMD2Flat, 
+  kFMD3Flat,
+  kFMDFlat,
+  kEgMax
+};
+
+//____________________________________________________________________
+// 
+// Generator types names
+//
+const char* egName[kEgMax] = {
+  "test50",
+  "kParam_8000",               //
+  "kParam_4000",               //
+  "kParam_2000",               //
+  "kParam_fmd",                        //
+  "kHijing_cent1",             //
+  "kHijing_cent2",             //
+  "kHijing_per1",              //
+  "kHijing_per2",              //
+  "kHijing_per3",              //
+  "kHijing_per4",              //
+  "kHijing_per5",              //
+  "kHijing_jj25",              //
+  "kHijing_jj50",              //
+  "kHijing_jj75",              //
+  "kHijing_jj100",             //
+  "kHijing_jj200",             //
+  "kHijing_gj25",              //
+  "kHijing_gj50",              //
+  "kHijing_gj75",              //
+  "kHijing_gj100",             //
+  "kHijing_gj200",             //
+  "kHijing_pA",                        //
+  "kPythia6",                  //
+  "kPythia6Jets20_24",         //
+  "kPythia6Jets24_29",         //
+  "kPythia6Jets29_35",         //
+  "kPythia6Jets35_42",         //
+  "kPythia6Jets42_50",         //
+  "kPythia6Jets50_60",         //
+  "kPythia6Jets60_72",         //
+  "kPythia6Jets72_86",         //
+  "kPythia6Jets86_104",                //
+  "kPythia6Jets104_125",       //
+  "kPythia6Jets125_150",       //
+  "kPythia6Jets150_180",       //
+  "kD0PbPb5500",               //
+  "kCharmSemiElPbPb5500",      //
+  "kBeautySemiElPbPb5500",     //
+  "kCocktailTRD",              //
+  "kPyJJ",                     //
+  "kPyGJ",                     //
+  "kMuonCocktailCent1",                //
+  "kMuonCocktailPer1",         //
+  "kMuonCocktailPer4",         //
+  "kMuonCocktailCent1HighPt",  //
+  "kMuonCocktailPer1HighPt",   //
+  "kMuonCocktailPer4HighPt",   //
+  "kMuonCocktailCent1Single",  //
+  "kMuonCocktailPer1Single",   //
+  "kMuonCocktailPer4Single",
+  "kFMD1Flat",
+  "kFMD2Flat",
+  "kFMD3Flat",
+  "kFMDFlat"
+};
+
+//____________________________________________________________________
+enum Geo_t {
+  kHoles,                      //
+  kNoHoles                     //
+};
+
+//____________________________________________________________________
+enum Rad_t {
+  kGluonRadiation,             //
+  kNoGluonRadiation            //
+};
+
+//____________________________________________________________________
+enum Mag_t {
+  k2kG,                                //
+  k4kG,                                //
+  k5kG                         //
+};
+
+//____________________________________________________________________
+enum MC_t {
+  kFLUKA, 
+  kGEANT3, 
+  kGEANT4, 
+  kGEANT3TGEO,
+};
+
+//____________________________________________________________________
+// Functions
+Float_t       EtaToTheta(Float_t eta);
+Eg_t          LookupEG(const Char_t* name);
+AliGenerator* GeneratorFactory(EG_t eg, Rad_t rad, TString& comment);
+AliGenHijing* HijingStandard();
+void          ProcessEnvironmentVars(EG_t& eg, Int_t& seed);
+
+//____________________________________________________________________
+void 
+Config()
+{
+  //____________________________________________________________________
+  // This part for configuration    
+  // EG_t  eg   = test50;
+  // EG_t  eg   = kParam_fmd;
+  EG_t  eg   = kParam_2000; // kPythia;
+  // EG_t  eg   = kFMDFlat;
+  Geo_t geo  = kNoHoles;
+  Rad_t rad  = kGluonRadiation;
+  Mag_t mag  = k5kG;
+  Int_t seed = 12345; //Set 0 to use the current time
+  MC_t  mc   = kGEANT3TGEO;
+  
+  //____________________________________________________________________
+  // Comment line 
+  static TString  comment;
+  
+  //____________________________________________________________________
+  // Get settings from environment variables
+  ProcessEnvironmentVars(eg, seed);
+
+  //____________________________________________________________________
+  // Set Random Number seed
+  gRandom->SetSeed(seed);
+  cout<<"Seed for random number generation= "<<gRandom->GetSeed()<<endl; 
+
+
+  //__________________________________________________________________
+  switch (mc) {
+  case kFLUKA: 
+    // 
+    // libraries required by fluka21
+    // 
+    gSystem->Load("libGeom");
+    cout << "\t* Loading TFluka..." << endl;  
+    gSystem->Load("libTFluka");    
+    gSystem->MakeDirectory("peg");
+    // 
+    // FLUKA MC
+    //
+    cout << "\t* Instantiating TFluka..." << endl;
+    new TFluka("C++ Interface to Fluka", 0/*verbosity*/);
+    break;
+  case kGEANT3: 
+    {
+      //
+      // Libraries needed by GEANT 3.21 
+      //
+      gSystem->Load("libgeant321");
+      
+      // 
+      // GEANT 3.21 MC 
+      // 
+      TGeant3* gmc = new TGeant3("C++ Interface to Geant3");
+      gmc->SetSWIT(4, 1000);
+    }
+    break;
+  case kGEANT3TGEO:
+    {
+      //
+      // Libraries needed by GEANT 3.21 
+      //
+      gSystem->Load("libgeant321");
+    
+      // 
+      // GEANT 3.21 MC 
+      // 
+      TGeant3TGeo* gmc  = new TGeant3TGeo("C++ Interface to Geant3");
+      gmc->SetSWIT(4, 1000);
+      Printf("Making a TGeant3TGeo objet");
+    }
+    break;
+  default:
+    gAlice->Fatal("Config.C", "No MC type chosen");
+    return;
+  }
+
+  //__________________________________________________________________
+  AliRunLoader* rl = 0;
+
+  cout<<"Config.C: Creating Run Loader ..."<<endl;
+  rl = AliRunLoader::Open("galice.root",
+                         AliConfig::GetDefaultEventFolderName(),
+                         "recreate");
+  if (!rl) {
+    gAlice->Fatal("Config.C","Can not instatiate the Run Loader");
+    return;
+  }
+  rl->SetCompressionLevel(2);
+  rl->SetNumberOfEventsPerFile(3);
+  gAlice->SetRunLoader(rl);
+
+  //__________________________________________________________________
+  // For FLUKA 
+  switch (mc) {
+  case kFLUKA: 
+    {
+      //
+      // Use kTRUE as argument to generate alice.pemf first
+      //
+      TString alice_pemf(gSystem->Which(".", "peg/mat17.pemf"));
+      if (!alice_pemf.IsNull()) 
+       ((TFluka*)gMC)->SetGeneratePemf(kFALSE);
+      else
+       ((TFluka*)gMC)->SetGeneratePemf(kTRUE);
+      TString flupro(gSystem->Getenv("FLUPRO"));
+      if (flupro.IsNull()) 
+       Fatal("Config.C", "Environment variable FLUPRO not set");
+#if 0
+      char* files[] = { "brems_fin.bin", "cohff.bin", "elasct.bin", 
+                       "gxsect.bin", "nuclear.bin", "sigmapi.bin", 
+                       0 };
+      char* file = files[0];
+      while (file) {
+       TString which(gSystem->Which(".", file));
+       if (which.IsNull()) {
+         if (gSystem->Symlink(Form("%s/%s", flupro.Data(), file), file)!=0) 
+           Fatal("Config.C", "Couldn't link $(FLUPRO)/%s -> .", file);
+       }
+       file++;
+      }
+#endif
+      TString neuxsc(gSystem->Which(".", "neuxsc.bin"));
+      if (neuxsc.IsNull()) 
+       gSystem->Symlink(Form("%s/neuxsc_72.bin", flupro.Data()), 
+                        "neuxsc.bin"); 
+      gSystem->CopyFile("$(FLUPRO)/random.dat", "old.seed", kTRUE);
+    }
+    break;
+  }
+
+  //__________________________________________________________________
+  //
+  // Set External decayer
+#if 0
+  AliDecayer *decayer = new AliDecayerPythia();
+  switch (eg) {
+  case kD0PbPb5500:           decayer->SetForceDecay(kHadronicD);      break;
+  case kCharmSemiElPbPb5500:  decayer->SetForceDecay(kSemiElectronic); break;
+  case kBeautySemiElPbPb5500: decayer->SetForceDecay(kSemiElectronic); break;
+  default:                    decayer->SetForceDecay(kAll);            break;
+  }
+  decayer->Init();
+  gMC->SetExternalDecayer(decayer);
+#endif
+
+  //__________________________________________________________________
+  // *********** STEERING parameters FOR ALICE SIMULATION ************
+  // - Specify event type to be tracked through the ALICE setup
+  // - All positions are in cm, angles in degrees, and P and E in GeV 
+  gMC->SetProcess("DCAY",1);
+  gMC->SetProcess("PAIR",1);
+  gMC->SetProcess("COMP",1);
+  gMC->SetProcess("PHOT",1);
+  gMC->SetProcess("PFIS",0);
+  gMC->SetProcess("DRAY",0);
+  gMC->SetProcess("ANNI",1);
+  gMC->SetProcess("BREM",1);
+  gMC->SetProcess("MUNU",1);
+  gMC->SetProcess("CKOV",1);
+  gMC->SetProcess("HADR",1);
+  gMC->SetProcess("LOSS",2);
+  gMC->SetProcess("MULS",1);
+  gMC->SetProcess("RAYL",1);
+
+  Float_t cut = 1.e-3;        // 1MeV cut by default
+  Float_t tofmax = 1.e10;
+
+  gMC->SetCut("CUTGAM", cut);
+  gMC->SetCut("CUTELE", cut);
+  gMC->SetCut("CUTNEU", cut);
+  gMC->SetCut("CUTHAD", cut);
+  gMC->SetCut("CUTMUO", cut);
+  gMC->SetCut("BCUTE",  cut); 
+  gMC->SetCut("BCUTM",  cut); 
+  gMC->SetCut("DCUTE",  cut); 
+  gMC->SetCut("DCUTM",  cut); 
+  gMC->SetCut("PPCUTM", cut);
+  gMC->SetCut("TOFMAX", tofmax); 
+
+  
+  //__________________________________________________________________
+  // Generator Configuration
+  AliGenerator* gener = GeneratorFactory(eg, rad, comment);
+  gener->SetOrigin(0, 0, 0);    // vertex position
+  gener->SetSigma(0, 0, 5.3);   // Sigma in (X,Y,Z) (cm) on IP position
+  gener->SetCutVertexZ(1.);     // Truncate at 1 sigma
+  gener->SetVertexSmear(kPerEvent); 
+  gener->SetTrackingFlag(1);
+  gener->Init();
+    
+  //__________________________________________________________________
+  // 
+  // Comments 
+  // 
+  switch (mag) {
+  case k2kG: comment = comment.Append(" | L3 field 0.2 T"); break;
+  case k4kG: comment = comment.Append(" | L3 field 0.4 T"); break;
+  case k5kG: comment = comment.Append(" | L3 field 0.5 T"); break;
+  }
+
+  switch (rad) {
+  case kGluonRadiation: 
+    comment = comment.Append(" | Gluon Radiation On");  break;
+  default:
+    comment = comment.Append(" | Gluon Radiation Off"); break;
+  }
+
+  switch(geo) {
+  case kHoles: comment = comment.Append(" | Holes for PHOS/HMPID"); break;
+  default:     comment = comment.Append(" | No holes for PHOS/HMPID"); break;
+  }
+
+  std::cout << "\n\n Comment: " << comment << "\n" << std::endl;
+
+  //__________________________________________________________________
+  // Field (L3 0.4 T)
+  AliMagFMaps* field = new AliMagFMaps("Maps","Maps", 2, 1., 10., mag);
+  field->SetL3ConstField(0); //Using const. field in the barrel
+  rl->CdGAFile();
+  gAlice->SetField(field);    
+
+  //__________________________________________________________________
+  // 
+  // Used detectors 
+  // 
+  Bool_t useABSO  = kTRUE; 
+  Bool_t useACORDE= kFALSE; 
+  Bool_t useDIPO  = kFALSE; 
+  Bool_t useFMD   = kTRUE; 
+  Bool_t useFRAME = kFALSE; 
+  Bool_t useHALL  = kFALSE; 
+  Bool_t useITS   = kTRUE;
+  Bool_t useMAG   = kFALSE; 
+  Bool_t useMUON  = kFALSE; 
+  Bool_t usePHOS  = kFALSE; 
+  Bool_t usePIPE  = kFALSE; 
+  Bool_t usePMD   = kFALSE; 
+  Bool_t useHMPID = kFALSE; 
+  Bool_t useSHIL  = kFALSE; 
+  Bool_t useT0    = kTRUE; 
+  Bool_t useTOF   = kFALSE; 
+  Bool_t useTPC   = kFALSE;
+  Bool_t useTRD   = kFALSE; 
+  Bool_t useZDC   = kFALSE; 
+  Bool_t useEMCAL = kFALSE; 
+  Bool_t useVZERO = kTRUE;
+
+  gROOT->LoadMacro("LoadDummy.C");
+  cout << "\t* Creating the detectors ..." << endl;
+  // ================= Alice BODY parameters =========================
+  AliBODY *BODY = new AliBODY("BODY", "Alice envelop");
+  
+  
+  if (useMAG) {
+    // =================== MAG parameters ============================
+    // Start with Magnet since detector layouts may be depending on
+    // the selected Magnet dimensions 
+    AliMAG *MAG = new AliMAG("MAG", "Magnet");
+  }
+
+  if (useABSO) {
+    // =================== ABSO parameters ===========================
+    AliABSO *ABSO = new AliABSOv0("ABSO", "Muon Absorber");
+  }
+
+  if (useDIPO) {
+    // =================== DIPO parameters ===========================
+    AliDIPO *DIPO = new DummyABSO("DIPO");
+  }
+
+  if (useHALL) {
+    // =================== HALL parameters ===========================
+    AliHALL *HALL = new AliHALL("HALL", "Alice Hall");
+  }
+
+
+  if (useFRAME) {
+    // ================== FRAME parameters ===========================
+    AliFRAMEv2 *FRAME = new DummyFRAME("FRAME");
+    switch (geo) {
+    case kHoles: FRAME->SetHoles(1); break;
+    default:     FRAME->SetHoles(0); break;
+    }
+  }
+
+  if (useSHIL) {
+    // ================== SHIL parameters ============================
+    AliSHIL *SHIL = new DummySHIl("SHIL");
+  }
+
+
+  if (usePIPE) {
+    // ================== PIPE parameters ============================
+    AliPIPE *PIPE = new AliPIPEv0("PIPE", "Beam Pipe");
+  }
+  
+  if (useITS) {
+    // =================== ITS parameters ============================
+    //
+    // As the innermost detector in ALICE, the Inner Tracking System
+    // "impacts" on almost all other detectors. This involves the fact
+    // that the ITS geometry still has several options to be followed
+    // in parallel in order to determine the best set-up which
+    // minimizes the induced background. All the geometries available
+    // to date are described in the following. Read carefully the
+    // comments and use the default version (the only one uncommented)
+    // unless you are making comparisons and you know what you are
+    // doing. In this case just uncomment the ITS geometry you want to
+    // use and run Aliroot.
+    //
+    // Detailed geometries:
+    //
+    //
+    // AliITS *ITS = 
+    //   new AliITSv5symm("ITS", "Updated ITS TDR detailed version "
+    //                   "with symmetric services");
+    // AliITS *ITS  = 
+    //   new AliITSv5asymm("ITS","Updates ITS TDR detailed version "
+    //                            "with asymmetric services");
+    //
+    AliITSvPPRasymmFMD *ITS  = new DummyITS("ITS");
+    // new AliITSvPPRasymmFMD("ITS","New ITS PPR detailed version "
+    // "with asymmetric services") 
+     // don't touch this parameter if you're not an ITS developer
+    ITS->SetMinorVersion(2); 
+    // don't touch this parameter if you're not an ITS developer
+    ITS->SetReadDet(kTRUE);
+    // don't touch this parameter if you're not an ITS developer
+    // ITS->SetWriteDet("$ALICE_ROOT/ITS/ITSgeometry_vPPRasymm2.det");  
+    // detector thickness on layer 1 must be in the range [100,300]
+    ITS->SetThicknessDet1(200.);   
+    // detector thickness on layer 2 must be in the range [100,300]
+    ITS->SetThicknessDet2(200.);   
+    // chip thickness on layer 1 must be in the range [150,300]
+    ITS->SetThicknessChip1(200.);  
+    // chip thickness on layer 2 must be in the range [150,300]
+    ITS->SetThicknessChip2(200.);
+    // 1 --> rails in ; 0 --> rails out
+    ITS->SetRails(0);          
+    // 1 --> water ; 0 --> freon
+    ITS->SetCoolingFluid(1);   
+
+    // Coarse geometries (warning: no hits are produced with these
+    // coarse geometries and they unuseful for reconstruction !):
+    //
+    //
+    // AliITSvPPRcoarseasymm *ITS  = 
+    //   new AliITSvPPRcoarseasymm("ITS","New ITS PPR coarse version "
+    //                             "with asymmetric services");
+    // 1 --> rails in ; 0 --> rails out
+    // ITS->SetRails(0);
+    // 0 --> Copper ; 1 --> Aluminum ; 2 --> Carbon
+    // ITS->SetSupportMaterial(0);      
+    //
+    // AliITS *ITS  = 
+    //  new AliITSvPPRcoarsesymm("ITS","New ITS PPR coarse version "
+    //                           "with symmetric services");
+    // 1 --> rails in ; 0 --> rails out
+    // ITS->SetRails(0);                
+    // 0 --> Copper ; 1 --> Aluminum ; 2 --> Carbon
+    // ITS->SetSupportMaterial(0);      
+    //
+    // Geant3 <-> EUCLID conversion
+    // ============================
+    //
+    // SetEUCLID is a flag to output (=1) or not to output (=0) both
+    // geometry and media to two ASCII files (called by default
+    // ITSgeometry.euc and ITSgeometry.tme) in a format understandable
+    // to the CAD system EUCLID.  The default (=0) means that you dont
+    // want to use this facility.
+    //
+    ITS->SetEUCLID(0);
+  }
+
+  if (useTPC) {
+    // =================== TPC parameters ============================
+    //
+    // This allows the user to specify sectors for the SLOW (TPC
+    // geometry 2) Simulator. SecAL (SecAU) <0 means that ALL lower
+    // (upper) sectors are specified, any value other than that
+    // requires at least one sector (lower or upper)to be specified!
+    //
+    // Reminder: 
+    //   sectors 1-24 are lower sectors (1-12 -> z>0, 13-24 -> z<0)
+    //   sectors 25-72 are the upper ones (25-48 -> z>0, 49-72 -> z<0)
+    //
+    //   SecLows - number of lower sectors specified (up to 6)
+    //   SecUps  - number of upper sectors specified (up to 12)
+    //   Sens    - sensitive strips for the Slow Simulator !!!
+    //
+    // This does NOT work if all S or L-sectors are specified, i.e.
+    // if SecAL or SecAU < 0
+    //
+    //
+    //----------------------------------------------------------------
+    //  gROOT->LoadMacro("SetTPCParam.C");
+    //  AliTPCParam *param = SetTPCParam();
+    AliTPC *TPC = new DummyTPC("TPC");
+  }
+
+  if (useTOF) {
+    // ================== TOF parameters =============================
+    AliTOF *TOF = new DummyTOF("TOF");
+  }
+
+  if (useHMPID) {
+    // ================== HMPID parameters ============================
+    AliHMPID *HMPID = new DummyHMPID("HMPID");
+
+  }
+
+  if (useZDC) {
+    // ================== ZDC parameters =============================
+    AliZDC *ZDC = new DummyZDC("ZDC");
+  }
+
+  if (useTRD) {
+    // ================== TRD parameters =============================
+    AliTRD *TRD = new DummyTRD("TRD");
+
+    // Select the gas mixture (0: 97% Xe + 3% isobutane, 1: 90% Xe + 10% CO2)
+    TRD->SetGasMix(1);
+    if (geo == kHoles) {
+      // With hole in front of PHOS
+      TRD->SetPHOShole();
+      // With hole in front of HMPID
+      TRD->SetHMPIDhole();
+    }
+    // Switch on TR
+    AliTRDsim *TRDsim = TRD->CreateTR();
+  }
+
+  if (useFMD) {
+    // =================== FMD parameters ============================
+    // AliLog::SetModuleDebugLevel("FMD", 15);
+    AliFMD *FMD = new AliFMDv1("FMD", "normal FMD");
+    // FMD->UseDetailed(kFALSE);
+    // FMD->UseAssembly();
+    // FMD->UseOld();
+  }
+
+  if (useMUON) {
+    // =================== MUON parameters ===========================
+    AliMUON *MUON = new DummyMUON("MUON");
+    // MUON->AddGeometryBuilder(new AliMUONSt1GeometryBuilder(MUON));
+    // MUON->AddGeometryBuilder(new AliMUONSt2GeometryBuilder(MUON));
+    // MUON->AddGeometryBuilder(new AliMUONSlatGeometryBuilder(MUON));
+    // MUON->AddGeometryBuilder(new AliMUONTriggerGeometryBuilder(MUON));
+  }
+
+  if (usePHOS) {
+    // =================== PHOS parameters ===========================
+    AliPHOS *PHOS = new DummyPHOS("PHOS");
+  }
+
+  if (usePMD) {
+    // =================== PMD parameters ============================
+    AliPMD *PMD = new DummyPMD("PMD");
+  }
+
+  if (useT0) {
+    // =================== T0 parameters ==========================
+    AliT0 *T0 = new DummyT0("T0");
+  }
+
+  if (useEMCAL) {
+    // =================== EMCAL parameters ==========================
+    AliEMCAL *EMCAL = new DummyEMCAL("EMCAL");
+  }
+
+  if (useACORDE) {
+    // =================== ACORDE parameters ============================
+    AliACORDE *ACORDE = new AliACORDEv0("ACORDE", "normal ACORDE");
+  }
+
+  if (useVZERO) {
+    // =================== V0 parameters =============================
+    AliVZERO *VZERO = new DummyVZERO("VZERO");
+  }
+}
+
+//____________________________________________________________________
+Float_t EtaToTheta(Float_t arg)
+{
+  return (180./TMath::Pi())*2.*TMath::ATan(TMath::Exp(-arg));
+}
+
+//____________________________________________________________________
+Int_t 
+LookupEG(const Char_t* name) 
+{
+  TString n(name);
+  for (Int_t i = 0; i < kEgMax; i++) {
+    if (n == egName[i]) return i;
+  }
+  return -1;
+}
+
+//____________________________________________________________________  
+AliGenerator* 
+GeneratorFactory(EG_t eg, Rad_t rad, TString& comment)  
+{
+  Int_t isw = 3;
+  if (rad == kNoGluonRadiation) isw = 0;
+  
+  
+  AliGenerator * gGener = 0;
+  switch (eg) {
+  case test50:
+    {
+      comment = comment.Append(":HIJINGparam test 50 particles");
+      AliGenHIJINGpara *gener = new AliGenHIJINGpara(50);
+      gener->SetMomentumRange(0, 999999.);
+      gener->SetPhiRange(0., 360.);
+      // Set pseudorapidity range from -8 to 8.
+      Float_t thmin = EtaToTheta(8);   // theta min. <---> eta max
+      Float_t thmax = EtaToTheta(-8);  // theta max. <---> eta min 
+      gener->SetThetaRange(thmin,thmax);
+      gGener=gener;
+    }
+    break;
+  case kParam_8000:
+    {
+      comment = comment.Append(":HIJINGparam N=8000");
+      AliGenHIJINGpara *gener = new AliGenHIJINGpara(86030);
+      gener->SetMomentumRange(0, 999999.);
+      gener->SetPhiRange(0., 360.);
+      // Set pseudorapidity range from -8 to 8.
+      Float_t thmin = EtaToTheta(8);   // theta min. <---> eta max
+      Float_t thmax = EtaToTheta(-8);  // theta max. <---> eta min 
+      gener->SetThetaRange(thmin,thmax);
+      gGener=gener;
+    }
+    break;
+  case kParam_4000:
+    {
+      comment = comment.Append("HIJINGparam N=4000");
+      AliGenHIJINGpara *gener = new AliGenHIJINGpara(43015);
+      gener->SetMomentumRange(0, 999999.);
+      gener->SetPhiRange(0., 360.);
+      // Set pseudorapidity range from -8 to 8.
+      Float_t thmin = EtaToTheta(8);   // theta min. <---> eta max
+      Float_t thmax = EtaToTheta(-8);  // theta max. <---> eta min 
+      gener->SetThetaRange(thmin,thmax);
+      gGener=gener;
+    }
+    break;
+  case kParam_2000:
+    {
+      comment = comment.Append("HIJINGparam N=2000");
+      AliGenHIJINGpara *gener = new AliGenHIJINGpara(21507);
+      gener->SetMomentumRange(0, 999999.);
+      gener->SetPhiRange(0., 360.);
+      // Set pseudorapidity range from -8 to 8.
+      Float_t thmin = EtaToTheta(9);   // theta min. <---> eta max
+      Float_t thmax = EtaToTheta(-9);  // theta max. <---> eta min 
+      gener->SetThetaRange(thmin,thmax);
+      gGener=gener;
+    }
+    break;
+  case kParam_fmd:
+    {
+      comment = comment.Append("HIJINGparam N=100");
+      AliGenHIJINGpara *gener = new AliGenHIJINGpara(500);
+      gener->SetMomentumRange(0, 999999.);
+      gener->SetPhiRange(0., 360.);
+      // Set pseudorapidity range from -8 to 8.
+      Float_t thmin = EtaToTheta(6);   // theta min. <---> eta max
+      Float_t thmax = EtaToTheta(2);  // theta max. <---> eta min 
+      gener->SetThetaRange(thmin,thmax);
+      gGener=gener;
+    }
+    break;
+    //
+    //  Hijing Central
+    //
+  case kHijing_cent1:
+    {
+      comment = comment.Append("HIJING cent1");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(0., 5.);
+      gGener=gener;
+    }
+    break;
+  case kHijing_cent2:
+    {
+      comment = comment.Append("HIJING cent2");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(0., 2.);
+      gGener=gener;
+    }
+    break;
+    //
+    // Hijing Peripheral 
+    //
+  case kHijing_per1:
+    {
+      comment = comment.Append("HIJING per1");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(5., 8.6);
+      gGener=gener;
+    }
+    break;
+  case kHijing_per2:
+    {
+      comment = comment.Append("HIJING per2");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(8.6, 11.2);
+      gGener=gener;
+    }
+    break;
+  case kHijing_per3:
+    {
+      comment = comment.Append("HIJING per3");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(11.2, 13.2);
+      gGener=gener;
+    }
+    break;
+  case kHijing_per4:
+    {
+      comment = comment.Append("HIJING per4");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(13.2, 15.);
+      gGener=gener;
+    }
+    break;
+  case kHijing_per5:
+    {
+      comment = comment.Append("HIJING per5");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(15., 100.);
+      gGener=gener;
+    }
+    break;
+    //
+    //  Jet-Jet
+    //
+  case kHijing_jj25:
+    {
+      comment = comment.Append("HIJING Jet 25 GeV");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(0., 5.);
+      // trigger
+      gener->SetTrigger(1);
+      gener->SetPtJet(25.);
+      gener->SetRadiation(isw);
+      gener->SetSimpleJets(!isw);
+      gener->SetJetEtaRange(-0.3,0.3);
+      gener->SetJetPhiRange(75., 165.);   
+      gGener=gener;
+    }
+    break;
+
+  case kHijing_jj50:
+    {
+      comment = comment.Append("HIJING Jet 50 GeV");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(0., 5.);
+      // trigger
+      gener->SetTrigger(1);
+      gener->SetPtJet(50.);
+      gener->SetRadiation(isw);
+      gener->SetSimpleJets(!isw);
+      gener->SetJetEtaRange(-0.3,0.3);
+      gener->SetJetPhiRange(75., 165.);   
+      gGener=gener;
+    }
+    break;
+
+  case kHijing_jj75:
+    {
+      comment = comment.Append("HIJING Jet 75 GeV");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(0., 5.);
+      // trigger
+      gener->SetTrigger(1);
+      gener->SetPtJet(75.);
+      gener->SetRadiation(isw);
+      gener->SetSimpleJets(!isw);
+      gener->SetJetEtaRange(-0.3,0.3);
+      gener->SetJetPhiRange(75., 165.);   
+      gGener=gener;
+    }
+    break;
+
+  case kHijing_jj100:
+    {
+      comment = comment.Append("HIJING Jet 100 GeV");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(0., 5.);
+      // trigger
+      gener->SetTrigger(1);
+      gener->SetPtJet(100.);
+      gener->SetRadiation(isw);
+      gener->SetSimpleJets(!isw);
+      gener->SetJetEtaRange(-0.3,0.3);
+      gener->SetJetPhiRange(75., 165.);   
+      gGener=gener;
+    }
+    break;
+
+  case kHijing_jj200:
+    {
+      comment = comment.Append("HIJING Jet 200 GeV");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(0., 5.);
+      // trigger
+      gener->SetTrigger(1);
+      gener->SetPtJet(200.);
+      gener->SetRadiation(isw);
+      gener->SetSimpleJets(!isw);
+      gener->SetJetEtaRange(-0.3,0.3);
+      gener->SetJetPhiRange(75., 165.);   
+      gGener=gener;
+    }
+    break;
+    //
+    // Gamma-Jet
+    //
+  case kHijing_gj25:
+    {
+      comment = comment.Append("HIJING Gamma 25 GeV");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(0., 5.);
+      // trigger
+      gener->SetTrigger(2);
+      gener->SetPtJet(25.);
+      gener->SetRadiation(isw);
+      gener->SetSimpleJets(!isw);
+      gener->SetJetEtaRange(-0.12, 0.12);
+      gener->SetJetPhiRange(220., 320.);
+      gGener=gener;
+    }
+    break;
+
+  case kHijing_gj50:
+    {
+      comment = comment.Append("HIJING Gamma 50 GeV");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(0., 5.);
+      // trigger
+      gener->SetTrigger(2);
+      gener->SetPtJet(50.);
+      gener->SetRadiation(isw);
+      gener->SetSimpleJets(!isw);
+      gener->SetJetEtaRange(-0.12, 0.12);
+      gener->SetJetPhiRange(220., 320.);
+      gGener=gener;
+    }
+    break;
+
+  case kHijing_gj75:
+    {
+      comment = comment.Append("HIJING Gamma 75 GeV");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(0., 5.);
+      // trigger
+      gener->SetTrigger(2);
+      gener->SetPtJet(75.);
+      gener->SetRadiation(isw);
+      gener->SetSimpleJets(!isw);
+      gener->SetJetEtaRange(-0.12, 0.12);
+      gener->SetJetPhiRange(220., 320.);
+      gGener=gener;
+    }
+    break;
+
+  case kHijing_gj100:
+    {
+      comment = comment.Append("HIJING Gamma 100 GeV");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(0., 5.);
+      // trigger
+      gener->SetTrigger(2);
+      gener->SetPtJet(100.);
+      gener->SetRadiation(isw);
+      gener->SetSimpleJets(!isw);
+      gener->SetJetEtaRange(-0.12, 0.12);
+      gener->SetJetPhiRange(220., 320.);
+      gGener=gener;
+    }
+    break;
+
+  case kHijing_gj200:
+    {
+      comment = comment.Append("HIJING Gamma 200 GeV");
+      AliGenHijing *gener = HijingStandard();
+      // impact parameter range
+      gener->SetImpactParameterRange(0., 5.);
+      // trigger
+      gener->SetTrigger(2);
+      gener->SetPtJet(200.);
+      gener->SetRadiation(isw);
+      gener->SetSimpleJets(!isw);
+      gener->SetJetEtaRange(-0.12, 0.12);
+      gener->SetJetPhiRange(220., 320.);
+      gGener=gener;
+    }
+    break;
+  case kHijing_pA:
+    {
+      comment = comment.Append("HIJING pA");
+
+      AliGenCocktail *gener  = new AliGenCocktail();
+
+      AliGenHijing   *hijing = new AliGenHijing(-1);
+      // centre of mass energy 
+      hijing->SetEnergyCMS(TMath::Sqrt(82./208.) * 14000.);
+      // impact parameter range
+      hijing->SetImpactParameterRange(0., 15.);
+      // reference frame
+      hijing->SetReferenceFrame("CMS");
+      hijing->SetBoostLHC(1);
+      // projectile
+      hijing->SetProjectile("P", 1, 1);
+      hijing->SetTarget    ("A", 208, 82);
+      // tell hijing to keep the full parent child chain
+      hijing->KeepFullEvent();
+      // enable jet quenching
+      hijing->SetJetQuenching(0);
+      // enable shadowing
+      hijing->SetShadowing(1);
+      // Don't track spectators
+      hijing->SetSpectators(0);
+      // kinematic selection
+      hijing->SetSelectAll(0);
+      //
+      AliGenSlowNucleons*  gray    = new AliGenSlowNucleons(1);
+      AliSlowNucleonModel* model   = new AliSlowNucleonModelExp();
+      gray->SetSlowNucleonModel(model);
+      gray->SetDebug(1);
+      gener->AddGenerator(hijing,"Hijing pPb", 1);
+      gener->AddGenerator(gray,  "Gray Particles",1);
+      gGener=gener;
+    }
+    break;
+  case kPythia6:
+    {
+      comment = comment.Append(":Pythia p-p @ 14 TeV");
+      AliGenPythia *gener = new AliGenPythia(-1); 
+      gener->SetMomentumRange(0,999999);
+      gener->SetThetaRange(0., 180.);
+      gener->SetYRange(-12,12);
+      gener->SetPtRange(0,1000);
+      gener->SetProcess(kPyMb);
+      gener->SetEnergyCMS(14000.);
+      gGener=gener;
+    }
+    break;
+  case kPythia6Jets20_24:
+    {
+      comment = comment.Append(":Pythia jets 20-24 GeV @ 5.5 TeV");
+      AliGenPythia * gener = new AliGenPythia(-1);
+      gener->SetEnergyCMS(5500.);//        Centre of mass energy
+      gener->SetProcess(kPyJets);//        Process type
+      gener->SetJetEtaRange(-0.5, 0.5);//  Final state kinematic cuts
+      gener->SetJetPhiRange(0., 360.);
+      gener->SetJetEtRange(10., 1000.);
+      gener->SetGluonRadiation(1,1);
+      //    gener->SetPtKick(0.);
+      //   Structure function
+      gener->SetStrucFunc(kCTEQ4L);
+      gener->SetPtHard(20., 24.);// Pt transfer of the hard scattering
+      gener->SetPycellParameters(2., 274, 432, 0., 4., 5., 1.0);
+      gener->SetForceDecay(kAll);//  Decay type (semielectronic, etc.)
+      gGener=gener;
+    }
+    break;
+  case kPythia6Jets24_29:
+    {
+      comment = comment.Append(":Pythia jets 24-29 GeV @ 5.5 TeV");
+      AliGenPythia * gener = new AliGenPythia(-1);
+      gener->SetEnergyCMS(5500.);//        Centre of mass energy
+      gener->SetProcess(kPyJets);//        Process type
+      gener->SetJetEtaRange(-0.5, 0.5);//  Final state kinematic cuts
+      gener->SetJetPhiRange(0., 360.);
+      gener->SetJetEtRange(10., 1000.);
+      gener->SetGluonRadiation(1,1);
+      //    gener->SetPtKick(0.);
+      //   Structure function
+      gener->SetStrucFunc(kCTEQ4L);
+      gener->SetPtHard(24., 29.);// Pt transfer of the hard scattering
+      gener->SetPycellParameters(2., 274, 432, 0., 4., 5., 1.0);
+      gener->SetForceDecay(kAll);//  Decay type (semielectronic, etc.)
+      gGener=gener;
+    }
+    break;
+  case kPythia6Jets29_35:
+    {
+      comment = comment.Append(":Pythia jets 29-35 GeV @ 5.5 TeV");
+      AliGenPythia * gener = new AliGenPythia(-1);
+      gener->SetEnergyCMS(5500.);//        Centre of mass energy
+      gener->SetProcess(kPyJets);//        Process type
+      gener->SetJetEtaRange(-0.5, 0.5);//  Final state kinematic cuts
+      gener->SetJetPhiRange(0., 360.);
+      gener->SetJetEtRange(10., 1000.);
+      gener->SetGluonRadiation(1,1);
+      //    gener->SetPtKick(0.);
+      //   Structure function
+      gener->SetStrucFunc(kCTEQ4L);
+      gener->SetPtHard(29., 35.);// Pt transfer of the hard scattering
+      gener->SetPycellParameters(2., 274, 432, 0., 4., 5., 1.0);
+      gener->SetForceDecay(kAll);//  Decay type (semielectronic, etc.)
+      gGener=gener;
+    }
+    break;
+  case kPythia6Jets35_42:
+    {
+      comment = comment.Append(":Pythia jets 35-42 GeV @ 5.5 TeV");
+      AliGenPythia * gener = new AliGenPythia(-1);
+      gener->SetEnergyCMS(5500.);//        Centre of mass energy
+      gener->SetProcess(kPyJets);//        Process type
+      gener->SetJetEtaRange(-0.5, 0.5);//  Final state kinematic cuts
+      gener->SetJetPhiRange(0., 360.);
+      gener->SetJetEtRange(10., 1000.);
+      gener->SetGluonRadiation(1,1);
+      //    gener->SetPtKick(0.);
+      //   Structure function
+      gener->SetStrucFunc(kCTEQ4L);
+      gener->SetPtHard(35., 42.);// Pt transfer of the hard scattering
+      gener->SetPycellParameters(2., 274, 432, 0., 4., 5., 1.0);
+      gener->SetForceDecay(kAll);//  Decay type (semielectronic, etc.)
+      gGener=gener;
+    }
+    break;
+  case kPythia6Jets42_50:
+    {
+      comment = comment.Append(":Pythia jets 42-50 GeV @ 5.5 TeV");
+      AliGenPythia * gener = new AliGenPythia(-1);
+      gener->SetEnergyCMS(5500.);//        Centre of mass energy
+      gener->SetProcess(kPyJets);//        Process type
+      gener->SetJetEtaRange(-0.5, 0.5);//  Final state kinematic cuts
+      gener->SetJetPhiRange(0., 360.);
+      gener->SetJetEtRange(10., 1000.);
+      gener->SetGluonRadiation(1,1);
+      //    gener->SetPtKick(0.);
+      //   Structure function
+      gener->SetStrucFunc(kCTEQ4L);
+      gener->SetPtHard(42., 50.);// Pt transfer of the hard scattering
+      gener->SetPycellParameters(2., 274, 432, 0., 4., 5., 1.0);
+      gener->SetForceDecay(kAll);//  Decay type (semielectronic, etc.)
+      gGener=gener;
+    }
+    break;
+  case kPythia6Jets50_60:
+    {
+      comment = comment.Append(":Pythia jets 50-60 GeV @ 5.5 TeV");
+      AliGenPythia * gener = new AliGenPythia(-1);
+      gener->SetEnergyCMS(5500.);//        Centre of mass energy
+      gener->SetProcess(kPyJets);//        Process type
+      gener->SetJetEtaRange(-0.5, 0.5);//  Final state kinematic cuts
+      gener->SetJetPhiRange(0., 360.);
+      gener->SetJetEtRange(10., 1000.);
+      gener->SetGluonRadiation(1,1);
+      //    gener->SetPtKick(0.);
+      //   Structure function
+      gener->SetStrucFunc(kCTEQ4L);
+      gener->SetPtHard(50., 60.);// Pt transfer of the hard scattering
+      gener->SetPycellParameters(2., 274, 432, 0., 4., 5., 1.0);
+      gener->SetForceDecay(kAll);//  Decay type (semielectronic, etc.)
+      gGener=gener;
+    }
+    break;
+  case kPythia6Jets60_72:
+    {
+      comment = comment.Append(":Pythia jets 60-72 GeV @ 5.5 TeV");
+      AliGenPythia * gener = new AliGenPythia(-1);
+      gener->SetEnergyCMS(5500.);//        Centre of mass energy
+      gener->SetProcess(kPyJets);//        Process type
+      gener->SetJetEtaRange(-0.5, 0.5);//  Final state kinematic cuts
+      gener->SetJetPhiRange(0., 360.);
+      gener->SetJetEtRange(10., 1000.);
+      gener->SetGluonRadiation(1,1);
+      //    gener->SetPtKick(0.);
+      //   Structure function
+      gener->SetStrucFunc(kCTEQ4L);
+      gener->SetPtHard(60., 72.);// Pt transfer of the hard scattering
+      gener->SetPycellParameters(2., 274, 432, 0., 4., 5., 1.0);
+      gener->SetForceDecay(kAll);//  Decay type (semielectronic, etc.)
+      gGener=gener;
+    }
+    break;
+  case kPythia6Jets72_86:
+    {
+      comment = comment.Append(":Pythia jets 72-86 GeV @ 5.5 TeV");
+      AliGenPythia * gener = new AliGenPythia(-1);
+      gener->SetEnergyCMS(5500.);//        Centre of mass energy
+      gener->SetProcess(kPyJets);//        Process type
+      gener->SetJetEtaRange(-0.5, 0.5);//  Final state kinematic cuts
+      gener->SetJetPhiRange(0., 360.);
+      gener->SetJetEtRange(10., 1000.);
+      gener->SetGluonRadiation(1,1);
+      //    gener->SetPtKick(0.);
+      //   Structure function
+      gener->SetStrucFunc(kCTEQ4L);
+      gener->SetPtHard(72., 86.);// Pt transfer of the hard scattering
+      gener->SetPycellParameters(2., 274, 432, 0., 4., 5., 1.0);
+      gener->SetForceDecay(kAll);//  Decay type (semielectronic, etc.)
+      gGener=gener;
+    }
+    break;
+  case kPythia6Jets86_104:
+    {
+      comment = comment.Append(":Pythia jets 86-104 GeV @ 5.5 TeV");
+      AliGenPythia * gener = new AliGenPythia(-1);
+      gener->SetEnergyCMS(5500.);//        Centre of mass energy
+      gener->SetProcess(kPyJets);//        Process type
+      gener->SetJetEtaRange(-0.5, 0.5);//  Final state kinematic cuts
+      gener->SetJetPhiRange(0., 360.);
+      gener->SetJetEtRange(10., 1000.);
+      gener->SetGluonRadiation(1,1);
+      //    gener->SetPtKick(0.);
+      //   Structure function
+      gener->SetStrucFunc(kCTEQ4L);
+      gener->SetPtHard(86., 104.);// Pt transfer of the hard scattering
+      gener->SetPycellParameters(2., 274, 432, 0., 4., 5., 1.0);
+      gener->SetForceDecay(kAll);//  Decay type (semielectronic, etc.)
+      gGener=gener;
+    }
+    break;
+  case kPythia6Jets104_125:
+    {
+      comment = comment.Append(":Pythia jets 105-125 GeV @ 5.5 TeV");
+      AliGenPythia * gener = new AliGenPythia(-1);
+      gener->SetEnergyCMS(5500.);//        Centre of mass energy
+      gener->SetProcess(kPyJets);//        Process type
+      gener->SetJetEtaRange(-0.5, 0.5);//  Final state kinematic cuts
+      gener->SetJetPhiRange(0., 360.);
+      gener->SetJetEtRange(10., 1000.);
+      gener->SetGluonRadiation(1,1);
+      //    gener->SetPtKick(0.);
+      //   Structure function
+      gener->SetStrucFunc(kCTEQ4L);
+      gener->SetPtHard(104., 125.);// Pt transfer of the hard scattering
+      gener->SetPycellParameters(2., 274, 432, 0., 4., 5., 1.0);
+      gener->SetForceDecay(kAll);//  Decay type (semielectronic, etc.)
+      gGener=gener;
+    }
+    break;
+  case kPythia6Jets125_150:
+    {
+      comment = comment.Append(":Pythia jets 125-150 GeV @ 5.5 TeV");
+      AliGenPythia * gener = new AliGenPythia(-1);
+      gener->SetEnergyCMS(5500.);//        Centre of mass energy
+      gener->SetProcess(kPyJets);//        Process type
+      gener->SetJetEtaRange(-0.5, 0.5);//  Final state kinematic cuts
+      gener->SetJetPhiRange(0., 360.);
+      gener->SetJetEtRange(10., 1000.);
+      gener->SetGluonRadiation(1,1);
+      //    gener->SetPtKick(0.);
+      //   Structure function
+      gener->SetStrucFunc(kCTEQ4L);
+      gener->SetPtHard(125., 150.);// Pt transfer of the hard scattering
+      gener->SetPycellParameters(2., 274, 432, 0., 4., 5., 1.0);
+      gener->SetForceDecay(kAll);//  Decay type (semielectronic, etc.)
+      gGener=gener;
+    }
+    break;
+  case kPythia6Jets150_180:
+    {
+      comment = comment.Append(":Pythia jets 150-180 GeV @ 5.5 TeV");
+      AliGenPythia * gener = new AliGenPythia(-1);
+      gener->SetEnergyCMS(5500.);//        Centre of mass energy
+      gener->SetProcess(kPyJets);//        Process type
+      gener->SetJetEtaRange(-0.5, 0.5);//  Final state kinematic cuts
+      gener->SetJetPhiRange(0., 360.);
+      gener->SetJetEtRange(10., 1000.);
+      gener->SetGluonRadiation(1,1);
+      //    gener->SetPtKick(0.);
+      //   Structure function
+      gener->SetStrucFunc(kCTEQ4L);
+      gener->SetPtHard(150., 180.);// Pt transfer of the hard scattering
+      gener->SetPycellParameters(2., 274, 432, 0., 4., 5., 1.0);
+      gener->SetForceDecay(kAll);//  Decay type (semielectronic, etc.)
+      gGener=gener;
+    }
+    break;
+  case kD0PbPb5500:
+    {
+      comment = comment.Append(" D0 in Pb-Pb at 5.5 TeV");
+      AliGenPythia * gener = new AliGenPythia(10);
+      gener->SetProcess(kPyD0PbPbMNR);
+      gener->SetStrucFunc(kCTEQ4L);
+      gener->SetPtHard(2.1,-1.0);
+      gener->SetEnergyCMS(5500.);
+      gener->SetNuclei(208,208);
+      gener->SetForceDecay(kHadronicD);
+      gener->SetYRange(-2,2);
+      gener->SetFeedDownHigherFamily(kFALSE);
+      gener->SetStackFillOpt(AliGenPythia::kParentSelection);
+      gener->SetCountMode(AliGenPythia::kCountParents);
+      gGener=gener;
+    }
+    break;
+  case kCharmSemiElPbPb5500:
+    {
+      comment = comment.Append(" Charm in Pb-Pb at 5.5 TeV");
+      AliGenPythia * gener = new AliGenPythia(10);
+      gener->SetProcess(kPyCharmPbPbMNR);
+      gener->SetStrucFunc(kCTEQ4L);
+      gener->SetPtHard(2.1,-1.0);
+      gener->SetEnergyCMS(5500.);
+      gener->SetNuclei(208,208);
+      gener->SetForceDecay(kSemiElectronic);
+      gener->SetYRange(-2,2);
+      gener->SetFeedDownHigherFamily(kFALSE);
+      gener->SetCountMode(AliGenPythia::kCountParents);
+      gGener=gener;
+    }
+    break;
+  case kBeautySemiElPbPb5500:
+    {
+      comment = comment.Append(" Beauty in Pb-Pb at 5.5 TeV");
+      AliGenPythia *gener = new AliGenPythia(10);
+      gener->SetProcess(kPyBeautyPbPbMNR);
+      gener->SetStrucFunc(kCTEQ4L);
+      gener->SetPtHard(2.75,-1.0);
+      gener->SetEnergyCMS(5500.);
+      gener->SetNuclei(208,208);
+      gener->SetForceDecay(kSemiElectronic);
+      gener->SetYRange(-2,2);
+      gener->SetFeedDownHigherFamily(kFALSE);
+      gener->SetCountMode(AliGenPythia::kCountParents);
+      gGener=gener;
+    }
+    break;
+  case kCocktailTRD:
+    {
+      comment = comment.Append(" Cocktail for TRD at 5.5 TeV");
+      AliGenCocktail *gener  = new AliGenCocktail();
+
+      AliGenParam *jpsi = new AliGenParam(10,
+                                         new AliGenMUONlib(),
+                                         AliGenMUONlib::kJpsiFamily,
+                                         "Vogt PbPb");
+
+      jpsi->SetPtRange(0, 100);
+      jpsi->SetYRange(-1., +1.);
+      jpsi->SetForceDecay(kDiElectron);
+
+      AliGenParam *ups = new AliGenParam(10,
+                                        new AliGenMUONlib(),
+                                        AliGenMUONlib::kUpsilonFamily,
+                                        "Vogt PbPb");
+      ups->SetPtRange(0, 100);
+      ups->SetYRange(-1., +1.);
+      ups->SetForceDecay(kDiElectron);
+       
+      AliGenParam *charm = new AliGenParam(10,
+                                          new AliGenMUONlib(), 
+                                          AliGenMUONlib::kCharm,
+                                          "central");
+      charm->SetPtRange(0, 100);
+      charm->SetYRange(-1.5, +1.5);
+      charm->SetForceDecay(kSemiElectronic);
+       
+       
+      AliGenParam *beauty = new AliGenParam(10,
+                                           new AliGenMUONlib(), 
+                                           AliGenMUONlib::kBeauty,
+                                           "central");
+      beauty->SetPtRange(0, 100);
+      beauty->SetYRange(-1.5, +1.5);
+      beauty->SetForceDecay(kSemiElectronic);
+
+      gener->AddGenerator(jpsi,"J/psi",1);
+      gener->AddGenerator(ups,"Upsilon",1);
+      gener->AddGenerator(charm,"Charm",1);
+      gener->AddGenerator(beauty,"Beauty",1);
+      gGener=gener;
+    }
+    break;
+  case kPyJJ:
+    {
+      comment = comment.Append(" Jet-jet at 5.5 TeV");
+      AliGenPythia *gener = new AliGenPythia(-1);
+      gener->SetEnergyCMS(5500.);
+      gener->SetProcess(kPyJets);
+      Double_t ptHardMin=10.0, ptHardMax=-1.0;
+      gener->SetPtHard(ptHardMin,ptHardMax);
+      gener->SetYHard(-0.7,0.7);
+      gener->SetJetEtaRange(-0.2,0.2);
+      gener->SetEventListRange(0,1);
+      gGener=gener;
+    }
+    break;
+  case kPyGJ:
+    {
+      comment = comment.Append(" Gamma-jet at 5.5 TeV");
+      AliGenPythia *gener = new AliGenPythia(-1);
+      gener->SetEnergyCMS(5500.);
+      gener->SetProcess(kPyDirectGamma);
+      Double_t ptHardMin=10.0, ptHardMax=-1.0;
+      gener->SetPtHard(ptHardMin,ptHardMax);
+      gener->SetYHard(-1.0,1.0);
+      gener->SetGammaEtaRange(-0.13,0.13);
+      gener->SetGammaPhiRange(210.,330.);
+      gener->SetEventListRange(0,1);
+      gGener=gener;
+    }
+    break;
+  case kMuonCocktailCent1:
+    {
+      comment = comment.Append(" Muon Cocktail Cent1");
+      AliGenMUONCocktail * gener = new AliGenMUONCocktail();
+      gener->SetPtRange(1.0,100.);       // Transverse momentum range   
+      gener->SetPhiRange(0.,360.);    // Azimuthal angle range  
+      gener->SetYRange(-4.0,-2.4);
+      gener->SetMuonPtCut(0.8);
+      gener->SetMuonThetaCut(171.,178.);
+      gener->SetMuonMultiplicity(2);
+      gener->SetNumberOfCollisions(1626.);  //Centrality class Cent1 for PDC04
+      gener->SetNumberOfParticipants(359.4);//Centrality class Cent1 for PDC04
+      gGener=gener;
+    }
+    break;
+  case kMuonCocktailPer1:
+    {
+      comment = comment.Append(" Muon Cocktail Per1");
+      AliGenMUONCocktail * gener = new AliGenMUONCocktail();
+      gener->SetPtRange(1.0,100.);       // Transverse momentum range   
+      gener->SetPhiRange(0.,360.);    // Azimuthal angle range  
+      gener->SetYRange(-4.0,-2.4);
+      gener->SetMuonPtCut(0.8);
+      gener->SetMuonThetaCut(171.,178.);
+      gener->SetMuonMultiplicity(2);
+      gener->SetNumberOfCollisions(820.0);//Centrality class Per1 for PDC04
+      gener->SetNumberOfParticipants(229.3);//Centrality class Per1 for PDC04
+      gGener=gener;
+    }
+    break;
+  case kMuonCocktailPer4:
+    {
+      comment = comment.Append(" Muon Cocktail Per4");
+      AliGenMUONCocktail * gener = new AliGenMUONCocktail();
+      gener->SetPtRange(1.0,100.);       // Transverse momentum range   
+      gener->SetPhiRange(0.,360.);    // Azimuthal angle range  
+      gener->SetYRange(-4.0,-2.4);
+      gener->SetMuonPtCut(0.8);
+      gener->SetMuonThetaCut(171.,178.);
+      gener->SetMuonMultiplicity(2);
+      gener->SetNumberOfCollisions(13.6);//Centrality class Per4 for PDC04
+      gener->SetNumberOfParticipants(13.3);//Centrality class Per4 for PDC04
+      gGener=gener;
+    }
+    break;
+  case kMuonCocktailCent1HighPt:
+    {
+      comment = comment.Append(" Muon Cocktail HighPt Cent1");
+      AliGenMUONCocktail * gener = new AliGenMUONCocktail();
+      gener->SetPtRange(1.0,100.);       // Transverse momentum range   
+      gener->SetPhiRange(0.,360.);    // Azimuthal angle range  
+      gener->SetYRange(-4.0,-2.4);
+      gener->SetMuonPtCut(2.5);
+      gener->SetMuonThetaCut(171.,178.);
+      gener->SetMuonMultiplicity(2);
+      gener->SetNumberOfCollisions(1626.);  //Centrality class Cent1 for PDC04
+      gener->SetNumberOfParticipants(359.4);//Centrality class Cent1 for PDC04
+      gGener=gener;
+    }
+    break;
+  case kMuonCocktailPer1HighPt :
+    {
+      comment = comment.Append(" Muon Cocktail HighPt Per1");
+      AliGenMUONCocktail * gener = new AliGenMUONCocktail();
+      gener->SetPtRange(1.0,100.);       // Transverse momentum range   
+      gener->SetPhiRange(0.,360.);    // Azimuthal angle range  
+      gener->SetYRange(-4.0,-2.4);
+      gener->SetMuonPtCut(2.5);
+      gener->SetMuonThetaCut(171.,178.);
+      gener->SetMuonMultiplicity(2);
+      gener->SetNumberOfCollisions(820.0);//Centrality class Per1 for PDC04
+      gener->SetNumberOfParticipants(229.3);//Centrality class Per1 for PDC04
+      gGener=gener;
+    }
+    break;
+  case kMuonCocktailPer4HighPt:
+    {
+      comment = comment.Append(" Muon Cocktail HighPt Per4");
+      AliGenMUONCocktail * gener = new AliGenMUONCocktail();
+      gener->SetPtRange(1.0,100.);       // Transverse momentum range   
+      gener->SetPhiRange(0.,360.);    // Azimuthal angle range  
+      gener->SetYRange(-4.0,-2.4);
+      gener->SetMuonPtCut(2.5);
+      gener->SetMuonThetaCut(171.,178.);
+      gener->SetMuonMultiplicity(2);
+      gener->SetNumberOfCollisions(13.6);//Centrality class Per4 for PDC04
+      gener->SetNumberOfParticipants(13.3);//Centrality class Per4 for PDC04
+      gGener=gener;
+    }
+    break;
+  case kMuonCocktailCent1Single:
+    {
+      comment = comment.Append(" Muon Cocktail Single Cent1");
+      AliGenMUONCocktail * gener = new AliGenMUONCocktail();
+      gener->SetPtRange(1.0,100.);       // Transverse momentum range   
+      gener->SetPhiRange(0.,360.);    // Azimuthal angle range  
+      gener->SetYRange(-4.0,-2.4);
+      gener->SetMuonPtCut(0.8);
+      gener->SetMuonThetaCut(171.,178.);
+      gener->SetMuonMultiplicity(1);
+      gener->SetNumberOfCollisions(1626.);  //Centrality class Cent1 for PDC04
+      gener->SetNumberOfParticipants(359.4);//Centrality class Cent1 for PDC04
+      gGener=gener;
+    }
+    break;
+  case kMuonCocktailPer1Single :
+    {
+      comment = comment.Append(" Muon Cocktail Single Per1");
+      AliGenMUONCocktail * gener = new AliGenMUONCocktail();
+      gener->SetPtRange(1.0,100.);       // Transverse momentum range   
+      gener->SetPhiRange(0.,360.);    // Azimuthal angle range  
+      gener->SetYRange(-4.0,-2.4);
+      gener->SetMuonPtCut(0.8);
+      gener->SetMuonThetaCut(171.,178.);
+      gener->SetMuonMultiplicity(1);
+      gener->SetNumberOfCollisions(820.0);//Centrality class Per1 for PDC04
+      gener->SetNumberOfParticipants(229.3);//Centrality class Per1 for PDC04
+      gGener=gener;
+    }
+    break;
+  case kMuonCocktailPer4Single:
+    {
+      comment = comment.Append(" Muon Cocktail Single Per4");
+      AliGenMUONCocktail * gener = new AliGenMUONCocktail();
+      gener->SetPtRange(1.0,100.);       // Transverse momentum range   
+      gener->SetPhiRange(0.,360.);    // Azimuthal angle range  
+      gener->SetYRange(-4.0,-2.4);
+      gener->SetMuonPtCut(0.8);
+      gener->SetMuonThetaCut(171.,178.);
+      gener->SetMuonMultiplicity(1);
+      gener->SetNumberOfCollisions(13.6);//Centrality class Per4 for PDC04
+      gener->SetNumberOfParticipants(13.3);//Centrality class Per4 for PDC04
+      gGener=gener;
+    }
+    break;
+  case kFMD1Flat: 
+    {
+      comment = comment.Append(" Flat in FMD1 range");
+      AliGenBox* gener = new AliGenBox(2000);
+      gener->SetPart(211);
+      gener->SetMomentumRange(3,4);
+      gener->SetPhiRange(0, 360);
+      gener->SetThetaRange(0.77, 3.08);
+      gGener = gener;
+    }
+    break;
+  case kFMD2Flat: 
+    {
+      comment = comment.Append(" Flat in FMD2 range");
+      AliGenBox* gener = new AliGenBox(2000);
+      gener->SetPart(211);
+      gener->SetMomentumRange(3,4);
+      gener->SetPhiRange(0, 360);
+      gener->SetThetaRange(2.95, 20.42);
+      gGener = gener;
+    }
+    break;
+  case kFMD3Flat: 
+    {
+      comment = comment.Append(" Flat in FMD3 range");
+      AliGenBox* gener = new AliGenBox(2000);
+      gener->SetPart(211);
+      gener->SetMomentumRange(3,4);
+      gener->SetPhiRange(0, 360);
+      gener->SetThetaRange(155.97, 176.73);
+      gGener = gener;
+    }
+    break;
+  case kFMDFlat:
+    {
+      comment = comment.Append(" Flat in FMD range");
+      AliGenCocktail* gener = new AliGenCocktail();
+      gener->SetMomentumRange(3,4);
+      gener->SetPhiRange(0, 360);
+      AliGenBox* gener3 = new AliGenBox(2000);
+      gener3->SetThetaRange(155.97, 176.73);
+      gener3->SetPart(211);
+      gener->AddGenerator(gener3, "FMD3", .33);
+      AliGenBox* gener2 = new AliGenBox(2000);
+      gener2->SetThetaRange(2.95, 20.42);
+      gener2->SetPart(211);
+      gener->AddGenerator(gener2, "FMD2", .33);
+      AliGenBox* gener1 = new AliGenBox(2000);
+      gener1->SetThetaRange(0.77, 3.08);
+      gener1->SetPart(211);
+      gener->AddGenerator(gener1, "FMD1", .34);
+      gGener = gener;
+    }
+    break;
+    
+  default: break;
+  }
+  return gGener;
+}
+
+//____________________________________________________________________
+AliGenHijing* 
+HijingStandard()
+{
+  AliGenHijing *gener = new AliGenHijing(-1);
+  // centre of mass energy 
+  gener->SetEnergyCMS(5500.);
+  // reference frame
+  gener->SetReferenceFrame("CMS");
+  // projectile
+  gener->SetProjectile("A", 208, 82);
+  gener->SetTarget    ("A", 208, 82);
+  // tell hijing to keep the full parent child chain
+  gener->KeepFullEvent();
+  // enable jet quenching
+  gener->SetJetQuenching(1);
+  // enable shadowing
+  gener->SetShadowing(1);
+  // neutral pion and heavy particle decays switched off
+  gener->SetDecaysOff(1);
+  // Don't track spectators
+  gener->SetSpectators(0);
+  // kinematic selection
+  gener->SetSelectAll(0);
+  return gener;
+}
+
+
+//____________________________________________________________________
+void 
+ProcessEnvironmentVars(EG_t& eg, Int_t& seed)
+{
+  // Run type
+  if (gSystem->Getenv("CONFIG_RUN_TYPE")) {
+    Int_t eg1 = LookupEG(gSystem->Getenv("CONFIG_RUN_TYPE"));
+    if  (eg1 >= 0) eg = EG_t(eg1);
+  }
+  // Random Number seed
+  if (gSystem->Getenv("CONFIG_SEED")) {
+    seed = atoi(gSystem->Getenv("CONFIG_SEED"));
+  }
+}
+
+//____________________________________________________________________
+//
+// EOF
+// 
diff --git a/FMD/scripts/FancyDigits.C b/FMD/scripts/FancyDigits.C
new file mode 100644 (file)
index 0000000..27cea2f
--- /dev/null
@@ -0,0 +1,25 @@
+//____________________________________________________________________
+//
+// $Id$
+//
+// Draw hits in the specialised FMD event fancy 
+//
+/** Fancy hits 
+    @ingroup FMD_script
+ */
+void
+FancyDigits()
+{
+  AliCDBManager* cdb = AliCDBManager::Instance();
+  cdb->SetDefaultStorage("local://$ALICE_ROOT");
+  gSystem->Load("libFMDutil.so");
+  AliFMDFancy* d = new AliFMDFancy;
+  d->AddLoad(AliFMDInput::kDigits);
+  // d->AddLoad(AliFMDInput::kKinematics);
+  d->Run();
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
diff --git a/FMD/scripts/FancyHits.C b/FMD/scripts/FancyHits.C
new file mode 100644 (file)
index 0000000..d7f880d
--- /dev/null
@@ -0,0 +1,25 @@
+//____________________________________________________________________
+//
+// $Id$
+//
+// Draw hits in the specialised FMD event fancy 
+//
+/** Fancy hits 
+    @ingroup FMD_script
+ */
+void
+FancyHits()
+{
+  AliCDBManager* cdb = AliCDBManager::Instance();
+  cdb->SetDefaultStorage("local://$ALICE_ROOT");
+  gSystem->Load("libFMDutil.so");
+  AliFMDFancy* d = new AliFMDFancy;
+  d->AddLoad(AliFMDInput::kHits);
+  d->AddLoad(AliFMDInput::kKinematics);
+  d->Run();
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
diff --git a/FMD/scripts/LoadDummy.C b/FMD/scripts/LoadDummy.C
new file mode 100644 (file)
index 0000000..5c2ba56
--- /dev/null
@@ -0,0 +1,32 @@
+//
+//
+//
+Bool_t
+LoadDummy()
+{
+  const char*  alice_root = gSystem->Getenv("ALICE_ROOT");
+  const char*  dirs[]     = { "", "include", "ITS", 0 };
+  const char** d          = dirs;
+  TString newpath("-DCOMPILING=1 ");
+  newpath += gSystem->GetIncludePath();
+  do {
+    TString flag(Form("-I%s/%s", alice_root, *d));
+    if (newpath.Index(flag) == TString::kNPOS) {
+      std::cerr << "Adding " << flag << std::endl;
+      newpath += " ";
+      newpath += flag;
+    }
+  } while (*(++d));
+
+  gSystem->SetIncludePath(newpath.Data());
+  std::cout << "Include path is\n\t" << gSystem->GetIncludePath() << std::endl;
+  gROOT->LoadMacro("Dummy.C+g");
+  if (!gROOT->GetClass("Dummy<AliITSvPPRasymmFMD>")) {
+    std::cerr << "Failed to make DummyITS" << std::endl;
+    return kFALSE;
+  }
+  return kTRUE;
+}
+//
+// EOF
+//
index e787d46..68a8bfd 100644 (file)
 /** Make fake calibration data 
     @ingroup simple_script
  */
+Float_t
+AdcPerMip2Gain(Int_t adc) 
+{
+  return 1. / adc * AliFMDParameters::Instance()->GetEdepMip();
+}
+
 void
 MakeCalibration()
 {
@@ -21,9 +27,9 @@ MakeCalibration()
   gSystem->Load("libFMDutil.so");
   AliFMDCalibFaker f(AliFMDCalibFaker::kAll, 0);
   f.SetRunRange(0,0);
-  f.SetGainSeed(.002272);
+  f.SetGainSeed(AdcPerMip2Gain(60)); // From astrid test beam 
   f.SetThresholdFactor(3);
-  f.SetPedestalRange(20,40);
+  f.SetPedestalRange(80,130); // From ASTRID test-beam
   f.SetDeadChance(0);
   f.SetZeroThreshold(0);
   f.SetStripRange(0, 127);
diff --git a/FMD/scripts/PatternDigits.C b/FMD/scripts/PatternDigits.C
new file mode 100644 (file)
index 0000000..3284fac
--- /dev/null
@@ -0,0 +1,25 @@
+//____________________________________________________________________
+//
+// $Id$
+//
+// Draw hits in the specialised FMD event display 
+//
+/** Display hits 
+    @ingroup FMD_script
+ */
+void
+PatternDigits()
+{
+  // AliCDBManager* cdb = AliCDBManager::Instance();
+  // cdb->SetDefaultStorage("local://$ALICE_ROOT");
+  gSystem->Load("libFMDutil.so");
+  AliFMDPattern* d = new AliFMDPattern;
+  d->AddLoad(AliFMDInput::kDigits);
+  // d->AddLoad(AliFMDInput::kKinematics);
+  d->Run();
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
diff --git a/FMD/scripts/PatternESD.C b/FMD/scripts/PatternESD.C
new file mode 100644 (file)
index 0000000..cf37509
--- /dev/null
@@ -0,0 +1,25 @@
+//____________________________________________________________________
+//
+// $Id$
+//
+// Draw hits in the specialised FMD event display 
+//
+/** Display hits 
+    @ingroup FMD_script
+ */
+void
+PatternESD()
+{
+  AliCDBManager* cdb = AliCDBManager::Instance();
+  cdb->SetDefaultStorage("local://$ALICE_ROOT");
+  gSystem->Load("libFMDutil.so");
+  AliFMDPattern* d = new AliFMDPattern;
+  d->SetMultiplicityCut(0);
+  d->AddLoad(AliFMDInput::kESD);
+  d->Run();
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
diff --git a/FMD/scripts/PatternHits.C b/FMD/scripts/PatternHits.C
new file mode 100644 (file)
index 0000000..625ac1d
--- /dev/null
@@ -0,0 +1,25 @@
+//____________________________________________________________________
+//
+// $Id$
+//
+// Draw hits in the specialised FMD event display 
+//
+/** Pattern hits 
+    @ingroup FMD_script
+ */
+void
+PatternHits()
+{
+  // AliCDBManager* cdb = AliCDBManager::Instance();
+  // cdb->SetDefaultStorage("local://cdb");
+  gSystem->Load("libFMDutil.so");
+  AliFMDPattern* d = new AliFMDPattern;
+  d->AddLoad(AliFMDInput::kHits);
+  // d->AddLoad(AliFMDInput::kKinematics);
+  d->Run();
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
diff --git a/FMD/scripts/PatternRecs.C b/FMD/scripts/PatternRecs.C
new file mode 100644 (file)
index 0000000..741ed4d
--- /dev/null
@@ -0,0 +1,26 @@
+//____________________________________________________________________
+//
+// $Id$
+//
+// Draw hits in the specialised FMD event pattern 
+//
+/** Pattern hits 
+    @ingroup FMD_script
+ */
+void
+PatternRecs()
+{
+  AliCDBManager* cdb = AliCDBManager::Instance();
+  cdb->SetDefaultStorage("local://$ALICE_ROOT");
+  gSystem->Load("libFMDutil.so");
+  AliFMDPattern* d = new AliFMDPattern;
+  d->AddLoad(AliFMDInput::kRecPoints);
+  // d->AddLoad(AliFMDInput::kDigits);
+  // d->AddLoad(AliFMDInput::kKinematics);
+  d->Run();
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
index 0c0a112..0f23165 100644 (file)
@@ -2,7 +2,7 @@
 //
 // $Id$
 //
-// Make fake alignment data.
+// Print calibration constants
 //
 /** @file    PrintCalibration.C
     @author  Christian Holm Christensen <cholm@nbi.dk>
     @ingroup simple_script
  */
 void
-PrintCalibration()
+PrintCalibration(Int_t r=0, const char* what="gain")
 {
   AliCDBManager* cdb   = AliCDBManager::Instance();
   cdb->SetDefaultStorage("local://$ALICE_ROOT");
-  cdb->SetRun(0);
+  cdb->SetRun(r);
   AliFMDParameters* p = AliFMDParameters::Instance();
-  p->Init();
-  p->Print("fmd1I[0,0]");
-  p->Draw("pedestal");
+  p->Init(kTRUE);
+  p->Print("fmd3*[8,0]");
+  // p->Draw(what);
 }
 //____________________________________________________________________
 //
index fa28cd1..85e7b3c 100644 (file)
@@ -79,9 +79,9 @@ CheckTrans(UShort_t det, Char_t ring, UShort_t sec, UShort_t str,
           UShort_t odet, Char_t oring, UShort_t osec, UShort_t ostr)
 {
   if (det != odet) 
-    Waring("TestHWMap", "Detector # differ %d != %d", det, odet);
+    Warning("TestHWMap", "Detector # differ %d != %d", det, odet);
   if (ring != oring) 
-    Waring("TestHWMap", "Ring Id differ %c != %c", ring, oring);  
+    Warning("TestHWMap", "Ring Id differ %c != %c", ring, oring);  
   if (sec != osec) 
     Warning("TestHWMap", "Sector # differ %d != %d", sec, osec);
   if (str != ostr) 
@@ -92,12 +92,14 @@ CheckTrans(UShort_t det, Char_t ring, UShort_t sec, UShort_t str,
 /** @ingroup ALTRO_test
  */
 void
-TestAltroMapping()
+TestAltroMapping(Int_t min=2, Int_t max=0)
 {
+  // if (min < 1 || min > 3) min = 1;
+  if (max < min)          max = min;
   AliFMDParameters* param = AliFMDParameters::Instance();
   AliFMDAltroMapping m;
   
-  for (UShort_t det = 2; det <= 2; det++) {
+  for (UShort_t det = min; det <= max; det++) {
     for (UShort_t rng = 0; rng < 2; rng++) {
       Char_t ring = (rng == 0 ? 'I' : 'O');
       Int_t  nsec = (ring == 'I' ?  20 :  40);
diff --git a/FMD/scripts/TestMap.C b/FMD/scripts/TestMap.C
new file mode 100644 (file)
index 0000000..7c18872
--- /dev/null
@@ -0,0 +1,84 @@
+//____________________________________________________________________
+//
+// $Id$
+//
+// Test I/O of ALiFMDMap
+//
+/** @file    TestMap.C
+    @author  Christian Holm Christensen <cholm@nbi.dk>
+    @date    Sat Dec 16 01:29:03 2006
+    @brief   Test of uniquenss of map
+    @ingroup FMD_script     
+*/
+#include "STEER/AliFMDFloatMap.h"
+#include <TArrayI.h>
+#include <iostream>
+#include <iomanip>
+#include <map>
+
+struct Check 
+{
+  UShort_t d;
+  Char_t   r;
+  UShort_t s;
+  UShort_t t;
+  Float_t  v;
+};
+
+std::ostream& operator<<(std::ostream& o, const Check& c) 
+{
+  UShort_t v = UShort_t(c.v);
+  o << "FMD" << c.d << c.r << '[' 
+    << std::setw(2) << c.s << ',' 
+    << std::setw(3) << c.t << "] (" 
+    << std::setw(6) << v << ')';
+   return o;
+}
+
+Check Name(UShort_t d, Char_t r, UShort_t s, UShort_t t, Float_t v) 
+{
+  Check c;
+  c.d = d;
+  c.r = r;
+  c.s = s;
+  c.t = t;
+  c.v = v;
+  return c;
+}
+
+
+void
+TestMap() 
+{
+  AliFMDFloatMap m;
+  // m.SetBit(AliFMDMap::kNeedUShort);
+  typedef std::map<Int_t, Check> CheckMap;
+  CheckMap c;
+  
+  for (UShort_t d = 1; d <= 3; d++) {
+    Char_t rings[] = { 'I', 'O', '\0' };
+    for (Char_t* rp = rings; *rp; rp++) {
+      Char_t r = *rp;
+      std::cout << "FMD" << d << r << " " << std::flush;
+      for (UShort_t s = 0; s < 40; s++) {
+       std::cout << "." << std::flush;
+       for (UShort_t t = 0; t < 512; t++) {
+         Int_t i = m.CheckIndex(d, r, s, t);
+         CheckMap::iterator z = c.find(i);
+         Float_t v = (t + 512 * (s + 40 * ((r=='I'? 0 : 1) + 2 * d)));
+         if (z != c.end()) 
+           std::cout << '\n' << Name(d,r,s,t,v)  << " but aleady seen " 
+                     << z->second  << std::flush;
+         else {
+           m(d,r,s,t) = v;
+           c[i] = Name(d,r,s,t,v);
+         } // else
+       } // for t
+      } // for s 
+      std::cout << "done" << std::endl;
+    }
+  }
+}
+
+    
+