]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Adding the new detector MFT (Antonio Uras)
authorhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 20 Oct 2011 19:26:08 +0000 (19:26 +0000)
committerhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 20 Oct 2011 19:26:08 +0000 (19:26 +0000)
91 files changed:
ALIROOT/CMakebinaliroot.pkg
CMakeLists.txt
HLT/BASE/AliHLTModulePreprocessor.cxx
MFT/AliESDEventMFT.cxx [new file with mode: 0644]
MFT/AliESDEventMFT.h [new file with mode: 0644]
MFT/AliMFT.cxx [new file with mode: 0644]
MFT/AliMFT.h [new file with mode: 0644]
MFT/AliMFTCluster.cxx [new file with mode: 0644]
MFT/AliMFTCluster.h [new file with mode: 0644]
MFT/AliMFTClusterFinder.cxx [new file with mode: 0644]
MFT/AliMFTClusterFinder.h [new file with mode: 0644]
MFT/AliMFTClusterQA.C [new file with mode: 0644]
MFT/AliMFTClusterQA.cxx [new file with mode: 0644]
MFT/AliMFTClusterQA.h [new file with mode: 0644]
MFT/AliMFTDigit.cxx [new file with mode: 0644]
MFT/AliMFTDigit.h [new file with mode: 0644]
MFT/AliMFTDigitizer.cxx [new file with mode: 0644]
MFT/AliMFTDigitizer.h [new file with mode: 0644]
MFT/AliMFTGeometry.root [new file with mode: 0644]
MFT/AliMFTHit.cxx [new file with mode: 0644]
MFT/AliMFTHit.h [new file with mode: 0644]
MFT/AliMFTPlane.cxx [new file with mode: 0644]
MFT/AliMFTPlane.h [new file with mode: 0644]
MFT/AliMFTReconstructor.cxx [new file with mode: 0644]
MFT/AliMFTReconstructor.h [new file with mode: 0644]
MFT/AliMFTSegmentation.cxx [new file with mode: 0644]
MFT/AliMFTSegmentation.h [new file with mode: 0644]
MFT/AliMuonForwardTrack.cxx [new file with mode: 0644]
MFT/AliMuonForwardTrack.h [new file with mode: 0644]
MFT/AliMuonForwardTrackFinder.C [new file with mode: 0644]
MFT/AliMuonForwardTrackFinder.cxx [new file with mode: 0644]
MFT/AliMuonForwardTrackFinder.h [new file with mode: 0644]
MFT/AliMuonForwardTrackPair.cxx [new file with mode: 0644]
MFT/AliMuonForwardTrackPair.h [new file with mode: 0644]
MFT/CMakelibMFTbase.pkg [new file with mode: 0644]
MFT/CMakelibMFTrec.pkg [new file with mode: 0644]
MFT/CMakelibMFTsim.pkg [new file with mode: 0644]
MFT/MFTbaseLinkDef.h [new file with mode: 0644]
MFT/MFTrecLinkDef.h [new file with mode: 0644]
MFT/MFTsimLinkDef.h [new file with mode: 0644]
MFT/SetMFTGeometry.C [new file with mode: 0644]
MUON/AliMUONTrack.cxx
MUON/runSimulation.C
OCDB/MFT/Align/Data/Run0_999999999_v0_s0.root [new file with mode: 0755]
OCDB/MFT/Calib/Data/Run0_9999999_v0_s0.root [new file with mode: 0755]
PWG1/TPC/macros/LoadMyLibs.C
STEER/AOD/AliAODEvent.cxx
STEER/AOD/AliAODEvent.h
STEER/CDB/AliCDBLocal.cxx
STEER/CDB/AliShuttleInterface.cxx
STEER/CDB/AliShuttleInterface.h
STEER/CMakelibAOD.pkg
STEER/CMakelibESD.pkg
STEER/CMakelibSTEERBase.pkg
STEER/ESD/AliESD.cxx
STEER/ESD/AliESD.h
STEER/ESD/AliESDEvent.cxx
STEER/ESD/AliESDEvent.h
STEER/ESD/AliTriggerInput.cxx
STEER/ESDLinkDef.h
STEER/STEER/AliGRPObject.cxx
STEER/STEER/AliGeomManager.cxx
STEER/STEER/AliGeomManager.h
STEER/STEER/AliQAv1.cxx
STEER/STEER/AliQAv1.h
STEER/STEER/AliRecoParam.h
STEER/STEER/AliReconstruction.cxx
STEER/STEER/AliReconstruction.h
STEER/STEER/AliReconstructor.cxx
STEER/STEER/AliRunLoader.cxx
STEER/STEER/AliSimulation.cxx
STEER/STEER/AliSimulation.h
STEER/STEERBase/AliDAQ.cxx
STEER/STEERBase/AliDAQ.h
STEER/STEERBase/AliDetectorTag.h
STEER/STEERBase/AliMCEvent.h
STEER/STEERBase/AliQA.cxx
STEER/STEERBase/AliQA.h
STEER/STEERBase/AliTrackReference.h
STEER/STEERBase/AliVEvent.h
STEER/STEERBase/AliVMFT.cxx [new file with mode: 0644]
STEER/STEERBase/AliVMFT.h [new file with mode: 0644]
STEER/STEERBaseLinkDef.h
STRUCT/AliPIPEv4.cxx [new file with mode: 0644]
STRUCT/AliPIPEv4.h [new file with mode: 0644]
STRUCT/CMakelibSTRUCT.pkg
STRUCT/STRUCTLinkDef.h
cmake/CMakeDA.cmake
macros/loadlibs.C
macros/loadlibsrec.C
macros/loadlibssim.C

index cf7a6bfb839676aa16bfb05b128ab8e62097320f..49a79918e86fb07c1f218aa811afd1df978ceea6 100644 (file)
@@ -31,7 +31,13 @@ set ( CSRCS fpu.c)
 
 set ( ELIBSDIR )
 
+set(MFT_UPGRADE $ENV{MFT_UPGRADE})
+  
+if(MFT_UPGRADE)
+set ( ELIBS  MUONevaluation    MUONmapping MUONshuttle MUONgraphics MUONsim MUONrec MUONgeometry MUONcalib MUONbase MUONraw MUONtrigger MUONcore TPCbase TPCsim TPCrec TPCfast ITSbase ITSsim ITSrec PMDbase PMDsim PMDrec TRDbase TRDsim TRDrec FMDbase FMDsim FMDrec TOFbase TOFrec TOFsim PHOSUtils PHOSbase PHOSsim PHOSrec ACORDEbase ACORDEsim ACORDErec HMPIDbase HMPIDrec HMPIDsim ZDCbase ZDCsim ZDCrec VZERObase VZEROsim VZEROrec MFTbase MFTsim MFTrec EMCALUtils EMCALbase EMCALsim EMCALrec EMCALraw BCM STRUCT T0base T0sim T0rec FASTSIM microcern HLTbase TRIGGERbase STEER STAT CDB AOD  STEERBase ESD ANALYSIS RAWDatasim RAWDatarec RAWDatabase)
+else(MFT_UPGRADE)
 set ( ELIBS  MUONevaluation    MUONmapping MUONshuttle MUONgraphics MUONsim MUONrec MUONgeometry MUONcalib MUONbase MUONraw MUONtrigger MUONcore TPCbase TPCsim TPCrec TPCfast ITSbase ITSsim ITSrec PMDbase PMDsim PMDrec TRDbase TRDsim TRDrec FMDbase FMDsim FMDrec TOFbase TOFrec TOFsim PHOSUtils PHOSbase PHOSsim PHOSrec ACORDEbase ACORDEsim ACORDErec HMPIDbase HMPIDrec HMPIDsim ZDCbase ZDCsim ZDCrec VZERObase VZEROsim VZEROrec EMCALUtils EMCALbase EMCALsim EMCALrec EMCALraw BCM STRUCT T0base T0sim T0rec FASTSIM microcern HLTbase TRIGGERbase STEER STAT CDB AOD  STEERBase ESD ANALYSIS RAWDatasim RAWDatarec RAWDatabase)
+endif(MFT_UPGRADE)
 
 if(PYTHIA6)
   list(APPEND ELIBS EVGEN)
@@ -48,7 +54,11 @@ if( ALICE_TARGET STREQUAL "macosx")
 
 endif( ALICE_TARGET STREQUAL "macosx")
 
-set (ARPACKS FMDbase FMDsim FMDrec ACORDEbase ACORDEsim ACORDErec HMPIDbase HMPIDsim HMPIDrec ZDCbase ZDCsim ZDCrec VZERObase VZEROsim VZEROrec EMCALUtils EMCALbase EMCALsim EMCALrec T0base T0sim T0rec TOFbase TOFsim TOFrec TRDbase TRDsim TRDrec PMDbase PMDsim PMDrec MUONmapping MUONmapping MUONgeometry MUONbase MUONsim MUONrec MUONraw PHOSUtils PHOSbase PHOSsim PHOSrec HLTbase ITSbase ITSsim ITSrec STRUCT TPCbase TPCsim TPCrec TPCfast STEER CDB ESD STEERBase RAWDatabase RAWDatasim RAWDatarec MDC TRIGGERbase)
+if(MFT_UPGRADE)
+  set (ARPACKS FMDbase FMDsim FMDrec ACORDEbase ACORDEsim ACORDErec HMPIDbase HMPIDsim HMPIDrec ZDCbase ZDCsim ZDCrec VZERObase VZEROsim VZEROrec MFTbase MFTsim MFTrec EMCALUtils EMCALbase EMCALsim EMCALrec T0base T0sim T0rec TOFbase TOFsim TOFrec TRDbase TRDsim TRDrec PMDbase PMDsim PMDrec MUONmapping MUONmapping MUONgeometry MUONbase MUONsim MUONrec MUONraw PHOSUtils PHOSbase PHOSsim PHOSrec HLTbase ITSbase ITSsim ITSrec STRUCT TPCbase TPCsim TPCrec TPCfast STEER CDB ESD STEERBase RAWDatabase RAWDatasim RAWDatarec MDC TRIGGERbase)
+else(MFT_UPGRADE)
+  set (ARPACKS FMDbase FMDsim FMDrec ACORDEbase ACORDEsim ACORDErec HMPIDbase HMPIDsim HMPIDrec ZDCbase ZDCsim ZDCrec VZERObase VZEROsim VZEROrec EMCALUtils EMCALbase EMCALsim EMCALrec T0base T0sim T0rec TOFbase TOFsim TOFrec TRDbase TRDsim TRDrec PMDbase PMDsim PMDrec MUONmapping MUONmapping MUONgeometry MUONbase MUONsim MUONrec MUONraw PHOSUtils PHOSbase PHOSsim PHOSrec HLTbase ITSbase ITSsim ITSrec STRUCT TPCbase TPCsim TPCrec TPCfast STEER CDB ESD STEERBase RAWDatabase RAWDatasim RAWDatarec MDC TRIGGERbase)
+endif(MFT_UPGRADE)
 
 set(GFILES)
 foreach (pkg ${ARPACKS})
index bb55c0e031521ba40b192e3ff290c625e71dc055..c8d7ae1fc45a1fadb4e4280c276989e23007ce0f 100644 (file)
@@ -16,7 +16,7 @@ project(AliRoot CXX C Fortran)
 
 # Environment variables
 set(ALICE_ROOT $ENV{ALICE_ROOT})
-set(ALICE $ENV{ALICE})
+set(ALICE $ENV{ALICEVE/E})
 set(ALICE_INSTALL $ENV{ALICE_INSTALL})
 if(${ALICE_INSTALL} MATCHES ${CMAKE_BINARY_DIR})
   message(FATAL_ERROR "Install dir should be different from build dir")
@@ -126,7 +126,7 @@ set(BINLIBDIRS "-L${CMAKE_LIBRARY_OUTPUT_DIRECTORY}")
 
 # Standard Modules
 # ------------------------------
-set(ALIROOTMODULES STEER PHOS TRD TPC ZDC MUON PMD FMD TOF ITS ACORDE HMPID T0 BCM STRUCT VZERO THijing THbtp EMCAL THerwig TEPEMGEN FASTSIM TPHIC RAW MONITOR ANALYSIS JETAN HLT STAT TTherminator CORRFW DPMJET TDPMjet PWG0 PWG1 PWG2 PWG3 PWG4 TRIGGER PYTHIA8 TAmpt OADB )
+set(ALIROOTMODULES STEER PHOS TRD TPC ZDC MUON PMD FMD TOF ITS ACORDE HMPID T0 BCM STRUCT VZERO THijing THbtp EMCAL THerwig TEPEMGEN FASTSIM TPHIC RAW MONITOR ANALYSIS JETAN HLT STAT TTherminator CORRFW DPMJET TDPMjet PWG0 PWG1 PWG2 PWG3 PWG4 TRIGGER PYTHIA8 TAmpt OADB MFT)
 
 if(THydjet)
   list(APPEND ALIROOTMODULES THydjet)
@@ -167,7 +167,7 @@ set(MODDIRS ${MODULES})
 
 # Libraries for Linking
 # ------------------------------
-set(ALILIBS MUON TPC PMD TRD FMD TOF ITS PHOS ACORDE HMPID VZERO ZDC STRUCT T0 EVGEN STEER TRIGGER)
+set(ALILIBS MUON TPC PMD TRD FMD TOF ITS PHOS ACORDE HMPID VZERO ZDC STRUCT T0 EVGEN STEER TRIGGER MFT)
 set(LIBS ${ROOTCLIBS} ${ROOTPLIBS} ${SYSLIBS})
 
 # Configure ARVerion.h
index 8ae3812e7303fd1591705fde8538d5de5e1fc8da..a542c3f69287ab844cc596ee560cd5aa9f7b2473 100644 (file)
@@ -53,7 +53,11 @@ AliHLTModulePreprocessor::~AliHLTModulePreprocessor()
 }
 
 // TODO: map this constants to AliHLTDAQ class
+#ifndef MFT_UPGRADE
+const Int_t AliHLTModulePreprocessor::kNDetectors = 22;
+#else
 const Int_t AliHLTModulePreprocessor::kNDetectors = 21;
+#endif
 
 const char* AliHLTModulePreprocessor::fgkDetectorName[kNDetectors] = 
 {
@@ -78,6 +82,9 @@ const char* AliHLTModulePreprocessor::fgkDetectorName[kNDetectors] =
   "EMCAL",
   "DAQ_TEST",
   "HLT"
+  #ifndef MFT_UPGRADE
+  , "MFT"
+  #endif
 };
 
 void AliHLTModulePreprocessor::SetShuttleInterface(AliHLTShuttleInterface* pInterface)
diff --git a/MFT/AliESDEventMFT.cxx b/MFT/AliESDEventMFT.cxx
new file mode 100644 (file)
index 0000000..ebf1a81
--- /dev/null
@@ -0,0 +1,114 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+//====================================================================================================================================================
+//
+//      ESD Event with MUON+MFT muon tracks (AliMuonForwardTrack)
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "AliESDEvent.h"
+#include "TClonesArray.h"
+#include "AliMuonForwardTrack.h"
+#include "AliESDEventMFT.h"
+
+ClassImp(AliESDEventMFT)
+
+//====================================================================================================================================================
+
+AliESDEventMFT::AliESDEventMFT():
+  AliESDEvent(), 
+  fMuonForwardTracks(0x0)
+{
+
+  // default constructor 
+  fMuonForwardTracks = new TClonesArray("AliMuonForwardTrack", 0);
+  AddObject(fMuonForwardTracks);
+
+}
+
+//====================================================================================================================================================
+
+AliESDEventMFT::AliESDEventMFT(AliESDEvent &esdEvent):
+  AliESDEvent(esdEvent), 
+  fMuonForwardTracks(0x0)
+{
+
+  AliDebug(1, "building array of muon tracks");
+  fMuonForwardTracks = new TClonesArray("AliMuonForwardTrack");
+  AliDebug(1, "adding array of muon tracks to list");
+  AddObject(fMuonForwardTracks);
+  AliDebug(1, "event created!");
+    
+}
+
+//====================================================================================================================================================
+
+AliESDEventMFT::AliESDEventMFT(const AliESDEventMFT &esdEventMFT): 
+  AliESDEvent(esdEventMFT),
+  fMuonForwardTracks(esdEventMFT.fMuonForwardTracks)
+{
+
+  // copy constructor
+  AddObject(fMuonForwardTracks);
+  
+}
+
+//====================================================================================================================================================
+
+AliESDEventMFT& AliESDEventMFT::operator=(const AliESDEventMFT &esdEventMFT) {
+
+  // Asignment operator
+
+  // check assignement to self
+  if (this == &esdEventMFT) return *this;
+
+  // base class assignement
+  AliESDEvent::operator=(esdEventMFT);
+  
+  // clear memory
+  Clear();
+  
+  fMuonForwardTracks = esdEventMFT.fMuonForwardTracks;
+
+  return *this;
+
+}
+
+//====================================================================================================================================================
+
+AliESDEventMFT::~AliESDEventMFT() {
+
+  // destructor
+
+  if (fMuonForwardTracks) {
+    //    fMuonForwardTracks->Delete();
+    delete fMuonForwardTracks;
+  }
+
+}
+
+//====================================================================================================================================================
+
+void AliESDEventMFT::AddMuonForwardTrack(const AliMuonForwardTrack *muonForwardTrack) {
+
+    TClonesArray &myMuonForwardTracks = *fMuonForwardTracks;
+    new (myMuonForwardTracks[fMuonForwardTracks->GetEntriesFast()]) AliMuonForwardTrack(*muonForwardTrack);
+
+}
+
+//====================================================================================================================================================
diff --git a/MFT/AliESDEventMFT.h b/MFT/AliESDEventMFT.h
new file mode 100644 (file)
index 0000000..b55dd22
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef AliESDEventMFT_H
+#define AliESDEventMFT_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+//====================================================================================================================================================
+//
+//      ESD Event with MUON+MFT muon tracks (AliMuonForwardTrack)
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "AliESDEvent.h"
+#include "TClonesArray.h"
+#include "AliMuonForwardTrack.h"
+
+//====================================================================================================================================================
+
+class AliMuonForwardTrack;
+
+class AliESDEventMFT: public AliESDEvent { 
+
+public:
+
+  AliESDEventMFT();
+  AliESDEventMFT(AliESDEvent &esdEvent);
+
+  AliESDEventMFT(const AliESDEventMFT&);
+  AliESDEventMFT &operator=(const AliESDEventMFT&);
+
+  virtual ~AliESDEventMFT();
+
+  AliMuonForwardTrack *GetMuonForwardTrack(Int_t i) const { 
+    return (AliMuonForwardTrack*)(fMuonForwardTracks?fMuonForwardTracks->UncheckedAt(i):0x0); 
+  }
+
+  void AddMuonForwardTrack(const AliMuonForwardTrack *muonForwardTrack);
+
+  Int_t GetNMuonForwardTracks() const { return fMuonForwardTracks?fMuonForwardTracks->GetEntriesFast():0; }
+
+private:
+  TClonesArray *fMuonForwardTracks;       // array of AliMuonForwardTrack
+
+  ClassDef(AliESDEventMFT, 1) 
+
+};
+
+//====================================================================================================================================================
+
+#endif
diff --git a/MFT/AliMFT.cxx b/MFT/AliMFT.cxx
new file mode 100644 (file)
index 0000000..1a23486
--- /dev/null
@@ -0,0 +1,658 @@
+// **************************************************************************
+// * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+// *                                                                        *
+// * Author: The ALICE Off-line Project.                                    *
+// * Contributors are mentioned in the code where appropriate.              *
+// *                                                                        *
+// * Permission to use, copy, modify and distribute this software and its   *
+// * documentation strictly for non-commercial purposes is hereby granted   *
+// * without fee, provided that the above copyright notice appears in all   *
+// * copies and that both the copyright notice and this permission notice   *
+// * appear in the supporting documentation. The authors make no claims     *
+// * about the suitability of this software for any purpose. It is          *
+// * provided "as is" without express or implied warranty.                  *
+// **************************************************************************
+
+//====================================================================================================================================================
+//
+//      Main class of the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "AliLog.h"
+#include "TFile.h"  
+#include "TGeoManager.h"    
+#include "TGeoVolume.h"
+#include "TGeoMatrix.h"
+#include "TVirtualMC.h"
+#include "TClonesArray.h"
+#include "TGeoGlobalMagField.h"
+#include "AliRun.h"
+#include "AliLoader.h"
+#include "AliDetector.h"
+#include "AliMC.h"
+#include "AliMagF.h"
+#include "AliMFT.h"
+#include "AliMFTHit.h"
+#include "AliMFTDigit.h"
+#include "AliMFTCluster.h"
+#include "AliTrackReference.h"
+#include "AliMFTSegmentation.h"
+#include "AliMFTDigitizer.h"
+#include "AliMFTPlane.h"
+#include "TString.h"
+#include "TObjArray.h"
+
+ClassImp(AliMFT) 
+
+//====================================================================================================================================================
+
+AliMFT::AliMFT():
+  AliDetector(),
+  fVersion(1),
+  fNPlanes(0),
+  fNSlices(0),
+  fSDigitsPerPlane(0),
+  fDigitsPerPlane(0),
+  fRecPointsPerPlane(0),
+  fSideDigits(0),
+  fSegmentation(0),
+  fNameGeomFile(0),
+  fChargeDispersion(0),
+  fSingleStepForChargeDispersion(0),
+  fNStepForChargeDispersion(0),
+  fDensitySiOverSupport(10)
+{
+
+  // default constructor
+
+}
+
+//====================================================================================================================================================
+
+AliMFT::AliMFT(const Char_t *name, const Char_t *title):
+  AliDetector(name, title),
+  fVersion(1),
+  fNPlanes(0),
+  fNSlices(0),
+  fSDigitsPerPlane(0),
+  fDigitsPerPlane(0),
+  fRecPointsPerPlane(0),
+  fSideDigits(0),
+  fSegmentation(0),
+  fNameGeomFile(0),
+  fChargeDispersion(0),
+  fSingleStepForChargeDispersion(0),
+  fNStepForChargeDispersion(0),
+  fDensitySiOverSupport(10)
+{
+
+  fNameGeomFile = "AliMFTGeometry.root";
+
+  SetGeometry();
+
+  Init();
+
+}
+
+//====================================================================================================================================================
+
+AliMFT::AliMFT(const Char_t *name, const Char_t *title, Char_t *nameGeomFile):
+  AliDetector(name, title),
+  fVersion(1),
+  fNPlanes(0),
+  fNSlices(0),
+  fSDigitsPerPlane(0),
+  fDigitsPerPlane(0),
+  fRecPointsPerPlane(0),
+  fSideDigits(0),
+  fSegmentation(0),
+  fNameGeomFile(0),
+  fChargeDispersion(0),
+  fSingleStepForChargeDispersion(0),
+  fNStepForChargeDispersion(0),
+  fDensitySiOverSupport(10)
+{
+
+  fNameGeomFile = nameGeomFile;
+
+  SetGeometry();
+
+  Init();
+
+}
+
+//====================================================================================================================================================
+
+AliMFT::~AliMFT() {
+
+  if (fSDigitsPerPlane)   { fSDigitsPerPlane->Delete();    delete fSDigitsPerPlane;   }
+  if (fDigitsPerPlane)    { fDigitsPerPlane->Delete();     delete fDigitsPerPlane;    }
+  if (fRecPointsPerPlane) { fRecPointsPerPlane->Delete();  delete fRecPointsPerPlane; }
+
+}
+
+//====================================================================================================================================================
+
+void AliMFT::CreateMaterials() {
+
+  // Definition of MFT materials  - to be updated to the most recent values
+
+  AliInfo("Start MFT materials");
+
+  // data from PDG booklet 2002     density [gr/cm^3] rad len [cm] abs len [cm]    
+  Float_t   aAir[4]={12,14,16,36} ,   zAir[4]={6,7,8,18} ,   wAir[4]={0.000124,0.755267,0.231781,0.012827} , dAir=0.00120479; Int_t nAir=4;   // Air mixture
+  Float_t   aSi = 28.085 ,            zSi   = 14 ,           dSi   =  2.329    ,   radSi   =  21.82/dSi , absSi   = 108.4/dSi  ;              // Silicon
+
+  Int_t   matId  = 0;                        // tmp material id number
+  Int_t   unsens = 0, sens=1;                // sensitive or unsensitive medium
+  Int_t   itgfld = 3;                       // type of field intergration 0 no field -1 user in guswim 1 Runge Kutta 2 helix 3 const field along z
+  Float_t maxfld = 5.;                              // max field value
+
+  Float_t tmaxfd = -10.0;                    // max deflection angle due to magnetic field in one step
+  Float_t stemax =  0.001;                   // max step allowed [cm]
+  Float_t deemax = -0.2;                     // maximum fractional energy loss in one step 0<deemax<=1  
+  Float_t epsil  =  0.001;                   // tracking precision [cm]   
+  Float_t stmin  = -0.001;                   // minimum step due to continuous processes [cm] (negative value: choose it automatically)
+
+  Float_t tmaxfdSi =  0.1;                    // max deflection angle due to magnetic field in one step
+  Float_t stemaxSi =  5.0e-4;                 // maximum step allowed [cm]
+  Float_t deemaxSi =  0.1;                    // maximum fractional energy loss in one step 0<deemax<=1
+  Float_t epsilSi  =  0.5e-4;                 // tracking precision [cm]
+  Float_t stminSi  = -0.001;                 // minimum step due to continuous processes [cm] (negative value: choose it automatically)
+
+  Int_t   isxfld = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();   // from CreateMaterials in STRUCT/AliPIPEv3.cxx
+  Float_t sxmgmx = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();     // from CreateMaterials in STRUCT/AliPIPEv3.cxx
+      
+  AliMixture(++matId,"Air", aAir,  zAir,   dAir,   nAir,   wAir); 
+  AliMedium(kAir,    "Air", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
+  
+  AliMaterial(++matId, "Si", aSi,   zSi,  dSi,    radSi,  absSi  );  
+  AliMedium(kSi,       "Si", matId, sens, isxfld, sxmgmx, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
+
+  AliMaterial(++matId, "Readout", aSi,   zSi,    dSi,    radSi,  absSi  );  
+  AliMedium(kReadout,  "Readout", matId, unsens, isxfld, sxmgmx, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
+
+  AliMaterial(++matId, "Support", aSi,   zSi,    dSi/fDensitySiOverSupport, fDensitySiOverSupport*radSi, fDensitySiOverSupport*absSi);  
+  AliMedium(kSupport,  "Support", matId, unsens, isxfld,  sxmgmx,    tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
+    
+  AliInfo("End MFT materials");
+          
+}
+
+//====================================================================================================================================================
+
+void AliMFT::CreateGeometry() {
+
+  // Creates detailed geometry simulation (currently GEANT volumes tree)        
+
+  AliInfo("Start MFT preliminary version building");
+  if(!gMC->IsRootGeometrySupported()) return;                
+  TGeoVolumeAssembly *vol = CreateVol();
+  AliInfo("TGeoVolumeAssembly created!");
+  gGeoManager->GetVolume("ALIC")->AddNode(vol,0);
+  AliInfo("Stop MFT preliminary version building");
+
+  if (fNStepForChargeDispersion) fSingleStepForChargeDispersion = fChargeDispersion/Double_t(fNStepForChargeDispersion);
+
+} 
+
+//====================================================================================================================================================
+
+void AliMFT::StepManager() {
+
+  // Full Step Manager
+
+  if (!fSegmentation) AliFatal("No segmentation available");    // DO WE HAVE A SEGMENTATION???
+
+  if (!(this->IsActive())) return;
+  if (!(gMC->TrackCharge())) return;
+
+  TString planeNumber   = gMC->CurrentVolName();
+  TString detElemNumber = gMC->CurrentVolName();
+  if (planeNumber.Contains("support")) return;
+  if (planeNumber.Contains("readout")) return;
+  planeNumber.Remove(0,9);
+  detElemNumber.Remove(0,19);
+  planeNumber.Remove(2);
+  detElemNumber.Remove(3);
+  Int_t detElemID = fSegmentation->GetDetElemID(planeNumber.Atoi(), detElemNumber.Atoi());
+
+  if (gMC->IsTrackExiting()) {
+    AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kMFT);
+  }
+
+  static TLorentzVector position, momentum;
+  static AliMFTHit hit;
+  
+  Int_t  status = 0;
+  
+  // Track status
+  if (gMC->IsTrackInside())      status +=  1;
+  if (gMC->IsTrackEntering())    status +=  2;
+  if (gMC->IsTrackExiting())     status +=  4;
+  if (gMC->IsTrackOut())         status +=  8;
+  if (gMC->IsTrackDisappeared()) status += 16;
+  if (gMC->IsTrackStop())        status += 32;
+  if (gMC->IsTrackAlive())       status += 64;
+
+  // ---------- Fill hit structure
+
+  hit.SetDetElemID(detElemID);
+  hit.SetPlane(planeNumber.Atoi());
+  hit.SetTrack(gAlice->GetMCApp()->GetCurrentTrackNumber());
+    
+  gMC->TrackPosition(position);
+  gMC->TrackMomentum(momentum);
+
+  AliDebug(1, Form("AliMFT::StepManager()->%s Hit #%06d (z=%f) belongs to track %02d\n", 
+                  gMC->CurrentVolName(), fNhits, position.Z(), gAlice->GetMCApp()->GetCurrentTrackNumber())); 
+
+  hit.SetPosition(position);
+  hit.SetTOF(gMC->TrackTime());
+  hit.SetMomentum(momentum);
+  hit.SetStatus(status);
+  hit.SetEloss(gMC->Edep());
+  //  hit.SetShunt(GetIshunt());
+//   if (gMC->IsTrackEntering()) {
+//     hit.SetStartPosition(position);
+//     hit.SetStartTime(gMC->TrackTime());
+//     hit.SetStartStatus(status);
+//     return; // don't save entering hit.
+//   } 
+
+  // Fill hit structure with this new hit.
+  new ((*fHits)[fNhits++]) AliMFTHit(hit);
+
+  // Save old position... for next hit.
+//   hit.SetStartPosition(position);
+//   hit.SetStartTime(gMC->TrackTime());
+//   hit.SetStartStatus(status);
+
+  return;
+
+}
+
+//====================================================================================================================================================
+
+TGeoVolumeAssembly* AliMFT::CreateVol() {
+
+  // method to create the MFT Geometry (silicon circular planes)
+
+  if (!fSegmentation) CreateGeometry();
+  
+  TGeoVolumeAssembly *vol = new TGeoVolumeAssembly("MFT");
+  TGeoMedium *silicon = gGeoManager->GetMedium("MFT_Si");
+  TGeoMedium *readout = gGeoManager->GetMedium("MFT_Readout");
+  TGeoMedium *support = gGeoManager->GetMedium("MFT_Support");
+  for (Int_t iPar=0; iPar<8; iPar++) AliInfo(Form("silicon->GetParam(%d) = %f", iPar, silicon->GetParam(iPar)));
+  for (Int_t iPar=0; iPar<8; iPar++) AliInfo(Form("readout->GetParam(%d) = %f", iPar, readout->GetParam(iPar)));
+  for (Int_t iPar=0; iPar<8; iPar++) AliInfo(Form("support->GetParam(%d) = %f", iPar, support->GetParam(iPar)));
+
+  Double_t origin[3] = {0};
+
+  for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+
+    AliDebug(1, Form("Creating volumes for MFT plane %02d",iPlane));
+
+    AliMFTPlane *plane = fSegmentation->GetPlane(iPlane);
+
+    // --------- support element(s)
+    
+    origin[0] =  0.5*(plane->GetSupportElement(0)->GetAxis(0)->GetXmax() + plane->GetSupportElement(0)->GetAxis(0)->GetXmin());
+    origin[1] =  0.5*(plane->GetSupportElement(0)->GetAxis(1)->GetXmax() + plane->GetSupportElement(0)->GetAxis(1)->GetXmin());
+    origin[2] = -0.5*(plane->GetSupportElement(0)->GetAxis(2)->GetXmax() + plane->GetSupportElement(0)->GetAxis(2)->GetXmin());
+    TGeoVolume *supportElem = gGeoManager->MakeTube(Form("MFT_plane%02d_support", iPlane), support, 
+                                                   plane->GetRMinSupport(), 
+                                                   plane->GetRMaxSupport(),
+                                                   0.5*(plane->GetSupportElement(0)->GetAxis(2)->GetXmax() - 
+                                                        plane->GetSupportElement(0)->GetAxis(2)->GetXmin()) );
+    vol -> AddNode(supportElem, 0, new TGeoTranslation(origin[0], origin[1], origin[2]));
+
+    AliDebug(1, "support elements created!");
+    
+    // --------- active elements
+
+    for (Int_t iActive=0; iActive<plane->GetNActiveElements(); iActive++) {
+      
+      Double_t dx = 0.5*TMath::Abs(plane->GetActiveElement(iActive)->GetAxis(0)->GetXmax() - plane->GetActiveElement(iActive)->GetAxis(0)->GetXmin());
+      Double_t dy = 0.5*TMath::Abs(plane->GetActiveElement(iActive)->GetAxis(1)->GetXmax() - plane->GetActiveElement(iActive)->GetAxis(1)->GetXmin());
+      Double_t dz = 0.5*TMath::Abs(plane->GetActiveElement(iActive)->GetAxis(2)->GetXmax() - plane->GetActiveElement(iActive)->GetAxis(2)->GetXmin());
+      dz /= Double_t(fNSlices);
+
+      origin[0] =  0.5*(plane->GetActiveElement(iActive)->GetAxis(0)->GetXmax() + plane->GetActiveElement(iActive)->GetAxis(0)->GetXmin());
+      origin[1] =  0.5*(plane->GetActiveElement(iActive)->GetAxis(1)->GetXmax() + plane->GetActiveElement(iActive)->GetAxis(1)->GetXmin());
+
+      for (Int_t iSlice=0; iSlice<fNSlices; iSlice++) {
+       origin[2] = -0.5*(plane->GetActiveElement(iActive)->GetAxis(2)->GetXmin() + 2*dz*(iSlice+1) + plane->GetActiveElement(iActive)->GetAxis(2)->GetXmin() + 2*dz*(iSlice) );
+       TGeoVolume *activeElem = gGeoManager->MakeBox(Form("MFT_plane%02d_active%03d_slice%02d", iPlane, iActive, iSlice), silicon, dx, dy, dz);
+       vol -> AddNode(activeElem, 0, new TGeoTranslation(origin[0], origin[1], origin[2]));
+      }
+
+    }
+
+    AliDebug(1, "active elements created!");
+
+    // --------- readout elements
+
+    for (Int_t iReadout=0; iReadout<plane->GetNReadoutElements(); iReadout++) {
+      
+      Double_t dx = 0.5*TMath::Abs(plane->GetReadoutElement(iReadout)->GetAxis(0)->GetXmax() - plane->GetReadoutElement(iReadout)->GetAxis(0)->GetXmin());
+      Double_t dy = 0.5*TMath::Abs(plane->GetReadoutElement(iReadout)->GetAxis(1)->GetXmax() - plane->GetReadoutElement(iReadout)->GetAxis(1)->GetXmin());
+      Double_t dz = 0.5*TMath::Abs(plane->GetReadoutElement(iReadout)->GetAxis(2)->GetXmax() - plane->GetReadoutElement(iReadout)->GetAxis(2)->GetXmin());
+
+      origin[0] =  0.5*(plane->GetReadoutElement(iReadout)->GetAxis(0)->GetXmax() + plane->GetReadoutElement(iReadout)->GetAxis(0)->GetXmin());
+      origin[1] =  0.5*(plane->GetReadoutElement(iReadout)->GetAxis(1)->GetXmax() + plane->GetReadoutElement(iReadout)->GetAxis(1)->GetXmin());
+      origin[2] = -0.5*(plane->GetReadoutElement(iReadout)->GetAxis(2)->GetXmax() + plane->GetReadoutElement(iReadout)->GetAxis(2)->GetXmin());
+
+      TGeoVolume *readoutElem = gGeoManager->MakeBox(Form("MFT_plane%02d_readout%03d", iPlane, iReadout), readout, dx, dy, dz);
+      vol -> AddNode(readoutElem, 0, new TGeoTranslation(origin[0], origin[1], origin[2]));
+      
+    }
+
+    AliDebug(1, "readout elements created!");
+
+  }
+
+  return vol;
+
+}
+
+//====================================================================================================================================================
+
+void AliMFT::Hits2SDigits(){
+  
+  // Interface method invoked from AliSimulation to create a list of sdigits corresponding to list of hits. Every hit generates one sdigit.
+
+  AliDebug(1,"Start Hits2SDigits.");
+  
+  if (!fSegmentation) CreateGeometry();
+  if (!fLoader->TreeH()) fLoader->LoadHits();
+
+  if (!fLoader->TreeS()) {
+
+    for (Int_t iEvt=0;iEvt<fLoader->GetRunLoader()->GetNumberOfEvents(); iEvt++) {
+
+      fLoader->GetRunLoader()->GetEvent(iEvt);
+      fLoader->MakeTree("S");
+      MakeBranch("S");
+      SetTreeAddress();
+
+      AliDebug(1, Form("Event %03d: fLoader->TreeH()->GetEntries() = %2d", iEvt, Int_t(fLoader->TreeH()->GetEntries())));
+
+      for (Int_t iTrack=0; iTrack<fLoader->TreeH()->GetEntries(); iTrack++) {
+       fLoader->TreeH()->GetEntry(iTrack);     
+       Hits2SDigitsLocal(Hits(), GetSDigitsList(), iTrack);    // convert these hits to a list of sdigits  
+      }
+      
+      fLoader->TreeS()->Fill();
+      fLoader->WriteSDigits("OVERWRITE");
+      ResetSDigits();
+
+    }
+  }
+
+  fLoader->UnloadHits();
+  fLoader->UnloadSDigits();
+
+  AliDebug(1,"Stop Hits2SDigits.");
+  
+}
+
+//====================================================================================================================================================
+
+void AliMFT::Hits2SDigitsLocal(TClonesArray *hits, const TObjArray *pSDig, Int_t track) {
+
+  //  Add sdigits of these hits to the list
+  
+  AliDebug(1, "Start Hits2SDigitsLocal");
+  
+  if (!fSegmentation) CreateGeometry();
+  
+  TClonesArray *pSDigList[fNMaxPlanes];
+  for (Int_t iPlane=0; iPlane<fNMaxPlanes; iPlane++) pSDigList[iPlane] = NULL; 
+  for (Int_t iPlane=0; iPlane<fNPlanes;    iPlane++) { 
+    pSDigList[iPlane] = (TClonesArray*) (*pSDig)[iPlane];
+    AliDebug(1,Form("Entries of pSDigList %3d; plane: %02d,",pSDigList[iPlane]->GetEntries(),iPlane));
+    if (!track && pSDigList[iPlane]->GetEntries()!=0) AliErrorClass("Some of sdigits lists is not empty");
+  }
+  
+  for (Int_t iHit=0; iHit<hits->GetEntries(); iHit++) {
+
+    AliMFTHit *hit = (AliMFTHit*) hits->At(iHit);
+
+    AliMFTDigit sDigit;
+    sDigit.SetEloss(hit->GetEloss());
+    sDigit.SetDetElemID(hit->GetDetElemID());
+    sDigit.SetPlane(hit->GetPlane());
+    sDigit.AddMCLabel(hit->GetTrack()); 
+
+    Int_t xPixel = -1;
+    Int_t yPixel = -1;
+    if (fSegmentation->Hit2PixelID(hit->X(), hit->Y(), sDigit.GetDetElemID(), xPixel, yPixel)) {
+      sDigit.SetPixID(xPixel, yPixel, 0);
+      sDigit.SetPixWidth(fSegmentation->GetPixelSizeX(sDigit.GetDetElemID()), 
+                        fSegmentation->GetPixelSizeY(sDigit.GetDetElemID()),
+                        fSegmentation->GetPixelSizeZ(sDigit.GetDetElemID()));  
+      sDigit.SetPixCenter(fSegmentation->GetPixelCenterX(sDigit.GetDetElemID(), xPixel), 
+                         fSegmentation->GetPixelCenterY(sDigit.GetDetElemID(), yPixel),
+                         fSegmentation->GetPixelCenterZ(sDigit.GetDetElemID(), 0));  
+      new ((*pSDigList[sDigit.GetPlane()])[pSDigList[sDigit.GetPlane()]->GetEntries()]) AliMFTDigit(sDigit);
+      AliDebug(1, Form("Created new sdigit (%f, %f, %f) from hit (%f, %f, %f)",
+                      sDigit.GetPixelCenterX(), sDigit.GetPixelCenterY(), sDigit.GetPixelCenterZ(), hit->X(), hit->Y(), hit->Z()));
+//       AliDebug(1, Form("Created new sdigit from hit: residual is (%f, %f, %f)",
+//                    sDigit.GetPixelCenterX()-hit->X(), sDigit.GetPixelCenterY()-hit->Y(), sDigit.GetPixelCenterZ()-hit->Z()));
+    }
+
+    // creating "side hits" to simulate the effect of charge dispersion
+
+    Int_t xPixelNew = -1;
+    Int_t yPixelNew = -1;
+    Double_t x0 = hit->X();
+    Double_t y0 = hit->Y();
+    Double_t pi4 = TMath::Pi()/4.;
+    for (Int_t iStep=0; iStep<fNStepForChargeDispersion; iStep++) {
+      Double_t shift = (iStep+1) * fSingleStepForChargeDispersion;
+      for (Int_t iAngle=0; iAngle<8; iAngle++) {
+       Double_t shiftX = shift*TMath::Cos(iAngle*pi4);
+       Double_t shiftY = shift*TMath::Sin(iAngle*pi4);
+       if (fSegmentation->Hit2PixelID(x0+shiftX, y0+shiftY, hit->GetDetElemID(), xPixelNew, yPixelNew)) {
+         Bool_t digitExists = kFALSE;
+         if (xPixelNew==xPixel && yPixelNew==yPixel) digitExists = kTRUE;
+         if (!digitExists) {
+           for (Int_t iSideDigit=0; iSideDigit<fSideDigits->GetEntries(); iSideDigit++) {
+             if (xPixelNew==((AliMFTDigit*) fSideDigits->At(iSideDigit))->GetPixelX() && 
+                 yPixelNew==((AliMFTDigit*) fSideDigits->At(iSideDigit))->GetPixelY()) {
+               digitExists = kTRUE;
+               break;
+             }
+           }
+         }
+         if (!digitExists) {
+           AliMFTDigit newSDigit;
+           newSDigit.SetEloss(0.);
+           newSDigit.SetDetElemID(hit->GetDetElemID());
+           newSDigit.SetPlane(hit->GetPlane());
+           newSDigit.AddMCLabel(hit->GetTrack());
+           newSDigit.SetPixID(xPixelNew, yPixelNew, 0);
+           newSDigit.SetPixWidth(fSegmentation->GetPixelSizeX(sDigit.GetDetElemID()), 
+                                 fSegmentation->GetPixelSizeY(sDigit.GetDetElemID()),
+                                 fSegmentation->GetPixelSizeZ(sDigit.GetDetElemID()));  
+           newSDigit.SetPixCenter(fSegmentation->GetPixelCenterX(sDigit.GetDetElemID(), xPixelNew), 
+                                  fSegmentation->GetPixelCenterY(sDigit.GetDetElemID(), yPixelNew),
+                                  fSegmentation->GetPixelCenterZ(sDigit.GetDetElemID(), 0)); 
+           new ((*fSideDigits)[fSideDigits->GetEntries()]) AliMFTDigit(newSDigit);
+         }
+       }
+      }
+    }
+
+    for (Int_t iSideDigit=0; iSideDigit<fSideDigits->GetEntries(); iSideDigit++) {
+      AliMFTDigit *newDigit = (AliMFTDigit*) fSideDigits->At(iSideDigit);
+      new ((*pSDigList[sDigit.GetPlane()])[pSDigList[sDigit.GetPlane()]->GetEntries()]) AliMFTDigit(*newDigit);
+    }
+
+    fSideDigits->Clear();    
+
+  }
+  
+  AliDebug(1,"Stop Hits2SDigitsLocal");
+
+}
+
+//====================================================================================================================================================
+
+void AliMFT::MakeBranch(Option_t *option) {
+
+  printf("AliMFT::MakeBranch(...)\n");
+
+  // Create Tree branches 
+  AliDebug(1, Form("Start with option= %s.",option));
+  
+  const Int_t kBufSize = 4000;
+  
+  const Char_t *cH = strstr(option,"H");
+  const Char_t *cD = strstr(option,"D");
+  const Char_t *cS = strstr(option,"S");
+
+  if (cH && fLoader->TreeH()) {
+    CreateHits();
+    MakeBranchInTree(fLoader->TreeH(), "MFT", &fHits, kBufSize, 0);   
+  }
+
+  if (cS && fLoader->TreeS()) {
+    CreateSDigits();
+    for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) MakeBranchInTree(fLoader->TreeS(), 
+                                                                   Form("Plane_%02d",iPlane), 
+                                                                   &((*fSDigitsPerPlane)[iPlane]), 
+                                                                   kBufSize, 0);
+  }
+  
+  if (cD && fLoader->TreeD()) {
+    CreateDigits();
+    for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) MakeBranchInTree(fLoader->TreeD(), 
+                                                                   Form("Plane_%02d",iPlane), 
+                                                                   &((*fDigitsPerPlane)[iPlane]),
+                                                                   kBufSize, 0);
+  }
+
+  AliDebug(1,"Stop.");
+
+}
+
+//====================================================================================================================================================
+
+void AliMFT::SetTreeAddress() {
+
+  AliDebug(1, "AliMFT::SetTreeAddress()");
+
+  //Set branch address for the Hits and Digits Tree.
+  AliDebug(1, "Start.");
+
+  AliDebug(1, Form("AliMFT::SetTreeAddress Hits  fLoader->TreeH() = %p\n", fLoader->TreeH()));
+  if (fLoader->TreeH() && fLoader->TreeH()->GetBranch("MFT")) {
+    CreateHits();
+    fLoader->TreeH()->SetBranchAddress("MFT", &fHits);
+  }
+    
+  AliDebug(1, Form("AliMFT::SetTreeAddress SDigits  fLoader->TreeS() = %p\n", fLoader->TreeS()));
+  if (fLoader->TreeS() && fLoader->TreeS()->GetBranch("Plane_00")) {
+    CreateSDigits();
+    for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+      fLoader->TreeS()->SetBranchAddress(Form("Plane_%02d",iPlane), &((*fSDigitsPerPlane)[iPlane]));
+    }
+  }
+    
+  AliDebug(1, Form("AliMFT::SetTreeAddress Digits  fLoader->TreeD() = %p\n", fLoader->TreeD()));
+  if (fLoader->TreeD() && fLoader->TreeD()->GetBranch("Plane_00")) {
+    CreateDigits(); 
+    for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+      fLoader->TreeD()->SetBranchAddress(Form("Plane_%02d",iPlane), &((*fDigitsPerPlane)[iPlane]));
+    }
+  }
+
+  AliDebug(1, Form("AliMFT::SetTreeAddress RecPoints  fLoader->TreeR() = %p\n", fLoader->TreeR()));
+  if (fLoader->TreeR() && fLoader->TreeR()->GetBranch("Plane_00")) {
+    CreateRecPoints(); 
+    for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+      fLoader->TreeR()->SetBranchAddress(Form("Plane_%02d",iPlane), &((*fRecPointsPerPlane)[iPlane]));
+    }
+  }
+
+  AliDebug(1,"Stop.");
+
+}
+
+//====================================================================================================================================================
+
+void AliMFT::SetGeometry() {
+
+  printf("AliMFT::SetGeometry\n");
+
+  fSegmentation = new AliMFTSegmentation(fNameGeomFile.Data());
+
+  fNPlanes = fSegmentation->GetNPlanes();
+
+}
+
+//====================================================================================================================================================
+
+void AliMFT::CreateHits() { 
+
+  // create array of hits
+
+  AliDebug(1, "AliMFT::CreateHits()");
+
+  if (fHits) return;    
+  fHits = new TClonesArray("AliMFTHit");  
+
+}
+
+//====================================================================================================================================================
+
+void AliMFT::CreateSDigits() { 
+  // create sdigits list
+
+  AliDebug(1, "AliMFT::CreateSDigits()");
+  if (fSDigitsPerPlane) return; 
+  fSDigitsPerPlane = new TObjArray(fNPlanes); 
+  for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) fSDigitsPerPlane->AddAt(new TClonesArray("AliMFTDigit"), iPlane);
+
+  fSideDigits = new TClonesArray("AliMFTDigit");
+
+}
+
+//====================================================================================================================================================
+
+void AliMFT::CreateDigits() {
+
+  // create digits list
+
+  AliDebug(1, "AliMFT::CreateDigits()");
+
+  if (fDigitsPerPlane) return; 
+  fDigitsPerPlane = new TObjArray(fNPlanes);
+  for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) fDigitsPerPlane->AddAt(new TClonesArray("AliMFTDigit"), iPlane);
+
+}
+
+//====================================================================================================================================================
+
+void AliMFT::CreateRecPoints() {
+
+  // create recPoints list
+
+  AliDebug(1, "AliMFT::CreateRecPoints()");
+
+  if (fRecPointsPerPlane) return; 
+  fRecPointsPerPlane = new TObjArray(fNPlanes);
+  for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) fRecPointsPerPlane->AddAt(new TClonesArray("AliMFTCluster"), iPlane);
+
+}
+
+//====================================================================================================================================================
diff --git a/MFT/AliMFT.h b/MFT/AliMFT.h
new file mode 100644 (file)
index 0000000..be506be
--- /dev/null
@@ -0,0 +1,140 @@
+#ifndef AliMFT_H
+#define AliMFT_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+//====================================================================================================================================================
+//
+//      Geometry of the Muon Forward Tracker based on TGeo
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "TFile.h"  
+#include "TGeoManager.h"    
+#include "TGeoVolume.h"
+#include "TGeoMatrix.h"
+#include "TVirtualMC.h"
+#include "TClonesArray.h"
+#include "TGeoGlobalMagField.h"
+#include "AliRun.h"
+#include "AliLoader.h"
+#include "AliDetector.h"
+#include "AliMC.h"
+#include "AliMagF.h"
+#include "AliMFT.h"
+#include "AliMFTHit.h"
+#include "AliMFTDigit.h"
+#include "AliMFTCluster.h"
+#include "AliTrackReference.h"
+#include "AliMFTSegmentation.h"
+#include "AliMFTDigitizer.h"
+#include "AliMFTPlane.h"
+#include "TString.h"
+#include "TObjArray.h"
+
+//====================================================================================================================================================
+
+class AliMFT : public AliDetector  {
+
+public:
+
+  AliMFT();
+  AliMFT(const Char_t *name, const Char_t *title);
+  AliMFT(const Char_t *name, const Char_t *title, Char_t *nameGeomFile);
+
+  virtual ~AliMFT();
+
+  Int_t IsVersion() const { return fVersion; }
+  
+  // ------- framework part -----------------------------------------------------------------------------------
+  void CreateMaterials();                       // from AliModule invoked from AliMC
+  void CreateGeometry();                        // from AliModule invoked from AliMC                     
+  void StepManager();                           // from AliModule invoked from AliMC::Stepping()
+  void Hits2SDigits();
+  void Hits2SDigitsLocal(TClonesArray *hits, const TObjArray *pSDig, Int_t track);
+  void MakeBranch(Option_t *option="");
+  void SetTreeAddress();
+          
+  // ------- create containers -----------------------------------------------------------------------------------
+  void CreateHits();
+  void CreateSDigits();
+  void CreateDigits();
+  void CreateRecPoints();
+
+  TObjArray*    GetSDigitsList()            const { return fSDigitsPerPlane; }                                                  // get sdigits list for all planes
+  TClonesArray* GetSDigitsList(Int_t plane) const { return fSDigitsPerPlane ? (TClonesArray*) fSDigitsPerPlane->At(plane):0; }  // get sdigits list for a plane
+
+  TObjArray*    GetDigitsList()            const{return fDigitsPerPlane;}                                                   // get digits list for all layers
+  TClonesArray* GetDigitsList(Int_t plane) const{return fDigitsPerPlane ? (TClonesArray*) fDigitsPerPlane->At(plane):0; }   // get digits list for a plane
+
+  TObjArray*    GetRecPointsList()            const{return fRecPointsPerPlane;}                                                      // get digits list for all layers
+  TClonesArray* GetRecPointsList(Int_t plane) const{return fRecPointsPerPlane ? (TClonesArray*) fRecPointsPerPlane->At(plane):0; }   // get digits list for a plane
+
+  void ResetSDigits()   { if(fSDigitsPerPlane)   for(int iPlane=0; iPlane<fNPlanes; iPlane++) ((TClonesArray*) fSDigitsPerPlane  ->At(iPlane))->Clear(); }   // reset sdigits list  
+  void ResetDigits()    { if(fDigitsPerPlane)    for(int iPlane=0; iPlane<fNPlanes; iPlane++) ((TClonesArray*) fDigitsPerPlane   ->At(iPlane))->Clear(); }   // reset digits list
+  void ResetRecPoints() { if(fRecPointsPerPlane) for(int iPlane=0; iPlane<fNPlanes; iPlane++) ((TClonesArray*) fRecPointsPerPlane->At(iPlane))->Clear(); }   // reset recPoints list
+  
+  AliDigitizer* CreateDigitizer(AliRunDigitizer *manager) const { return new AliMFTDigitizer(manager); }   // from AliModule invoked from AliSimulation::RunDigitization()
+  
+  AliMFTSegmentation* GetSegmentation() const { return fSegmentation; }
+
+  enum EMedia{kAir, kSi, kReadout, kSupport};  // media IDs used in CreateMaterials  
+    
+  // Geometry/segmentation creation part
+  TGeoVolumeAssembly* CreateVol();
+  void AddAlignableVolumes() const { /* not needed */ return; }
+  void SetGeometry();
+
+  void  SetNSlices(Int_t nSlices) { fNSlices = nSlices; }
+  Int_t GetNSlices() const { return fNSlices; }
+
+  Int_t GetNPlanes() const { return fNPlanes; }
+
+  void SetChargeDispersion(Double_t chargeDispersion) { fChargeDispersion = chargeDispersion; }
+  Double_t GetChargeDispersion() { return fChargeDispersion; }
+  void SetNStepForChargeDispersion(Int_t nStepForChargeDispersion) { fNStepForChargeDispersion = nStepForChargeDispersion; }
+  Int_t GetNStepForChargeDispersion() { return fNStepForChargeDispersion; }
+  Double_t GetSingleStepForChargeDispersion() { return fSingleStepForChargeDispersion; }
+
+  void SetDensitySiOverSupport(Double_t density) { fDensitySiOverSupport = density; }
+
+protected:
+
+  static const Int_t fNMaxPlanes = 20;        // max number of MFT planes
+
+  Int_t fVersion;
+
+  Int_t fNPlanes;                             // # of MFT planes
+  Int_t fNSlices;                             // # of slices per MFT plane
+  
+  TObjArray *fSDigitsPerPlane;                // ![fNPlanes] list of sdigits [per plane]
+  TObjArray *fDigitsPerPlane;                 // ![fNPlanes] list of digits [per plane]
+  TObjArray *fRecPointsPerPlane;              // ![fNPlanes] list of recPoints [per plane]
+  TClonesArray *fSideDigits;                  // ! list of digits fired by the charge dispersion coming from the main hit
+
+  AliMFTSegmentation *fSegmentation;
+
+  TString fNameGeomFile;
+
+  Double_t fChargeDispersion;
+  Double_t fSingleStepForChargeDispersion;
+  Int_t fNStepForChargeDispersion;
+
+  Double_t fDensitySiOverSupport;
+  
+private:
+
+  AliMFT (const AliMFT& mft);             // dummy copy constructor
+  AliMFT &operator=(const AliMFT& mft);   // dummy assignment operator
+  
+  ClassDef(AliMFT,1) 
+    
+};
+
+//====================================================================================================================================================
+
+#endif
+
diff --git a/MFT/AliMFTCluster.cxx b/MFT/AliMFTCluster.cxx
new file mode 100644 (file)
index 0000000..3cfb7a2
--- /dev/null
@@ -0,0 +1,69 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+
+//====================================================================================================================================================
+//
+//      Class for the description of the clusters of the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "TObject.h"
+#include "AliMUONRawCluster.h"
+#include "AliMUONVCluster.h"
+#include "AliMFTCluster.h"
+
+ClassImp(AliMFTCluster)
+
+//====================================================================================================================================================
+
+AliMFTCluster::AliMFTCluster():
+  TObject(),
+  fX(0), 
+  fY(0), 
+  fZ(0),
+  fErrX(0), 
+  fErrY(0), 
+  fErrZ(0),
+  fNElectrons(0),
+  fNMCTracks(0),
+  fPlane(0),
+  fSize(0),
+  fTrackChi2(0),
+  fLocalChi2(0)
+{
+
+  // default constructor
+
+  for (Int_t iTrack=0; iTrack<fNMaxMCTracks; iTrack++) fMCLabel[iTrack] = -1;
+
+}
+
+//====================================================================================================================================================
+
+AliMUONRawCluster* AliMFTCluster::CreateMUONCluster() {
+
+  AliMUONRawCluster *cluster = new AliMUONRawCluster();
+  
+  cluster->SetXYZ(GetX(), GetY(), GetZ());
+  cluster->SetErrXY(GetErrX(),GetErrY());
+  cluster->SetDetElemId(100);   // to get the cluster compatible with the AliMUONTrack::AddTrackParamAtCluster(...) method
+
+  return cluster;
+
+}
+
+//====================================================================================================================================================
diff --git a/MFT/AliMFTCluster.h b/MFT/AliMFTCluster.h
new file mode 100644 (file)
index 0000000..898418a
--- /dev/null
@@ -0,0 +1,99 @@
+#ifndef AliMFTCluster_H
+#define AliMFTCluster_H 
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+//====================================================================================================================================================
+//
+//      Class for the description of the clusters of the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "AliMUONRawCluster.h"
+#include "AliMUONVCluster.h"
+#include "TObject.h"
+
+//====================================================================================================================================================
+
+class AliMFTCluster : public TObject {
+
+public:
+
+  AliMFTCluster();
+//   AliMFTCluster(const AliMFTCluster& pt);
+//   AliMFTCluster& operator=(const AliMFTCluster &source);
+
+  virtual ~AliMFTCluster() {};  // destructor
+
+  void SetXYZ(Double_t x, Double_t y, Double_t z) { fX=x; fY=y; fZ=z; }
+
+  void SetX(Double_t x) { fX = x; }
+  void SetY(Double_t y) { fY = y; }
+  void SetZ(Double_t z) { fZ = z; }
+
+  Double_t GetX() const { return fX; }
+  Double_t GetY() const { return fY; }
+  Double_t GetZ() const { return fZ; }
+  
+  void SetErrXYZ(Double_t errX, Double_t errY, Double_t errZ) { fErrX = errX; fErrY = errY; fErrZ = errZ; }
+       
+  void SetErrX(Double_t errX) { fErrX = errX; }
+  void SetErrY(Double_t errY) { fErrY = errY; }
+  void SetErrZ(Double_t errZ) { fErrZ = errZ; }
+
+  Double_t GetErrX()  const { return fErrX; }
+  Double_t GetErrY()  const { return fErrY; }
+  Double_t GetErrZ()  const { return fErrZ; }
+  Double_t GetErrX2() const { return fErrX*fErrX; }
+  Double_t GetErrY2() const { return fErrY*fErrY; }
+  Double_t GetErrZ2() const { return fErrZ*fErrZ; }
+  
+  void     SetNElectrons(Double_t nElectrons) { fNElectrons = nElectrons; }
+  Double_t GetNElectrons() const { return fNElectrons; }
+  
+  void  AddMCLabel(Int_t label) { if (fNMCTracks==fNMaxMCTracks) return; else fMCLabel[fNMCTracks++]=label; }
+  Int_t GetNMCTracks() const { return fNMCTracks; }
+  Int_t GetMCLabel(Int_t track) const { if (track<fNMCTracks && track>=0) return fMCLabel[track]; else return -1; }
+
+  void  SetPlane(Int_t plane) { fPlane = plane; }
+  Int_t GetPlane() const { return fPlane; }
+
+  void  SetSize(Int_t size) { fSize = size; }
+  Int_t GetSize() const { return fSize; }
+
+  void SetLocalChi2(Double_t chi2) { fLocalChi2 = chi2; }
+  void SetTrackChi2(Double_t chi2) { fTrackChi2 = chi2; }
+
+  Double_t GetLocalChi2() { return fLocalChi2; }
+  Double_t GetTrackChi2() { return fTrackChi2; }
+
+  AliMUONRawCluster* CreateMUONCluster();
+  
+private:
+
+  static const Int_t fNMaxMCTracks = 30;
+
+  Double_t fX, fY, fZ;   // cluster global coordinates
+  Double_t fErrX, fErrY, fErrZ;
+
+  Double_t fNElectrons;
+  Int_t fNMCTracks;
+  Int_t fPlane;
+  Int_t fMCLabel[fNMaxMCTracks];
+
+  Int_t fSize;   // the number of digits composing the cluster
+
+  Double_t fTrackChi2; // Chi2 of the track when the associated cluster was attached
+  Double_t fLocalChi2; // Local chi2 of the associated cluster with respect to the track
+  
+  ClassDef(AliMFTCluster, 1)
+
+};
+
+//====================================================================================================================================================
+       
+#endif
+
diff --git a/MFT/AliMFTClusterFinder.cxx b/MFT/AliMFTClusterFinder.cxx
new file mode 100644 (file)
index 0000000..083401e
--- /dev/null
@@ -0,0 +1,273 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+//====================================================================================================================================================
+//
+//      Class for finding and building the clusters of the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "AliLog.h"
+#include "TObjArray.h"
+#include "TClonesArray.h"
+#include "AliMFTDigit.h"
+#include "AliMFTCluster.h"
+#include "AliMFTSegmentation.h"
+#include "TTree.h"
+#include "TMath.h"
+#include "AliMFTClusterFinder.h"
+
+ClassImp(AliMFTClusterFinder)
+
+//====================================================================================================================================================
+
+AliMFTClusterFinder::AliMFTClusterFinder() : 
+  TObject(),
+  fDigitsInCluster(0),
+  fCurrentDig(0),
+  fSegmentation(0),
+  fNPlanes(0)
+{
+
+  // Default constructor
+  
+  for (Int_t iPlane=0; iPlane<fNMaxPlanes; iPlane++) fClustersPerPlane[iPlane] = NULL;
+  fDigitsInCluster = new TClonesArray("AliMFTDigit", fNMaxDigitsPerCluster);
+
+}
+
+//====================================================================================================================================================
+
+AliMFTClusterFinder::~AliMFTClusterFinder() {
+
+  AliDebug(1, "Deleting AliMFTClusterFinder...");
+
+  for (Int_t iPlane=0; iPlane<fNMaxPlanes; iPlane++) delete fClustersPerPlane[iPlane];
+
+  AliDebug(1, "... done!");
+
+}
+
+//====================================================================================================================================================
+
+void AliMFTClusterFinder::Init(Char_t *nameGeomFile) {
+
+  fSegmentation = new AliMFTSegmentation(nameGeomFile);
+  fNPlanes = fSegmentation -> GetNPlanes();
+  
+}
+
+//====================================================================================================================================================
+
+void AliMFTClusterFinder::StartEvent() {
+
+  // Cleaning up and preparation for the clustering procedure
+
+  AliDebug(1, "Starting Event...");
+  
+  for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+    fClustersPerPlane[iPlane]->Clear();
+  }
+
+  AliDebug(1, "... done!");
+
+}
+
+//====================================================================================================================================================
+
+void AliMFTClusterFinder::DigitsToClusters(const TObjArray *pDigitList) {
+
+  // where the clusterization is performed
+
+  AliInfo("Starting Clusterization for MFT");
+  AliDebug(1, Form("nPlanes = %d", fNPlanes));
+
+  StartEvent(); 
+  
+  for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+
+    AliDebug(1, Form("Plane %02d", iPlane));
+
+    TClonesArray *myDigitList = (TClonesArray*) pDigitList->At(iPlane);
+    //    myDigitList->Sort();
+
+    AliDebug(1, Form("myDigitList->GetEntries() = %d", myDigitList->GetEntries()));
+
+    while (myDigitList->GetEntries()) {
+
+      fDigitsInCluster->Clear();
+      
+      Bool_t clusterUpdated=kTRUE;
+
+      //---------------------------------------------------------------------------------------------------------
+
+      while (clusterUpdated) {    // repeat the loop on the digits until no new compatible digit is found
+
+       clusterUpdated = kFALSE;
+
+       for (Int_t iDig=0; iDig<myDigitList->GetEntries(); iDig++) {
+         fCurrentDig = (AliMFTDigit*) myDigitList->At(iDig);
+         if (fDigitsInCluster->GetEntries()<fNMaxDigitsPerCluster) {
+           if (fDigitsInCluster->GetEntries()==0) {
+             new ((*fDigitsInCluster)[fDigitsInCluster->GetEntries()]) AliMFTDigit(*fCurrentDig);
+             myDigitList->Remove(fCurrentDig);
+             clusterUpdated = kTRUE;
+           }
+           else if (IsCurrentDigitCompatible()) {
+             new ((*fDigitsInCluster)[fDigitsInCluster->GetEntries()]) AliMFTDigit(*fCurrentDig);
+             myDigitList->Remove(fCurrentDig);
+             clusterUpdated = kTRUE;
+           }
+         }
+       }
+       
+       if (clusterUpdated) myDigitList->Compress();
+
+      }
+
+      //---------------------------------------------------------------------------------------------------------
+
+      AliDebug(1, "Building new cluster");
+
+      BuildNewCluster(iPlane);  // here the new cluster is built
+
+    }
+
+  }
+
+}
+
+//====================================================================================================================================================
+
+Bool_t AliMFTClusterFinder::IsCurrentDigitCompatible() {
+
+  // where it is decided if the current digit (fCurrentDig) is compatible with the current digits array (fDigitsInCluster)
+
+  for (Int_t iDigit=0; iDigit<fDigitsInCluster->GetEntries(); iDigit++) {
+    AliMFTDigit *tmpDig = (AliMFTDigit*) fDigitsInCluster->At(iDigit);
+    Int_t distX = TMath::Abs(tmpDig->GetPixelX() - fCurrentDig->GetPixelX());
+    Int_t distY = TMath::Abs(tmpDig->GetPixelY() - fCurrentDig->GetPixelY());
+    if (distX<=1 &&  distY<=1) return kTRUE;
+  }
+
+  return kFALSE;
+    
+}
+
+//====================================================================================================================================================
+
+void AliMFTClusterFinder::BuildNewCluster(Int_t plane) {
+
+  // where a new cluster is built, starting from the array of compatible digits (fDigitsInCluster)
+
+  AliDebug(1, Form("Starting cluster building from %d digits", fDigitsInCluster->GetEntries()));
+
+  AliMFTCluster *newCluster = new AliMFTCluster();
+
+  Double_t xCenters[fNMaxDigitsPerCluster] = {0};
+  Double_t yCenters[fNMaxDigitsPerCluster] = {0};
+  Double_t nElectrons = 0.;
+
+  for (Int_t iDigit=0; iDigit<fDigitsInCluster->GetEntries(); iDigit++) {
+    AliMFTDigit *tmpDig = (AliMFTDigit*) fDigitsInCluster->At(iDigit);
+    xCenters[iDigit] = tmpDig->GetPixelCenterX();
+    yCenters[iDigit] = tmpDig->GetPixelCenterY();
+    nElectrons      += tmpDig->GetNElectrons();
+    for (Int_t iTrack=0; iTrack<tmpDig->GetNMCTracks(); iTrack++) newCluster->AddMCLabel(tmpDig->GetMCLabel(iTrack));
+  }
+
+  newCluster -> SetX(TMath::Mean(fDigitsInCluster->GetEntries(), xCenters));
+  newCluster -> SetY(TMath::Mean(fDigitsInCluster->GetEntries(), yCenters));
+  newCluster -> SetZ(((AliMFTDigit*) fDigitsInCluster->At(0))->GetPixelCenterZ());
+
+  Double_t minErrX = ((AliMFTDigit*) fDigitsInCluster->At(0))->GetPixelWidthX() / TMath::Sqrt(12.);
+  Double_t minErrY = ((AliMFTDigit*) fDigitsInCluster->At(0))->GetPixelWidthY() / TMath::Sqrt(12.);
+  Double_t minErrZ = ((AliMFTDigit*) fDigitsInCluster->At(0))->GetPixelWidthZ() / TMath::Sqrt(12.);
+  newCluster -> SetErrX( TMath::Max(TMath::RMS(fDigitsInCluster->GetEntries(), xCenters), minErrX) );
+  newCluster -> SetErrY( TMath::Max(TMath::RMS(fDigitsInCluster->GetEntries(), yCenters), minErrY) );
+  newCluster -> SetErrZ( minErrZ );
+    
+  newCluster -> SetNElectrons(nElectrons);
+  newCluster -> SetPlane(plane);
+
+  newCluster -> SetSize(fDigitsInCluster->GetEntries());
+
+  AliDebug(1, Form("Adding cluster #%02d to tree (%f, %f, %f)", 
+                  fClustersPerPlane[plane]->GetEntries(), newCluster->GetX(), newCluster->GetY(), newCluster->GetZ()));
+
+  new ((*fClustersPerPlane[plane])[fClustersPerPlane[plane]->GetEntries()]) AliMFTCluster(*newCluster);
+
+}
+
+//====================================================================================================================================================
+
+void AliMFTClusterFinder::MakeClusterBranch(TTree *treeCluster) {
+
+  // Creating the cluster branches, one for each plane (see AliMFTReconstructor::Reconstruct)
+
+  AliDebug(1, "Making Cluster Branch");
+
+  CreateClusters();
+
+  if (treeCluster) {
+    for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+      AliDebug(1, Form("Setting Branch Plane_%02d for treeCluster",iPlane));
+      TBranch *branch = treeCluster->GetBranch(Form("Plane_%02d",iPlane));
+      if (branch) continue;
+      AliDebug(1, Form("Branch Plane_%02d does not exist, creating!",iPlane));
+      branch = treeCluster->Branch(Form("Plane_%02d",iPlane), &(fClustersPerPlane[iPlane])); 
+    }
+  }
+
+}
+
+//====================================================================================================================================================
+
+void AliMFTClusterFinder::SetClusterTreeAddress(TTree *treeCluster) {
+
+  // Addressing the cluster branches, one for each plane (see AliMFTReconstructor::Reconstruct)
+
+  if (treeCluster && treeCluster->GetBranch("Plane_00")) {
+    CreateClusters();
+    for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+      if (treeCluster->GetBranch(Form("Plane_%02d",iPlane))) {
+       treeCluster->SetBranchAddress(Form("Plane_%02d",iPlane), &(fClustersPerPlane[iPlane]));
+      }
+      else AliError(Form("No branch available with name Plane_%02d", iPlane));
+    }
+  }
+
+}
+
+//====================================================================================================================================================
+
+void AliMFTClusterFinder::CreateClusters() {
+
+  // create cluster list
+
+  AliDebug(1, Form("Creating clusters list: nPlanes = %d",fNPlanes));
+
+  if (fClustersPerPlane[0]) return;
+  
+  for(Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+    AliDebug(1, Form("plane %02d", iPlane));
+    fClustersPerPlane[iPlane] = new TClonesArray("AliMFTCluster");
+  }
+
+}
+
+//====================================================================================================================================================
diff --git a/MFT/AliMFTClusterFinder.h b/MFT/AliMFTClusterFinder.h
new file mode 100644 (file)
index 0000000..25d1532
--- /dev/null
@@ -0,0 +1,68 @@
+/* Copyright(c) 2004-2006, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice     */
+
+//====================================================================================================================================================
+//
+//      Class for finding and building the clusters of the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#ifndef AliMFTClusterFinder_H
+#define AliMFTClusterFinder_H
+
+#include "AliLog.h"
+#include "TObjArray.h"
+#include "TClonesArray.h"
+#include "AliMFTDigit.h"
+#include "AliMFTCluster.h"
+#include "AliMFTSegmentation.h"
+#include "TTree.h"
+#include "TMath.h"
+
+//====================================================================================================================================================
+
+class AliMFTClusterFinder : public TObject {
+
+public:
+
+  AliMFTClusterFinder();
+  ~AliMFTClusterFinder();
+
+  void Init(Char_t *nameGeomFile);
+  
+  void MakeClusterBranch(TTree *treeCluster);
+  void SetClusterTreeAddress(TTree *treeCluster);
+  void CreateClusters();
+
+  void DigitsToClusters(const TObjArray *pDigitList);
+
+  void StartEvent();
+  void BuildNewCluster(Int_t plane);
+  Bool_t IsCurrentDigitCompatible();
+
+private:
+  static const Int_t fNMaxDigitsPerCluster = 10;
+  static const Int_t fNMaxPlanes = 20;
+
+  TClonesArray *fClustersPerPlane[fNMaxPlanes];    // ![fNPlanes] list of clusters [per plane]
+
+  TClonesArray *fDigitsInCluster;
+  AliMFTDigit *fCurrentDig;
+
+  AliMFTSegmentation *fSegmentation;
+
+  Int_t fNPlanes;
+
+  AliMFTClusterFinder(const AliMFTClusterFinder &source);
+  AliMFTClusterFinder& operator=(const AliMFTClusterFinder &source);
+
+  ClassDef(AliMFTClusterFinder,1) 
+
+};
+
+//====================================================================================================================================================
+
+#endif
diff --git a/MFT/AliMFTClusterQA.C b/MFT/AliMFTClusterQA.C
new file mode 100644 (file)
index 0000000..12dba3a
--- /dev/null
@@ -0,0 +1,17 @@
+//================================================================================================================================
+
+void AliMFTClusterQA(const Char_t *readDir= ".",
+                    const Char_t *outDir = ".",
+                    Int_t nEventsToAnalyze = -1) {
+  
+  AliMFTClusterQA *myAnalysis = new AliMFTClusterQA();
+  myAnalysis -> Init(readDir, outDir, nEventsToAnalyze);
+
+  while (myAnalysis->LoadNextEvent()) continue;
+
+  myAnalysis->Terminate();
+
+}
+
+//================================================================================================================================
+
diff --git a/MFT/AliMFTClusterQA.cxx b/MFT/AliMFTClusterQA.cxx
new file mode 100644 (file)
index 0000000..f150c38
--- /dev/null
@@ -0,0 +1,160 @@
+#include "TObject.h"
+#include "AliRunLoader.h"
+#include "AliRun.h"
+#include "AliLoader.h"
+#include "AliMFT.h"
+#include "TClonesArray.h"
+#include "AliMFTCluster.h"
+#include "AliMFTSegmentation.h"
+#include "TFile.h"
+#include "TH1D.h"
+#include "AliLog.h"
+#include "TString.h"
+
+#include "AliMFTClusterQA.h"
+
+//====================================================================================================================================================
+//
+// Class for the analysis of the MFT clusters (a.k.a. rec points). Few QA histograms are created
+//
+// Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+ClassImp(AliMFTClusterQA)
+
+//====================================================================================================================================================
+
+AliMFTClusterQA::AliMFTClusterQA():
+  TObject(),
+  fMFTLoader(0),
+  fRunLoader(0),
+  fMFT(0),
+  fNPlanes(0),
+  fNEvents(0),
+  fEv(0),
+  fFileOut(0),
+  fReadDir(0),
+  fOutDir(0)
+{
+  
+  // default constructor
+
+  for (Int_t iPlane=0; iPlane<fMaxNPlanesMFT; iPlane++) {
+    fHistNClustersPerEvent[iPlane] = 0;
+    fHistNPixelsPerCluster[iPlane] = 0;
+    fHistClusterSizeX[iPlane] = 0; 
+    fHistClusterSizeY[iPlane] = 0;
+  }
+
+}
+
+//====================================================================================================================================================
+
+void AliMFTClusterQA::Init(Char_t *readDir, Char_t *outDir, Int_t nEventsToAnalyze) {
+
+  fReadDir = readDir;
+  fOutDir  = outDir;
+
+  fRunLoader = AliRunLoader::Open(Form("%s/galice.root", fReadDir.Data()));
+  gAlice = fRunLoader->GetAliRun();
+  if (!gAlice) fRunLoader->LoadgAlice();
+  fNEvents = fRunLoader->GetNumberOfEvents();
+  if (nEventsToAnalyze>0) fNEvents = TMath::Min(fNEvents, nEventsToAnalyze);
+
+  fMFT = (AliMFT*) gAlice->GetDetector("MFT"); 
+  fNPlanes = fMFT->GetSegmentation()->GetNPlanes();
+
+  BookHistos();
+
+  fMFTLoader = fRunLoader->GetDetectorLoader("MFT");
+  fMFTLoader -> LoadRecPoints("READ");
+
+}
+
+//====================================================================================================================================================
+
+Bool_t AliMFTClusterQA::LoadNextEvent() {
+
+  if (fEv>=fNEvents) return kFALSE;
+  AliDebug(1, Form("event %5d",fEv));
+  
+  fRunLoader->GetEvent(fEv);
+  fEv++;
+
+  if (!fMFTLoader->TreeR()->GetEvent()) return kTRUE;
+
+  for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+    Int_t nClusters = fMFT->GetRecPointsList(iPlane)->GetEntries();
+    fHistNClustersPerEvent[iPlane] -> Fill(nClusters);
+    AliDebug(1,Form("nClusters = %5d", nClusters));
+    for (Int_t iCluster=0; iCluster<nClusters; iCluster++) {
+      AliMFTCluster *cluster = (AliMFTCluster*) (fMFT->GetRecPointsList(iPlane))->At(iCluster);
+      fHistNPixelsPerCluster[iPlane] -> Fill(cluster->GetSize());
+      fHistClusterSizeX[iPlane]      -> Fill(cluster->GetErrX()*1.e4);   // converted in microns
+      fHistClusterSizeY[iPlane]      -> Fill(cluster->GetErrY()*1.e4);   // converted in microns
+    }
+  }
+
+  return kTRUE;
+
+}  
+
+//====================================================================================================================================================
+
+void AliMFTClusterQA::BookHistos() {
+
+  fFileOut = new TFile(Form("%s/MFT.RecPoints.QA.root",fOutDir.Data()), "recreate");
+
+  for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+
+    fHistNClustersPerEvent[iPlane] = new TH1D(Form("fHistNClustersPerEvent_Pl%02d",iPlane), 
+                                             Form("Number of clusters per event in Plane%02d",iPlane),
+                                             10000, -0.5, 9999.5);
+
+    fHistNPixelsPerCluster[iPlane] = new TH1D(Form("fHistNPixelsPerCluster_Pl%02d",iPlane), 
+                                             Form("Number of pixels per cluster in Plane%02d",iPlane),
+                                             15, -0.5, 14.5);
+
+    fHistClusterSizeX[iPlane]      = new TH1D(Form("fHistClusterSizeX_Pl%02d",iPlane), 
+                                             Form("#Deltax for clusters in Plane%02d",iPlane), 
+                                             100, 0., 100.);
+    
+    fHistClusterSizeY[iPlane]      = new TH1D(Form("fHistClusterSizeY_Pl%02d",iPlane), 
+                                             Form("#Deltay for clusters in Plane%02d",iPlane), 
+                                             100, 0., 100.);
+    
+    fHistNClustersPerEvent[iPlane] -> SetXTitle("N_{clusters} per Event");
+    fHistNPixelsPerCluster[iPlane] -> SetXTitle("N_{pixels} per Cluster");
+    fHistClusterSizeX[iPlane]      -> SetXTitle("#Deltax  [#mum]");
+    fHistClusterSizeY[iPlane]      -> SetXTitle("#Deltay  [#mum]");
+
+    fHistNClustersPerEvent[iPlane] -> Sumw2();
+    fHistNPixelsPerCluster[iPlane] -> Sumw2();
+    fHistClusterSizeX[iPlane]      -> Sumw2();
+    fHistClusterSizeY[iPlane]      -> Sumw2();
+    
+  }
+  
+}
+
+//====================================================================================================================================================
+
+void AliMFTClusterQA::Terminate() {
+
+  AliInfo("Writing QA histos...");
+
+  fFileOut->cd();
+
+  for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+    fHistNClustersPerEvent[iPlane] -> Write();
+    fHistNPixelsPerCluster[iPlane] -> Write();
+    fHistClusterSizeX[iPlane]      -> Write();
+    fHistClusterSizeY[iPlane]      -> Write();
+  }
+
+  fFileOut -> Close();
+
+}
+
+//====================================================================================================================================================
diff --git a/MFT/AliMFTClusterQA.h b/MFT/AliMFTClusterQA.h
new file mode 100644 (file)
index 0000000..0301e23
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef AliMFTClusterQA_H
+#define AliMFTClusterQA_H
+
+#include "TObject.h"
+#include "AliRunLoader.h"
+#include "AliRun.h"
+#include "AliLoader.h"
+#include "AliMFT.h"
+#include "TClonesArray.h"
+#include "AliMFTCluster.h"
+#include "AliMFTSegmentation.h"
+#include "TFile.h"
+#include "TH1D.h"
+#include "AliLog.h"
+#include "TString.h"
+
+//====================================================================================================================================================
+//
+// Class for the analysis of the MFT clusters (a.k.a. rec points). Few QA histograms are created
+//
+// Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+class AliMFTClusterQA : public TObject {
+  
+public:
+
+  AliMFTClusterQA();
+  virtual ~AliMFTClusterQA() {;}
+
+  void Init(Char_t *readDir, Char_t *outDir, Int_t nEventsToAnalyze);
+  Bool_t LoadNextEvent();
+  void BookHistos();
+  void Terminate();
+
+private:
+
+  AliMFTClusterQA(const AliMFTClusterQA& obj);
+  AliMFTClusterQA& operator=(const AliMFTClusterQA& other);
+
+protected:
+
+  static const Int_t fMaxNPlanesMFT = 20;
+
+  TH1D *fHistNClustersPerEvent[fMaxNPlanesMFT], *fHistNPixelsPerCluster[fMaxNPlanesMFT];
+  TH1D *fHistClusterSizeX[fMaxNPlanesMFT], *fHistClusterSizeY[fMaxNPlanesMFT];
+
+  TClonesArray *fMFTClusterArray[fMaxNPlanesMFT];
+
+  AliLoader *fMFTLoader;
+  AliRunLoader *fRunLoader;
+  AliMFT *fMFT;
+
+  Int_t fNPlanes, fNEvents, fEv;
+
+  TFile *fFileOut;
+
+  TString fReadDir, fOutDir;
+
+  ClassDef(AliMFTClusterQA, 1); 
+
+};
+
+//======================================================================================================
+#endif
+
+
diff --git a/MFT/AliMFTDigit.cxx b/MFT/AliMFTDigit.cxx
new file mode 100644 (file)
index 0000000..9364fc1
--- /dev/null
@@ -0,0 +1,55 @@
+/**************************************************************************
+ * Copyright(c) 2004-2006, 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.                  *
+ **************************************************************************/
+
+//====================================================================================================================================================
+//
+//      Digit description for the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "AliDigit.h"
+#include "AliMFTDigit.h"
+
+ClassImp(AliMFTDigit)
+
+//====================================================================================================================================================
+
+AliMFTDigit::AliMFTDigit():
+  AliDigit(),
+  fNMCTracks(0),
+  fPixelX(-1),
+  fPixelY(-1),
+  fPixelZ(0),
+  fPixelCenterX(0),
+  fPixelCenterY(0),  
+  fPixelCenterZ(0),  
+  fPixelWidthX(0),
+  fPixelWidthY(0),  
+  fPixelWidthZ(0),  
+  fPlane(-1),
+  fDetElemID(-1),
+  fEloss(0),
+  fNElectrons(0)
+{
+
+  // default cosntructor
+
+  for (Int_t iTr=0; iTr<fNMaxMCTracks; iTr++) fMCLabel[iTr] = -1; 
+
+}
+
+//====================================================================================================================================================
diff --git a/MFT/AliMFTDigit.h b/MFT/AliMFTDigit.h
new file mode 100644 (file)
index 0000000..3dd5c19
--- /dev/null
@@ -0,0 +1,95 @@
+#ifndef AliMFTDigit_H
+#define AliMFTDigit_H
+
+/* Copyright(c) 2004-2006, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice     */
+
+//====================================================================================================================================================
+//
+//      Digit description for the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "AliDigit.h"
+
+//====================================================================================================================================================
+
+class AliMFTDigit: public AliDigit {
+
+public:
+
+  AliMFTDigit();
+//   AliMFTDigit(const AliMFTDigit &d);
+
+  virtual ~AliMFTDigit() {}
+
+  void AddOffset2TrackID(Int_t offset) { for(Int_t iTr=0; iTr<fNMCTracks; iTr++) if (fMCLabel[iTr]>0) fMCLabel[iTr]+=offset; }  // needed for merging (?)
+    
+  void SetPlane(Int_t plane) { fPlane = plane; }
+  void SetDetElemID(Int_t detElemID) { fDetElemID = detElemID; }
+  void SetPixID(Int_t pixelX, Int_t pixelY, Int_t pixelZ) { fPixelX = pixelX;  fPixelY = pixelY; fPixelZ = pixelZ; }
+  void SetPixCenter(Double_t pixelCenterX, Double_t pixelCenterY, Double_t pixelCenterZ) { 
+    fPixelCenterX = pixelCenterX;  
+    fPixelCenterY = pixelCenterY; 
+    fPixelCenterZ = pixelCenterZ; 
+  }
+  void SetPixWidth(Double_t pixelWidthX, Double_t pixelWidthY, Double_t pixelWidthZ) { 
+    fPixelWidthX = pixelWidthX;  
+    fPixelWidthY = pixelWidthY;
+    fPixelWidthZ = pixelWidthZ; 
+  }
+  void SetEloss(Double_t sig) { fEloss = sig; fNElectrons = fEloss/fElossPerElectron; }
+
+  void  AddMCLabel(Int_t label) { if (fNMCTracks>=fNMaxMCTracks) return; else fMCLabel[fNMCTracks++]=label; }
+  Int_t GetNMCTracks() const { return fNMCTracks; }
+  Int_t GetMCLabel(Int_t track) const { if (track<fNMCTracks && track>=0) return fMCLabel[track]; else return -1; }
+
+  Double_t  GetEloss()         const { return fEloss; }
+  Double_t  GetNElectrons()    const { return fNElectrons; }
+  Int_t     GetPlane()         const { return fPlane; }
+  Int_t     GetDetElemID()     const { return fDetElemID; }
+  Int_t     GetPixelX()        const { return fPixelX; }
+  Int_t     GetPixelY()        const { return fPixelY; }
+  Int_t     GetPixelZ()        const { return fPixelZ; }
+  Double_t  GetPixelCenterX()  const { return fPixelCenterX; }
+  Double_t  GetPixelCenterY()  const { return fPixelCenterY; }
+  Double_t  GetPixelCenterZ()  const { return fPixelCenterZ; }
+  Double_t  GetPixelWidthX()   const { return fPixelWidthX; }
+  Double_t  GetPixelWidthY()   const { return fPixelWidthY; }
+  Double_t  GetPixelWidthZ()   const { return fPixelWidthZ; }
+    
+protected:
+    
+  static const Double_t fElossPerElectron = 3.62e-09;
+  static const Int_t fNMaxMCTracks = 10;
+
+  Int_t fNMCTracks;
+
+  Int_t fPixelX;
+  Int_t fPixelY;  
+  Int_t fPixelZ;
+  Double_t fPixelCenterX;
+  Double_t fPixelCenterY;
+  Double_t fPixelCenterZ;
+  Double_t fPixelWidthX;
+  Double_t fPixelWidthY;
+  Double_t fPixelWidthZ;
+  Int_t fPlane;     
+  Int_t fDetElemID;     
+  Double_t fEloss;       // total signal as Eloss in the medium
+  Double_t fNElectrons; 
+  
+  Int_t fMCLabel[fNMaxMCTracks];
+
+  ClassDef(AliMFTDigit,3)
+
+};
+
+//====================================================================================================================================================
+
+#endif
+
+
+
diff --git a/MFT/AliMFTDigitizer.cxx b/MFT/AliMFTDigitizer.cxx
new file mode 100644 (file)
index 0000000..bd4dc64
--- /dev/null
@@ -0,0 +1,221 @@
+/**************************************************************************
+ * Copyright(c) 1998-2000, 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.                  *
+ **************************************************************************/
+
+//====================================================================================================================================================
+//
+//      Digitizer class for the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "AliRun.h"
+#include "AliRunLoader.h"
+#include "AliRunDigitizer.h"
+#include "AliLoader.h"
+#include "AliLog.h"
+#include "AliMFTDigitizer.h"
+#include "AliMFTDigit.h"
+#include "AliMFT.h"
+#include "AliMFTSegmentation.h"
+#include "TObjArray.h"
+#include "TClonesArray.h"
+#include "AliDigitizer.h"
+
+ClassImp(AliMFTDigitizer)
+
+//====================================================================================================================================================
+    
+AliMFTDigitizer::AliMFTDigitizer():
+  AliDigitizer(),
+  fNPlanes(0),
+  fSegmentation(0)
+{
+
+  // default constructor 
+
+}
+
+//====================================================================================================================================================
+
+AliMFTDigitizer::AliMFTDigitizer(AliRunDigitizer *pRunDig):
+  AliDigitizer(pRunDig),
+  fNPlanes(0),
+  fSegmentation(0)
+{
+
+}
+
+//====================================================================================================================================================
+
+void AliMFTDigitizer::Exec(Option_t*) {
+
+  // This method is responsible for merging sdigits to a list of digits
+
+  AliDebug(1, "************************************************************************");
+  AliDebug(1, "************************ AliMFTDigitizer::Exec *************************");
+  AliDebug(1, "************************************************************************");
+  
+  if (!fSegmentation) {
+    fSegmentation = new AliMFTSegmentation("AliMFTGeometry.root");
+    fNPlanes = fSegmentation -> GetNPlanes();
+  }
+
+  AliDebug(1, Form("nPlanes = %d",fNPlanes));
+
+  AliDebug(1,Form("Start with %i input(s) for event %i", fManager->GetNinputs(), fManager->GetOutputEventNr()));
+    
+  AliRunLoader *pInRunLoader=0;
+  AliLoader    *pInMFTLoader=0;
+  
+  TClonesArray sDigits[fNMaxPlanes];
+  for (Int_t iPlane=0; iPlane<fNMaxPlanes; iPlane++) sDigits[iPlane].SetClass("AliMFTDigit");  // tmp storage for sdigits sum up from all input files
+  
+  // filling the arrays of sdigits...
+
+  for (Int_t iFile=0; iFile<fManager->GetNinputs(); iFile++) {
+    
+    pInRunLoader = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(iFile));
+    pInMFTLoader = pInRunLoader->GetLoader("MFTLoader"); 
+    if (!pInMFTLoader) {
+      AliDebug(1,"no MFT lodader, checking in the other input \n"); 
+      continue;
+    }
+    
+    if (!pInRunLoader->GetAliRun()) pInRunLoader->LoadgAlice();
+    AliMFT *pInMFT = (AliMFT*) pInRunLoader->GetAliRun()->GetDetector("MFT"); 
+    
+    AliDebug(1, "pInMFTLoader->LoadSDigits()...");
+    pInMFTLoader->LoadSDigits();
+    AliDebug(1, "... done!");
+    AliDebug(1, "    pInMFTLoader->TreeS()->GetEntry(0);");
+    pInMFTLoader->TreeS()->GetEntry(0);
+    AliDebug(1, "... done!");
+    
+    for (Int_t iPlane=0; iPlane<pInMFT->GetSDigitsList()->GetEntries(); iPlane++) {      
+      for(Int_t iSDig=0; iSDig<((TClonesArray*)pInMFT->GetSDigitsList()->At(iPlane))->GetEntries(); iSDig++) {
+       AliDebug(2, Form("Reading digit %03d of plane %02d (A)", iSDig, iPlane));
+       AliMFTDigit *pSDig = (AliMFTDigit*) ((TClonesArray*)pInMFT->GetSDigitsList()->At(iPlane))->At(iSDig);
+       AliDebug(2, Form("Reading digit %03d of plane %02d (B)", iSDig, iPlane));
+       pSDig->AddOffset2TrackID(fManager->GetMask(iFile));   // -> To be introduced for merging (since all inputs count tracks independently from 0)
+       AliDebug(2, Form("Reading digit %03d of plane %02d (C)", iSDig, iPlane));
+       new ((sDigits[iPlane])[sDigits[iPlane].GetEntries()]) AliMFTDigit(*pSDig);  
+       AliDebug(2, Form("Reading digit %03d of plane %02d (D)", iSDig, iPlane));
+      }
+    }
+    
+    pInMFTLoader->UnloadSDigits();   
+    pInMFT->ResetSDigits();
+
+  }
+  
+  AliRunLoader *pOutRunLoader = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());  // open output stream (only 1 possible)
+  AliLoader    *pOutMFTLoader = pOutRunLoader->GetLoader("MFTLoader");                        
+  AliRun       *pAliRun       = pOutRunLoader->GetAliRun();
+  AliMFT       *pOutMFT       = (AliMFT*) pAliRun->GetDetector("MFT");      
+  pOutMFTLoader->MakeTree("D");   
+  pOutMFT->MakeBranch("D");
+  pOutMFT->SetTreeAddress();
+  
+  SDigits2Digits(sDigits, pOutMFT->GetDigitsList());   // here the sdigits are merged into digits
+  
+  pOutMFTLoader->TreeD()->Fill();              // fill the output tree with the list of digits
+  pOutMFTLoader->WriteDigits("OVERWRITE");     // serialize them to file
+  
+  for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) sDigits[iPlane].Clear();   // remove all tmp sdigits
+  pOutMFTLoader->UnloadDigits();   
+  pOutMFT->ResetDigits(); 
+
+}
+
+//====================================================================================================================================================
+
+void AliMFTDigitizer::SDigits2Digits(TClonesArray *pSDigitList, TObjArray *pDigitList) {   
+
+  TClonesArray *myDigitList[fNMaxPlanes] = {0};
+  for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) { 
+    myDigitList[iPlane] = (TClonesArray*)(*pDigitList)[iPlane];
+    if (myDigitList[iPlane]->GetEntries()!=0) AliErrorClass("Some of digits lists is not empty");   // in principle those lists should be empty 
+  }
+   
+  AliDebug(1,"starting loop over planes");
+   
+  for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+     
+    AliMFTDigit *newDig=NULL;
+    AliMFTDigit *oldDig=NULL;
+    pSDigitList[iPlane].Sort();
+
+    AliDebug(1,"starting loop over sdigits to create digits");
+    AliDebug(1, Form("MFT plane #%02d has %d SDigits", iPlane, Int_t(pSDigitList[iPlane].GetEntries())));
+
+    for (Int_t iSDig=0; iSDig<pSDigitList[iPlane].GetEntries(); iSDig++) {
+
+      newDig = (AliMFTDigit*) (pSDigitList[iPlane].At(iSDig));
+      Bool_t digitExists = kFALSE;
+      Int_t nDigits = myDigitList[iPlane]->GetEntries();
+      
+      for (Int_t iDig=0; iDig<nDigits; iDig++) {
+       oldDig = (AliMFTDigit*) (myDigitList[iPlane]->At(iDig));
+       if (newDig->GetDetElemID()==oldDig->GetDetElemID() &&
+           newDig->GetPixelX()==oldDig->GetPixelX() &&
+           newDig->GetPixelY()==oldDig->GetPixelY() &&
+           newDig->GetPixelZ()==oldDig->GetPixelZ()) {
+         digitExists = kTRUE;
+         MergeDigits(oldDig, newDig);
+         break;
+       }
+      }
+
+      if (!digitExists) new ((*myDigitList[iPlane])[myDigitList[iPlane]->GetEntries()]) AliMFTDigit(*newDig);
+
+    }
+    
+    AliDebug(1, Form("MFT plane #%02d has %d Digits", iPlane, Int_t(myDigitList[iPlane]->GetEntries())));
+    
+//     for (Int_t iDigit=0; iDigit<myDigitList[iPlane]->GetEntries(); iDigit++) {
+//       AliDebug(1, Form("Digit %03d of MFT plane %02d has pixel coordinates (%05d, %05d)", 
+//                    iDigit, iPlane, ((AliMFTDigit*) myDigitList[iPlane]->At(iDigit))->GetPixelX(), ((AliMFTDigit*) myDigitList[iPlane]->At(iDigit))->GetPixelY()) );
+//     }
+
+    AliDebug(1, "ending loop over sdigits to create digits");
+
+  }
+
+  AliDebug(1,"ending loop over layers");  
+
+}
+
+//====================================================================================================================================================
+
+void AliMFTDigitizer::MergeDigits(AliMFTDigit *mainDig, AliMFTDigit *digToSum) {
+  
+  mainDig -> SetEloss(mainDig->GetEloss() + digToSum->GetEloss());
+  
+  Bool_t trackExists = kFALSE;
+  for (Int_t iTrack=0; iTrack<mainDig->GetNMCTracks(); iTrack++) {
+    if (digToSum->GetMCLabel(0) == mainDig->GetMCLabel(iTrack)) {
+      trackExists = kTRUE;
+      break;
+    }
+  }
+  
+  if (!trackExists) mainDig->AddMCLabel(digToSum->GetMCLabel(0));
+  
+}
+
+//====================================================================================================================================================
+
diff --git a/MFT/AliMFTDigitizer.h b/MFT/AliMFTDigitizer.h
new file mode 100644 (file)
index 0000000..d002eaa
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef AliMFTDigitizer_H
+#define AliMFTDigitizer_H
+
+/* Copyright (c) 1998-2001, ALICE Experiment at CERN, All rights reserved *
+ * See cxx source for full Copyright notice                               */
+
+//====================================================================================================================================================
+//
+//      Digitizer class for the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "AliRun.h"
+#include "AliRunLoader.h"
+#include "AliRunDigitizer.h"
+#include "AliLoader.h"
+#include "AliLog.h"
+#include "AliMFTDigit.h"
+#include "AliMFTSegmentation.h"
+#include "TObjArray.h"
+#include "TClonesArray.h"
+#include "AliDigitizer.h"
+
+//====================================================================================================================================================
+
+class AliMFTDigitizer : public AliDigitizer {
+
+public:
+
+  AliMFTDigitizer();
+  AliMFTDigitizer(AliRunDigitizer *pRunDig);
+  virtual ~AliMFTDigitizer() { }
+
+  void Exec(Option_t *option);
+  void SDigits2Digits(TClonesArray *pSDigitList, TObjArray *pDigitLst);
+
+  void MergeDigits(AliMFTDigit *mainDig, AliMFTDigit *digToSum);
+  
+  
+protected:
+  static const Int_t fNMaxPlanes = 20;     // max number of MFT planes
+  static const Int_t fNMaxMCTracks = 10;   // max MC tracks sharing a digit  
+
+  Int_t fNPlanes;    
+  
+  AliMFTSegmentation *fSegmentation;
+
+private:
+
+  AliMFTDigitizer (const AliMFTDigitizer& mftDigitizer);             // dummy copy constructor
+  AliMFTDigitizer &operator=(const AliMFTDigitizer& mftDigitizer);   // dummy assignment operator
+
+  ClassDef(AliMFTDigitizer,1)
+    
+};
+
+//====================================================================================================================================================
+
+#endif
+
+
diff --git a/MFT/AliMFTGeometry.root b/MFT/AliMFTGeometry.root
new file mode 100644 (file)
index 0000000..45f81b6
Binary files /dev/null and b/MFT/AliMFTGeometry.root differ
diff --git a/MFT/AliMFTHit.cxx b/MFT/AliMFTHit.cxx
new file mode 100644 (file)
index 0000000..f3195a4
--- /dev/null
@@ -0,0 +1,62 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+//====================================================================================================================================================
+//
+//      Hit description for the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "TLorentzVector.h"
+#include "TParticle.h"
+#include "AliHit.h"
+#include "AliRun.h"
+#include "AliMC.h"
+
+#include "AliMFTHit.h"
+
+ClassImp(AliMFTHit)
+
+//====================================================================================================================================================
+
+AliMFTHit::AliMFTHit():
+  AliHit(),
+  fStatus(0),
+  fPlane(-1),
+  fDetElemID(-1),
+  fPx(0),
+  fPy(0),
+  fPz(0),
+  fEloss(0),
+  fTOF(0) 
+{
+
+  // default constructor 
+
+}
+
+//====================================================================================================================================================
+
+TParticle* AliMFTHit::GetParticle() const {
+
+    //   The TParticle of the track that created this hit.
+
+    return gAlice->GetMCApp()->Particle(GetTrack());
+
+}
+
+//====================================================================================================================================================
diff --git a/MFT/AliMFTHit.h b/MFT/AliMFTHit.h
new file mode 100644 (file)
index 0000000..1210840
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef AliMFTHit_H
+#define AliMFTHit_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+//====================================================================================================================================================
+//
+//      Hit description for the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "TLorentzVector.h"
+#include "TParticle.h"
+#include "AliHit.h"
+#include "AliRun.h"
+#include "AliMC.h"
+
+//====================================================================================================================================================
+
+class TParticle;
+
+class AliMFTHit : public AliHit {
+
+public:
+
+  AliMFTHit();
+//   AliMFTHit(const AliMFTHit &h);
+//   AliMFTHit& operator=(const AliMFTHit &h);
+  
+  virtual ~AliMFTHit() {}
+  
+  virtual void SetPlane(Int_t plane) { fPlane = plane; }
+  virtual void SetDetElemID(Int_t detElemID) { fDetElemID = detElemID; }
+  virtual void SetPosition(TLorentzVector &x) { fX =x.X(); fY =x.Y(); fZ =x.Z(); }
+  virtual void SetTOF(Double_t time) { fTOF = time; }
+  virtual void SetStatus(Int_t status) { fStatus  = status; }
+  virtual void SetEloss(Double_t energy) { fEloss = energy; }
+  virtual void SetMomentum(TLorentzVector &p) { fPx=p.Px(); fPy=p.Py(); fPz=p.Pz(); }
+  
+  virtual Int_t GetTrackStatus() const { return fStatus;  }
+  virtual Int_t GetPlane()       const { return fPlane; }
+  virtual Int_t GetDetElemID()   const { return fDetElemID; }
+  virtual Double_t GetEloss()    const { return fEloss; }
+  virtual Double_t GetTOF()      const { return fTOF; }
+  
+  virtual void GetPosition(Double_t &x,Double_t &y,Double_t &z) const { x=fX; y=fY; z=fZ; }
+  virtual Double_t GetX() const { return fX; }
+  virtual Double_t GetY() const { return fY; }
+  virtual Double_t GetZ() const { return fZ; }
+
+  virtual void GetMomentum(Double_t &px,Double_t &py,Double_t &pz) const { px=fPx; py=fPy; pz=fPz; }
+  virtual Double_t GetPx() const { return fPx; }
+  virtual Double_t GetPy() const { return fPy; }
+  virtual Double_t GetPz() const { return fPz; }
+
+  TParticle* GetParticle() const;
+
+  Bool_t IsInside()      const { return (fStatus ==  1); }
+  Bool_t IsEntering()    const { return (fStatus ==  2); }
+  Bool_t IsExiting()     const { return (fStatus ==  4); }
+  Bool_t IsOut()         const { return (fStatus ==  8); }
+  Bool_t IsDisappeared() const { return (fStatus == 16); }
+  Bool_t IsStopped()     const { return (fStatus == 32); }
+  Bool_t IsAlive()       const { return (fStatus == 64); }
+
+protected:
+
+  Int_t   fStatus;   /* The track status flag. This flag indicates the track status
+                       at the time of creating this hit. 
+                       It is made up of the following 8 status bits from highest order to lowest order bits 0 :  
+                       IsTrackAlive(): IsTrackStop(): IsTrackDisappeared(): IsTrackOut(): IsTrackExiting(): IsTrackEntering(): IsTrackInside()     .
+                       See AliMC for a description of these functions. 
+                       If the function is true then the bit is set to one, otherwise it is zero. */
+  
+  Int_t    fPlane;      // Plane number
+  Int_t    fDetElemID;  // Detection Element unique ID 
+  Double_t fPx;         // PX of particle at the point of the hit
+  Double_t fPy;         // PY of particle at the point of the hit
+  Double_t fPz;         // PZ of particle at the point of the hit
+  Double_t fEloss;      // Energy deposited in the current step
+  Double_t fTOF;        // Time of flight at the point of the hit
+  
+  ClassDef(AliMFTHit,3)
+    
+};
+
+//====================================================================================================================================================
+
+#endif
diff --git a/MFT/AliMFTPlane.cxx b/MFT/AliMFTPlane.cxx
new file mode 100644 (file)
index 0000000..78fb56f
--- /dev/null
@@ -0,0 +1,624 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+
+//====================================================================================================================================================
+//
+//      Class for the description of the structure for the planes of the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "TNamed.h"
+#include "THnSparse.h"
+#include "TClonesArray.h"
+#include "AliMFTPlane.h"
+#include "TAxis.h"
+#include "TPave.h"
+#include "TCanvas.h"
+#include "TH2D.h"
+#include "TEllipse.h"
+#include "TMath.h"
+#include "AliLog.h"
+
+ClassImp(AliMFTPlane)
+
+//====================================================================================================================================================
+
+AliMFTPlane::AliMFTPlane():
+  TNamed(),
+  fPlaneNumber(0),
+  fZCenter(0), 
+  fRMinSupport(0), 
+  fRMax(0),
+  fRMaxSupport(0),
+  fPixelSizeX(0), 
+  fPixelSizeY(0), 
+  fThicknessActive(0), 
+  fThicknessSupport(0), 
+  fThicknessReadout(0),
+  fZCenterActiveFront(0),
+  fZCenterActiveBack(0),
+  fEquivalentSilicon(0),
+  fEquivalentSiliconBeforeFront(0),
+  fEquivalentSiliconBeforeBack(0),
+  fActiveElements(0),
+  fReadoutElements(0),
+  fSupportElements(0)
+{
+
+  fPlaneNumber = -1;
+
+  fActiveElements  = new TClonesArray("THnSparseC");
+  fReadoutElements = new TClonesArray("THnSparseC");
+  fSupportElements = new TClonesArray("THnSparseC");
+
+  // default constructor
+
+}
+
+//====================================================================================================================================================
+
+AliMFTPlane::AliMFTPlane(const Char_t *name, const Char_t *title):
+  TNamed(name, title),
+  fPlaneNumber(0),
+  fZCenter(0), 
+  fRMinSupport(0), 
+  fRMax(0),
+  fRMaxSupport(0),
+  fPixelSizeX(0), 
+  fPixelSizeY(0), 
+  fThicknessActive(0), 
+  fThicknessSupport(0), 
+  fThicknessReadout(0),
+  fZCenterActiveFront(0),
+  fZCenterActiveBack(0),
+  fEquivalentSilicon(0),
+  fEquivalentSiliconBeforeFront(0),
+  fEquivalentSiliconBeforeBack(0),
+  fActiveElements(0),
+  fReadoutElements(0),
+  fSupportElements(0)
+{
+
+  fPlaneNumber = -1;
+
+  fActiveElements  = new TClonesArray("THnSparseC");
+  fReadoutElements = new TClonesArray("THnSparseC");
+  fSupportElements = new TClonesArray("THnSparseC");
+
+  // default constructor
+
+}
+
+//====================================================================================================================================================
+
+AliMFTPlane::AliMFTPlane(const AliMFTPlane& plane):
+  TNamed(plane),
+  fPlaneNumber(plane.fPlaneNumber),
+  fZCenter(plane.fZCenter), 
+  fRMinSupport(plane.fRMinSupport), 
+  fRMax(plane.fRMax),
+  fRMaxSupport(plane.fRMaxSupport),
+  fPixelSizeX(plane.fPixelSizeX), 
+  fPixelSizeY(plane.fPixelSizeY), 
+  fThicknessActive(plane.fThicknessActive), 
+  fThicknessSupport(plane.fThicknessSupport), 
+  fThicknessReadout(plane.fThicknessReadout),
+  fZCenterActiveFront(plane.fZCenterActiveFront),
+  fZCenterActiveBack(plane.fZCenterActiveBack),
+  fEquivalentSilicon(plane.fEquivalentSilicon),
+  fEquivalentSiliconBeforeFront(plane.fEquivalentSiliconBeforeFront),
+  fEquivalentSiliconBeforeBack(plane.fEquivalentSiliconBeforeBack),
+  fActiveElements(plane.fActiveElements),
+  fReadoutElements(plane.fReadoutElements),
+  fSupportElements(plane.fSupportElements)
+{
+
+  // copy constructor
+  
+}
+
+//====================================================================================================================================================
+
+AliMFTPlane& AliMFTPlane::operator=(const AliMFTPlane& plane) {
+
+  // Assignment operator
+
+  // check assignement to self
+  if (this == &plane) return *this;
+
+  // base class assignement
+  TNamed::operator=(plane);
+  
+  // clear memory
+  Clear();
+
+  fPlaneNumber                  = plane.fPlaneNumber;
+  fZCenter                      = plane.fZCenter; 
+  fRMinSupport                  = plane.fRMinSupport; 
+  fRMax                         = plane.fRMax;
+  fRMaxSupport                  = plane.fRMaxSupport;
+  fPixelSizeX                   = plane.fPixelSizeX;
+  fPixelSizeY                   = plane.fPixelSizeY; 
+  fThicknessActive              = plane.fThicknessActive; 
+  fThicknessSupport             = plane.fThicknessSupport; 
+  fThicknessReadout             = plane.fThicknessReadout;
+  fZCenterActiveFront           = plane.fZCenterActiveFront;
+  fZCenterActiveBack            = plane.fZCenterActiveBack;
+  fEquivalentSilicon            = plane.fEquivalentSilicon;
+  fEquivalentSiliconBeforeFront = plane.fEquivalentSiliconBeforeFront;
+  fEquivalentSiliconBeforeBack  = plane.fEquivalentSiliconBeforeBack;
+  fActiveElements               = plane.fActiveElements;
+  fReadoutElements              = plane.fReadoutElements;
+  fSupportElements              = plane.fSupportElements;
+
+  return *this;
+
+}
+
+//====================================================================================================================================================
+
+Bool_t AliMFTPlane::Init(Int_t    planeNumber,
+                        Double_t zCenter, 
+                        Double_t rMin, 
+                        Double_t rMax, 
+                        Double_t pixelSizeX, 
+                        Double_t pixelSizeY, 
+                        Double_t thicknessActive, 
+                        Double_t thicknessSupport, 
+                        Double_t thicknessReadout) {
+
+  AliDebug(1, Form("Initializing Plane Structure for Plane %s", GetName()));
+
+  fPlaneNumber      = planeNumber;
+  fZCenter          = zCenter;
+  fRMinSupport      = rMin;
+  fRMax             = rMax;
+  fPixelSizeX       = pixelSizeX;
+  fPixelSizeY       = pixelSizeY;
+  fThicknessActive  = thicknessActive;
+  fThicknessSupport = thicknessSupport;
+  fThicknessReadout = thicknessReadout;
+
+  fZCenterActiveFront = fZCenter - 0.5*fThicknessSupport - 0.5*fThicknessActive;
+  fZCenterActiveBack  = fZCenter + 0.5*fThicknessSupport + 0.5*fThicknessActive;
+
+  if (fRMinSupport <= fRadiusMin) fRMinSupport = fRadiusMin;
+  else {
+    fRMinSupport = fRadiusMin + (fHeightActive-fActiveSuperposition) * Int_t((fRMinSupport-fRadiusMin)/(fHeightActive-fActiveSuperposition));
+  }
+  
+  if (fRMax < fRMinSupport+fHeightActive) fRMax = fRMinSupport + fHeightActive;
+  
+  fRMax = fRMinSupport + (fHeightActive-fActiveSuperposition) * 
+    (Int_t((fRMax-fRMinSupport-fHeightActive)/(fHeightActive-fActiveSuperposition))+1) + fHeightActive;
+  
+  fRMaxSupport = TMath::Sqrt(fHeightActive*(rMax-fHeightActive) + fRMax*fRMax) + fSupportExtMargin;
+  return kTRUE;
+}
+
+//====================================================================================================================================================
+
+Bool_t AliMFTPlane::CreateStructure() {
+
+  Int_t nBins[3]={0};
+  Double_t minPosition[3]={0}, maxPosition[3]={0};
+  
+  // ------------------- support element -------------------------------------------------
+  
+  nBins[0] = 1;
+  nBins[1] = 1;
+  nBins[2] = 1;
+  
+  minPosition[0] = -1.*fRMaxSupport;
+  minPosition[1] = -1.*fRMaxSupport;
+  minPosition[2] = fZCenter - 0.5*fThicknessSupport;
+  
+  maxPosition[0] = +1.*fRMaxSupport;
+  maxPosition[1] = +1.*fRMaxSupport;
+  maxPosition[2] = fZCenter + 0.5*fThicknessSupport;
+  
+  new ((*fSupportElements)[fSupportElements->GetEntries()]) THnSparseC(Form("MFTSupportElemHist_%02d%03d", fPlaneNumber, fSupportElements->GetEntries()), 
+                                                                      Form("MFTSupportElemHist_%02d%03d", fPlaneNumber, fSupportElements->GetEntries()), 
+                                                                      3, nBins, minPosition, maxPosition);
+
+  // ------------------- det elements: active + readout ----------------------------------
+  
+  Double_t lowEdgeActive = -1.*fRMax;
+  Double_t supEdgeActive = lowEdgeActive + fHeightActive;
+  Double_t zMin = 0.;
+  Bool_t isFront = kTRUE;
+  
+  while (supEdgeActive < fRMax+0.01) {
+    
+    if (isFront) zMin = fZCenter - 0.5*fThicknessSupport - fThicknessActive;
+    else         zMin = fZCenter + 0.5*fThicknessSupport;
+    
+    Double_t extLimitAtLowEdgeActive = TMath::Sqrt((fRMax-TMath::Abs(lowEdgeActive)) * TMath::Abs(2*fRMax - (fRMax-TMath::Abs(lowEdgeActive))));
+    Double_t extLimitAtSupEdgeActive = TMath::Sqrt((fRMax-TMath::Abs(supEdgeActive)) * TMath::Abs(2*fRMax - (fRMax-TMath::Abs(supEdgeActive))));
+    
+    // creating new det element: active + readout
+    
+    Double_t extLimitDetElem = TMath::Max(extLimitAtLowEdgeActive, extLimitAtSupEdgeActive);
+    
+    if (supEdgeActive<-1.*fRMinSupport+0.01 || lowEdgeActive>1.*fRMinSupport-0.01) {     // single element covering the row
+      
+      nBins[0] = TMath::Nint(2.*extLimitDetElem/fPixelSizeX);
+      nBins[1] = TMath::Nint(fHeightActive/fPixelSizeY);
+      nBins[2] = 1;
+      
+      minPosition[0] = -1.*extLimitDetElem;
+      minPosition[1] = lowEdgeActive;
+      minPosition[2] = zMin;
+      
+      maxPosition[0] = +1.*extLimitDetElem;
+      maxPosition[1] = supEdgeActive;
+      maxPosition[2] = zMin+fThicknessActive; 
+      
+      new ((*fActiveElements)[fActiveElements->GetEntries()]) THnSparseC(Form("MFTActiveElemHist_%02d%03d", fPlaneNumber, fActiveElements->GetEntries()), 
+                                                                        Form("MFTActiveElemHist_%02d%03d", fPlaneNumber, fActiveElements->GetEntries()), 
+                                                                        3, nBins, minPosition, maxPosition);
+      
+      if (supEdgeActive>0.) {
+       minPosition[1] = supEdgeActive;
+       maxPosition[1] = supEdgeActive+fHeightReadout;
+      }
+      else {
+       minPosition[1] = lowEdgeActive-fHeightReadout;
+       maxPosition[1] = lowEdgeActive;
+      }
+      
+      new ((*fReadoutElements)[fReadoutElements->GetEntries()]) THnSparseC(Form("MFTReadoutElemHist_%02d%03d", fPlaneNumber, fReadoutElements->GetEntries()), 
+                                                                          Form("MFTReadoutElemHist_%02d%03d", fPlaneNumber, fReadoutElements->GetEntries()), 
+                                                                          3, nBins, minPosition, maxPosition);
+      
+    }
+    
+    else {     // two elements covering the row
+      
+      Double_t intLimitAtLowEdge = 0., intLimitAtSupEdge = 0.;
+      if (fRMinSupport-TMath::Abs(lowEdgeActive)>0.) intLimitAtLowEdge = TMath::Sqrt((fRMinSupport-TMath::Abs(lowEdgeActive)) * TMath::Abs(2*fRMinSupport - (fRMinSupport-TMath::Abs(lowEdgeActive))));
+      if (fRMinSupport-TMath::Abs(supEdgeActive)>0.) intLimitAtSupEdge = TMath::Sqrt((fRMinSupport-TMath::Abs(supEdgeActive)) * TMath::Abs(2*fRMinSupport - (fRMinSupport-TMath::Abs(supEdgeActive))));
+      Double_t intLimitDetElem = TMath::Max(intLimitAtLowEdge, intLimitAtSupEdge);
+      
+      nBins[0] = TMath::Nint((extLimitDetElem-intLimitDetElem)/fPixelSizeX);
+      nBins[1] = TMath::Nint(fHeightActive/fPixelSizeY);
+      nBins[2] = 1;
+      
+      // left element
+      
+      minPosition[0] = -1.*extLimitDetElem;
+      minPosition[1] = lowEdgeActive;
+      minPosition[2] = zMin;
+      
+      maxPosition[0] = -1.*intLimitDetElem;
+      maxPosition[1] = supEdgeActive;
+      maxPosition[2] = zMin+fThicknessActive; 
+      
+      new ((*fActiveElements)[fActiveElements->GetEntries()]) THnSparseC(Form("MFTActiveElemHist_%02d%03d", fPlaneNumber, fActiveElements->GetEntries()), 
+                                                                        Form("MFTActiveElemHist_%02d%03d", fPlaneNumber, fActiveElements->GetEntries()), 
+                                                                        3, nBins, minPosition, maxPosition);   
+      
+      if (supEdgeActive>0.) {
+       minPosition[1] = supEdgeActive;
+       maxPosition[1] = supEdgeActive+fHeightReadout;
+      }
+      else {
+       minPosition[1] = lowEdgeActive-fHeightReadout;
+       maxPosition[1] = lowEdgeActive;
+      }
+      
+      new ((*fReadoutElements)[fReadoutElements->GetEntries()]) THnSparseC(Form("MFTReadoutElemHist_%02d%03d", fPlaneNumber, fReadoutElements->GetEntries()), 
+                                                                          Form("MFTReadoutElemHist_%02d%03d", fPlaneNumber, fReadoutElements->GetEntries()), 
+                                                                          3, nBins, minPosition, maxPosition);
+      
+      // right element
+      
+      minPosition[0] = +1.*intLimitDetElem;
+      minPosition[1] = lowEdgeActive;
+      minPosition[2] = zMin;
+      
+      maxPosition[0] = +1.*extLimitDetElem;
+      maxPosition[1] = supEdgeActive;
+      maxPosition[2] = zMin+fThicknessActive; 
+      
+      new ((*fActiveElements)[fActiveElements->GetEntries()]) THnSparseC(Form("MFTActiveElemHist_%02d%03d", fPlaneNumber, fActiveElements->GetEntries()), 
+                                                                        Form("MFTActiveElemHist_%02d%03d", fPlaneNumber, fActiveElements->GetEntries()), 
+                                                                        3, nBins, minPosition, maxPosition);   
+      
+      if (supEdgeActive>0.) {
+       minPosition[1] = supEdgeActive;
+       maxPosition[1] = supEdgeActive+fHeightReadout;
+      }
+      else {
+       minPosition[1] = lowEdgeActive-fHeightReadout;
+       maxPosition[1] = lowEdgeActive;
+      }
+      
+      new ((*fReadoutElements)[fReadoutElements->GetEntries()]) THnSparseC(Form("MFTReadoutElemHist_%02d%03d", fPlaneNumber, fReadoutElements->GetEntries()), 
+                                                                          Form("MFTReadoutElemHist_%02d%03d", fPlaneNumber, fReadoutElements->GetEntries()), 
+                                                                          3, nBins, minPosition, maxPosition);
+      
+    }
+    
+    lowEdgeActive += fHeightActive - fActiveSuperposition;
+    supEdgeActive = lowEdgeActive + fHeightActive;
+    isFront = !isFront;
+    
+  }
+  
+  AliDebug(1, Form("Structure completed for MFT plane %s", GetName()));
+
+  return kTRUE;
+  
+}
+
+//====================================================================================================================================================
+
+THnSparseC* AliMFTPlane::GetActiveElement(Int_t id) {
+
+  if (id<0 || id>=GetNActiveElements()) return NULL;
+  else return (THnSparseC*) fActiveElements->At(id);
+
+}
+
+//====================================================================================================================================================
+
+THnSparseC* AliMFTPlane::GetReadoutElement(Int_t id) {
+
+  if (id<0 || id>=GetNReadoutElements()) return NULL;
+  else return (THnSparseC*) fReadoutElements->At(id);
+
+}
+
+//====================================================================================================================================================
+
+THnSparseC* AliMFTPlane::GetSupportElement(Int_t id) {
+
+  if (id<0 || id>=GetNSupportElements()) return NULL;
+  else return (THnSparseC*) fSupportElements->At(id);
+
+}
+
+//====================================================================================================================================================
+
+void AliMFTPlane::DrawPlane(Char_t *opt) {
+
+  // ------------------- "FRONT" option ------------------
+
+  if (!strcmp(opt, "front")) {
+
+    TCanvas *cnv = new TCanvas("cnv", GetName(), 900, 900);
+    cnv->Draw();
+
+    //    printf("Created Canvas\n");
+
+    TH2D *h = new TH2D("tmp", GetName(), 
+                      1, 1.1*GetSupportElement(0)->GetAxis(0)->GetXmin(), 1.1*GetSupportElement(0)->GetAxis(0)->GetXmax(), 
+                      1, 1.1*GetSupportElement(0)->GetAxis(1)->GetXmin(), 1.1*GetSupportElement(0)->GetAxis(1)->GetXmax());
+    h->SetXTitle("x [cm]");
+    h->SetYTitle("y [cm]");
+    h->Draw();
+
+    printf("Created hist\n");
+
+    TEllipse *supportExt = new TEllipse(0.0, 0.0, fRMaxSupport, fRMaxSupport);
+    TEllipse *supportInt = new TEllipse(0.0, 0.0, fRMinSupport, fRMinSupport);
+    supportExt->SetFillColor(kCyan-10);
+    supportExt -> Draw("same");
+    supportInt -> Draw("same");
+
+    //    printf("Created Ellipses\n");
+
+    for (Int_t iEl=0; iEl<GetNActiveElements(); iEl++) {
+      //      printf("Active element %d\n", iEl);
+      if (!IsFront(GetActiveElement(iEl))) continue;
+      TPave *pave = new TPave(GetActiveElement(iEl)->GetAxis(0)->GetXmin(), 
+                             GetActiveElement(iEl)->GetAxis(1)->GetXmin(), 
+                             GetActiveElement(iEl)->GetAxis(0)->GetXmax(), 
+                             GetActiveElement(iEl)->GetAxis(1)->GetXmax(), 1);
+      pave -> SetFillColor(kGreen);
+      pave -> Draw("same");
+    }
+
+    for (Int_t iEl=0; iEl<GetNReadoutElements(); iEl++) {
+      //      printf("Readout element %d\n", iEl);
+      if (!IsFront(GetReadoutElement(iEl))) continue;
+      TPave *pave = new TPave(GetReadoutElement(iEl)->GetAxis(0)->GetXmin(), 
+                             GetReadoutElement(iEl)->GetAxis(1)->GetXmin(), 
+                             GetReadoutElement(iEl)->GetAxis(0)->GetXmax(), 
+                             GetReadoutElement(iEl)->GetAxis(1)->GetXmax(), 1);
+      pave -> SetFillColor(kRed);
+      pave -> Draw("same");
+    }
+
+  }
+    
+  // ------------------- "BACK" option ------------------
+
+  else if (!strcmp(opt, "back")) {
+
+    TCanvas *cnv = new TCanvas("cnv", GetName(), 900, 900);
+    cnv->Draw();
+    
+    TH2D *h = new TH2D("tmp", GetName(), 
+                      1, 1.1*GetSupportElement(0)->GetAxis(0)->GetXmin(), 1.1*GetSupportElement(0)->GetAxis(0)->GetXmax(), 
+                      1, 1.1*GetSupportElement(0)->GetAxis(1)->GetXmin(), 1.1*GetSupportElement(0)->GetAxis(1)->GetXmax());
+    h->SetXTitle("x [cm]");
+    h->SetYTitle("y [cm]");
+    h->Draw();
+
+    TEllipse *supportExt = new TEllipse(0.0, 0.0, fRMaxSupport, fRMaxSupport);
+    TEllipse *supportInt = new TEllipse(0.0, 0.0, fRMinSupport, fRMinSupport);
+    supportExt -> SetFillColor(kCyan-10);
+    supportExt -> Draw("same");
+    supportInt -> Draw("same");
+
+    for (Int_t iEl=0; iEl<GetNActiveElements(); iEl++) {
+      if (IsFront(GetActiveElement(iEl))) continue;
+      TPave *pave = new TPave(GetActiveElement(iEl)->GetAxis(0)->GetXmin(), 
+                             GetActiveElement(iEl)->GetAxis(1)->GetXmin(), 
+                             GetActiveElement(iEl)->GetAxis(0)->GetXmax(), 
+                             GetActiveElement(iEl)->GetAxis(1)->GetXmax(), 1);
+      pave -> SetFillColor(kGreen);
+      pave -> Draw("same");
+    }
+
+    for (Int_t iEl=0; iEl<GetNReadoutElements(); iEl++) {
+      if (IsFront(GetReadoutElement(iEl))) continue;
+      TPave *pave = new TPave(GetReadoutElement(iEl)->GetAxis(0)->GetXmin(), 
+                             GetReadoutElement(iEl)->GetAxis(1)->GetXmin(), 
+                             GetReadoutElement(iEl)->GetAxis(0)->GetXmax(), 
+                             GetReadoutElement(iEl)->GetAxis(1)->GetXmax(), 1);
+      pave -> SetFillColor(kRed);
+      pave -> Draw("same");
+    }
+
+  }
+
+  // ------------------- "BOTH" option ------------------
+
+  else if (!strcmp(opt, "both")) {
+
+    TCanvas *cnv = new TCanvas("cnv", GetName(), 900, 900);
+    cnv->Draw();
+
+    TH2D *h = new TH2D("tmp", GetName(), 
+                      1, 1.1*GetSupportElement(0)->GetAxis(0)->GetXmin(), 1.1*GetSupportElement(0)->GetAxis(0)->GetXmax(), 
+                      1, 1.1*GetSupportElement(0)->GetAxis(1)->GetXmin(), 1.1*GetSupportElement(0)->GetAxis(1)->GetXmax());
+    h->SetXTitle("x [cm]");
+    h->SetYTitle("y [cm]");
+    h->Draw();
+
+    TEllipse *supportExt = new TEllipse(0.0, 0.0, fRMaxSupport, fRMaxSupport);
+    TEllipse *supportInt = new TEllipse(0.0, 0.0, fRMinSupport, fRMinSupport);
+    supportExt -> SetFillColor(kCyan-10);
+    supportExt -> Draw("same");
+    supportInt -> Draw("same");
+
+    for (Int_t iEl=0; iEl<GetNActiveElements(); iEl++) {
+      if (IsFront(GetActiveElement(iEl)) && GetActiveElement(iEl)->GetAxis(0)->GetXmin()<0.) {
+       TPave *pave = new TPave(GetActiveElement(iEl)->GetAxis(0)->GetXmin(), 
+                               GetActiveElement(iEl)->GetAxis(1)->GetXmin(), 
+                               TMath::Min(GetActiveElement(iEl)->GetAxis(0)->GetXmax(), 0.),
+                               GetActiveElement(iEl)->GetAxis(1)->GetXmax(), 1);
+       pave -> SetFillColor(kGreen);
+       pave -> Draw("same");
+      }
+      else if (!IsFront(GetActiveElement(iEl)) && GetActiveElement(iEl)->GetAxis(0)->GetXmax()>0.) {
+       TPave *pave = new TPave(TMath::Max(GetActiveElement(iEl)->GetAxis(0)->GetXmin(), 0.), 
+                               GetActiveElement(iEl)->GetAxis(1)->GetXmin(), 
+                               GetActiveElement(iEl)->GetAxis(0)->GetXmax(), 
+                               GetActiveElement(iEl)->GetAxis(1)->GetXmax(), 1);
+       pave -> SetFillColor(kGreen);
+       pave -> Draw("same");
+      }
+    }
+    
+    for (Int_t iEl=0; iEl<GetNReadoutElements(); iEl++) {
+      if (IsFront(GetReadoutElement(iEl)) && GetReadoutElement(iEl)->GetAxis(0)->GetXmin()<0.) {
+       TPave *pave = new TPave(GetReadoutElement(iEl)->GetAxis(0)->GetXmin(), 
+                               GetReadoutElement(iEl)->GetAxis(1)->GetXmin(), 
+                               TMath::Min(GetReadoutElement(iEl)->GetAxis(0)->GetXmax(), 0.), 
+                               GetReadoutElement(iEl)->GetAxis(1)->GetXmax(), 1);
+       pave -> SetFillColor(kRed);
+       pave -> Draw("same");
+      }
+      else if (!IsFront(GetReadoutElement(iEl)) && GetReadoutElement(iEl)->GetAxis(0)->GetXmax()>0.) {
+       TPave *pave = new TPave(TMath::Max(GetReadoutElement(iEl)->GetAxis(0)->GetXmin(), 0.),  
+                               GetReadoutElement(iEl)->GetAxis(1)->GetXmin(), 
+                               GetReadoutElement(iEl)->GetAxis(0)->GetXmax(), 
+                               GetReadoutElement(iEl)->GetAxis(1)->GetXmax(), 1);
+       pave -> SetFillColor(kRed);
+       pave -> Draw("same");
+      }
+    }
+    
+  }
+
+  // ------------------- "PROFILE" option ------------------
+
+  else if (!strcmp(opt, "profile")) {
+
+    TCanvas *cnv = new TCanvas("cnv", GetName(), 300, 900);
+    cnv->Draw();
+
+    TH2D *h = new TH2D("tmp", GetName(), 
+                      1, fZCenter-0.5, fZCenter+0.5, 
+                      1, 1.1*GetSupportElement(0)->GetAxis(1)->GetXmin(), 1.1*GetSupportElement(0)->GetAxis(1)->GetXmax());
+    h->SetXTitle("z [cm]");
+    h->SetYTitle("y [cm]");
+    h->Draw();
+
+    TPave *supportExt = new TPave(GetSupportElement(0)->GetAxis(2)->GetXmin(), -fRMaxSupport, 
+                                 GetSupportElement(0)->GetAxis(2)->GetXmax(),  fRMaxSupport);
+    TPave *supportInt = new TPave(GetSupportElement(0)->GetAxis(2)->GetXmin(), -fRMinSupport, 
+                                 GetSupportElement(0)->GetAxis(2)->GetXmax(),  fRMinSupport);
+    supportExt -> SetFillColor(kCyan-10);
+    supportInt -> SetFillColor(kCyan-10);
+    supportExt -> SetBorderSize(1);
+    supportInt -> SetBorderSize(1);
+    supportExt -> Draw("same");
+    supportInt -> Draw("same");
+
+    for (Int_t iEl=0; iEl<GetNActiveElements(); iEl++) {
+      TPave * pave = 0;
+      if (IsFront(GetActiveElement(iEl))) {
+       pave = new TPave(GetActiveElement(iEl)->GetAxis(2)->GetXmax() - 
+                        5*(GetActiveElement(iEl)->GetAxis(2)->GetXmax()-GetActiveElement(iEl)->GetAxis(2)->GetXmin()), 
+                        GetActiveElement(iEl)->GetAxis(1)->GetXmin(), 
+                        GetActiveElement(iEl)->GetAxis(2)->GetXmax(), 
+                        GetActiveElement(iEl)->GetAxis(1)->GetXmax(), 1);
+      }
+      else {
+       pave = new TPave(GetActiveElement(iEl)->GetAxis(2)->GetXmin(), 
+                        GetActiveElement(iEl)->GetAxis(1)->GetXmin(), 
+                        GetActiveElement(iEl)->GetAxis(2)->GetXmin() + 
+                        5*(GetActiveElement(iEl)->GetAxis(2)->GetXmax()-GetActiveElement(iEl)->GetAxis(2)->GetXmin()), 
+                        GetActiveElement(iEl)->GetAxis(1)->GetXmax(), 1);
+      }        
+      pave -> SetFillColor(kGreen);
+      pave -> Draw("same");
+    }
+    
+    for (Int_t iEl=0; iEl<GetNReadoutElements(); iEl++) {
+      TPave *pave = 0;
+      if (IsFront(GetReadoutElement(iEl))) {
+       pave = new TPave(GetReadoutElement(iEl)->GetAxis(2)->GetXmax() - 
+                        5*(GetReadoutElement(iEl)->GetAxis(2)->GetXmax()-GetReadoutElement(iEl)->GetAxis(2)->GetXmin()), 
+                        GetReadoutElement(iEl)->GetAxis(1)->GetXmin(), 
+                        GetReadoutElement(iEl)->GetAxis(2)->GetXmax(), 
+                        GetReadoutElement(iEl)->GetAxis(1)->GetXmax(), 1);
+      }
+      else {
+       pave = new TPave(GetReadoutElement(iEl)->GetAxis(2)->GetXmin(), 
+                        GetReadoutElement(iEl)->GetAxis(1)->GetXmin(), 
+                        GetReadoutElement(iEl)->GetAxis(2)->GetXmin() + 
+                        5*(GetReadoutElement(iEl)->GetAxis(2)->GetXmax()-GetReadoutElement(iEl)->GetAxis(2)->GetXmin()), 
+                        GetReadoutElement(iEl)->GetAxis(1)->GetXmax(), 1);
+      }        
+      pave -> SetFillColor(kRed);
+      pave -> Draw("same");
+    }
+    
+  }
+
+}
+
+//====================================================================================================================================================
+
diff --git a/MFT/AliMFTPlane.h b/MFT/AliMFTPlane.h
new file mode 100644 (file)
index 0000000..6961ee2
--- /dev/null
@@ -0,0 +1,109 @@
+#ifndef AliMFTPlane_H
+#define AliMFTPlane_H 
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+//====================================================================================================================================================
+//
+//      Class for the description of the structure for the planes of the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "TNamed.h"
+#include "THnSparse.h"
+#include "TClonesArray.h"
+#include "TAxis.h"
+#include "TPave.h"
+#include "TCanvas.h"
+#include "TH2D.h"
+#include "TEllipse.h"
+#include "TMath.h"
+#include "AliLog.h"
+
+//====================================================================================================================================================
+
+class AliMFTPlane : public TNamed {
+
+public:
+
+  AliMFTPlane();
+  AliMFTPlane(const Char_t *name, const Char_t *title);
+  AliMFTPlane(const AliMFTPlane& pt);
+  AliMFTPlane& operator=(const AliMFTPlane &source);
+
+  virtual ~AliMFTPlane() {};  // destructor
+
+  Bool_t Init(Int_t    planeNumber,
+             Double_t zCenter, 
+             Double_t rMin, 
+             Double_t rMax, 
+             Double_t pixelSizeX, 
+             Double_t pixelSizeY, 
+             Double_t thicknessActive, 
+             Double_t thicknessSupport, 
+             Double_t thicknessReadout);
+  
+  Bool_t CreateStructure();
+
+  Int_t GetNActiveElements()  { return fActiveElements->GetEntries();  }
+  Int_t GetNReadoutElements() { return fReadoutElements->GetEntries(); }
+  Int_t GetNSupportElements() { return fSupportElements->GetEntries(); }
+
+  TClonesArray* GetActiveElements()  { return fActiveElements;  }
+  TClonesArray* GetReadoutElements() { return fReadoutElements; }
+  TClonesArray* GetSupportElements() { return fSupportElements; }
+
+  THnSparseC* GetActiveElement(Int_t id);
+  THnSparseC* GetReadoutElement(Int_t id);
+  THnSparseC* GetSupportElement(Int_t id);
+
+  Bool_t IsFront(THnSparseC *element) { return (element->GetAxis(2)->GetXmin() < fZCenter); }
+
+  void DrawPlane(Char_t *opt="");
+
+  Double_t GetRMinSupport() { return fRMinSupport; }
+  Double_t GetRMaxSupport() { return fRMaxSupport; }
+  Double_t GetThicknessSupport() { return GetSupportElement(0)->GetAxis(2)->GetXmax() - GetSupportElement(0)->GetAxis(2)->GetXmin(); }
+  
+  Double_t GetZCenter() { return fZCenter; }
+  Double_t GetZCenterActiveFront() { return fZCenterActiveFront; }
+  Double_t GetZCenterActiveBack()  { return fZCenterActiveBack; }
+
+  void SetEquivalentSilicon(Double_t equivalentSilicon)                       { fEquivalentSilicon            = equivalentSilicon; }
+  void SetEquivalentSiliconBeforeFront(Double_t equivalentSiliconBeforeFront) { fEquivalentSiliconBeforeFront = equivalentSiliconBeforeFront; }
+  void SetEquivalentSiliconBeforeBack(Double_t equivalentSiliconBeforeBack)   { fEquivalentSiliconBeforeBack  = equivalentSiliconBeforeBack; }
+  Double_t GetEquivalentSilicon()            { return fEquivalentSilicon; }
+  Double_t GetEquivalentSiliconBeforeFront() { return fEquivalentSiliconBeforeFront; }
+  Double_t GetEquivalentSiliconBeforeBack()  { return fEquivalentSiliconBeforeBack; }
+  
+private:
+
+  // measures in cm
+
+  static const Double_t fRadiusMin = 2.225;           // minimum radial distance of the MFT sensors. To be carefully coordinated with fActiveSuperposition
+
+  static const Double_t fActiveSuperposition = 0.05;  // superposition between the active elements tasselling the MFT planes, for having a 
+                                                      // full acceptance coverage even in case of 10 degrees inclined tracks
+  static const Double_t fHeightActive = 0.5;          // height of the active elements
+  static const Double_t fHeightReadout = 0.3;         // height of the readout elements attached to the active ones
+
+  static const Double_t fSupportExtMargin = 0.3 + 0.3;    // minimum border size between the end of the support plane and the sensors: fHeightReadout + 0.3
+
+  Int_t fPlaneNumber;
+
+  Double_t fZCenter, fRMinSupport, fRMax, fRMaxSupport, fPixelSizeX, fPixelSizeY, fThicknessActive, fThicknessSupport, fThicknessReadout;
+  Double_t fZCenterActiveFront, fZCenterActiveBack, fEquivalentSilicon, fEquivalentSiliconBeforeFront, fEquivalentSiliconBeforeBack;
+
+  TClonesArray *fActiveElements, *fReadoutElements, *fSupportElements;
+
+  ClassDef(AliMFTPlane, 1)
+
+};
+
+//====================================================================================================================================================
+       
+#endif
+
diff --git a/MFT/AliMFTReconstructor.cxx b/MFT/AliMFTReconstructor.cxx
new file mode 100644 (file)
index 0000000..b8198b6
--- /dev/null
@@ -0,0 +1,138 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+//====================================================================================================================================================
+//
+//      Event reconstruction class for the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "TObjArray.h"
+#include "TTree.h"
+#include "AliMFTSegmentation.h"
+#include "AliMFTClusterFinder.h"
+#include "AliReconstructor.h"
+#include "AliMFTReconstructor.h"
+
+ClassImp(AliMFTReconstructor)
+
+//====================================================================================================================================================
+
+AliMFTReconstructor::AliMFTReconstructor():
+  AliReconstructor(), 
+  fDigits(0x0),
+  fNPlanes(0)
+{
+
+  // default constructor 
+
+}
+
+//====================================================================================================================================================
+
+AliMFTReconstructor::~AliMFTReconstructor(){
+
+  // destructor
+
+  if (fDigits) {
+    fDigits->Delete();
+    delete fDigits;
+    fDigits=0;
+  }
+
+}
+
+//====================================================================================================================================================
+
+void AliMFTReconstructor::Init() {
+
+  AliMFTSegmentation *segmentation = new AliMFTSegmentation("AliMFTGeometry.root");
+  fNPlanes = segmentation->GetNPlanes();
+  delete segmentation;
+
+  fDigits = new TObjArray(fNPlanes);
+  fDigits->SetOwner(kTRUE);
+  for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) fDigits->AddAt(new TClonesArray("AliMFTDigit",fNMaxDigitPerPlane),iPlane);
+
+  AliInfo("    ************* Using the MFT reconstructor! ****** ");
+
+  return;
+
+}
+
+//====================================================================================================================================================
+
+void AliMFTReconstructor::ResetDigits() {
+
+  // Reset number of digits and the digits array for the MFT detector.
+
+  if (!fDigits) return;
+  for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+    ResetDigits(iPlane);
+  }
+
+}
+
+//====================================================================================================================================================
+
+void AliMFTReconstructor::ResetDigits(Int_t plane) {
+
+  // Reset number of digits and the digits array for this branch.
+
+  if (fDigits->At(plane)) ((TClonesArray*)fDigits->At(plane))->Clear();
+
+}
+
+//====================================================================================================================================================
+
+void AliMFTReconstructor::Reconstruct(TTree *digitsTree, TTree *clustersTree) const {
+
+  AliInfo("Starting Reconstruction for MFT");
+
+  // Clusterization
+
+  AliDebug(1, Form("nPlanes = %d",fNPlanes));
+
+  for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+    AliDebug(1, Form("Setting Address for Branch Plane_%02d", iPlane)); 
+    digitsTree->SetBranchAddress(Form("Plane_%02d",iPlane), &(*fDigits)[iPlane]);
+  }
+  digitsTree->GetEntry(0);
+
+  AliDebug(1, "Creating clusterFinder");
+  AliMFTClusterFinder *clusterFinder = new AliMFTClusterFinder();
+  clusterFinder->Init("AliMFTGeometry.root");
+  AliDebug(1, "clusterFinder->MakeClusterBranch(clustersTree)");
+  clusterFinder->MakeClusterBranch(clustersTree);
+  AliDebug(1, "clusterFinder->SetClusterTreeAddress(clustersTree)");
+  clusterFinder->SetClusterTreeAddress(clustersTree);
+  AliDebug(1, "clusterFinder->DigitsToClusters(fDigits)");
+  clusterFinder->DigitsToClusters(fDigits);
+  AliDebug(1, "clustersTree->Fill()");
+  clustersTree->Fill();                         // fill tree for current event
+  AliDebug(1, "delete clusterFinder");
+  delete clusterFinder;
+
+  for (Int_t iPlane=0; iPlane<fNPlanes; iPlane++) {
+    AliDebug(1, Form("fDigits->At(%d)->Clear()",iPlane));
+    fDigits->At(iPlane)->Clear();
+  }
+
+}
+
+//====================================================================================================================================================
diff --git a/MFT/AliMFTReconstructor.h b/MFT/AliMFTReconstructor.h
new file mode 100644 (file)
index 0000000..9299765
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef AliMFTReconstructor_H
+#define AliMFTReconstructor_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+//====================================================================================================================================================
+//
+//      Reconstructor class for the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "TObjArray.h"
+#include "TTree.h"
+#include "AliMFTSegmentation.h"
+#include "AliReconstructor.h"
+#include "AliMFTClusterFinder.h"
+
+//====================================================================================================================================================
+
+class AliRawReader;
+
+class AliMFTReconstructor: public AliReconstructor { 
+
+public:
+
+  AliMFTReconstructor();
+  virtual ~AliMFTReconstructor();
+  virtual void Init();
+
+  virtual void ResetDigits(); 
+  virtual void ResetDigits(Int_t plane);
+
+  virtual void  Reconstruct(TTree *digitsTree, TTree *clustersTree) const; 
+  virtual void  Reconstruct(AliRawReader* /*rawdata*/, TTree* /*clustersTree*/) const { AliInfo("Not implemented"); } 
+
+  //  static const AliMFTRecoParam* GetRecoParam() { return dynamic_cast<const AliMFTRecoParam*>(AliReconstructor::GetRecoParam(0)); }
+
+private:
+  AliMFTReconstructor(const AliMFTReconstructor&);              // Not implemented
+  AliMFTReconstructor &operator=(const AliMFTReconstructor&);   // Not implemented
+
+  static const Int_t fNMaxDigitPerPlane = 10000;
+
+  TObjArray  *fDigits;     
+  Int_t      fNPlanes;
+
+  ClassDef(AliMFTReconstructor, 1)        // class for the MFT reconstruction
+
+};
+
+//====================================================================================================================================================
+
+#endif
diff --git a/MFT/AliMFTSegmentation.cxx b/MFT/AliMFTSegmentation.cxx
new file mode 100644 (file)
index 0000000..deb7e22
--- /dev/null
@@ -0,0 +1,137 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+//====================================================================================================================================================
+//
+//      Segmentation class for the planes of the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "TFile.h"
+#include "TNtuple.h"
+#include "TClonesArray.h"
+#include "TMath.h"
+#include "AliMFTPlane.h"
+#include "AliMFTSegmentation.h"
+
+ClassImp(AliMFTSegmentation)
+
+//====================================================================================================================================================
+
+AliMFTSegmentation::AliMFTSegmentation(): 
+  TObject(),
+  fMFTPlanes(0)
+{ 
+
+  // TO BE CHECKED
+  
+  // default constructor
+
+  fMFTPlanes = new TClonesArray("AliMFTPlane", fNMaxPlanes);
+
+}
+
+//====================================================================================================================================================
+
+AliMFTSegmentation::AliMFTSegmentation(const Char_t *nameGeomFile): 
+  TObject(),
+  fMFTPlanes(0)
+{ 
+
+  fMFTPlanes = new TClonesArray("AliMFTPlane", fNMaxPlanes);
+
+  Float_t zCenter, rMin, rMax, pixelSizeX, pixelSizeY, thicknessActive, thicknessSupport, thicknessReadout;
+  Float_t equivalentSilicon, equivalentSiliconBeforeFront, equivalentSiliconBeforeBack;
+
+  TFile *geomFile = new TFile(nameGeomFile);
+  TNtuple *geomNtuple = (TNtuple*) geomFile->Get("AliMFTGeometry");
+
+  geomNtuple -> SetBranchAddress("zCenter", &zCenter);
+  geomNtuple -> SetBranchAddress("rMin",    &rMin);
+  geomNtuple -> SetBranchAddress("rMax",    &rMax);
+  geomNtuple -> SetBranchAddress("pixelSizeX", &pixelSizeX);
+  geomNtuple -> SetBranchAddress("pixelSizeY", &pixelSizeY);
+  geomNtuple -> SetBranchAddress("thicknessActive",  &thicknessActive);
+  geomNtuple -> SetBranchAddress("thicknessSupport", &thicknessSupport);
+  geomNtuple -> SetBranchAddress("thicknessReadout", &thicknessReadout);
+  geomNtuple -> SetBranchAddress("equivalentSilicon",            &equivalentSilicon);
+  geomNtuple -> SetBranchAddress("equivalentSiliconBeforeFront", &equivalentSiliconBeforeFront);
+  geomNtuple -> SetBranchAddress("equivalentSiliconBeforeBack",  &equivalentSiliconBeforeBack);
+  
+  Int_t nPlanes = geomNtuple->GetEntries();
+
+  for (Int_t iPlane=0; iPlane<nPlanes; iPlane++) {
+
+    // Create new plane
+
+    printf("Setting segmentation for MFT plane #%02d\n", iPlane);
+
+    geomNtuple -> GetEntry(iPlane);
+    zCenter = TMath::Abs(zCenter);
+
+    AliMFTPlane *plane = new AliMFTPlane(Form("MFTPlane_%02d", iPlane), Form("MFTPlane_%02d", iPlane));
+    plane -> Init(iPlane, zCenter, rMin, rMax, pixelSizeX, pixelSizeY, thicknessActive, thicknessSupport, thicknessReadout);
+    plane -> SetEquivalentSilicon(equivalentSilicon);
+    plane -> SetEquivalentSiliconBeforeFront(equivalentSiliconBeforeFront);
+    plane -> SetEquivalentSiliconBeforeBack(equivalentSiliconBeforeBack);
+    plane -> CreateStructure();
+    
+    new ((*fMFTPlanes)[fMFTPlanes->GetEntries()]) AliMFTPlane(*plane);
+
+  }
+  
+  delete geomFile;
+
+  printf("MFT segmentation set!\n");
+
+}
+
+//====================================================================================================================================================
+
+THnSparseC* AliMFTSegmentation::GetDetElem(Int_t detElemID) {
+      
+  // Find det elem
+
+  Int_t planeNb = detElemID/fNMaxDetElemPerPlane;
+  Int_t detElemNb = detElemID - planeNb*fNMaxDetElemPerPlane;
+  
+  THnSparseC *detElem = GetPlane(planeNb)->GetActiveElement(detElemNb);
+
+  return detElem;
+
+}
+
+//====================================================================================================================================================
+
+Bool_t AliMFTSegmentation::Hit2PixelID(Double_t xHit, Double_t yHit, Int_t detElemID, Int_t &xPixel, Int_t &yPixel) {
+
+  THnSparseC *detElem = GetDetElem(detElemID);
+
+  if ( xHit<detElem->GetAxis(0)->GetXmin() ||
+       xHit>detElem->GetAxis(0)->GetXmax() ||
+       yHit<detElem->GetAxis(1)->GetXmin() ||
+       yHit>detElem->GetAxis(1)->GetXmax() ) return kFALSE;
+
+  xPixel = detElem->GetAxis(0)->FindBin(xHit) - 1;
+  yPixel = detElem->GetAxis(1)->FindBin(yHit) - 1;
+
+  return kTRUE;
+
+}
+
+//====================================================================================================================================================
+
diff --git a/MFT/AliMFTSegmentation.h b/MFT/AliMFTSegmentation.h
new file mode 100644 (file)
index 0000000..c5c7d5f
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef AliMFTSegmentation_H
+#define AliMFTSegmentation_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+//====================================================================================================================================================
+//
+//      Segmentation class for the planes of the ALICE Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "TFile.h"
+#include "TNtuple.h"
+#include "TClonesArray.h"
+#include "TMath.h"
+#include "AliMFTPlane.h"
+#include "TMath.h"
+
+//====================================================================================================================================================
+
+class AliMFTSegmentation : public TObject {
+
+public:
+  
+  AliMFTSegmentation();
+  AliMFTSegmentation(const Char_t *nameGeomFile);
+
+  virtual ~AliMFTSegmentation() {}
+
+  THnSparseC* GetDetElem(Int_t detElemID);
+
+  Int_t GetDetElemID(Int_t plane, Int_t detElem) { return fNMaxDetElemPerPlane*plane + detElem; }
+    
+  Bool_t Hit2PixelID(Double_t xHit, Double_t yHit, Int_t detElemID, Int_t &xPixel, Int_t &yPixel);  
+
+  Double_t GetPixelSizeX(Int_t detElemID) { THnSparseC *detElem = GetDetElem(detElemID); return detElem->GetAxis(0)->GetBinWidth(1); }
+  Double_t GetPixelSizeY(Int_t detElemID) { THnSparseC *detElem = GetDetElem(detElemID); return detElem->GetAxis(1)->GetBinWidth(1); }
+  Double_t GetPixelSizeZ(Int_t detElemID) { THnSparseC *detElem = GetDetElem(detElemID); return detElem->GetAxis(2)->GetBinWidth(1); }
+
+  Double_t GetPixelCenterX(Int_t detElemID, Int_t iPixel) { THnSparseC *detElem = GetDetElem(detElemID); return detElem->GetAxis(0)->GetBinCenter(iPixel+1); }
+  Double_t GetPixelCenterY(Int_t detElemID, Int_t iPixel) { THnSparseC *detElem = GetDetElem(detElemID); return detElem->GetAxis(1)->GetBinCenter(iPixel+1); }
+  Double_t GetPixelCenterZ(Int_t detElemID, Int_t iPixel) { THnSparseC *detElem = GetDetElem(detElemID); return -1.*(detElem->GetAxis(2)->GetBinCenter(iPixel+1)); }
+
+  Int_t GetNPlanes() { return fMFTPlanes->GetEntries(); }
+
+  AliMFTPlane* GetPlane(Int_t iPlane) { if (iPlane>=0 && iPlane<fMFTPlanes->GetEntries()) return (AliMFTPlane*) fMFTPlanes->At(iPlane); else return NULL; }
+protected:
+
+  static const Int_t fNMaxPlanes = 20;                // max number of MFT planes
+  static const Double_t fRadiusMin = 2.225;           // minimum radial distance of the MFT sensors. To be carefully coordinated with fDetElemSuperposition
+  static const Double_t fDetElemSuperposition = 0.05; // superposition between bands tasselling the MFT planes, for having a full acceptance coverage
+                                                      // even in case of 10 degrees inclined tracks
+  static const Double_t fHeightDetElem = 0.5;         // height of the active volume bands composing the planes
+  static const Double_t fSupportExtMargin = 0.3;      // minimum border size between the end of the support plane and the sensors
+
+  static const Int_t fNMaxDetElemPerPlane = 1000;
+
+  TClonesArray *fMFTPlanes;
+
+private:
+
+  AliMFTSegmentation(const AliMFTSegmentation &source);
+  AliMFTSegmentation& operator=(const AliMFTSegmentation &source);
+
+  ClassDef(AliMFTSegmentation,1)
+    
+};
+
+//====================================================================================================================================================
+
+#endif
+
diff --git a/MFT/AliMuonForwardTrack.cxx b/MFT/AliMuonForwardTrack.cxx
new file mode 100644 (file)
index 0000000..0a5897f
--- /dev/null
@@ -0,0 +1,363 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+//====================================================================================================================================================
+//
+//      Description of an ALICE muon forward track, combining the information of the Muon Spectrometer and the Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "AliLog.h"
+#include "AliMUONTrack.h"
+#include "AliMFTCluster.h"
+#include "AliMUONVCluster.h"
+#include "AliMUONTrackParam.h"
+#include "AliMUONTrackExtrap.h"
+#include "TClonesArray.h"
+#include "TMatrixD.h"
+#include "TParticle.h"
+#include "AliMuonForwardTrack.h"
+
+ClassImp(AliMuonForwardTrack)
+
+//====================================================================================================================================================
+
+AliMuonForwardTrack::AliMuonForwardTrack():
+  AliMUONTrack(),
+  fMUONTrack(0),
+  fMCTrackRef(0),
+  fMFTClusters(0)
+{
+
+  // default constructor
+  for (Int_t iPlane=0; iPlane<fMaxNPlanesMFT; iPlane++) fPlaneExists[iPlane] = kFALSE;
+  fMFTClusters = new TClonesArray("AliMFTCluster");
+
+}
+
+//====================================================================================================================================================
+
+AliMuonForwardTrack::AliMuonForwardTrack(AliMUONTrack *MUONTrack):
+  AliMUONTrack(),
+  fMUONTrack(0),
+  fMCTrackRef(0),
+  fMFTClusters(0)
+{
+
+  SetMUONTrack(MUONTrack);
+  for (Int_t iPlane=0; iPlane<fMaxNPlanesMFT; iPlane++) fPlaneExists[iPlane] = kFALSE;
+  fMFTClusters = new TClonesArray("AliMFTCluster");
+
+}
+
+//====================================================================================================================================================
+
+AliMuonForwardTrack::AliMuonForwardTrack(const AliMuonForwardTrack& track): 
+  AliMUONTrack(track),
+  fMUONTrack(track.fMUONTrack),
+  fMCTrackRef(track.fMCTrackRef),
+  fMFTClusters(track.fMFTClusters)
+{
+
+  // copy constructor
+  for (Int_t iPlane=0; iPlane<fMaxNPlanesMFT; iPlane++) fPlaneExists[iPlane] = (track.fPlaneExists)[iPlane];
+  
+}
+
+//====================================================================================================================================================
+
+AliMuonForwardTrack& AliMuonForwardTrack::operator=(const AliMuonForwardTrack& track) {
+
+  // Asignment operator
+
+  // check assignement to self
+  if (this == &track) return *this;
+
+  // base class assignement
+  AliMUONTrack::operator=(track);
+  
+  // clear memory
+  Clear();
+  
+  fMUONTrack    = track.fMUONTrack;
+  fMCTrackRef   = track.fMCTrackRef;
+  fMFTClusters  = track.fMFTClusters;
+
+  for (Int_t iPlane=0; iPlane<fMaxNPlanesMFT; iPlane++) fPlaneExists[iPlane] = (track.fPlaneExists)[iPlane];
+  
+  return *this;
+
+}
+
+//====================================================================================================================================================
+
+void AliMuonForwardTrack::SetMUONTrack(AliMUONTrack *MUONTrack) {
+
+  if (fMUONTrack) {
+    AliInfo("fMUONTrack already exists, nothing will be done");
+    return;
+  }
+
+  fMUONTrack = MUONTrack;
+  
+}
+
+//====================================================================================================================================================
+
+void AliMuonForwardTrack::SetMCTrackRef(TParticle *MCTrackRef) {
+
+  if (fMCTrackRef) {
+    AliInfo("fMCTrackRef already exists, nothing will be done");
+    return;
+  }
+
+  fMCTrackRef = MCTrackRef;
+  
+}
+
+//====================================================================================================================================================
+
+void AliMuonForwardTrack::AddTrackParamAtMFTCluster(AliMUONTrackParam &trackParam, AliMFTCluster &mftCluster) {
+
+  AliDebug(1, Form("fMFTClusters=%p has %d entries", fMFTClusters, fMFTClusters->GetEntries()));
+  Int_t iMFTCluster = fMFTClusters->GetEntries();
+  AliDebug(1, Form("mftCluster->GetX() = %f  mftCluster->GetY() = %f  mftCluster->GetErrX() = %f  cmftCluster->GetErrY() = %f", 
+          mftCluster.GetX(), mftCluster.GetY(), mftCluster.GetErrX(), mftCluster.GetErrY()));
+  AliMUONVCluster *muonCluster = (AliMUONVCluster*) mftCluster.CreateMUONCluster();
+  AliDebug(1, Form("Created MUON cluster %p", muonCluster));
+  trackParam.SetUniqueID(iMFTCluster);    // we profit of this slot to store the reference to the corresponding MFTCluster
+  AliDebug(1, Form("Now adding muonCluster %p and trackParam %p",muonCluster, &trackParam));
+  AddTrackParamAtCluster(trackParam, *muonCluster, kTRUE);
+  AliDebug(1, Form("GetTrackParamAtCluster() = %p  has %d entries",GetTrackParamAtCluster(), GetTrackParamAtCluster()->GetEntries()));
+  // we pass the parameters this->GetTrackParamAtCluster()->First() to the Kalman Filter algorithm: they will be updated!!
+  Double_t chi2Kalman = RunKalmanFilter(*(AliMUONTrackParam*)(GetTrackParamAtCluster()->First()));
+  Double_t newGlobalChi2 = GetGlobalChi2() + chi2Kalman;
+  mftCluster.SetLocalChi2(chi2Kalman);
+  mftCluster.SetTrackChi2(newGlobalChi2);
+  new ((*fMFTClusters)[iMFTCluster]) AliMFTCluster(mftCluster);
+  AliDebug(1, Form("muonCluster->GetZ() = %f, trackParam->GetZ() = %f",muonCluster->GetZ(), trackParam.GetZ()));
+  SetGlobalChi2(newGlobalChi2);
+  ((AliMUONTrackParam*) GetTrackParamAtCluster()->First())->SetTrackChi2(newGlobalChi2);
+  for (Int_t iPar=0; iPar<GetTrackParamAtCluster()->GetEntries(); iPar++) {
+    AliDebug(1, Form("GetTrackParamAtCluster()->At(%d)->GetClusterPtr() = %p",
+                    iPar, ((AliMUONTrackParam*)(GetTrackParamAtCluster()->At(iPar)))->GetClusterPtr()));
+  }
+
+}
+
+//====================================================================================================================================================
+
+AliMUONTrackParam* AliMuonForwardTrack::GetTrackParamAtMUONCluster(Int_t iMUONCluster) {
+
+  if (iMUONCluster<0 || iMUONCluster>=GetNMUONClusters()) {
+    AliError("Invalid MUON cluster index. NULL pointer will be returned");
+    return NULL;
+  }
+
+  AliMUONTrackParam *trackParam = (AliMUONTrackParam*) fMUONTrack->GetTrackParamAtCluster()->At(iMUONCluster); 
+
+  return trackParam;
+
+}
+
+//====================================================================================================================================================
+
+AliMUONTrackParam* AliMuonForwardTrack::GetTrackParamAtMFTCluster(Int_t iMFTCluster) {
+
+  if (iMFTCluster<0 || iMFTCluster>=GetNMFTClusters()) {
+    AliError("Invalid MFT cluster index. NULL pointer will be returned");
+    return NULL;
+  }
+
+  AliMUONTrackParam *trackParam = (AliMUONTrackParam*) GetTrackParamAtCluster()->At(iMFTCluster); 
+
+  return trackParam;
+
+}
+
+//====================================================================================================================================================
+
+AliMUONVCluster* AliMuonForwardTrack::GetMUONCluster(Int_t iMUONCluster) {
+
+  if (iMUONCluster<0 || iMUONCluster>=GetNMUONClusters()) {
+    AliError("Invalid MUON cluster index. NULL pointer will be returned");
+    return NULL;
+  }
+
+  AliMUONTrackParam *trackParam = GetTrackParamAtMUONCluster(iMUONCluster);
+  AliMUONVCluster *muonCluster = trackParam->GetClusterPtr();
+
+  return muonCluster;
+
+}
+
+//====================================================================================================================================================
+
+AliMFTCluster* AliMuonForwardTrack::GetMFTCluster(Int_t iMFTCluster) {
+
+  if (iMFTCluster<0 || iMFTCluster>=GetNMFTClusters()) {
+    AliError("Invalid MFT cluster index. NULL pointer will be returned");
+    return NULL;
+  }
+
+  AliMUONTrackParam *trackParam = GetTrackParamAtMFTCluster(iMFTCluster);
+  AliMFTCluster *mftCluster = (AliMFTCluster*) fMFTClusters->At(trackParam->GetUniqueID());
+
+  return mftCluster;
+
+}
+
+//====================================================================================================================================================
+
+Double_t AliMuonForwardTrack::RunKalmanFilter(AliMUONTrackParam &trackParamAtCluster) {
+
+  AliDebug(1, Form("Running Kalman filter for parameters %p (z = %f) and cluster %p (z = %f)", 
+                  &trackParamAtCluster, trackParamAtCluster.GetZ(), trackParamAtCluster.GetClusterPtr(), trackParamAtCluster.GetClusterPtr()->GetZ()));
+  
+  // Compute new track parameters and their covariances including new cluster using kalman filter
+  // return the *additional* track chi2
+  
+  // Get actual track parameters (p)
+  TMatrixD param(trackParamAtCluster.GetParameters());
+  
+  // Get new cluster parameters (m)
+  AliMUONVCluster *cluster = trackParamAtCluster.GetClusterPtr();
+  AliDebug(1, Form("cluster->GetX() = %f  cluster->GetY() = %f  cluster->GetErrX() = %f  cluster->GetErrY() = %f", 
+                  cluster->GetX(), cluster->GetY(), cluster->GetErrX(), cluster->GetErrY()));
+  TMatrixD clusterParam(5,1);
+  clusterParam.Zero();
+  clusterParam(0,0) = cluster->GetX();
+  clusterParam(2,0) = cluster->GetY();
+
+  // Compute the current parameter weight (W)
+  TMatrixD paramWeight(trackParamAtCluster.GetCovariances());
+  if (paramWeight.Determinant() != 0) {
+    paramWeight.Invert();
+  } else {
+    Warning("RunKalmanFilter"," Determinant = 0");
+    return 1.e10;
+  }
+  
+  // Compute the new cluster weight (U)
+  TMatrixD clusterWeight(5,5);
+  clusterWeight.Zero();
+  clusterWeight(0,0) = 1. / cluster->GetErrX2();
+  clusterWeight(2,2) = 1. / cluster->GetErrY2();
+
+  // Compute the new parameters covariance matrix ( (W+U)^-1 )
+  TMatrixD newParamCov(paramWeight,TMatrixD::kPlus,clusterWeight);
+  if (newParamCov.Determinant() != 0) {
+    newParamCov.Invert();
+  } 
+  else {
+    Warning("RunKalmanFilter"," Determinant = 0");
+    return 1.e10;
+  }
+  
+  // Save the new parameters covariance matrix
+  trackParamAtCluster.SetCovariances(newParamCov);
+  
+  // Compute the new parameters (p' = ((W+U)^-1)U(m-p) + p)
+  TMatrixD tmp(clusterParam,TMatrixD::kMinus,param);
+  TMatrixD tmp2(clusterWeight,TMatrixD::kMult,tmp);    // U(m-p)
+  TMatrixD newParam(newParamCov,TMatrixD::kMult,tmp2); // ((W+U)^-1)U(m-p)
+  newParam += param;                                   // ((W+U)^-1)U(m-p) + p
+
+  // Save the new parameters
+  trackParamAtCluster.SetParameters(newParam);
+  
+  // Compute the additional chi2 (= ((p'-p)^-1)W(p'-p) + ((p'-m)^-1)U(p'-m))
+  tmp = newParam; // p'
+  tmp -= param;   // (p'-p)
+  TMatrixD tmp3(paramWeight,TMatrixD::kMult,tmp);           // W(p'-p)
+  TMatrixD addChi2Track(tmp,TMatrixD::kTransposeMult,tmp3); // ((p'-p)^-1)W(p'-p)
+  tmp = newParam;      // p'
+  tmp -= clusterParam; // (p'-m)
+  TMatrixD tmp4(clusterWeight,TMatrixD::kMult,tmp);            // U(p'-m)
+  addChi2Track += TMatrixD(tmp,TMatrixD::kTransposeMult,tmp4); // ((p'-p)^-1)W(p'-p) + ((p'-m)^-1)U(p'-m)
+  
+  AliDebug(1,Form("Adding Kalman chi2 = %f",addChi2Track(0,0)));
+
+  return addChi2Track(0,0);
+  
+}
+
+//====================================================================================================================================================
+
+Double_t AliMuonForwardTrack::GetWeightedOffset(Double_t x, Double_t y, Double_t z) {
+
+  AliMUONTrackParam *param = GetTrackParamAtMFTCluster(0);
+  AliMUONTrackExtrap::ExtrapToZCov(param, z);
+
+  TMatrixD cov(5,5);
+  cov = param->GetCovariances();
+
+  TMatrixD covCoordinates(2,2);
+  covCoordinates(0,0) = cov(0,0);
+  covCoordinates(0,1) = cov(0,2);
+  covCoordinates(1,0) = cov(2,0);
+  covCoordinates(1,1) = cov(2,2);
+  
+  TMatrixD covCoordinatesInverse = covCoordinates.Invert();
+
+  Double_t dX = param->GetNonBendingCoor() - x;
+  Double_t dY = param->GetBendingCoor()    - y;
+  
+  Double_t weightedOffset = TMath::Sqrt(0.5*(dX*dX*covCoordinatesInverse(0,0) + 
+                                            dY*dY*covCoordinatesInverse(1,1) + 
+                                            2.*dX*dY*covCoordinatesInverse(0,1)));
+
+  return weightedOffset;
+
+}
+
+//====================================================================================================================================================
+
+Double_t AliMuonForwardTrack::GetOffsetX(Double_t x, Double_t z) {
+
+  AliMUONTrackParam *param = GetTrackParamAtMFTCluster(0);
+  AliMUONTrackExtrap::ExtrapToZCov(param, z);
+  Double_t dX = param->GetNonBendingCoor() - x;
+  return dX;
+
+}
+
+//====================================================================================================================================================
+
+Double_t AliMuonForwardTrack::GetOffsetY(Double_t y, Double_t z) {
+
+  AliMUONTrackParam *param = GetTrackParamAtMFTCluster(0);
+  AliMUONTrackExtrap::ExtrapToZCov(param, z);
+  Double_t dY = param->GetBendingCoor() - y;
+  return dY;
+
+}
+
+//====================================================================================================================================================
+
+Double_t AliMuonForwardTrack::GetOffset(Double_t x, Double_t y, Double_t z) {
+
+  AliMUONTrackParam *param = GetTrackParamAtMFTCluster(0);
+  AliMUONTrackExtrap::ExtrapToZCov(param, z);
+  Double_t dX = param->GetNonBendingCoor() - x;
+  Double_t dY = param->GetBendingCoor()    - y;
+  return TMath::Sqrt(dX*dX + dY*dY);
+
+}
+
+//====================================================================================================================================================
+
diff --git a/MFT/AliMuonForwardTrack.h b/MFT/AliMuonForwardTrack.h
new file mode 100644 (file)
index 0000000..7546db3
--- /dev/null
@@ -0,0 +1,86 @@
+#ifndef AliMuonForwardTrack_H
+#define AliMuonForwardTrack_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+//====================================================================================================================================================
+//
+//      Description of an ALICE muon forward track, combining the information of the Muon Spectrometer and the Muon Forward Tracker
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "AliLog.h"
+#include "AliMUONTrack.h"
+#include "AliMFTCluster.h"
+#include "AliMUONVCluster.h"
+#include "AliMUONTrackParam.h"
+#include "TMatrixD.h"
+#include "TClonesArray.h"
+#include "TParticle.h"
+
+//====================================================================================================================================================
+
+class AliMuonForwardTrack : public AliMUONTrack {
+
+public:
+
+  AliMuonForwardTrack();
+  AliMuonForwardTrack(AliMUONTrack *MUONTrack);
+
+  AliMuonForwardTrack(const AliMuonForwardTrack&);
+  AliMuonForwardTrack &operator=(const AliMuonForwardTrack&);
+  
+  virtual ~AliMuonForwardTrack() {}
+
+  void SetMUONTrack(AliMUONTrack *MUONTrack);
+  void SetMCTrackRef(TParticle *MCTrackRef);
+  AliMUONTrack* GetMUONTrack() { return fMUONTrack; }
+  TParticle* GetMCTrackRef() { return fMCTrackRef; }
+
+  AliMUONVCluster* GetMUONCluster(Int_t iMUONCluster);
+  AliMFTCluster*   GetMFTCluster(Int_t iMFTCluster);
+  
+  AliMUONTrackParam* GetTrackParamAtMUONCluster(Int_t iMUONCluster);
+  AliMUONTrackParam* GetTrackParamAtMFTCluster(Int_t iMFTCluster);
+
+  void SetPlaneExists(Int_t iPlane, Bool_t value=kTRUE) { fPlaneExists[iPlane] = value; }
+  Bool_t PlaneExists(Int_t iPlane) { return fPlaneExists[iPlane]; }
+
+  Int_t GetNMUONClusters() { return fMUONTrack->GetNClusters(); }
+  Int_t GetNMFTClusters()  { return GetNClusters(); }
+
+  Int_t GetMCLabelMUONTrack() { return fMUONTrack->GetMCLabel(); }
+
+  void AddTrackParamAtMFTCluster(AliMUONTrackParam &trackParam, AliMFTCluster &mftCluster);
+  
+  Double_t RunKalmanFilter(AliMUONTrackParam &trackParamAtCluster);
+
+  Double_t GetWeightedOffset(Double_t x, Double_t y, Double_t z);
+  Double_t GetOffset(Double_t x, Double_t y, Double_t z);
+  Double_t GetOffsetX(Double_t x, Double_t z);
+  Double_t GetOffsetY(Double_t y, Double_t z);
+
+protected:
+
+  static const Int_t fMaxNPlanesMFT = 20;
+
+  Bool_t fPlaneExists[fMaxNPlanesMFT];
+
+  AliMUONTrack *fMUONTrack;
+  TParticle *fMCTrackRef;
+
+  TClonesArray *fMFTClusters;
+
+  ClassDef(AliMuonForwardTrack,1)
+    
+};
+
+//====================================================================================================================================================
+
+#endif
+
+
+
diff --git a/MFT/AliMuonForwardTrackFinder.C b/MFT/AliMuonForwardTrackFinder.C
new file mode 100644 (file)
index 0000000..8a4db65
--- /dev/null
@@ -0,0 +1,37 @@
+//================================================================================================================================
+
+void AliMuonForwardTrackFinder(Int_t run=0,
+                              const Char_t *readDir= ".",
+                              const Char_t *outDir = ".",
+                              Int_t nEventsToAnalyze = -1) {
+  
+  //  TGeoGlobalMagField::Instance()->SetField(new AliMagF("Maps","Maps", -1., -1, AliMagF::k5kG));
+
+  AliCDBManager* man = AliCDBManager::Instance();
+  man->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
+  man->SetSpecificStorage("GRP/GRP/Data", Form("local://%s",gSystem->pwd()));
+
+  AliMuonForwardTrackFinder *finder = new AliMuonForwardTrackFinder();
+  finder->SetDraw(kFALSE);
+  finder->Init(run, readDir, outDir, nEventsToAnalyze);
+
+  finder -> SetSigmaSpectrometerCut(4.0);
+  finder -> SetSigmaClusterCut(4.0);
+  finder -> SetChi2GlobalCut(2.0);
+  finder -> SetRAbsorberCut(0.0);
+  //  finder -> SetRAbsorberCut(26.4);
+  finder -> SetLowPtCut(0.0);
+  //  finder -> SetLowPtCut(0.5);
+  finder -> SetExtrapOriginTransvError(0.05);   // To be imposed if the gen. vertex is fixed in (0,0,0)
+  finder -> SetGaussianBlurZVert(5.0);          // To be imposed if the gen. vertex is fixed in (0,0,0) 
+  finder -> SetMatchingMode(0);                 // 0 -> real matching   1 -> ideal matching
+  finder -> SetMinResearchRadiusAtLastPlane(0.5);
+
+  while (finder->LoadNextTrack()) continue;
+
+  if (finder->GetNRealTracksAnalyzed()) finder->Terminate();
+
+}
+
+//================================================================================================================================
+
diff --git a/MFT/AliMuonForwardTrackFinder.cxx b/MFT/AliMuonForwardTrackFinder.cxx
new file mode 100644 (file)
index 0000000..17881e9
--- /dev/null
@@ -0,0 +1,1624 @@
+// ROOT includes
+#include "TObject.h"
+#include "TClonesArray.h"
+#include "TObjArray.h"
+#include "TH2D.h"
+#include "TH1D.h"
+#include "TFile.h"
+#include "TGeoManager.h"
+#include "TMatrixD.h"
+#include "TParticle.h"
+#include "TMath.h"
+#include "TGraph.h"
+#include "TEllipse.h"
+#include "TCanvas.h"
+#include "TString.h"
+#include "TLatex.h"
+#include "TMarker.h"
+#include "TNtuple.h"
+#include "TRandom.h"
+#include "TIterator.h"
+
+// STEER includes
+#include "AliLog.h"
+#include "AliRun.h"
+#include "AliRunLoader.h"
+#include "AliLoader.h"
+#include "AliHeader.h"
+#include "AliMC.h"
+#include "AliStack.h"
+#include "AliMagF.h"
+#include "AliTracker.h"
+#include "AliGRPObject.h"
+#include "AliCDBEntry.h"
+#include "AliCDBManager.h"
+
+// MUON includes
+#include "AliMUONConstants.h"
+#include "AliMUONTrack.h"
+#include "AliMUONRecoCheck.h"
+#include "AliMUONTrackParam.h"
+#include "AliMUONTrackExtrap.h"
+#include "AliMUONVTrackStore.h"
+#include "AliMUONVCluster.h"
+
+// MFT includes
+#include "AliMuonForwardTrack.h"
+#include "AliMFTCluster.h"
+#include "AliMFT.h"
+#include "AliMFTSegmentation.h"
+
+#include "AliMuonForwardTrackFinder.h"
+
+//====================================================================================================================================================
+//
+// Class for the creation of the "global muon tracks" built from the clusters in the 
+// muon spectrometer and the clusters of the Muon Forward Tracker. QA histograms are also created
+//
+// Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+ClassImp(AliMuonForwardTrackFinder)
+
+//=====================================================================================================
+
+AliMuonForwardTrackFinder::AliMuonForwardTrackFinder():
+  TObject(),
+  fRun(0),
+  fNEventsToAnalyze(0),
+  fSigmaClusterCut(0),
+  fChi2GlobalCut(0),
+  fSigmaSpectrometerCut(0),
+  fExtrapOriginTransvError(0),
+  fGaussianBlurZVert(0),
+  fNFinalCandidatesCut(0),
+  fReadDir(0),
+  fOutDir(0),
+  fDrawOption(0),
+
+  fDistanceFromGoodClusterAndTrackAtLastPlane(-1),
+  fDistanceFromBestClusterAndTrackAtLastPlane(-1),
+  
+  fRAbsorberCut(0),
+  fLowPtCut(0),
+  fNPlanesMFT(0),
+  fNPlanesMFTAnalyzed(0),
+  fNMaxMissingMFTClusters(0),
+
+  fEv(0),
+  fLabelMC(0),
+
+  fHistPtSpectrometer(0), 
+  fHistPtMuonTrackWithGoodMatch(0),
+  fHistPtMuonTrackWithBadMatch(0),
+  fHistRadiusEndOfAbsorber(0), 
+  fHistNGoodClustersForFinalTracks(0),
+  fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane(0),
+  fHistDistanceGoodClusterFromTrackAtLastPlane(0),
+
+  fNtuFinalCandidates1(0),
+  fNtuFinalBestCandidates1(0),
+  fNtuFinalCandidates2(0),
+  fNtuFinalBestCandidates2(0),
+
+  fCanvas(0),
+
+  fTxtMuonHistory(0), 
+  fTxtTrackGoodClusters(0), 
+  fTxtTrackFinalChi2(0), 
+  fTxtFinalCandidates(0), 
+  fTxtDummy(0),
+  fTxtAllClust(0), 
+  fTxtClustGoodChi2(0), 
+  fTxtClustMC(0), 
+  fTxtClustOfTrack(0), 
+  fMrkAllClust(0), 
+  fMrkClustGoodChi2(0), 
+  fMrkClustMC(0), 
+  fMrkClustOfTrack(0),
+
+  fCountRealTracksAnalyzed(0), 
+  fCountRealTracksWithRefMC(0), 
+  fCountRealTracksWithRefMC_andTrigger(0),
+  fCountRealTracksWithRefMC_andTrigger_andGoodPt(0),
+  fCountRealTracksWithRefMC_andTrigger_andGoodPt_andGoodTheta(0),
+  fCountRealTracksAnalyzedOfEvent(0),
+  fCountRealTracksAnalyzedWithFinalCandidates(0),
+
+  fFileCluster(0),
+  fFileESD(0),
+  fFile_gAlice(0),
+
+  fRunLoader(0),
+  fMFTLoader(0),
+  fMuonRecoCheck(0),
+  fMFTClusterTree(0),
+  fMuonTrackReco(0),
+  fCurrentTrack(0),
+  fIsCurrentMuonTrackable(0),
+  fCandidateTracks(0),
+  fTrackStore(0),
+  fTrackRefStore(0),
+  fNextTrack(0),
+  fStack(0),
+  fMFT(0),
+  fSegmentation(0),
+  fOutputTreeFile(0),
+  fOutputEventTree(0),
+  fMuonForwardTracks(0),
+  fMatchingMode(-1),
+  fMinResearchRadiusAtLastPlane(0),
+  fGRPData(0),
+  fRunInfo(0)
+
+{
+
+  // Default constructor
+
+  for (Int_t iPlane=0; iPlane<fMaxNPlanesMFT; iPlane++) {
+
+    fHistNTracksAfterExtrapolation[iPlane] = 0;
+    fHistChi2Cluster_GoodCluster[iPlane] = 0;
+    fHistChi2Cluster_BadCluster[iPlane] = 0;
+    fHistResearchRadius[iPlane] = 0;      
+    
+    fIsGoodClusterInPlane[iPlane] = kFALSE;
+    
+    fHistChi2Cluster_GoodCluster[iPlane] = 0;
+    fHistChi2Cluster_BadCluster[iPlane]  = 0;
+    
+    fHistChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] = 0;
+    fHistChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] = 0;
+    
+    fZPlane[iPlane] = 0.;
+    fRPlaneMax[iPlane] = 0.;
+    fRPlaneMin[iPlane] = 0.;
+    
+    for (Int_t i=0; i<4; i++) fGrMFTPlane[iPlane][i] = 0;
+    fCircleExt[iPlane] = 0;
+    fCircleInt[iPlane] = 0;
+    
+    fTxtTrackChi2[iPlane] = 0;
+    
+    fIsClusterCompatible[iPlane] = 0;
+    
+    fMFTClusterArray[iPlane]      = 0;
+    fMFTClusterArrayFront[iPlane] = new TClonesArray("AliMFTCluster");
+    fMFTClusterArrayBack[iPlane]  = new TClonesArray("AliMFTCluster");
+
+    fIsPlaneMandatory[iPlane] = kFALSE;
+    
+  }
+
+  //  fNextTrack = 0;
+
+  fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane = 0;
+  fHistDistanceGoodClusterFromTrackAtLastPlane = 0;
+
+  fMFTClusterTree = 0;
+  fCandidateTracks = 0;
+
+  fOutputTreeFile = new TFile("MuonGlobalTracks.root", "recreate");
+  fOutputEventTree   = new TTree("AliMuonForwardTracks", "Tree of AliMuonForwardTracks");
+  fMuonForwardTracks = new TClonesArray("AliMuonForwardTrack");
+  fOutputEventTree   -> Branch("tracks", &fMuonForwardTracks);
+
+}
+
+//=====================================================================================================
+
+void AliMuonForwardTrackFinder::Init(Int_t nRun, 
+                                    Char_t *readDir,
+                                    Char_t *outDir,
+                                    Int_t nEventsToAnalyze) {
+  
+  if (fRunLoader) {
+    printf("WARNING: run already initialized!!\n");
+  }
+
+  SetRun(nRun);
+  SetReadDir(readDir);
+  SetOutDir(outDir);
+
+  printf("input  dir = %s\n", fReadDir.Data());
+  printf("output dir = %s\n", fOutDir.Data());
+
+  // -------------------------- initializing files...
+
+  printf("initializing files for run %d...\n", fRun);
+
+  Char_t geoFileName[300];
+  Char_t esdFileName[300];
+  Char_t gAliceName[300];
+  Char_t clusterName[300];
+  
+  sprintf(geoFileName , "%s/geometry.root",      fReadDir.Data());
+  sprintf(esdFileName , "%s/AliESDs.root" ,      fReadDir.Data());
+  sprintf(gAliceName  , "%s/galice.root"  ,      fReadDir.Data());
+  sprintf(clusterName , "%s/MFT.RecPoints.root", fReadDir.Data());
+  
+  // Import TGeo geometry (needed by AliMUONTrackExtrap::ExtrapToVertex)
+  if (!gGeoManager) {
+    TGeoManager::Import(geoFileName);
+    if (!gGeoManager) {
+      printf("getting geometry from file %s failed", geoFileName);
+      return;
+    }
+  }
+  
+  fFileESD = new TFile(esdFileName);
+  if (!fFileESD || !fFileESD->IsOpen()) return;
+  else printf("file %s successfully opened\n", fFileESD->GetName());
+  
+  fMuonRecoCheck = new AliMUONRecoCheck(esdFileName, Form("%s/generated/", fReadDir.Data()));       // Utility class to check reconstruction
+  fFile_gAlice = new TFile(gAliceName);
+  if (!fFile_gAlice || !fFile_gAlice->IsOpen()) return;
+  else printf("file %s successfully opened\n", fFile_gAlice->GetName());
+  
+  fRunLoader = AliRunLoader::Open(gAliceName);
+  gAlice = fRunLoader->GetAliRun();
+  if (!gAlice) fRunLoader->LoadgAlice();
+  fMFT = (AliMFT*) gAlice->GetDetector("MFT"); 
+  fSegmentation = fMFT->GetSegmentation();
+  SetNPlanesMFT(fSegmentation->GetNPlanes());
+
+  if (!SetRunNumber()) return;
+  if (!InitGRP()) return;
+  AliMUONTrackExtrap::SetField();        // set the magnetic field for track extrapolations
+
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    fZPlane[iPlane]    = fSegmentation->GetPlane(iPlane)->GetZCenter();
+    fRPlaneMax[iPlane] = fSegmentation->GetPlane(iPlane)->GetRMaxSupport();
+    fRPlaneMin[iPlane] = fSegmentation->GetPlane(iPlane)->GetRMinSupport();
+  }
+  
+  // Loading MFT clusters
+  fMFTLoader = fRunLoader->GetDetectorLoader("MFT");
+  fMFTLoader->LoadRecPoints("READ");
+  
+  fMFTClusterTree = fMFTLoader->TreeR();
+
+
+  Int_t nEventsInFile = fMuonRecoCheck->NumberOfEvents();
+  if (!nEventsInFile) {
+    printf("no events available!!!\n");
+    return;
+  }
+  if (nEventsInFile<nEventsToAnalyze || nEventsToAnalyze<0) fNEventsToAnalyze = nEventsInFile;
+  else fNEventsToAnalyze = nEventsToAnalyze;
+
+  fCandidateTracks = new TClonesArray("AliMuonForwardTrack",200000);
+
+  // -------------------------- initializing histograms...
+
+  printf("\ninitializing histograms...\n");
+  BookHistos();
+  SetTitleHistos();
+  printf("... done!\n\n");
+
+  // -------------------------- initializing graphics...
+
+  printf("initializing graphics...\n");
+  BookPlanes();
+  printf("... done!\n\n");
+
+  SetSigmaSpectrometerCut(4.0);
+  SetSigmaClusterCut(4.5);
+  SetChi2GlobalCut(2.0);
+  SetNFinalCandidatesCut(10);
+  SetRAbsorberCut(26.4);
+  SetLowPtCut(0.5);
+  SetExtrapOriginTransvError(1.0);
+
+}
+
+//======================================================================================================================================
+
+Bool_t AliMuonForwardTrackFinder::LoadNextEvent() {
+
+  // load next reconstructed event from the tree
+
+  if (fEv) FillOutputTree();
+
+  if (fEv>=fNEventsToAnalyze) return kFALSE;
+
+  fCountRealTracksAnalyzedOfEvent = 0;
+  
+  printf(" **** analyzing event # %d  \n", fEv);
+  
+  fTrackStore    = fMuonRecoCheck->ReconstructedTracks(fEv);
+  fTrackRefStore = fMuonRecoCheck->ReconstructibleTracks(fEv);
+  
+  fRunLoader->GetEvent(fEv);
+  if (!fMFTLoader->TreeR()->GetEvent()) return kFALSE;
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    printf("plane %02d: nClusters = %d\n", iPlane, (fMFT->GetRecPointsList(iPlane))->GetEntries());
+    fMFTClusterArray[iPlane] = fMFT->GetRecPointsList(iPlane);
+  }
+  SeparateFrontBackClusters();
+
+  fRunLoader -> LoadKinematics();
+  fStack = fRunLoader->Stack();
+  fNextTrack = fTrackStore->CreateIterator();
+  fMuonForwardTracks->Clear();
+
+  fEv++;
+  
+  return kTRUE;
+
+}
+
+//======================================================================================================================================
+
+Int_t AliMuonForwardTrackFinder::LoadNextTrack() {
+
+  fNPlanesMFTAnalyzed = 0;
+
+  // load next muon track from the reconstructed event
+
+  if (!fCountRealTracksAnalyzed) if (!LoadNextEvent()) return kFALSE;
+
+  while ( !(fMuonTrackReco = static_cast<AliMUONTrack*>(fNextTrack->Next())) ) if (!LoadNextEvent()) return kFALSE;
+
+  printf("**************************************************************************************\n");
+  printf("***************************   MUON TRACK %3d   ***************************************\n", fCountRealTracksAnalyzedOfEvent);
+  printf("**************************************************************************************\n");
+
+  fCountRealTracksAnalyzed++;
+
+  fCandidateTracks -> Clear();
+
+  fLabelMC = -1;
+  fDistanceFromGoodClusterAndTrackAtLastPlane = -1.;
+  fDistanceFromBestClusterAndTrackAtLastPlane = -1.;
+  ResetPlanes();
+
+  TIter nextTrackRef(fTrackRefStore->CreateIterator());
+  AliMUONTrack *trackRef=0;
+  
+  // --------------------------------------- loop on MC generated tracks to find the MC reference...
+  
+  while ( (trackRef = static_cast<AliMUONTrack*>(nextTrackRef())) ) {
+    // number of compatible clusters between trackReco and trackRef
+    Int_t nMatchCluster = fMuonTrackReco->FindCompatibleClusters(*trackRef, fSigmaSpectrometerCut, fIsClusterCompatible);  
+    if ( (fIsClusterCompatible[0] || fIsClusterCompatible[1] || fIsClusterCompatible[2] || fIsClusterCompatible[3]) &&   // before the dipole
+        (fIsClusterCompatible[6] || fIsClusterCompatible[7] || fIsClusterCompatible[8] || fIsClusterCompatible[9]) &&   // after the dipole
+        2*nMatchCluster>fMuonTrackReco->GetNClusters() ) {
+      fMuonTrackReco->SetMCLabel(trackRef->GetUniqueID());   // MC reference has been found for trackReco!
+      break;
+    }
+  }
+  
+  // ------------------------------------- ...done!
+
+  if (fMuonTrackReco->GetMCLabel()>=0) fCountRealTracksWithRefMC++;
+  
+  fLabelMC = fMuonTrackReco->GetMCLabel();
+
+  CheckCurrentMuonTrackable();
+
+  PrintParticleHistory();
+  
+  if (fMuonTrackReco->GetMatchTrigger()) fCountRealTracksWithRefMC_andTrigger++;
+  
+  // the track we are going to build, starting from fMuonTrackReco and adding the MFT clusters
+  AliMuonForwardTrack *track = new ((*fCandidateTracks)[0]) AliMuonForwardTrack();
+  track -> SetMUONTrack(fMuonTrackReco);
+  if (fLabelMC>=0) track -> SetMCTrackRef(fStack->Particle(fLabelMC));
+  track -> SetMCLabel(fMuonTrackReco->GetMCLabel());
+  track -> SetMatchTrigger(fMuonTrackReco->GetMatchTrigger());
+  
+  // track parameters at the first tracking station in the Muon Spectrometer
+  AliMUONTrackParam *param = (AliMUONTrackParam*) (fMuonTrackReco->GetTrackParamAtCluster()->First());
+  Double_t ptSpectrometer = TMath::Sqrt(param->Px()*param->Px() + param->Py()*param->Py());
+  Double_t thetaSpectrometer = TMath::ATan(ptSpectrometer/param->Pz());
+  if (thetaSpectrometer<0.) thetaSpectrometer += TMath::Pi();
+  Double_t etaSpectrometer = -1.*TMath::Log(TMath::Tan(0.5*thetaSpectrometer));
+  fHistPtSpectrometer -> Fill(ptSpectrometer);
+  
+  // if the transverse momentum in the Muon Spectrometer is smaller than the threshold, skip to the next track
+  if (ptSpectrometer < fLowPtCut) return 3;
+  
+  // track parameters linearly extrapolated from the first tracking station to the end of the absorber
+  AliMUONTrackParam trackParamEndOfAbsorber(*((AliMUONTrackParam*)(fMuonTrackReco->GetTrackParamAtCluster()->First())));
+  AliMUONTrackExtrap::ExtrapToZCov(&trackParamEndOfAbsorber, -503.);   // absorber extends from -90 to -503 cm
+  Double_t xEndOfAbsorber = trackParamEndOfAbsorber.GetNonBendingCoor();
+  Double_t yEndOfAbsorber = trackParamEndOfAbsorber.GetBendingCoor();
+  Double_t rAbsorber      = TMath::Sqrt(xEndOfAbsorber*xEndOfAbsorber + yEndOfAbsorber*yEndOfAbsorber);
+  fHistRadiusEndOfAbsorber -> Fill(rAbsorber);
+  
+  // if the radial distance of the track at the end of the absorber is smaller than a radius corresponding to 
+  // 3 degrees as seen from the interaction point, skip to the next track
+  if (rAbsorber < fRAbsorberCut) return 4;
+  
+  //------------------------- NOW THE CYCLE OVER THE MFT PLANES STARTS ---------------------------------------
+  
+  for (Int_t iPlane=fNPlanesMFT-1; iPlane>=0; iPlane--) {          // *** do not reverse the order of this cycle!!! 
+                                                                   // *** this reflects the fact that the extrapolation is performed 
+                                                                   // *** starting from the last MFT plane back to the origin
+    
+    // --------- updating the array of tracks according to the clusters available in the i-th plane ---------
+    
+    fNPlanesMFTAnalyzed++;
+
+    if (fMatchingMode==kRealMatching) {
+      Int_t nTracksToBeAnalyzed = fCandidateTracks->GetEntriesFast();
+      for (Int_t iTrack=0; iTrack<nTracksToBeAnalyzed; iTrack++) {
+       fCurrentTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(iTrack);
+       // if the old track is compatible with the new cluster, the track is updated and inserted as new track in the array 
+       // (several new tracks can be created for one old track)
+       FindClusterInPlane(iPlane);   
+       if ((fNPlanesMFTAnalyzed-fCurrentTrack->GetNMFTClusters())>fNMaxMissingMFTClusters || fIsPlaneMandatory[iPlane]) {
+         fCandidateTracks->Remove(fCurrentTrack);     // the old track is removed after the check;
+       }
+      }
+      fCandidateTracks->Compress();
+      if (fIsCurrentMuonTrackable) fHistNTracksAfterExtrapolation[iPlane] -> Fill(fCandidateTracks->GetEntriesFast());
+    }
+
+    else if (fMatchingMode==kIdealMatching) {
+      fCurrentTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(0);
+      printf("plane %02d: fCandidateTracks->GetEntriesFast() = %d   fCandidateTracks->UncheckedAt(0) = %p   fCurrentTrack = %p\n", 
+            iPlane, fCandidateTracks->GetEntriesFast(), fCandidateTracks->UncheckedAt(0), fCurrentTrack);
+      AttachGoodClusterInPlane(iPlane);
+    }
+
+  }      
+  
+  // -------------------------- END OF THE CYCLE OVER THE MFT PLANES --------------------------------------------
+  
+  if (fMatchingMode==kIdealMatching) {
+    printf("Adding track to output tree...\n");
+    AliMuonForwardTrack *newTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(0);
+    new ((*fMuonForwardTracks)[fMuonForwardTracks->GetEntries()]) AliMuonForwardTrack(*newTrack);  // AU
+    printf("...track added!\n");
+    fCandidateTracks->Clear();
+    fCountRealTracksAnalyzedOfEvent++;
+    return 5;
+  }
+
+  // If we have several final tracks, we must find the best candidate:
+
+  Int_t nFinalTracks = fCandidateTracks->GetEntriesFast();
+
+  if (nFinalTracks) fCountRealTracksAnalyzedWithFinalCandidates++;
+  
+  Double_t theVariable_Best        = -1.;                    // variable defining the best candidate
+  Bool_t bestCandidateExists       = kFALSE;
+  Int_t nGoodClustersBestCandidate = 0;
+  Int_t idBestCandidate            = 0;
+  Double_t chi2HistoryForBestCandidate[fMaxNPlanesMFT]={0};    // chi2 on each plane, for the best candidate
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) chi2HistoryForBestCandidate[iPlane] = -1.;
+  
+  fTxtFinalCandidates = new TLatex(0.10, 0.78, Form("N_{FinalCandidates} = %d", nFinalTracks));
+  
+  Int_t nClustersMC = 0;
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) nClustersMC += fIsGoodClusterInPlane[iPlane];
+
+  for (Int_t iTrack=0; iTrack<nFinalTracks; iTrack++) {
+    
+    AliMuonForwardTrack *finalTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(iTrack);
+    
+    Double_t chi2AtPlane[fMaxNPlanesMFT]={0};
+    Int_t nGoodClusters = 0;
+    Int_t nMFTClusters  = finalTrack->GetNMFTClusters();
+    Int_t nMUONClusters = finalTrack->GetNMUONClusters();
+
+    Int_t plane = 0;
+    for (Int_t iCluster=0; iCluster<nMFTClusters; iCluster++) {
+      while (!finalTrack->PlaneExists(plane)) plane++;
+      AliMFTCluster *localCluster = finalTrack->GetMFTCluster(iCluster);
+      chi2AtPlane[plane++] = localCluster->GetTrackChi2();
+      if (IsCorrectMatch(localCluster)) nGoodClusters++;
+      Int_t nClustersGlobalTrack = nMUONClusters + (nMFTClusters-iCluster);        // Muon Spectrometer clusters + clusters in the Vertex Telescope
+      Int_t ndfGlobalTrack = GetNDF(nClustersGlobalTrack);
+      chi2AtPlane[plane] /= Double_t(ndfGlobalTrack);
+    }
+    
+    if (fIsCurrentMuonTrackable) fHistNGoodClustersForFinalTracks -> Fill(nGoodClusters);
+
+    fNtuFinalCandidates1 -> Fill(Double_t(fRun),
+                                Double_t(fEv),
+                                Double_t(fCountRealTracksAnalyzedOfEvent),
+                                Double_t(nFinalTracks),
+                                Double_t(nClustersMC),
+                                Double_t(nGoodClusters),
+                                ptSpectrometer,
+                                thetaSpectrometer,
+                                etaSpectrometer);
+
+    fNtuFinalCandidates2 -> Fill(chi2AtPlane[0],
+                                chi2AtPlane[1],
+                                chi2AtPlane[2],
+                                chi2AtPlane[3],
+                                chi2AtPlane[4],
+                                chi2AtPlane[5],
+                                chi2AtPlane[6],
+                                chi2AtPlane[7],
+                                chi2AtPlane[8],
+                                chi2AtPlane[9],
+                                chi2AtPlane[10],
+                                chi2AtPlane[11],
+                                chi2AtPlane[12],
+                                chi2AtPlane[13],
+                                chi2AtPlane[14]);
+    
+    // now comparing the tracks with various criteria, in order to find the best one
+    
+    Double_t theVariable = 0.;
+    for (Int_t iCluster=0; iCluster<nMFTClusters; iCluster++) theVariable += chi2AtPlane[iCluster];
+    theVariable /= Double_t(nMFTClusters);
+      
+    if (theVariable<theVariable_Best || theVariable_Best<0.) {
+      nGoodClustersBestCandidate = nGoodClusters;
+      for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) chi2HistoryForBestCandidate[iPlane] = chi2AtPlane[iPlane];
+      theVariable_Best = theVariable;
+      fTxtTrackFinalChi2 = new TLatex(0.20, 0.52, Form("#chi^{2}_{final} = %3.1f", chi2HistoryForBestCandidate[0]));
+      for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+       fTxtTrackChi2[iPlane] = new TLatex(0.55*fRPlaneMax[fNPlanesMFT-1], 
+                                          0.90*fRPlaneMax[fNPlanesMFT-1], 
+                                          Form("#chi^{2} = %3.1f", chi2AtPlane[iPlane]));
+      }
+      idBestCandidate = iTrack;
+      bestCandidateExists=kTRUE;
+    }
+
+    // ----------------------------------------------------------
+
+  }
+  
+  if (nFinalTracks) {
+    FillPlanesWithTrackHistory((AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(idBestCandidate));
+    AliMuonForwardTrack *newTrack = (AliMuonForwardTrack*) fCandidateTracks->UncheckedAt(idBestCandidate);
+    new ((*fMuonForwardTracks)[fMuonForwardTracks->GetEntries()]) AliMuonForwardTrack(*newTrack);   // AU
+    fNtuFinalBestCandidates1 -> Fill(Double_t(fRun),
+                                    Double_t(fEv),
+                                    Double_t(fCountRealTracksAnalyzedOfEvent),
+                                    Double_t(nFinalTracks),
+                                    Double_t(nClustersMC),
+                                    Double_t(nGoodClustersBestCandidate),
+                                    ptSpectrometer,
+                                    thetaSpectrometer,
+                                    etaSpectrometer);
+
+    fNtuFinalBestCandidates2 -> Fill(chi2HistoryForBestCandidate[0],
+                                    chi2HistoryForBestCandidate[1],
+                                    chi2HistoryForBestCandidate[2],
+                                    chi2HistoryForBestCandidate[3],
+                                    chi2HistoryForBestCandidate[4],
+                                    chi2HistoryForBestCandidate[5],
+                                    chi2HistoryForBestCandidate[6],
+                                    chi2HistoryForBestCandidate[7],
+                                    chi2HistoryForBestCandidate[8],
+                                    chi2HistoryForBestCandidate[9],
+                                    chi2HistoryForBestCandidate[10],
+                                    chi2HistoryForBestCandidate[11],
+                                    chi2HistoryForBestCandidate[12],
+                                    chi2HistoryForBestCandidate[13],
+                                    chi2HistoryForBestCandidate[14]);
+
+  }
+  
+  if (fDrawOption && bestCandidateExists) {
+    fTxtTrackGoodClusters = new TLatex(0.20, 0.59, Form("N_{GoodClusters} = %d", nGoodClustersBestCandidate));
+    DrawPlanes();
+  }
+
+  if (fIsCurrentMuonTrackable) {
+    if (nGoodClustersBestCandidate==5) fHistPtMuonTrackWithGoodMatch -> Fill(ptSpectrometer);
+    else                               fHistPtMuonTrackWithBadMatch  -> Fill(ptSpectrometer);
+  }
+
+  // -------------------------------------------------------------------------------------------
+
+  fCandidateTracks->Clear();
+  
+  fCountRealTracksAnalyzedOfEvent++;
+
+  return 5;
+  
+}
+
+//===========================================================================================================================================
+
+void AliMuonForwardTrackFinder::FindClusterInPlane(Int_t planeId) { 
+  
+  printf(">>>> executing AliMuonForwardTrackFinder::FindClusterInPlane(%d)\n", planeId);
+
+  // !!!!!!!!! coordinates and errors on the interaction vertex should be taken from the event itself (ITS) if available
+
+  // propagate track to plane #planeId (both to front and back active sensors)
+  // look for compatible clusters
+  // update TrackParam at found cluster (if any) using Kalman Filter
+
+  AliMUONTrackParam currentParamFront, currentParamBack, currentParamForResearchFront, currentParamForResearchBack;
+
+  if (planeId == fNPlanesMFT-1) {      // last plane of the telecope
+    currentParamFront = (*((AliMUONTrackParam*)(fMuonTrackReco->GetTrackParamAtCluster()->First())));
+    currentParamBack  = (*((AliMUONTrackParam*)(fMuonTrackReco->GetTrackParamAtCluster()->First())));
+    currentParamForResearchFront = currentParamFront;
+    currentParamForResearchBack  = currentParamBack;
+    AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&currentParamFront, 0.); 
+    AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&currentParamBack,  0.); 
+    AliMUONTrackExtrap::ExtrapToVertex(&currentParamForResearchFront, 0., 0., gRandom->Gaus(0,fGaussianBlurZVert), fExtrapOriginTransvError, fExtrapOriginTransvError); 
+    AliMUONTrackExtrap::ExtrapToVertex(&currentParamForResearchBack,  0., 0., gRandom->Gaus(0,fGaussianBlurZVert), fExtrapOriginTransvError, fExtrapOriginTransvError); 
+  }
+  else {          // MFT planes others than the last one: mult. scattering correction because of the upstream MFT planes is performed
+    currentParamFront = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
+    currentParamBack  = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
+    currentParamForResearchFront = currentParamFront;
+    currentParamForResearchBack  = currentParamBack;
+    AliMUONTrackExtrap::AddMCSEffect(&currentParamFront,           (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
+                                                                   fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/radLengthSi,-1.);
+    AliMUONTrackExtrap::AddMCSEffect(&currentParamForResearchFront,(fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
+                                                                   fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/radLengthSi,-1.);
+    AliMUONTrackExtrap::AddMCSEffect(&currentParamBack,            (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
+                                                                   fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/radLengthSi,-1.);
+    AliMUONTrackExtrap::AddMCSEffect(&currentParamForResearchBack, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
+                                                                   fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/radLengthSi,-1.);
+  }
+  // for all planes: extrapolation to the Z of the plane
+  AliMUONTrackExtrap::ExtrapToZCov(&currentParamFront,            -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveFront());   
+  AliMUONTrackExtrap::ExtrapToZCov(&currentParamForResearchFront, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveFront());
+  AliMUONTrackExtrap::ExtrapToZCov(&currentParamBack,             -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveBack());   
+  AliMUONTrackExtrap::ExtrapToZCov(&currentParamForResearchBack,  -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveBack());
+
+  //---------------------------------------------------------------------------------------
+
+  TMatrixD covFront(5,5); covFront = currentParamForResearchFront.GetCovariances();
+  TMatrixD covBack(5,5);  covBack  = currentParamForResearchBack.GetCovariances();
+  
+  Double_t squaredError_X_Front = covFront(0,0);
+  Double_t squaredError_Y_Front = covFront(2,2);
+  Double_t squaredError_X_Back  = covBack(0,0);
+  Double_t squaredError_Y_Back  = covBack(2,2);
+
+  Double_t corrFact = 1.0;
+
+  Double_t researchRadiusFront = TMath::Sqrt(squaredError_X_Front + squaredError_Y_Front);
+  Double_t researchRadiusBack  = TMath::Sqrt(squaredError_X_Back  + squaredError_Y_Back);
+  if (planeId==fNPlanesMFT-1 && 0.5*(researchRadiusFront+researchRadiusBack)<fMinResearchRadiusAtLastPlane) {
+    corrFact = fMinResearchRadiusAtLastPlane/(0.5*(researchRadiusFront+researchRadiusBack));
+  }
+  if (fIsCurrentMuonTrackable) fHistResearchRadius[planeId] -> Fill(corrFact*0.5*(researchRadiusFront+researchRadiusBack));
+
+  Double_t position_X_Front = currentParamForResearchFront.GetNonBendingCoor();
+  Double_t position_Y_Front = currentParamForResearchFront.GetBendingCoor();
+  Double_t position_X_Back = currentParamForResearchBack.GetNonBendingCoor();
+  Double_t position_Y_Back = currentParamForResearchBack.GetBendingCoor();
+  Double_t radialPositionOfTrackFront = TMath::Sqrt(position_X_Front*position_X_Front + position_Y_Front*position_Y_Front);
+  Double_t radialPositionOfTrackBack  = TMath::Sqrt(position_X_Back*position_X_Back   + position_Y_Back*position_Y_Back);
+
+  //---------------------------------------------------------------------------------------
+
+  Double_t chi2cut = 2.*fSigmaClusterCut*fSigmaClusterCut;     // depends on the number of variables (here, 2)
+  
+  // Analyizing the clusters: FRONT ACTIVE ELEMENTS
+  
+  Int_t nClustersFront = fMFTClusterArrayFront[planeId]->GetEntries();
+  printf("There are %3d clusters in plane %02d FRONT\n", nClustersFront, planeId);
+  
+  for (Int_t iCluster=0; iCluster<nClustersFront; iCluster++) {
+
+    Bool_t isGoodChi2 = kFALSE;
+
+    AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayFront[planeId]->At(iCluster); 
+    Double_t chi2 = (1./(corrFact*corrFact)) * TryOneCluster(currentParamForResearchFront, cluster);     // describes the compatibility between the track and the cluster
+    if (chi2<chi2cut) isGoodChi2 = kTRUE;
+
+    Double_t radialPositionOfClusterFront = TMath::Sqrt(cluster->GetX()*cluster->GetX() + cluster->GetY()*cluster->GetY());    
+    if (planeId == fNPlanesMFT-1) {
+      if (TMath::Abs(radialPositionOfTrackFront-radialPositionOfClusterFront)<fDistanceFromBestClusterAndTrackAtLastPlane ||
+         fDistanceFromBestClusterAndTrackAtLastPlane<0.) {
+       fDistanceFromBestClusterAndTrackAtLastPlane = TMath::Abs(radialPositionOfTrackFront-radialPositionOfClusterFront);
+      }
+      if (IsCorrectMatch(cluster)) {
+       fDistanceFromGoodClusterAndTrackAtLastPlane = TMath::Abs(radialPositionOfTrackFront-radialPositionOfClusterFront);
+      }
+    }
+
+    if (fIsCurrentMuonTrackable) {
+      if (IsCorrectMatch(cluster)) fHistChi2Cluster_GoodCluster[planeId]->Fill(chi2/2.);     //  chi2/ndf
+      else                         fHistChi2Cluster_BadCluster[planeId] ->Fill(chi2/2.);     //  chi2/ndf
+    }
+
+    if (isGoodChi2) {
+      printf("accepting cluster: chi2=%f (cut = %f)\n", chi2, chi2cut);
+      AliMuonForwardTrack *newTrack = new ((*fCandidateTracks)[fCandidateTracks->GetEntriesFast()]) AliMuonForwardTrack(*fCurrentTrack);
+      newTrack->AddTrackParamAtMFTCluster(currentParamFront, *cluster);    // creating new track param and attaching the cluster
+      newTrack->SetPlaneExists(planeId);
+      printf("current muon is trackable: %d\n", fIsCurrentMuonTrackable);
+      if (fIsCurrentMuonTrackable) {
+       Double_t newGlobalChi2 = ((AliMUONTrackParam*) newTrack->GetTrackParamAtCluster()->First())->GetTrackChi2();
+       printf("new chi2 = %f (= %f)\n", newGlobalChi2, newTrack->GetMFTCluster(0)->GetTrackChi2());
+       Int_t nClustersGlobalTrack = newTrack->GetNMUONClusters() + newTrack->GetNMFTClusters();        // Muon Spectrometer clusters + clusters in the Vertex Telescope
+       Int_t ndfGlobalTrack = GetNDF(nClustersGlobalTrack);
+       if (IsCorrectMatch(cluster)) fHistChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[planeId]->Fill(newGlobalChi2/Double_t(ndfGlobalTrack));
+       else                         fHistChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[planeId] ->Fill(newGlobalChi2/Double_t(ndfGlobalTrack));
+      }
+      fGrMFTPlane[planeId][kClustersGoodChi2] -> SetPoint(fGrMFTPlane[planeId][kClustersGoodChi2]->GetN(), cluster->GetX(), cluster->GetY());
+    }
+    else printf("discarding cluster: chi2=%f (cut = %f)\n", chi2, chi2cut);
+
+  }
+
+  // Analyizing the clusters: BACK ACTIVE ELEMENTS
+  
+  Int_t nClustersBack = fMFTClusterArrayBack[planeId]->GetEntries();
+  printf("There are %3d clusters in plane %02d BACK\n", nClustersBack, planeId);
+  
+  for (Int_t iCluster=0; iCluster<nClustersBack; iCluster++) {
+
+    Bool_t isGoodChi2 = kFALSE;
+
+    AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayBack[planeId]->At(iCluster); 
+    Double_t chi2 = (1./(corrFact*corrFact)) * TryOneCluster(currentParamForResearchBack, cluster);     // describes the compatibility between the track and the cluster
+    if (chi2<chi2cut) isGoodChi2 = kTRUE;
+
+    Double_t radialPositionOfClusterBack = TMath::Sqrt(cluster->GetX()*cluster->GetX() + cluster->GetY()*cluster->GetY());    
+    if (planeId == fNPlanesMFT-1) {
+      if (TMath::Abs(radialPositionOfTrackBack-radialPositionOfClusterBack)<fDistanceFromBestClusterAndTrackAtLastPlane ||
+         fDistanceFromBestClusterAndTrackAtLastPlane<0.) {
+       fDistanceFromBestClusterAndTrackAtLastPlane = TMath::Abs(radialPositionOfTrackBack-radialPositionOfClusterBack);
+      }
+      if (IsCorrectMatch(cluster)) {
+       fDistanceFromGoodClusterAndTrackAtLastPlane = TMath::Abs(radialPositionOfTrackBack-radialPositionOfClusterBack);
+      }
+    }
+
+    if (fIsCurrentMuonTrackable) {
+      if (IsCorrectMatch(cluster)) fHistChi2Cluster_GoodCluster[planeId]->Fill(chi2/2.);     //  chi2/ndf
+      else                         fHistChi2Cluster_BadCluster[planeId] ->Fill(chi2/2.);     //  chi2/ndf
+    }
+
+    if (isGoodChi2) {
+      printf("accepting cluster: chi2=%f (cut = %f)\n", chi2, chi2cut);
+      AliMuonForwardTrack *newTrack = new ((*fCandidateTracks)[fCandidateTracks->GetEntriesFast()]) AliMuonForwardTrack(*fCurrentTrack);
+      newTrack->AddTrackParamAtMFTCluster(currentParamBack, *cluster);    // creating new track param and attaching the cluster
+      newTrack->SetPlaneExists(planeId);
+      printf("current muon is trackable: %d\n", fIsCurrentMuonTrackable);
+      if (fIsCurrentMuonTrackable) {
+       Double_t newGlobalChi2 = ((AliMUONTrackParam*) newTrack->GetTrackParamAtCluster()->First())->GetTrackChi2();
+       printf("new chi2 = %f (= %f)\n", newGlobalChi2, newTrack->GetMFTCluster(0)->GetTrackChi2());
+       Int_t nClustersGlobalTrack = newTrack->GetNMUONClusters() + newTrack->GetNMFTClusters();        // Muon Spectrometer clusters + clusters in the Vertex Telescope
+       Int_t ndfGlobalTrack = GetNDF(nClustersGlobalTrack);
+       if (IsCorrectMatch(cluster)) fHistChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[planeId]->Fill(newGlobalChi2/Double_t(ndfGlobalTrack));
+       else                         fHistChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[planeId] ->Fill(newGlobalChi2/Double_t(ndfGlobalTrack));
+      }
+      fGrMFTPlane[planeId][kClustersGoodChi2] -> SetPoint(fGrMFTPlane[planeId][kClustersGoodChi2]->GetN(), cluster->GetX(), cluster->GetY());
+    }
+    else printf("discarding cluster: chi2=%f (cut = %f)\n", chi2, chi2cut);
+
+  }
+
+  //---------------------------------------------------------------------------------------------
+
+  if (planeId == fNPlanesMFT-1) {
+    if (fIsCurrentMuonTrackable && fDistanceFromGoodClusterAndTrackAtLastPlane>0.) {
+      fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane -> Fill(TMath::Abs(fDistanceFromBestClusterAndTrackAtLastPlane-
+                                                                                                      fDistanceFromGoodClusterAndTrackAtLastPlane));
+      fHistDistanceGoodClusterFromTrackAtLastPlane -> Fill(fDistanceFromGoodClusterAndTrackAtLastPlane);
+    }
+  }
+  
+}
+
+//==========================================================================================================================================
+
+void AliMuonForwardTrackFinder::AttachGoodClusterInPlane(Int_t planeId) { 
+  
+  printf(">>>> executing AliMuonForwardTrackFinder::AttachGoodClusterInPlane(%d)\n", planeId);
+
+  AliMUONTrackParam currentParamFront, currentParamBack;
+
+  if (planeId == fNPlanesMFT-1) {      // last plane of the telecope
+    currentParamFront = (*((AliMUONTrackParam*)(fMuonTrackReco->GetTrackParamAtCluster()->First())));
+    currentParamBack  = (*((AliMUONTrackParam*)(fMuonTrackReco->GetTrackParamAtCluster()->First())));
+    AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&currentParamFront, 0.); 
+    AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&currentParamBack,  0.); 
+  }
+  else {          // MFT planes others than the last one: mult. scattering correction because of the upstream MFT planes is performed
+    printf("fCurrentTrack = %p\n", fCurrentTrack);
+    currentParamFront = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
+    currentParamBack  = (*((AliMUONTrackParam*)(fCurrentTrack->GetTrackParamAtCluster()->First())));
+    AliMUONTrackExtrap::AddMCSEffect(&currentParamFront, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
+                                                         fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/radLengthSi,-1.);
+    AliMUONTrackExtrap::AddMCSEffect(&currentParamBack,  (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
+                                                         fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/radLengthSi,-1.);
+  }
+  // for all planes: linear extrapolation to the Z of the plane
+  AliMUONTrackExtrap::ExtrapToZCov(&currentParamFront, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveFront());   
+  AliMUONTrackExtrap::ExtrapToZCov(&currentParamBack,  -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveBack());   
+
+  Bool_t goodClusterFound = kFALSE;
+  
+  // Analyizing the clusters: FRONT ACTIVE ELEMENTS
+
+  Int_t nClustersFront = fMFTClusterArrayFront[planeId]->GetEntries();
+  
+  printf("nClustersFront = %d\n", nClustersFront);
+  for (Int_t iCluster=0; iCluster<nClustersFront; iCluster++) {
+    AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayFront[planeId]->UncheckedAt(iCluster);
+    printf("checking cluster %02d of %02d: cluter=%p, fCurrentTrack=%p\n", iCluster, nClustersFront, cluster, fCurrentTrack);
+    if (IsCorrectMatch(cluster)) {
+      fCurrentTrack->AddTrackParamAtMFTCluster(currentParamFront, *cluster);  // creating new track param and attaching the cluster
+      fCurrentTrack->SetPlaneExists(planeId);
+      goodClusterFound = kTRUE;
+      break;
+    }
+  }
+
+  if (goodClusterFound) return;
+
+  // Analyizing the clusters: BACK ACTIVE ELEMENTS
+
+  Int_t nClustersBack = fMFTClusterArrayBack[planeId]->GetEntries();
+  
+  printf("nClustersBack = %d\n", nClustersBack);
+  for (Int_t iCluster=0; iCluster<nClustersBack; iCluster++) {
+    AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArrayBack[planeId]->UncheckedAt(iCluster);
+    printf("checking cluster %02d of %02d: cluter=%p, fCurrentTrack=%p\n", iCluster, nClustersBack, cluster, fCurrentTrack);
+    if (IsCorrectMatch(cluster)) {
+      fCurrentTrack->AddTrackParamAtMFTCluster(currentParamBack, *cluster);  // creating new track param and attaching the cluster
+      fCurrentTrack->SetPlaneExists(planeId);
+      goodClusterFound = kTRUE;
+      break;
+    }
+  }
+
+}
+
+//==========================================================================================================================================
+
+void AliMuonForwardTrackFinder::CheckCurrentMuonTrackable() {
+
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    fIsGoodClusterInPlane[iPlane] = kFALSE;
+    Int_t nClusters = fMFTClusterArray[iPlane]->GetEntriesFast();
+    for (Int_t iCluster=0; iCluster<nClusters; iCluster++) {
+      AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArray[iPlane]->At(iCluster); 
+      for (Int_t iTrack=0; iTrack<cluster->GetNMCTracks(); iTrack++) {
+       if (cluster->GetMCLabel(iTrack)==fLabelMC) {
+         fIsGoodClusterInPlane[iPlane] = kTRUE;
+         break;
+       }
+      }
+    }
+  }
+
+  fIsCurrentMuonTrackable = kTRUE;
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) fIsCurrentMuonTrackable = (fIsCurrentMuonTrackable&&fIsGoodClusterInPlane[iPlane]);
+
+}
+
+//==========================================================================================================================================
+
+void AliMuonForwardTrackFinder::FillPlanesWithTrackHistory(AliMuonForwardTrack *track) { 
+  
+  // recover track parameters on each planes and look for the corresponding clusters
+
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    
+    AliMFTCluster *trackCluster = (AliMFTCluster *) track->GetMFTCluster(iPlane);
+
+    fGrMFTPlane[iPlane][kClusterOfTrack] -> SetPoint(fGrMFTPlane[iPlane][kClusterOfTrack]->GetN(), trackCluster->GetX(), trackCluster->GetY());
+    
+    Int_t nClusters = fMFTClusterArray[iPlane]->GetEntriesFast();
+    
+    for (Int_t iCluster=0; iCluster<nClusters; iCluster++) {
+      
+      AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArray[iPlane]->UncheckedAt(iCluster); 
+
+      fGrMFTPlane[iPlane][kAllClusters] -> SetPoint(fGrMFTPlane[iPlane][kAllClusters]->GetN(), cluster->GetX(), cluster->GetY());
+      
+      if (IsCorrectMatch(cluster)) {
+       fGrMFTPlane[iPlane][kClusterCorrectMC] -> SetPoint(fGrMFTPlane[iPlane][kClusterCorrectMC]->GetN(), cluster->GetX(), cluster->GetY());
+      }
+
+    }
+
+  }
+
+}
+
+//======================================================================================================================================
+
+Bool_t AliMuonForwardTrackFinder::IsCorrectMatch(AliMFTCluster *cluster) {
+
+  Bool_t result = kFALSE;
+
+  // check if the cluster belongs to the correct MC track
+
+  for (Int_t iTrack=0; iTrack<cluster->GetNMCTracks(); iTrack++) {
+    if (cluster->GetMCLabel(iTrack)==fLabelMC) {
+      result = kTRUE;
+      break;
+    }
+  }
+
+  printf("returning %d\n", result);
+
+  return result;
+
+}
+
+//======================================================================================================================================
+
+Double_t AliMuonForwardTrackFinder::TryOneCluster(const AliMUONTrackParam &trackParam, AliMFTCluster *cluster) {
+
+  // Test the compatibility between the track and the cluster (using trackParam's covariance matrix):
+  // return the corresponding Chi2
+  // assume the track parameters are given at the Z of the cluster
+  
+  // Set differences between trackParam and cluster in the bending and non bending directions
+  Double_t dX = cluster->GetX() - trackParam.GetNonBendingCoor();
+  Double_t dY = cluster->GetY() - trackParam.GetBendingCoor();
+  printf("dX = %f, dY = %f\n", dX, dY);
+  
+  // Calculate errors and covariances
+  const TMatrixD& kParamCov = trackParam.GetCovariances();
+  Double_t sigmaX2 = kParamCov(0,0) + cluster->GetErrX2();
+  Double_t sigmaY2 = kParamCov(2,2) + cluster->GetErrY2();
+  printf("dX2 = %f, dY2 = %f\n", sigmaX2, sigmaY2);
+  Double_t covXY   = kParamCov(0,2);
+  Double_t det     = sigmaX2 * sigmaY2 - covXY * covXY;
+  
+  // Compute chi2
+  if (det==0.) return 1.e10;
+  return (dX*dX*sigmaY2 + dY*dY*sigmaX2 - 2.*dX*dY*covXY) / det;
+  
+}
+
+//=========================================================================================================================================
+
+void AliMuonForwardTrackFinder::SeparateFrontBackClusters() {
+
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    fMFTClusterArrayFront[iPlane]->Clear();
+    fMFTClusterArrayBack[iPlane] ->Clear();
+    for (Int_t iCluster=0; iCluster<fMFTClusterArray[iPlane]->GetEntries(); iCluster++) {
+      AliMFTCluster *cluster = (AliMFTCluster*) fMFTClusterArray[iPlane]->At(iCluster);
+      if (TMath::Abs(cluster->GetZ())<TMath::Abs(fSegmentation->GetPlane(iPlane)->GetZCenter())) {
+       new ((*fMFTClusterArrayFront[iPlane])[fMFTClusterArrayFront[iPlane]->GetEntries()]) AliMFTCluster(*cluster);
+      }
+      else {
+       new ((*fMFTClusterArrayBack[iPlane])[fMFTClusterArrayBack[iPlane]->GetEntries()]) AliMFTCluster(*cluster);
+      }
+    }
+  }
+
+}
+
+//=========================================================================================================================================
+
+Int_t AliMuonForwardTrackFinder::GetNDF(Int_t nClusters) {
+
+  // the same definition as in AliMUONTrack is implemented, since here we just add more clusters to the Muon track
+  
+  Int_t ndf = 2 * nClusters - 5;
+  return (ndf > 0) ? ndf : 0;
+
+}
+
+//============================================================================================================================================
+
+void AliMuonForwardTrackFinder::BookHistos() {
+  
+  const Int_t nMaxNewTracks[]  = {150,     200,   250, 600, 1000};
+  const Double_t radiusPlane[] = {0.001, 0.010, 0.100, 5.0,  5.0};
+
+  fHistPtSpectrometer = new TH1D("hPtSpectrometer", "p_{T} as given by the Muon Spectrometer", 200, 0, 20.); 
+
+  fHistPtMuonTrackWithGoodMatch = new TH1D("fHistPtMuonTrackWithGoodMatch", "p_{T} of muon track with good match", 200, 0, 20.); 
+  fHistPtMuonTrackWithBadMatch  = new TH1D("fHistPtMuonTrackWithBadMatch",  "p_{T} of muon track with bad match",  200, 0, 20.); 
+
+  fHistRadiusEndOfAbsorber = new TH1D("hRadiusEndOfAbsorber", "Track radial distance at the end of the absorber",  1000, 0, 100.); 
+
+  fHistNGoodClustersForFinalTracks = new TH1D("hNGoodClustersForFinalTracks", "Number of Good Clusters per Final Track", 20, -0.25, 9.75);
+
+  fHistDistanceGoodClusterFromTrackAtLastPlane = new TH1D("hDistanceGoodClusterFromTrackAtLastPlane",
+                                                         "Distance of MC Good Cluster from Track in last MFT plane", 200, 0., 2.);
+  
+  fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane = 
+    new TH1D("hDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane",
+            "Good Cluster distance from track - Best Cluster distance from track in last MFT plane", 200, 0., 2.);
+  
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    
+    fHistNTracksAfterExtrapolation[iPlane] = new TH1D(Form("hNTracksAfterExtrapolation_pl%02d", iPlane),
+                                                     Form("Number of Candidates after analysis of MFT plane %02d", iPlane),
+                                                     nMaxNewTracks[iPlane], -0.5, nMaxNewTracks[iPlane]-0.5);
+    
+    fHistResearchRadius[iPlane] = new TH1D(Form("hResearchRadius_pl%02d", iPlane),
+                                          Form("Research Radius for candidate clusters in MFT plane %02d", iPlane),
+                                          1000, 0., radiusPlane[iPlane]);
+    
+    fHistChi2Cluster_GoodCluster[iPlane] = new TH1D(Form("hChi2Cluster_GoodCluster_pl%02d", iPlane),
+                                                   Form("#chi^{2}_{clust} for Good clusters in MFT plane %02d", iPlane),
+                                                   100, 0., 15.);
+    
+    fHistChi2Cluster_BadCluster[iPlane] = new TH1D(Form("hChi2Cluster_BadCluster_pl%02d", iPlane),
+                                                  Form("#chi^{2}_{clust} for Bad clusters in MFT plane %02d", iPlane),
+                                                  100, 0., 15.);
+
+    fHistChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] = new TH1D(Form("fHistChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons_pl%02d", iPlane),
+                                                                          Form("#chi^{2}/ndf at plane %d for GOOD candidates of trackable muons",iPlane),
+                                                                          100, 0., 15.);
+
+    fHistChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane] = new TH1D(Form("fHistChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons_pl%02d", iPlane),
+                                                                          Form("#chi^{2}/ndf at plane %d for BAD candidates of trackable muons",iPlane),
+                                                                          100, 0., 15.);
+
+  }
+  
+  //------------------------------------------
+  
+  fHistPtSpectrometer               -> Sumw2();
+  fHistPtMuonTrackWithGoodMatch     -> Sumw2();
+  fHistPtMuonTrackWithBadMatch      -> Sumw2();
+  fHistRadiusEndOfAbsorber          -> Sumw2();
+  fHistNGoodClustersForFinalTracks  -> Sumw2();
+
+  fHistDistanceGoodClusterFromTrackAtLastPlane                                  -> Sumw2();  
+  fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane -> Sumw2();  
+
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    
+    fHistNTracksAfterExtrapolation[iPlane] -> Sumw2();
+    fHistResearchRadius[iPlane]            -> Sumw2();
+    
+    fHistChi2Cluster_GoodCluster[iPlane]        -> Sumw2();
+    fHistChi2Cluster_BadCluster[iPlane]         -> Sumw2();
+
+    fHistChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] -> Sumw2();
+    fHistChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane]  -> Sumw2();
+    
+  }
+
+  fNtuFinalCandidates1     = new TNtuple("ntuFinalCandidates1",     "Final Candidates (ALL)", "run:event:muonTrack:nFinalCandidates:nClustersMC:nGoodClusters:ptSpectrometer:thetaSpectrometer:etaSpectrometer");
+
+  fNtuFinalBestCandidates1 = new TNtuple("ntuFinalBestCandidates1", "Final Best Candidates",  "run:event:muonTrack:nFinalCandidates:nClustersMC:nGoodClusters:ptSpectrometer:thetaSpectrometer:etaSpectrometer");
+
+  fNtuFinalCandidates2     = new TNtuple("ntuFinalCandidates2",     "Final Candidates (ALL)", "chi2AtPlane0:chi2AtPlane1:chi2AtPlane2:chi2AtPlane3:chi2AtPlane4:chi2AtPlane5:chi2AtPlane6:chi2AtPlane7:chi2AtPlane8:chi2AtPlane9:chi2AtPlane10:chi2AtPlane11:chi2AtPlane12:chi2AtPlane13:chi2AtPlane14");
+
+  fNtuFinalBestCandidates2 = new TNtuple("ntuFinalBestCandidates2", "Final Best Candidates",  "chi2AtPlane0:chi2AtPlane1:chi2AtPlane2:chi2AtPlane3:chi2AtPlane4:chi2AtPlane5:chi2AtPlane6:chi2AtPlane7:chi2AtPlane8:chi2AtPlane9:chi2AtPlane10:chi2AtPlane11:chi2AtPlane12:chi2AtPlane13:chi2AtPlane14");
+
+}
+
+//============================================================================================================================================
+
+void AliMuonForwardTrackFinder::SetTitleHistos() {
+
+  fHistPtSpectrometer              -> SetXTitle("p_{T}  [GeV/c]");
+  fHistPtMuonTrackWithGoodMatch    -> SetXTitle("p_{T}  [GeV/c]");
+  fHistPtMuonTrackWithBadMatch     -> SetXTitle("p_{T}  [GeV/c]");
+  fHistRadiusEndOfAbsorber         -> SetXTitle("R_{abs}  [cm]");
+  fHistNGoodClustersForFinalTracks -> SetXTitle("N_{GoodClusters}");
+
+  fHistDistanceGoodClusterFromTrackAtLastPlane                                  -> SetXTitle("Distance  [cm]");  
+  fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane -> SetXTitle("Distance  [cm]");  
+
+
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    
+    fHistNTracksAfterExtrapolation[iPlane] -> SetXTitle("N_{tracks}");
+    fHistResearchRadius[iPlane]            -> SetXTitle("Research Radius  [cm]");
+    
+    fHistChi2Cluster_GoodCluster[iPlane]         -> SetXTitle("#chi^{2}/ndf");
+    fHistChi2Cluster_BadCluster[iPlane]          -> SetXTitle("#chi^{2}/ndf");
+
+    fHistChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] -> SetXTitle("#chi^{2}/ndf");
+    fHistChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane]  -> SetXTitle("#chi^{2}/ndf");
+    
+  }
+
+}
+
+//===========================================================================================================================================
+
+void AliMuonForwardTrackFinder::BookPlanes() {
+
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    fGrMFTPlane[iPlane][kAllClusters] = new TGraph();
+    fGrMFTPlane[iPlane][kAllClusters] -> SetName(Form("fGrMFTPlane_%02d_AllClusters",iPlane));
+    fGrMFTPlane[iPlane][kAllClusters] -> SetMarkerStyle(20);
+    //    fGrMFTPlane[iPlane][kAllClusters] -> SetMarkerSize(0.5);
+    //    fGrMFTPlane[iPlane][kAllClusters] -> SetMarkerSize(0.3);
+    fGrMFTPlane[iPlane][kAllClusters] -> SetMarkerSize(0.2);
+  }
+
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    fGrMFTPlane[iPlane][kClustersGoodChi2] = new TGraph();
+    fGrMFTPlane[iPlane][kClustersGoodChi2] -> SetName(Form("fGrMFTPlane_%02d_ClustersGoodChi2",iPlane));
+    fGrMFTPlane[iPlane][kClustersGoodChi2] -> SetMarkerStyle(20);
+    //    fGrMFTPlane[iPlane][kClustersGoodChi2] -> SetMarkerSize(0.8);
+    //    fGrMFTPlane[iPlane][kClustersGoodChi2] -> SetMarkerSize(0.4);
+    fGrMFTPlane[iPlane][kClustersGoodChi2] -> SetMarkerSize(0.3);
+    fGrMFTPlane[iPlane][kClustersGoodChi2] -> SetMarkerColor(kBlue);
+  }
+
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    fGrMFTPlane[iPlane][kClusterOfTrack] = new TGraph();
+    fGrMFTPlane[iPlane][kClusterOfTrack] -> SetName(Form("fGrMFTPlane_%02d_ClustersOfTrack",iPlane));
+    fGrMFTPlane[iPlane][kClusterOfTrack] -> SetMarkerStyle(25);
+    //    fGrMFTPlane[iPlane][kClusterOfTrack] -> SetMarkerSize(1.2);
+    fGrMFTPlane[iPlane][kClusterOfTrack] -> SetMarkerSize(0.9);
+    fGrMFTPlane[iPlane][kClusterOfTrack] -> SetMarkerColor(kRed);
+    fGrMFTPlane[iPlane][kClusterOfTrack] -> SetTitle(Form("Plane %d (%3.1f cm)", iPlane, fZPlane[iPlane]));
+  }
+
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    fGrMFTPlane[iPlane][kClusterCorrectMC] = new TGraph();
+    fGrMFTPlane[iPlane][kClusterCorrectMC] -> SetName(Form("fGrMFTPlane_%02d_ClustersCorrectMC",iPlane));
+    fGrMFTPlane[iPlane][kClusterCorrectMC] -> SetMarkerStyle(20);
+    //    fGrMFTPlane[iPlane][kClusterCorrectMC] -> SetMarkerSize(0.8);
+    fGrMFTPlane[iPlane][kClusterCorrectMC] -> SetMarkerSize(0.5);
+    fGrMFTPlane[iPlane][kClusterCorrectMC] -> SetMarkerColor(kGreen);
+  }
+
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    fCircleExt[iPlane] = new TEllipse(0., 0., fRPlaneMax[iPlane], fRPlaneMax[iPlane]);
+    fCircleInt[iPlane] = new TEllipse(0., 0., fRPlaneMin[iPlane], fRPlaneMin[iPlane]);
+  }
+  
+  fTxtDummy = new TLatex(0.10, 0.67, "Best Candidate:");
+
+  //---------------------------------------------------
+
+  fMrkAllClust = new TMarker(0.10, 0.32, 20);
+  fMrkAllClust -> SetMarkerSize(0.5);
+
+  fMrkClustGoodChi2 = new TMarker(0.10, 0.26, 20);
+  fMrkClustGoodChi2 -> SetMarkerSize(0.8);
+  fMrkClustGoodChi2 -> SetMarkerColor(kBlue);
+
+  fMrkClustMC = new TMarker(0.10, 0.20, 20);
+  fMrkClustMC -> SetMarkerSize(0.8);
+  fMrkClustMC -> SetMarkerColor(kGreen);
+
+  fMrkClustOfTrack = new TMarker(0.10, 0.14, 25);
+  fMrkClustOfTrack -> SetMarkerSize(1.2);
+  fMrkClustOfTrack -> SetMarkerColor(kRed);
+
+  fTxtAllClust = new TLatex(0.15, 0.30, "All Clusters");
+  fTxtAllClust -> SetTextSize(0.040);
+
+  fTxtClustGoodChi2 = new TLatex(0.15, 0.24, "Clusters involved in the research");
+  fTxtClustGoodChi2 -> SetTextSize(0.040);
+
+  fTxtClustMC = new TLatex(0.15, 0.18, "MC good clusters");
+  fTxtClustMC -> SetTextSize(0.040);
+
+  fTxtClustOfTrack = new TLatex(0.15, 0.12, "Clusters of the best candidate");
+  fTxtClustOfTrack -> SetTextSize(0.040);
+
+}
+
+//===========================================================================================================================================
+
+void AliMuonForwardTrackFinder::ResetPlanes() {
+
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    for (Int_t iGr=0; iGr<4; iGr++) {
+      Int_t nOldClusters = fGrMFTPlane[iPlane][iGr]->GetN();
+      for (Int_t iPoint=nOldClusters-1; iPoint>=0; iPoint--) fGrMFTPlane[iPlane][iGr]->RemovePoint(iPoint);
+    }
+  }
+
+}
+
+//===========================================================================================================================================
+
+void AliMuonForwardTrackFinder::PrintParticleHistory() {
+
+  TString history = "";
+  
+  TParticle *part = fStack->Particle(fLabelMC);
+  
+  if (part->GetFirstMother() != -1) {
+    TParticle *partMother = fStack->Particle(part->GetFirstMother());
+    if (partMother->GetFirstMother() != -1) history += "...  #rightarrow ";
+    Char_t newName[100];
+    PDGNameConverter(partMother->GetName(), newName);
+    history += Form("%s #rightarrow ", newName);
+  }
+  Char_t newName[100];
+  PDGNameConverter(part->GetName(), newName);
+  history += Form("%s  at  z = %5.1f cm", newName, part->Vz());
+  
+  //  printf("%s", history.Data());
+  
+  fTxtMuonHistory = new TLatex(0.10, 0.86, history.Data());
+  
+}
+
+//===========================================================================================================================================
+
+Bool_t AliMuonForwardTrackFinder::IsMother(Char_t *nameMother) {
+  
+  Bool_t result = kFALSE;
+  
+  TParticle *part = fStack->Particle(fLabelMC);
+  
+  if (part->GetFirstMother() != -1) {
+    TParticle *partMother = fStack->Particle(part->GetFirstMother());
+    if (!strcmp(partMother->GetName(), nameMother)) result=kTRUE;
+  }
+
+  return result;
+
+}
+
+//===========================================================================================================================================
+
+void AliMuonForwardTrackFinder::DrawPlanes() {
+
+  fCanvas -> Clear();
+  if (fNPlanesMFT <= 5)       fCanvas -> Divide(3,2);
+  else if (fNPlanesMFT <= 11) fCanvas -> Divide(4,3);
+  else if (fNPlanesMFT <= 19) fCanvas -> Divide(5,4);
+
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    
+    fCanvas->cd(fNPlanesMFT-iPlane+1);
+    
+    fGrMFTPlane[iPlane][kClusterOfTrack] -> GetXaxis() -> SetLimits(-1.1*fRPlaneMax[fNPlanesMFT-1], +1.1*fRPlaneMax[fNPlanesMFT-1]);
+    fGrMFTPlane[iPlane][kClusterOfTrack] -> GetYaxis() -> SetRangeUser(-1.1*fRPlaneMax[fNPlanesMFT-1], +1.1*fRPlaneMax[fNPlanesMFT-1]);
+    fGrMFTPlane[iPlane][kClusterOfTrack] -> GetXaxis() -> SetTitle("X  [cm]");
+    fGrMFTPlane[iPlane][kClusterOfTrack] -> GetYaxis() -> SetTitle("Y  [cm]");
+    fGrMFTPlane[iPlane][kClusterOfTrack] -> Draw("ap");
+
+    fCircleExt[iPlane] -> Draw("same");
+    fCircleInt[iPlane] -> Draw("same");
+    
+    if (fGrMFTPlane[iPlane][kAllClusters]->GetN())       fGrMFTPlane[iPlane][kAllClusters]      -> Draw("psame");
+    if (fGrMFTPlane[iPlane][kClustersGoodChi2]->GetN())  fGrMFTPlane[iPlane][kClustersGoodChi2] -> Draw("psame");
+    if (fGrMFTPlane[iPlane][kClusterOfTrack]->GetN())    fGrMFTPlane[iPlane][kClusterOfTrack]   -> Draw("psame");
+    if (fGrMFTPlane[iPlane][kClusterCorrectMC]->GetN())  fGrMFTPlane[iPlane][kClusterCorrectMC] -> Draw("psame");
+
+    fTxtTrackChi2[iPlane] -> Draw("same");
+
+  }
+
+  fCanvas -> cd(1);
+  fTxtMuonHistory       -> Draw();
+  fTxtDummy             -> Draw("same");
+  fTxtTrackGoodClusters -> Draw("same");
+  fTxtTrackFinalChi2    -> Draw("same");
+  fTxtFinalCandidates   -> Draw("same");
+
+  fMrkAllClust      -> Draw("same");
+  fMrkClustGoodChi2 -> Draw("same");
+  fMrkClustMC       -> Draw("same");
+  fMrkClustOfTrack  -> Draw("same");
+
+  fTxtAllClust      -> Draw("same");
+  fTxtClustGoodChi2 -> Draw("same");
+  fTxtClustMC       -> Draw("same");
+  fTxtClustOfTrack  -> Draw("same");
+
+  //  fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.eps", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
+  fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.gif", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
+  if (IsMother("phi")) {
+    fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.phi.gif", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
+    fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.phi.eps", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
+  }
+  if (IsMother("J/psi")) {
+    fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.jPsi.gif", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
+    fCanvas -> SaveAs(Form("%s/figures/eventDisplay/run%d_event%d_track%d.jPsi.eps", fOutDir.Data(), fRun, fEv, fCountRealTracksAnalyzedOfEvent));
+  }
+    
+}
+
+//===========================================================================================================================================
+
+void AliMuonForwardTrackFinder::Terminate() {
+  
+  printf("\n");
+  printf("---------------------------------------------------------------------------------------------------------------\n");
+  printf("%8d  tracks analyzed\n",                                                     fCountRealTracksAnalyzed);
+  printf("%8d  tracks with MC ref\n",                                                  fCountRealTracksWithRefMC);
+  printf("%8d  tracks with MC ref & trigger match\n",                                  fCountRealTracksWithRefMC_andTrigger);
+  printf("%8d  tracks analyzed with final candidates\n",                               fCountRealTracksAnalyzedWithFinalCandidates);
+//   printf("%8d  tracks with MC ref & trigger match & pt>%3.1f GeV/c\n",                 fCountRealTracksWithRefMC_andTrigger_andGoodPt, fLowPtCut);
+//   printf("%8d  tracks with MC ref & trigger match & pt>%3.1f GeV/c & correct R_abs\n", fCountRealTracksWithRefMC_andTrigger_andGoodPt_andGoodTheta, fLowPtCut);
+  printf("---------------------------------------------------------------------------------------------------------------\n");
+
+  WriteOutputTree();
+  WriteHistos();
+
+}
+
+//==========================================================================================================================================
+
+void AliMuonForwardTrackFinder::FillOutputTree() {
+
+  if (!fMuonForwardTracks || !fOutputEventTree) return;
+
+  AliDebug(1, Form("Filling output tree %p with %p having %d entries whose 1st entry is %p", 
+                  fOutputEventTree, fMuonForwardTracks, fMuonForwardTracks->GetEntries(), fMuonForwardTracks->At(0)));
+  
+  fOutputEventTree->Fill();
+  AliDebug(1, Form("\n\nFilled Tree: nEvents = %d!!!!\n\n", Int_t(fOutputEventTree->GetEntries())));
+
+}
+
+//==========================================================================================================================================
+
+void AliMuonForwardTrackFinder::WriteOutputTree() {
+
+  if (!fOutputEventTree || !fOutputTreeFile) return;
+
+  fOutputTreeFile -> cd();
+
+  fOutputEventTree -> Write();
+  fOutputTreeFile -> Close();
+
+}
+
+//==========================================================================================================================================
+
+void AliMuonForwardTrackFinder::WriteHistos() {
+
+  TFile *fileOut = new TFile(Form("%s/MuonGlobalTracking.QA.run%d.root", fOutDir.Data(), fRun), "recreate");
+
+  fHistPtSpectrometer              -> Write();
+  fHistPtMuonTrackWithGoodMatch    -> Write();
+  fHistPtMuonTrackWithBadMatch     -> Write();
+  fHistRadiusEndOfAbsorber         -> Write();
+  fHistNGoodClustersForFinalTracks -> Write();
+
+  fHistDistanceGoodClusterFromTrackAtLastPlane                                  -> Write();  
+  fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane -> Write();  
+
+  for (Int_t iPlane=0; iPlane<fNPlanesMFT; iPlane++) {
+    
+    fHistNTracksAfterExtrapolation[iPlane] -> Write();
+    fHistResearchRadius[iPlane]            -> Write();
+    
+    fHistChi2Cluster_GoodCluster[iPlane]   -> Write();
+    fHistChi2Cluster_BadCluster[iPlane]    -> Write();
+    
+    fHistChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[iPlane] -> Write();
+    fHistChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[iPlane]  -> Write();
+
+  }
+
+  fNtuFinalCandidates1     -> Write();
+  fNtuFinalBestCandidates1 -> Write();
+  fNtuFinalCandidates2     -> Write();
+  fNtuFinalBestCandidates2 -> Write();
+
+  fileOut -> Close();
+
+}
+
+//===========================================================================================================================================
+
+void AliMuonForwardTrackFinder::PDGNameConverter(const Char_t *nameIn, Char_t *nameOut) {
+
+  if      (!strcmp(nameIn, "mu+"))     sprintf(nameOut, "#mu^{+}");
+  else if (!strcmp(nameIn, "mu-"))     sprintf(nameOut, "#mu^{-}");
+  else if (!strcmp(nameIn, "pi+"))     sprintf(nameOut, "#pi^{+}");
+  else if (!strcmp(nameIn, "pi-"))     sprintf(nameOut, "#pi^{-}");
+  else if (!strcmp(nameIn, "K+"))      sprintf(nameOut, "K^{+}");
+  else if (!strcmp(nameIn, "K-"))      sprintf(nameOut, "K^{-}");
+  else if (!strcmp(nameIn, "K*+"))     sprintf(nameOut, "K^{*+}");
+  else if (!strcmp(nameIn, "K*-"))     sprintf(nameOut, "K^{*-}");
+  else if (!strcmp(nameIn, "K_S0"))    sprintf(nameOut, "K_{S}^{0}");
+  else if (!strcmp(nameIn, "K_L0"))    sprintf(nameOut, "K_{L}^{0}");
+  else if (!strcmp(nameIn, "K0"))      sprintf(nameOut, "K^{0}");
+  else if (!strcmp(nameIn, "K0_bar"))  sprintf(nameOut, "#bar{K}^{0}");
+  else if (!strcmp(nameIn, "K*0"))     sprintf(nameOut, "K^{*0}");
+  else if (!strcmp(nameIn, "K*0_bar")) sprintf(nameOut, "#bar{K}^{*0}");
+  else if (!strcmp(nameIn, "rho0"))    sprintf(nameOut, "#rho^{0}");
+  else if (!strcmp(nameIn, "rho+"))    sprintf(nameOut, "#rho^{+}");
+  else if (!strcmp(nameIn, "rho-"))    sprintf(nameOut, "#rho^{-}");
+  else if (!strcmp(nameIn, "omega"))   sprintf(nameOut, "#omega");
+  else if (!strcmp(nameIn, "eta'"))    sprintf(nameOut, "#eta'");
+  else if (!strcmp(nameIn, "phi"))     sprintf(nameOut, "#phi");
+
+  else if (!strcmp(nameIn, "D-"))     sprintf(nameOut, "D^{-}");
+  else if (!strcmp(nameIn, "D+"))     sprintf(nameOut, "D^{+}");
+  else if (!strcmp(nameIn, "D0"))     sprintf(nameOut, "D^{0}");
+  else if (!strcmp(nameIn, "D0_bar")) sprintf(nameOut, "#bar{D}^{0}");
+  else if (!strcmp(nameIn, "D*-"))    sprintf(nameOut, "D^{*-}");
+  else if (!strcmp(nameIn, "D*+"))    sprintf(nameOut, "D^{*+}");
+  else if (!strcmp(nameIn, "D_s+"))   sprintf(nameOut, "D_{s}^{+}");
+  else if (!strcmp(nameIn, "D*_s+"))  sprintf(nameOut, "D_{s}^{*+}");
+
+  else if (!strcmp(nameIn, "B-"))       sprintf(nameOut, "B^{-}");
+  else if (!strcmp(nameIn, "B+"))       sprintf(nameOut, "B^{+}");
+  else if (!strcmp(nameIn, "B_s0_bar")) sprintf(nameOut, "#bar{B}_{s}^{0}");
+
+  else if (!strcmp(nameIn, "antiproton"))  sprintf(nameOut, "#bar{p}");
+  else if (!strcmp(nameIn, "proton"))      sprintf(nameOut, "p");
+  else if (!strcmp(nameIn, "neutron"))     sprintf(nameOut, "n");
+  else if (!strcmp(nameIn, "Sigma+"))      sprintf(nameOut, "#Sigma^{+}");
+  else if (!strcmp(nameIn, "Delta+"))      sprintf(nameOut, "#Delta{+}");
+  else if (!strcmp(nameIn, "Delta--"))     sprintf(nameOut, "#Delta{--}");
+  else if (!strcmp(nameIn, "Lambda0"))     sprintf(nameOut, "#Lambda_0");
+  else if (!strcmp(nameIn, "Lambda0_bar")) sprintf(nameOut, "#bar{Lambda}_0");
+
+  else sprintf(nameOut, "%s", nameIn);
+
+}
+
+//===========================================================================================================================================
+
+void AliMuonForwardTrackFinder::SetDraw(Bool_t drawOption) { 
+
+  fDrawOption = drawOption;
+
+  if (!fCanvas) {
+    fCanvas = new TCanvas("tracking", "tracking", 1200, 800);
+    fCanvas -> Divide(3,2);
+  }
+
+}
+
+//===========================================================================================================================================
+
+Bool_t AliMuonForwardTrackFinder::InitGRP() {
+
+  //------------------------------------
+  // Initialization of the GRP entry 
+  //------------------------------------
+
+  AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/Data");
+
+  if (entry) {
+
+    TMap* m = dynamic_cast<TMap*>(entry->GetObject());  // old GRP entry
+
+    if (m) {
+       AliInfo("Found a TMap in GRP/GRP/Data, converting it into an AliGRPObject");
+       m->Print();
+       fGRPData = new AliGRPObject();
+       fGRPData->ReadValuesFromMap(m);
+    }
+
+    else {
+       AliInfo("Found an AliGRPObject in GRP/GRP/Data, reading it");
+       fGRPData = dynamic_cast<AliGRPObject*>(entry->GetObject());  // new GRP entry
+       entry->SetOwner(0);
+    }
+
+    //    FIX ME: The unloading of GRP entry is temporarily disabled
+    //    because ZDC and VZERO are using it in order to initialize
+    //    their reconstructor objects. In the future one has to think
+    //    of propagating AliRunInfo to the reconstructors.
+    //    AliCDBManager::Instance()->UnloadFromCache("GRP/GRP/Data");
+  }
+
+  if (!fGRPData) {
+     AliError("No GRP entry found in OCDB!");
+     return kFALSE;
+  }
+
+  TString lhcState = fGRPData->GetLHCState();
+  if (lhcState==AliGRPObject::GetInvalidString()) {
+    AliError("GRP/GRP/Data entry:  missing value for the LHC state ! Using UNKNOWN");
+    lhcState = "UNKNOWN";
+  }
+
+  TString beamType = fGRPData->GetBeamType();
+  if (beamType==AliGRPObject::GetInvalidString()) {
+    AliError("GRP/GRP/Data entry:  missing value for the beam type ! Using UNKNOWN");
+    beamType = "UNKNOWN";
+  }
+
+  Float_t beamEnergy = fGRPData->GetBeamEnergy();
+  if (beamEnergy==AliGRPObject::GetInvalidFloat()) {
+    AliError("GRP/GRP/Data entry:  missing value for the beam energy ! Using 0");
+    beamEnergy = 0;
+  }
+
+  TString runType = fGRPData->GetRunType();
+  if (runType==AliGRPObject::GetInvalidString()) {
+    AliError("GRP/GRP/Data entry:  missing value for the run type ! Using UNKNOWN");
+    runType = "UNKNOWN";
+  }
+
+  Int_t activeDetectors = fGRPData->GetDetectorMask();
+  if (activeDetectors==AliGRPObject::GetInvalidUInt()) {
+    AliError("GRP/GRP/Data entry:  missing value for the detector mask ! Using 1074790399");
+    activeDetectors = 1074790399;
+  }
+  AliDebug(1, Form("activeDetectors = %d", activeDetectors));
+
+  fRunInfo = new AliRunInfo(lhcState, beamType, beamEnergy, runType, activeDetectors);
+  fRunInfo->Dump();
+
+  // *** Dealing with the magnetic field map
+
+  if ( TGeoGlobalMagField::Instance()->IsLocked() ) {
+    if (TGeoGlobalMagField::Instance()->GetField()->TestBit(AliMagF::kOverrideGRP)) {
+      AliInfo("ExpertMode!!! GRP information will be ignored !");
+      AliInfo("ExpertMode!!! Running with the externally locked B field !");
+    }
+    else {
+      AliInfo("Destroying existing B field instance!");
+      delete TGeoGlobalMagField::Instance();
+    }    
+  }
+  if ( !TGeoGlobalMagField::Instance()->IsLocked() ) {
+    // Construct the field map out of the information retrieved from GRP.
+    Bool_t ok = kTRUE;
+    // L3
+    Float_t l3Current = fGRPData->GetL3Current((AliGRPObject::Stats)0);
+    if (l3Current == AliGRPObject::GetInvalidFloat()) {
+      AliError("GRP/GRP/Data entry:  missing value for the L3 current !");
+      ok = kFALSE;
+    }
+    
+    Char_t l3Polarity = fGRPData->GetL3Polarity();
+    if (l3Polarity == AliGRPObject::GetInvalidChar()) {
+      AliError("GRP/GRP/Data entry:  missing value for the L3 polarity !");
+      ok = kFALSE;
+    }
+
+    // Dipole
+    Float_t diCurrent = fGRPData->GetDipoleCurrent((AliGRPObject::Stats)0);
+    if (diCurrent == AliGRPObject::GetInvalidFloat()) {
+      AliError("GRP/GRP/Data entry:  missing value for the dipole current !");
+      ok = kFALSE;
+    }
+
+    Char_t diPolarity = fGRPData->GetDipolePolarity();
+    if (diPolarity == AliGRPObject::GetInvalidChar()) {
+      AliError("GRP/GRP/Data entry:  missing value for the dipole polarity !");
+      ok = kFALSE;
+    }
+
+    // read special bits for the polarity convention and map type
+    Int_t  polConvention = fGRPData->IsPolarityConventionLHC() ? AliMagF::kConvLHC : AliMagF::kConvDCS2008;
+    Bool_t uniformB = fGRPData->IsUniformBMap();
+
+    if (ok) { 
+      AliMagF* fld = AliMagF::CreateFieldMap(TMath::Abs(l3Current) * (l3Polarity ? -1:1), 
+                                            TMath::Abs(diCurrent) * (diPolarity ? -1:1), 
+                                            polConvention,uniformB,beamEnergy, beamType.Data());
+      if (fld) {
+       TGeoGlobalMagField::Instance()->SetField( fld );
+       TGeoGlobalMagField::Instance()->Lock();
+       AliInfo("Running with the B field constructed out of GRP !");
+      }
+      else AliFatal("Failed to create a B field map !");
+    }
+    else AliFatal("B field is neither set nor constructed from GRP ! Exitig...");
+  }
+  
+  return kTRUE;
+} 
+
+//====================================================================================================================================================
+
+Bool_t AliMuonForwardTrackFinder::SetRunNumber() {
+
+  AliCDBManager *man = AliCDBManager::Instance();
+
+  if (!fRunLoader) {
+    AliError("No run loader found!");
+    return kFALSE;
+  }
+  else {
+    fRunLoader->LoadHeader();
+    // read run number from gAlice
+    if (fRunLoader->GetHeader()) {
+      man->SetRun(fRunLoader->GetHeader()->GetRun());
+      fRunLoader->UnloadHeader();
+    }
+    else {
+      AliError("No run-loader header found!");
+      return kFALSE;
+    }
+  }
+
+  return kTRUE;
+
+}
+
+//====================================================================================================================================================
+
diff --git a/MFT/AliMuonForwardTrackFinder.h b/MFT/AliMuonForwardTrackFinder.h
new file mode 100644 (file)
index 0000000..7089479
--- /dev/null
@@ -0,0 +1,263 @@
+#ifndef AliMuonForwardTrackFinder_H
+#define AliMuonForwardTrackFinder_H
+
+// ROOT includes
+#include "TObject.h"
+#include "TClonesArray.h"
+#include "TH2D.h"
+#include "TH1D.h"
+#include "TFile.h"
+#include "TGeoManager.h"
+#include "TMatrixD.h"
+#include "TParticle.h"
+#include "TMath.h"
+#include "TGraph.h"
+#include "TEllipse.h"
+#include "TCanvas.h"
+#include "TString.h"
+#include "TLatex.h"
+#include "TMarker.h"
+#include "TNtuple.h"
+#include "TRandom.h"
+#include "TIterator.h"
+
+// STEER includes
+#include "AliLog.h"
+#include "AliRun.h"
+#include "AliRunLoader.h"
+#include "AliLoader.h"
+#include "AliHeader.h"
+#include "AliMC.h"
+#include "AliStack.h"
+#include "AliMagF.h"
+#include "AliTracker.h"
+#include "AliGRPObject.h"
+#include "AliRunInfo.h"
+
+// MUON includes
+#include "AliMUONConstants.h"
+#include "AliMUONTrack.h"
+#include "AliMUONRecoCheck.h"
+#include "AliMUONTrackParam.h"
+#include "AliMUONTrackExtrap.h"
+#include "AliMUONVTrackStore.h"
+#include "AliMUONVCluster.h"
+
+// MFT includes
+#include "AliMuonForwardTrack.h"
+#include "AliMFTCluster.h"
+#include "AliMFT.h"
+#include "AliMFTSegmentation.h"
+
+//====================================================================================================================================================
+//
+// Class for the creation of the "global muon tracks" built from the clusters in the 
+// muon spectrometer and the clusters of the Muon Forward Tracker. QA histograms are also created
+//
+// Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+class AliMuonForwardTrackFinder : public TObject {
+  
+public:
+
+  enum matchingOption {kRealMatching, kIdealMatching};
+
+  AliMuonForwardTrackFinder();
+  
+  virtual ~AliMuonForwardTrackFinder() {;}
+  
+  enum {kAllClusters, kClustersGoodChi2, kClusterOfTrack, kClusterCorrectMC};
+
+  void Init(Int_t nRun, Char_t *readDir, Char_t *outDir, Int_t nEventsToAnalyze = -1);
+  Bool_t LoadNextEvent();
+  Int_t LoadNextTrack();
+  Int_t GetNDF(Int_t nClusters);
+  void PDGNameConverter(const Char_t *nameIn, Char_t *nameOut);
+  void DrawPlanes();
+  void Terminate();
+  void WriteHistos();
+
+  void SetRun(Int_t nRun) { fRun = nRun; }
+  void SetNEventsToAnalyze(Int_t nEventsToAnalyze) { fNEventsToAnalyze = nEventsToAnalyze; }
+  void SetSigmaSpectrometerCut(Double_t sigmaSpectrometerCut) { fSigmaSpectrometerCut = sigmaSpectrometerCut; }
+  void SetSigmaClusterCut(Double_t sigmaClusterCut) { fSigmaClusterCut = sigmaClusterCut; }
+  void SetChi2GlobalCut(Double_t chi2GlobalCut) { fChi2GlobalCut = chi2GlobalCut; }
+  void SetReadDir(Char_t *dirName) { fReadDir = dirName; }
+  void SetOutDir(Char_t *dirName) { fOutDir = dirName; }
+  void SetDraw(Bool_t drawOption);
+  void SetRAbsorberCut(Double_t rAbsorberCut) { fRAbsorberCut = rAbsorberCut; }
+  void SetLowPtCut(Double_t lowPtCut) { fLowPtCut = lowPtCut; }
+  void SetNFinalCandidatesCut(Int_t nFinalCandidatesCut) { fNFinalCandidatesCut = nFinalCandidatesCut; }
+  void SetExtrapOriginTransvError(Double_t extrapOriginTransvError) { fExtrapOriginTransvError = extrapOriginTransvError; }
+  void SetGaussianBlurZVert(Double_t gaussianBlurZVert) { fGaussianBlurZVert = gaussianBlurZVert; }
+
+  Int_t GetRun() { return fRun; }
+  Int_t GetNEvents() { return fNEventsToAnalyze; }
+  Double_t GetSigmaSpectrometerCut() { return fSigmaSpectrometerCut; }
+  Double_t GetSigmaClusterCut() { return fSigmaClusterCut; }
+  Double_t GetChi2GlobalCut() { return fChi2GlobalCut; }
+  Double_t GetRAbsorberCut() { return fRAbsorberCut; }
+  Double_t GetLowPtCut() { return fLowPtCut; }
+  Double_t GetExtrapOriginTransvError() { return fExtrapOriginTransvError; }
+  Int_t GetNPlanesMFT() { return fNPlanesMFT; }
+  Int_t GetNFinalCandidatesCut() { return fNFinalCandidatesCut; }
+  Int_t GetCurrentEvent() { return fEv; }
+
+  Int_t GetNRealTracksAnalyzed() const { return fCountRealTracksAnalyzed; }
+  Int_t GetNRealTracksAnalyzedOfEvent() const { return fCountRealTracksAnalyzedOfEvent; }
+  Int_t GetNRealTracksWithRefMC() const { return fCountRealTracksWithRefMC; }
+  Int_t GetNRealTracksWithRefMC_andTrigger() const { return fCountRealTracksWithRefMC_andTrigger; }
+  Int_t GetNRealTracksWithRefMC_andTrigger_andGoodPt() const { return fCountRealTracksWithRefMC_andTrigger_andGoodPt; }
+  Int_t GetNRealTracksWithRefMC_andTrigger_andGoodPt_andGoodTheta() const { return fCountRealTracksWithRefMC_andTrigger_andGoodPt_andGoodTheta; }
+
+  void SetNPlanesMFT(Int_t nPlanesMFT) { fNPlanesMFT = nPlanesMFT; }
+  void SeparateFrontBackClusters();
+  void SetNMaxMissingMFTClusters(Int_t nMaxMissingMFTClusters) { fNMaxMissingMFTClusters = nMaxMissingMFTClusters; }
+  void SetMandatoryPlane(Int_t iPlane) { if (0<=iPlane && iPlane<fMaxNPlanesMFT) fIsPlaneMandatory[iPlane] = kTRUE; }
+
+  void FindClusterInPlane(Int_t planeId);
+  void AttachGoodClusterInPlane(Int_t planeId);
+  void FillPlanesWithTrackHistory(AliMuonForwardTrack *track);
+  Double_t TryOneCluster(const AliMUONTrackParam &trackParam, AliMFTCluster *cluster);
+  void BookHistos();
+  void SetTitleHistos();
+  void BookPlanes();
+  void ResetPlanes();
+  void PrintParticleHistory();
+
+  Bool_t IsCorrectMatch(AliMFTCluster *cluster);
+  void CheckCurrentMuonTrackable();
+  Bool_t IsMother(Char_t *nameMother);
+
+  void SetMatchingMode(Int_t matchingMode) { fMatchingMode = matchingMode; }
+  void SetMinResearchRadiusAtLastPlane(Double_t minResearchRadius) { fMinResearchRadiusAtLastPlane = minResearchRadius; }
+
+  void FillOutputTree();
+  void WriteOutputTree();
+
+  Bool_t InitGRP();
+  Bool_t SetRunNumber();
+
+private:
+
+  AliMuonForwardTrackFinder(const AliMuonForwardTrackFinder& obj);
+  AliMuonForwardTrackFinder& operator=(const AliMuonForwardTrackFinder& other);
+
+protected:
+
+  static const Int_t fMaxNPlanesMFT = 20;
+  static const Double_t radLengthSi = 9.37;  // expressed in cm
+  
+  Int_t fRun; 
+  Int_t fNEventsToAnalyze;           // events to analyze
+  Double_t fSigmaClusterCut;         // to select the clusters in the MFT planes which are compatible with the extrapolated muon track
+  Double_t fChi2GlobalCut;           // cut on the final chi2 of the global muon track
+  Double_t fSigmaSpectrometerCut;    // for the selection of the tracks in the muon spectrometer
+  Double_t fExtrapOriginTransvError; // uncertainty on the x and y position of the muon's origin
+  Double_t fGaussianBlurZVert;       // smearing of the z position of the vertex, to simulate real case when the simulation was performed at fixed zVert=0.
+  Int_t fNFinalCandidatesCut;        // cut on the number of the final candidates for the muon track
+  TString fReadDir;
+  TString fOutDir;
+  Bool_t fDrawOption;
+
+  Double_t fDistanceFromGoodClusterAndTrackAtLastPlane;
+  Double_t fDistanceFromBestClusterAndTrackAtLastPlane;
+
+  TClonesArray *fMFTClusterArray[fMaxNPlanesMFT];         // array of clusters for the planes of the MFT
+  TClonesArray *fMFTClusterArrayFront[fMaxNPlanesMFT];    // array of front clusters for the planes of the MFT
+  TClonesArray *fMFTClusterArrayBack[fMaxNPlanesMFT];     // array of back clusters for the planes of the MFT
+
+  Double_t fRAbsorberCut;  // in cm, corresponds to the radial position of a 3 degrees track at the end of the absorber (-503 cm)
+  Double_t fLowPtCut;      // in GeV/c, the lower limit for the pt of a track in the muon spectrometer
+  Int_t fNPlanesMFT;              // number of planes of the Vertex Telescope (Muon Internal Tracker) -> This should be taken from the new version of  AliVZERO2
+  Int_t fNPlanesMFTAnalyzed;
+  Int_t fNMaxMissingMFTClusters;  // max. number of MFT clusters which can be missed in the global fit procedure
+  Bool_t fIsPlaneMandatory[fMaxNPlanesMFT];    // specifies which MFT planes cannot be missed in the global fit procedure
+
+  Int_t fEv;               // current event being analyzed
+  Int_t fLabelMC;          // MC label of the muon track reconstructed in the spectrometer
+
+  Bool_t fIsClusterCompatible[10];       // here the clusters in the Muon Spectrometer are concerned
+
+  Double_t fZPlane[fMaxNPlanesMFT];        // z-position of the MFT planes (center of the support)
+  Double_t fRPlaneMax[fMaxNPlanesMFT];     // max radius of the MFT planes (the support)
+  Double_t fRPlaneMin[fMaxNPlanesMFT];     // min radius of the MFT planes (the support)
+
+  TH1D *fHistPtSpectrometer, *fHistPtMuonTrackWithGoodMatch, *fHistPtMuonTrackWithBadMatch;
+  TH1D *fHistRadiusEndOfAbsorber, *fHistNTracksAfterExtrapolation[fMaxNPlanesMFT];
+  TH1D *fHistNGoodClustersForFinalTracks, *fHistResearchRadius[fMaxNPlanesMFT];
+  TH1D *fHistDistanceGoodClusterFromTrackMinusDistanceBestClusterFromTrackAtLastPlane;
+  TH1D *fHistDistanceGoodClusterFromTrackAtLastPlane;
+  TH1D *fHistChi2Cluster_GoodCluster[fMaxNPlanesMFT], *fHistChi2Cluster_BadCluster[fMaxNPlanesMFT];
+  TH1D *fHistChi2AtPlaneFor_GOOD_CandidatesOfTrackableMuons[fMaxNPlanesMFT], *fHistChi2AtPlaneFor_BAD_CandidatesOfTrackableMuons[fMaxNPlanesMFT];
+
+  TNtuple *fNtuFinalCandidates1, *fNtuFinalBestCandidates1;
+  TNtuple *fNtuFinalCandidates2, *fNtuFinalBestCandidates2;
+
+  TGraph *fGrMFTPlane[fMaxNPlanesMFT][4];
+  TEllipse *fCircleExt[fMaxNPlanesMFT], *fCircleInt[fMaxNPlanesMFT];
+  TCanvas *fCanvas;
+
+  TLatex  *fTxtMuonHistory, *fTxtTrackGoodClusters, *fTxtTrackChi2[fMaxNPlanesMFT], *fTxtTrackFinalChi2, *fTxtFinalCandidates, *fTxtDummy;
+  TLatex  *fTxtAllClust, *fTxtClustGoodChi2, *fTxtClustMC, *fTxtClustOfTrack; 
+  TMarker *fMrkAllClust, *fMrkClustGoodChi2, *fMrkClustMC, *fMrkClustOfTrack;
+
+  Int_t fCountRealTracksAnalyzed; 
+  Int_t fCountRealTracksWithRefMC; 
+  Int_t fCountRealTracksWithRefMC_andTrigger;
+  Int_t fCountRealTracksWithRefMC_andTrigger_andGoodPt;
+  Int_t fCountRealTracksWithRefMC_andTrigger_andGoodPt_andGoodTheta;
+  Int_t fCountRealTracksAnalyzedOfEvent;
+  Int_t fCountRealTracksAnalyzedWithFinalCandidates;
+
+  Int_t fNClustersGlobalTrack[fMaxNPlanesMFT], fNDFGlobalTrack[fMaxNPlanesMFT];
+  
+  TFile *fFileCluster;
+  TFile *fFileESD;
+  TFile *fFile_gAlice;
+
+  AliRunLoader *fRunLoader;
+  AliLoader *fMFTLoader;
+  AliMUONRecoCheck *fMuonRecoCheck;
+
+  TTree *fMFTClusterTree;
+
+  AliMUONTrack *fMuonTrackReco;           // muon track being analyzed
+  AliMuonForwardTrack *fCurrentTrack;     // muon extrapolated track being tested
+  Bool_t fIsCurrentMuonTrackable;
+  Bool_t fIsGoodClusterInPlane[fMaxNPlanesMFT];
+
+  TClonesArray *fCandidateTracks;   // array of track we are going to build (starting from fMuonTrackReco)
+
+  AliMUONVTrackStore *fTrackStore;      // list of reconstructed MUON tracks 
+  AliMUONVTrackStore *fTrackRefStore;   // list of reconstructible MUON tracks
+  
+  TIterator *fNextTrack;   //! Iterator for reading the MUON tracks
+  
+  AliStack *fStack;
+
+  AliMFT *fMFT;
+  AliMFTSegmentation *fSegmentation;
+
+  TFile *fOutputTreeFile;
+  TTree *fOutputEventTree;
+
+  TClonesArray *fMuonForwardTracks;       // array of AliMuonForwardTrack
+
+  Int_t fMatchingMode;
+  Double_t fMinResearchRadiusAtLastPlane;
+
+  AliGRPObject *fGRPData;              // Data from the GRP/GRP/Data CDB folder
+  AliRunInfo *fRunInfo;
+
+  ClassDef(AliMuonForwardTrackFinder, 1); 
+
+};
+
+//======================================================================================================
+#endif
+
+
diff --git a/MFT/AliMuonForwardTrackPair.cxx b/MFT/AliMuonForwardTrackPair.cxx
new file mode 100644 (file)
index 0000000..ac23f1c
--- /dev/null
@@ -0,0 +1,232 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+//====================================================================================================================================================
+//
+//      Description of an ALICE muon forward track pair, i.e. a pair of AliMuonForwardTrack objects
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "AliLog.h"
+#include "AliMUONTrackParam.h"
+#include "TParticle.h"
+#include "AliMuonForwardTrack.h"
+#include "AliMUONTrackExtrap.h"
+#include "TClonesArray.h"
+#include "TDatabasePDG.h"
+#include "TLorentzVector.h"
+#include "TRandom.h"
+#include "AliMuonForwardTrackPair.h"
+
+ClassImp(AliMuonForwardTrackPair)
+
+//====================================================================================================================================================
+
+AliMuonForwardTrackPair::AliMuonForwardTrackPair():
+  TObject(),
+  fMuonForwardTracks(0)
+{
+
+  // default constructor
+
+  fMuonForwardTracks = new TClonesArray("AliMuonForwardTrack", 2);
+
+}
+
+//====================================================================================================================================================
+
+AliMuonForwardTrackPair::AliMuonForwardTrackPair(AliMuonForwardTrack *track0, AliMuonForwardTrack *track1):
+  TObject(),
+  fMuonForwardTracks(0)
+{
+
+  fMuonForwardTracks = new TClonesArray("AliMuonForwardTrack", 2);
+
+  new ((*fMuonForwardTracks)[0]) AliMuonForwardTrack(*track0);
+  new ((*fMuonForwardTracks)[1]) AliMuonForwardTrack(*track1);
+
+}
+
+//====================================================================================================================================================
+
+AliMuonForwardTrackPair::AliMuonForwardTrackPair(const AliMuonForwardTrackPair& trackPair): 
+  TObject(trackPair),
+  fMuonForwardTracks(trackPair.fMuonForwardTracks)
+{
+
+  // copy constructor
+  
+}
+
+//====================================================================================================================================================
+
+AliMuonForwardTrackPair& AliMuonForwardTrackPair::operator=(const AliMuonForwardTrackPair& trackPair) {
+
+  // Asignment operator
+
+  // check assignement to self
+  if (this == &trackPair) return *this;
+
+  // base class assignement
+  AliMuonForwardTrackPair::operator=(trackPair);
+  
+  // clear memory
+  Clear();
+  
+  fMuonForwardTracks = trackPair.fMuonForwardTracks;
+
+  return *this;
+
+}
+
+//====================================================================================================================================================
+
+void AliMuonForwardTrackPair::SetTrack(Int_t iTrack, AliMuonForwardTrack *track) {
+
+  if (iTrack==0 || iTrack==1) {
+    new ((*fMuonForwardTracks)[iTrack]) AliMuonForwardTrack(*track);
+  }
+
+}
+
+//====================================================================================================================================================
+
+Double_t AliMuonForwardTrackPair::GetWeightedOffset(Double_t x, Double_t y, Double_t z) {
+
+  Double_t weightedOffset[2]={0};
+
+  weightedOffset[0] = ((AliMuonForwardTrack*) fMuonForwardTracks->At(0))->GetWeightedOffset(x, y, z);
+  weightedOffset[1] = ((AliMuonForwardTrack*) fMuonForwardTracks->At(1))->GetWeightedOffset(x, y, z);
+
+  Double_t weightedOffsetDimuon = TMath::Sqrt(0.5 * (weightedOffset[0]*weightedOffset[0] + weightedOffset[1]*weightedOffset[1]));
+
+  return weightedOffsetDimuon;
+
+}
+
+//====================================================================================================================================================
+
+Double_t AliMuonForwardTrackPair::GetMass(Double_t z, Int_t nClusters) {
+
+  Int_t idCluster[2] = {0};
+  if (nClusters>0) {
+    idCluster[0] = ((AliMuonForwardTrack*) fMuonForwardTracks->At(0))->GetNMFTClusters() - nClusters;
+    idCluster[1] = ((AliMuonForwardTrack*) fMuonForwardTracks->At(1))->GetNMFTClusters() - nClusters;
+  }
+  if (idCluster[0]<0) idCluster[0] = 0;
+  if (idCluster[1]<0) idCluster[1] = 0;
+
+  Double_t momentum[2] = {0};
+  
+  AliMUONTrackParam *param0 = ((AliMuonForwardTrack*) fMuonForwardTracks->At(0))->GetTrackParamAtMFTCluster(idCluster[0]);
+  AliMUONTrackParam *param1 = ((AliMuonForwardTrack*) fMuonForwardTracks->At(1))->GetTrackParamAtMFTCluster(idCluster[1]);
+
+  if (TMath::Abs(z)<1e6) {
+    AliMUONTrackExtrap::ExtrapToZCov(param0, z);
+    AliMUONTrackExtrap::ExtrapToZCov(param1, z);
+  }
+
+  momentum[0] = (param0->P());
+  momentum[1] = (param1->P());
+
+  Double_t mMu = TDatabasePDG::Instance()->GetParticle("mu-")->Mass();
+
+  TLorentzVector dimu;
+
+  dimu.SetE(TMath::Sqrt(mMu*mMu + momentum[0]*momentum[0]) + TMath::Sqrt(mMu*mMu + momentum[1]*momentum[1]));
+
+  dimu.SetPx(((AliMuonForwardTrack*) fMuonForwardTracks->At(0))->GetTrackParamAtMFTCluster(idCluster[0])->Px()+
+            ((AliMuonForwardTrack*) fMuonForwardTracks->At(1))->GetTrackParamAtMFTCluster(idCluster[1])->Px());
+
+  dimu.SetPy(((AliMuonForwardTrack*) fMuonForwardTracks->At(0))->GetTrackParamAtMFTCluster(idCluster[0])->Py()+
+            ((AliMuonForwardTrack*) fMuonForwardTracks->At(1))->GetTrackParamAtMFTCluster(idCluster[1])->Py());
+
+  dimu.SetPz(((AliMuonForwardTrack*) fMuonForwardTracks->At(0))->GetTrackParamAtMFTCluster(idCluster[0])->Pz()+
+            ((AliMuonForwardTrack*) fMuonForwardTracks->At(1))->GetTrackParamAtMFTCluster(idCluster[1])->Pz());
+
+  return dimu.M();
+
+}
+
+//====================================================================================================================================================
+
+Double_t AliMuonForwardTrackPair::GetMassWithoutMFT(Double_t x, Double_t y, Double_t z, Int_t nClusters) {
+
+  Int_t idCluster[2] = {0};
+  if (nClusters>0) {
+    idCluster[0] = ((AliMuonForwardTrack*) fMuonForwardTracks->At(0))->GetNMUONClusters() - nClusters;
+    idCluster[1] = ((AliMuonForwardTrack*) fMuonForwardTracks->At(1))->GetNMUONClusters() - nClusters;
+  }
+  if (idCluster[0]<0) idCluster[0] = 0;
+  if (idCluster[1]<0) idCluster[1] = 0;
+
+  AliMUONTrackParam *param0 = ((AliMuonForwardTrack*) fMuonForwardTracks->At(0))->GetTrackParamAtMUONCluster(idCluster[0]);
+  AliMUONTrackParam *param1 = ((AliMuonForwardTrack*) fMuonForwardTracks->At(1))->GetTrackParamAtMUONCluster(idCluster[1]);
+
+  AliMUONTrackExtrap::ExtrapToVertex(param0, x, y, z, 0., 0.);   // this should reproduce what is done in AliMUONESDInterface::MUONToESD(...) 
+  AliMUONTrackExtrap::ExtrapToVertex(param1, x, y, z, 0., 0.);   // this should reproduce what is done in AliMUONESDInterface::MUONToESD(...) 
+
+  Double_t momentum[2] = {0}; 
+
+  momentum[0] = param0->P();
+  momentum[1] = param1->P();
+
+  Double_t mMu = TDatabasePDG::Instance()->GetParticle("mu-")->Mass();
+
+  TLorentzVector dimu;
+
+  dimu.SetE(TMath::Sqrt(mMu*mMu + momentum[0]*momentum[0]) + TMath::Sqrt(mMu*mMu + momentum[1]*momentum[1]));
+
+  dimu.SetPx(param0->Px() + param1->Px());
+  dimu.SetPy(param0->Py() + param1->Py());
+  dimu.SetPz(param0->Pz() + param1->Pz());
+
+  return dimu.M();
+
+}
+
+//====================================================================================================================================================
+
+Double_t AliMuonForwardTrackPair::GetMassMC() {
+
+  TLorentzVector dimu;
+
+  dimu.SetE(((AliMuonForwardTrack*) fMuonForwardTracks->At(0))->GetMCTrackRef()->Energy() +
+           ((AliMuonForwardTrack*) fMuonForwardTracks->At(1))->GetMCTrackRef()->Energy());
+
+  dimu.SetPx(((AliMuonForwardTrack*) fMuonForwardTracks->At(0))->GetMCTrackRef()->Px() +
+            ((AliMuonForwardTrack*) fMuonForwardTracks->At(1))->GetMCTrackRef()->Px());
+
+  dimu.SetPy(((AliMuonForwardTrack*) fMuonForwardTracks->At(0))->GetMCTrackRef()->Py() +
+            ((AliMuonForwardTrack*) fMuonForwardTracks->At(1))->GetMCTrackRef()->Py());
+
+  dimu.SetPz(((AliMuonForwardTrack*) fMuonForwardTracks->At(0))->GetMCTrackRef()->Pz() +
+            ((AliMuonForwardTrack*) fMuonForwardTracks->At(1))->GetMCTrackRef()->Pz());
+
+  return dimu.M();
+
+}
+
+//====================================================================================================================================================
+
+
+
+
+
+
+
+
diff --git a/MFT/AliMuonForwardTrackPair.h b/MFT/AliMuonForwardTrackPair.h
new file mode 100644 (file)
index 0000000..34e85b6
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef AliMuonForwardTrackPair_H
+#define AliMuonForwardTrackPair_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+//====================================================================================================================================================
+//
+//      Description of an ALICE muon forward track pair, i.e. a pair of AliMuonForwardTrack objects
+//
+//      Contact author: antonio.uras@cern.ch
+//
+//====================================================================================================================================================
+
+#include "AliLog.h"
+#include "AliMUONTrackParam.h"
+#include "TParticle.h"
+#include "AliMuonForwardTrack.h"
+#include "TClonesArray.h"
+#include "TDatabasePDG.h"
+#include "AliMUONTrackExtrap.h"
+#include "TLorentzVector.h"
+
+//====================================================================================================================================================
+
+class AliMuonForwardTrackPair : public TObject {
+
+public:
+
+  AliMuonForwardTrackPair();
+  AliMuonForwardTrackPair(AliMuonForwardTrack *track0, AliMuonForwardTrack *track1);
+
+  AliMuonForwardTrackPair(const AliMuonForwardTrackPair&);
+  AliMuonForwardTrackPair &operator=(const AliMuonForwardTrackPair&);
+  
+  virtual ~AliMuonForwardTrackPair() {}
+
+  void SetTrack(Int_t iTrack, AliMuonForwardTrack *track);
+  AliMuonForwardTrack* GetTrack(Int_t iTrack) { if (iTrack==0 || iTrack==1) return (AliMuonForwardTrack*) fMuonForwardTracks->At(iTrack); else return NULL; }
+
+  Double_t GetWeightedOffset(Double_t x, Double_t y, Double_t z);
+  Double_t GetMass(Double_t z, Int_t nClusters=-1);
+  Double_t GetMassWithoutMFT(Double_t x, Double_t y, Double_t z, Int_t nClusters=-1);
+  Double_t GetMassMC();
+
+protected:
+
+  TClonesArray *fMuonForwardTracks;
+
+  ClassDef(AliMuonForwardTrackPair,1)
+    
+};
+
+//====================================================================================================================================================
+
+#endif
+
+
+
diff --git a/MFT/CMakelibMFTbase.pkg b/MFT/CMakelibMFTbase.pkg
new file mode 100644 (file)
index 0000000..9eec69d
--- /dev/null
@@ -0,0 +1,40 @@
+#--------------------------------------------------------------------------------#
+# Package File for MFTbase                                                     #
+# Author : Johny Jose (johny.jose@cern.ch)                                       #
+# Variables Defined :                                                            #
+#                                                                                #
+# SRCS - C++ source files                                                        #
+# HDRS - C++ header files                                                        #
+# DHDR - ROOT Dictionary Linkdef header file                                     #
+# CSRCS - C source files                                                         #
+# CHDRS - C header files                                                         #
+# EINCLUDE - Include directories                                                 #
+# EDEFINE - Compiler definitions                                                 #
+# ELIBS - Extra libraries to link                                                #
+# ELIBSDIR - Extra library directories                                           #
+# PACKFFLAGS - Fortran compiler flags for package                                #
+# PACKCXXFLAGS - C++ compiler flags for package                                  #
+# PACKCFLAGS - C compiler flags for package                                      #
+# PACKSOFLAGS - Shared library linking flags                                     #
+# PACKLDFLAGS - Module linker flags                                              #
+# PACKBLIBS - Libraries to link (Executables only)                               #
+# EXPORT - Header files to be exported                                           #
+# CINTHDRS - Dictionary header files                                             #
+# CINTAUTOLINK - Set automatic dictionary generation                             #
+# ARLIBS - Archive Libraries and objects for linking (Executables only)          #
+# SHLIBS - Shared Libraries and objects for linking (Executables only)           #
+#--------------------------------------------------------------------------------#
+
+set ( SRCS  AliMFTPlane.cxx AliMFTSegmentation.cxx AliMFTDigit.cxx AliMFTCluster.cxx )
+
+string ( REPLACE ".cxx" ".h" HDRS "${SRCS}" )
+
+set ( DHDR MFTbaseLinkDef.h)
+
+set ( EINCLUDE  STRUCT STEER RAW MUON )
+
+if( ALICE_TARGET STREQUAL "win32gcc")
+       
+               set ( PACKSOFLAGS  ${SOFLAGS} -L${ALICE_ROOT}/lib/tgt_${ALICE_TARGET} -lSTEER -lCDB -lSTEERBase )
+
+endif( ALICE_TARGET STREQUAL "win32gcc")
diff --git a/MFT/CMakelibMFTrec.pkg b/MFT/CMakelibMFTrec.pkg
new file mode 100644 (file)
index 0000000..89dcbec
--- /dev/null
@@ -0,0 +1,40 @@
+#--------------------------------------------------------------------------------#
+# Package File for MFTrec                                                        #
+# Author : Johny Jose (johny.jose@cern.ch)                                       #
+# Variables Defined :                                                            #
+#                                                                                #
+# SRCS - C++ source files                                                        #
+# HDRS - C++ header files                                                        #
+# DHDR - ROOT Dictionary Linkdef header file                                     #
+# CSRCS - C source files                                                         #
+# CHDRS - C header files                                                         #
+# EINCLUDE - Include directories                                                 #
+# EDEFINE - Compiler definitions                                                 #
+# ELIBS - Extra libraries to link                                                #
+# ELIBSDIR - Extra library directories                                           #
+# PACKFFLAGS - Fortran compiler flags for package                                #
+# PACKCXXFLAGS - C++ compiler flags for package                                  #
+# PACKCFLAGS - C compiler flags for package                                      #
+# PACKSOFLAGS - Shared library linking flags                                     #
+# PACKLDFLAGS - Module linker flags                                              #
+# PACKBLIBS - Libraries to link (Executables only)                               #
+# EXPORT - Header files to be exported                                           #
+# CINTHDRS - Dictionary header files                                             #
+# CINTAUTOLINK - Set automatic dictionary generation                             #
+# ARLIBS - Archive Libraries and objects for linking (Executables only)          #
+# SHLIBS - Shared Libraries and objects for linking (Executables only)           #
+#--------------------------------------------------------------------------------#
+
+set ( SRCS AliMFTReconstructor.cxx AliMFTClusterFinder.cxx AliMuonForwardTrack.cxx AliMuonForwardTrackPair.cxx AliESDEventMFT.cxx AliMuonForwardTrackFinder.cxx AliMFTClusterQA.cxx )
+
+string ( REPLACE ".cxx" ".h" HDRS "${SRCS}" )
+
+set ( DHDR MFTrecLinkDef.h)
+
+set ( EINCLUDE  STRUCT STEER RAW MUON )
+
+if( ALICE_TARGET STREQUAL "win32gcc")
+       
+                               set ( PACKSOFLAGS  ${SOFLAGS} -L${ALICE_ROOT}/lib/tgt_${ALICE_TARGET} -lMFTbase -lSTEER -lCDB -lESD -lSTEERBase -lRAWDatarec -lRAWDatabase -L${ROOTLIBDIR} -lGeom)
+
+endif( ALICE_TARGET STREQUAL "win32gcc")
diff --git a/MFT/CMakelibMFTsim.pkg b/MFT/CMakelibMFTsim.pkg
new file mode 100644 (file)
index 0000000..ea6256f
--- /dev/null
@@ -0,0 +1,40 @@
+#--------------------------------------------------------------------------------#
+# Package File for MFTsim                                                      #
+# Author : Johny Jose (johny.jose@cern.ch)                                       #
+# Variables Defined :                                                            #
+#                                                                                #
+# SRCS - C++ source files                                                        #
+# HDRS - C++ header files                                                        #
+# DHDR - ROOT Dictionary Linkdef header file                                     #
+# CSRCS - C source files                                                         #
+# CHDRS - C header files                                                         #
+# EINCLUDE - Include directories                                                 #
+# EDEFINE - Compiler definitions                                                 #
+# ELIBS - Extra libraries to link                                                #
+# ELIBSDIR - Extra library directories                                           #
+# PACKFFLAGS - Fortran compiler flags for package                                #
+# PACKCXXFLAGS - C++ compiler flags for package                                  #
+# PACKCFLAGS - C compiler flags for package                                      #
+# PACKSOFLAGS - Shared library linking flags                                     #
+# PACKLDFLAGS - Module linker flags                                              #
+# PACKBLIBS - Libraries to link (Executables only)                               #
+# EXPORT - Header files to be exported                                           #
+# CINTHDRS - Dictionary header files                                             #
+# CINTAUTOLINK - Set automatic dictionary generation                             #
+# ARLIBS - Archive Libraries and objects for linking (Executables only)          #
+# SHLIBS - Shared Libraries and objects for linking (Executables only)           #
+#--------------------------------------------------------------------------------#
+
+set ( SRCS  AliMFT.cxx AliMFTHit.cxx AliMFTDigitizer.cxx )
+
+string ( REPLACE ".cxx" ".h" HDRS "${SRCS}" )
+
+set ( DHDR MFTsimLinkDef.h)
+
+set ( EINCLUDE  STRUCT STEER RAW MUON )
+
+if( ALICE_TARGET STREQUAL "win32gcc")
+       
+                               set ( PACKSOFLAGS  ${SOFLAGS} -L${ALICE_ROOT}/lib/tgt_${ALICE_TARGET} -lMFTbase -lMFTrec -lSTEER -lCDB -lSTEERBase -lRAWDatabase -L${ROOTLIBDIR} -lVMC -lGeom)
+
+endif( ALICE_TARGET STREQUAL "win32gcc")
diff --git a/MFT/MFTbaseLinkDef.h b/MFT/MFTbaseLinkDef.h
new file mode 100644 (file)
index 0000000..0ebfe5c
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef __CINT__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+#pragma link C++ class  AliMFTPlane+;
+#pragma link C++ class  AliMFTSegmentation+;
+#pragma link C++ class  AliMFTDigit+;
+#pragma link C++ class  AliMFTCluster+;
+
+#endif
diff --git a/MFT/MFTrecLinkDef.h b/MFT/MFTrecLinkDef.h
new file mode 100644 (file)
index 0000000..deec871
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef __CINT__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+#pragma link C++ class  AliMFTReconstructor+;
+#pragma link C++ class  AliMFTClusterFinder+;
+#pragma link C++ class  AliMuonForwardTrack+;
+#pragma link C++ class  AliMuonForwardTrackPair+;
+#pragma link C++ class  AliESDEventMFT+;
+#pragma link C++ class  AliMuonForwardTrackFinder+;
+#pragma link C++ class  AliMFTClusterQA+;
+
+#endif
diff --git a/MFT/MFTsimLinkDef.h b/MFT/MFTsimLinkDef.h
new file mode 100644 (file)
index 0000000..56c06ee
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __CINT__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+#pragma link C++ class  AliMFT+;
+#pragma link C++ class  AliMFTHit+;
+#pragma link C++ class  AliMFTDigitizer+;
+
+#endif
diff --git a/MFT/SetMFTGeometry.C b/MFT/SetMFTGeometry.C
new file mode 100644 (file)
index 0000000..4a3528a
--- /dev/null
@@ -0,0 +1,49 @@
+//==========================================================================================================================================
+
+// Macro to create the config file (AliMFTGeometry.root) for the geometry of the ALICE Muon Forward Tracker
+//
+// Contact author: antonio.uras@cern.ch
+
+//==========================================================================================================================================
+
+void SetMFTGeometry() {
+
+  const Int_t nPlanes = 5;
+  
+  const Float_t zCenter[nPlanes]          = {  -50.0,   -58.0,   -66.0,   -74.0,   -82.0 };   // expressed in cm
+                                         
+  const Float_t rMin[nPlanes]             = {   2.00,    2.31,    2.66,    3.01,    3.36 };   // expressed in cm  
+  const Float_t rMax[nPlanes]             = {   9.70,   11.11,   12.52,   13.93,   15.34 };   // expressed in cm
+                                         
+  const Float_t pixelSizeX[nPlanes]       = { 20.e-4,  20.e-4,  20.e-4,  20.e-4,  20.e-4 };   // expressed in cm
+  const Float_t pixelSizeY[nPlanes]       = { 20.e-4,  20.e-4,  20.e-4,  20.e-4,  20.e-4 };   // expressed in cm
+
+  const Float_t thicknessActive[nPlanes]  = {  50.e-4,   50.e-4,   50.e-4,   50.e-4,   50.e-4 };   // expressed in cm
+  const Float_t thicknessSupport[nPlanes] = {2000.e-4, 2000.e-4, 2000.e-4, 2000.e-4, 2000.e-4 };   // expressed in cm
+  const Float_t thicknessReadout[nPlanes] = {  50.e-4,   50.e-4,   50.e-4,   50.e-4,   50.e-4 };   // expressed in cm
+
+  const Float_t equivalentSilicon[nPlanes]            = { 300.e-4, 300.e-4, 300.e-4, 300.e-4, 300.e-4};    // expressed in cm
+  const Float_t equivalentSiliconBeforeFront[nPlanes] = {   0.e-4,   0.e-4,   0.e-4,   0.e-4,   0.e-4};    // expressed in cm
+  const Float_t equivalentSiliconBeforeBack[nPlanes]  = { 250.e-4, 250.e-4, 250.e-4, 250.e-4, 250.e-4};    // expressed in cm
+
+  TNtuple *geomMFT = new TNtuple("AliMFTGeometry", "ALICE MFT Geometry", "zCenter:rMin:rMax:pixelSizeX:pixelSizeY:thicknessActive:thicknessSupport:thicknessReadout:equivalentSilicon:equivalentSiliconBeforeFront:equivalentSiliconBeforeBack");
+
+  for (Int_t iPlane=0; iPlane<nPlanes; iPlane++) geomMFT -> Fill(zCenter[iPlane],
+                                                                rMin[iPlane],
+                                                                rMax[iPlane],
+                                                                pixelSizeX[iPlane],
+                                                                pixelSizeY[iPlane],
+                                                                thicknessActive[iPlane],
+                                                                thicknessSupport[iPlane],
+                                                                thicknessReadout[iPlane],
+                                                                equivalentSilicon[iPlane],
+                                                                equivalentSiliconBeforeFront[iPlane],
+                                                                equivalentSiliconBeforeBack[iPlane]);
+
+  TFile *fileGeomMFT = new TFile("AliMFTGeometry.root", "recreate");
+  geomMFT -> Write();
+  fileGeomMFT -> Close();
+
+}
+
+//==========================================================================================================================================
index a810aa81e1948fa065b4f9ed7152e0193ab3a086..ecdcf555ad512314e974ea0b1e2d43bbfba1f14e 100644 (file)
@@ -351,7 +351,7 @@ void AliMUONTrack::AddTrackParamAtCluster(const AliMUONTrackParam &trackParam, A
   }
   
   // check whether track parameters are given at the correct cluster z position
-  if (cluster.GetZ() != trackParam.GetZ()) {
+  if (TMath::Abs(cluster.GetZ() - trackParam.GetZ())>1.e-5) {   // AU
     AliError("track parameters are given at a different z position than the one of the associated cluster");
     return;
   }
index 829154bb0a9654d2d47a04a27080b482b2efdee6..32531d86e62116f7db63271e00b33a66dda868ae 100644 (file)
@@ -108,7 +108,7 @@ void runSimulation(int seed,
   
   MuonSim.SetSeed(seed);
   MuonSim.SetTriggerConfig("MUON");
-  MuonSim.SetWriteRawData("MUON HLT","raw.root",kTRUE);
+  MuonSim.SetWriteRawData("MUON ","raw.root",kTRUE);
 
   MuonSim.SetMakeSDigits("MUON");
   MuonSim.SetMakeDigits("MUON ITS"); // ITS needed to propagate the simulated vertex
diff --git a/OCDB/MFT/Align/Data/Run0_999999999_v0_s0.root b/OCDB/MFT/Align/Data/Run0_999999999_v0_s0.root
new file mode 100755 (executable)
index 0000000..d2953b1
Binary files /dev/null and b/OCDB/MFT/Align/Data/Run0_999999999_v0_s0.root differ
diff --git a/OCDB/MFT/Calib/Data/Run0_9999999_v0_s0.root b/OCDB/MFT/Calib/Data/Run0_9999999_v0_s0.root
new file mode 100755 (executable)
index 0000000..be115fc
Binary files /dev/null and b/OCDB/MFT/Calib/Data/Run0_9999999_v0_s0.root differ
index f05becb1b1c803147c529ac8f561b99203947488..a2fbfb40655396bdd8e3f2bf4affca2b94bddc23 100644 (file)
@@ -59,7 +59,11 @@ void LoadMyLibs() {
   CheckLoadLibrary("libTOFbase");
   CheckLoadLibrary("libTOFrec");
   CheckLoadLibrary("libTOFsim");
-
+  #ifdef MFT_UPGRADE
+  CheckLoadLibrary("libMFTbase");
+  CheckLoadLibrary("libMFTrec");
+  CheckLoadLibrary("libMFTsim");
+  #endif
   CheckLoadLibrary("libPWG1");
 }
 
index 65dbf72e3e0c853725eb35c5c09e8d1f4f3c12cc..6f9b7c071fb318ce4bb4cd73f94fe744287773ed 100644 (file)
@@ -50,6 +50,9 @@ ClassImp(AliAODEvent)
                                                      "dimuons",
                                                      "AliAODVZERO",
                                                      "AliAODZDC"
+#ifdef MFT_UPGRADE       
+                                                     ,"AliAODMFT"
+#endif                                               
                                                      
 };
 //______________________________________________________________________________
@@ -73,6 +76,9 @@ AliAODEvent::AliAODEvent() :
   fDimuons(0),
   fAODVZERO(0),
   fAODZDC(0)
+#ifdef MFT_UPGRADE
+  ,fAODMFT(0)
+#endif
 {
   // default constructor
 }
@@ -98,6 +104,9 @@ AliAODEvent::AliAODEvent(const AliAODEvent& aod):
   fDimuons(new TClonesArray(*aod.fDimuons)),
   fAODVZERO(new AliAODVZERO(*aod.fAODVZERO)),
   fAODZDC(new AliAODZDC(*aod.fAODZDC))
+#ifdef MFT_UPGRADE
+  ,fAODMFT(new AliAODMFT(*aod.fAODMFT))
+#endif
 {
   // Copy constructor
   AddObject(fHeader);
@@ -115,6 +124,9 @@ AliAODEvent::AliAODEvent(const AliAODEvent& aod):
   AddObject(fDimuons);
   AddObject(fAODVZERO);
   AddObject(fAODZDC);
+#ifdef MFT_UPGRADE     
+  AddObject(fAODVZERO);
+#endif
   fConnected = aod.fConnected;
   GetStdContent();
   CreateStdFolders();
@@ -274,6 +286,9 @@ void AliAODEvent::CreateStdContent()
   AddObject(new TClonesArray("AliAODDimuon", 0));
   AddObject(new AliAODVZERO());
   AddObject(new AliAODZDC());
+#ifdef MFT_UPGRADE
+  AddObject(new AliAODMFT());
+#endif
   // set names
   SetStdNames();
 
@@ -359,6 +374,9 @@ void AliAODEvent::GetStdContent()
   fDimuons       = (TClonesArray*)fAODObjects->FindObject("dimuons");
   fAODVZERO      = (AliAODVZERO*)fAODObjects->FindObject("AliAODVZERO");
   fAODZDC        = (AliAODZDC*)fAODObjects->FindObject("AliAODZDC");
+#ifdef MFT_UPGRADE
+  fAODMFT        = (AliAODMFT*)fAODObjects->FindObject("AliAODMFT");
+#endif
 }
 
 //______________________________________________________________________________
index fe36ca9662a63b4316cad38b158d545e49e14959..a0a269378b81825e2facc0531bc38898b67b85d1 100644 (file)
@@ -32,6 +32,9 @@
 #include "AliAODDimuon.h"
 #include "AliAODVZERO.h"
 #include "AliAODZDC.h"
+#ifdef MFT_UPGRADE
+#include "AliAODMFT.h"
+#endif
 
 class TTree;
 class TFolder;
@@ -57,6 +60,9 @@ class AliAODEvent : public AliVEvent {
                       kAODVZERO,
                       kAODZDC,
                       kAODListN
+                  #ifdef MFT_UPGRADE
+                  ,kAODVZERO
+                          #endif
   };
 
   AliAODEvent();
@@ -249,6 +255,11 @@ class AliAODEvent : public AliVEvent {
   //ZDC
   AliAODZDC   *GetZDCData() const { return fAODZDC; }
 
+#ifdef MFT_UPGRADE
+  // MFT 
+  AliAODMFT *GetMFTData() const { return fAODMFT; }
+#endif
+
   private :
 
   TList   *fAODObjects; //  list of AODObjects
@@ -270,6 +281,9 @@ class AliAODEvent : public AliVEvent {
   TClonesArray    *fDimuons;      //! dimuons
   AliAODVZERO     *fAODVZERO;     //! VZERO AOD
   AliAODZDC       *fAODZDC;       //! ZDC AOD
+#ifdef MFT_UPGRADE
+  AliAODMFT       *fAODMFT;       //! VZERO AOD
+#endif
   
   static const char* fAODListName[kAODListN]; //!
 
index 8de36a9f228ec981c31b22c48a82812292991ffe..d3f046cc9b38e066ade4c8217c1b706225052dc9 100644 (file)
@@ -39,6 +39,8 @@ fBaseDirectory(baseDir)
 {
 // constructor
 
+  AliDebug(1, Form("fBaseDirectory = %s",fBaseDirectory.Data()));
+
        // check baseDire: trying to cd to baseDir; if it does not exist, create it
        void* dir = gSystem->OpenDirectory(baseDir);
        if (dir == NULL) {
@@ -102,6 +104,8 @@ Bool_t AliCDBLocal::FilenameToId(const char* filename, AliCDBRunRange& runRange,
 Bool_t AliCDBLocal::IdToFilename(const AliCDBId& id, TString& filename) const {
 // build file name from AliCDBId data (run range, version, subVersion)
 
+  AliDebug(1, Form("fBaseDirectory = %s",fBaseDirectory.Data()));
+
        if (!id.GetAliCDBRunRange().IsValid()) {
                AliDebug(2,Form("Invalid run range <%d, %d>.", 
                        id.GetFirstRun(), id.GetLastRun()));
index 437eaacb3c2b88846e21796d22c2c7a4141133bb..fb8b56babc7099581afbd27d72292646ec403fe1 100644 (file)
@@ -32,11 +32,21 @@ ClassImp(AliShuttleInterface)
 
 // names of the detectors preprocessors
 const char* AliShuttleInterface::fgkDetName[kNDetectors] = {"SPD", "SDD", "SSD", "TPC", "TRD", "TOF",
-       "PHS", "CPV", "HMP", "EMC", "MCH", "MTR", "FMD", "ZDC", "PMD", "T00", "V00", "GRP", "HLT", "ACO", "TRI"};
+       "PHS", "CPV", "HMP", "EMC", "MCH", "MTR", "FMD", "ZDC", "PMD", "T00", "V00", "GRP", "HLT", "ACO", "TRI"
+// #ifdef MFT_UPGRADE
+//                                                         , "MFT" 
+// #endif 
+                                                           , "MFT"     // AU
+       };
 
 // names of the detectors in OCDB
 const char* AliShuttleInterface::fgkOfflineDetName[kNDetectors] = {"ITS", "ITS", "ITS", "TPC", "TRD", "TOF",
-       "PHOS", "PHOS", "HMPID", "EMCAL", "MUON", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "GRP", "HLT", "ACORDE", "TRIGGER"};
+       "PHOS", "PHOS", "HMPID", "EMCAL", "MUON", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "GRP", "HLT", "ACORDE", "TRIGGER"
+// #ifdef MFT_UPGRADE
+//        , "MFT" 
+// #endif 
+                                                                  , "MFT"     // AU
+          };
 
 TString AliShuttleInterface::fgkMainCDB("alien://folder=ShuttleCDB");
 TString AliShuttleInterface::fgkLocalCDB("local://LocalShuttleCDB");
index 40bf087e740f3409c20677e221e6dafab1ed18b9..a346090a88b0c802b013ffe547c2006fd02f8a8d 100644 (file)
@@ -23,7 +23,7 @@ class AliShuttleInterface : public TObject
 {
   public:
        enum System { kDAQ = 0, kDCS, kHLT, kDQM };
-    enum { kNDetectors = 21 }; // number of subdetectors in ALICE
+    enum { kNDetectors = 22 }; // number of subdetectors in ALICE
 
     virtual Bool_t Store(const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData,
                                Int_t validityStart = 0, Bool_t validityInfinite = kFALSE) = 0;
index 16ae16eaddcf55856e3b239d7cc6a657aeab1893..835b6a136bf43f57c23a88929463a57fbc41d920 100644 (file)
@@ -1,5 +1,14 @@
+set(MFT_UPGRADE $ENV{MFT_UPGRADE})
+
+if(MFT_UPGRADE)
+set ( SRCS  AliAODEvent.cxx AliAODHeader.cxx AliAODTrack.cxx AliAODPid.cxx AliAODVertex.cxx AliAODCluster.cxx AliAODCaloCluster.cxx AliAODPmdCluster.cxx AliAODFmdCluster.cxx AliAODJet.cxx AliAODJetEventBackground.cxx AliAODPhoton.cxx AliAODRedCov.cxx AliAODRecoDecay.cxx AliAODExtension.cxx AliAODHandler.cxx AliAODTracklets.cxx AliAODTagCreator.cxx AliAODv0.cxx AliAODcascade.cxx AliAODCaloCells.cxx AliAODInputHandler.cxx AliAODDiJet.cxx AliAODMCParticle.cxx AliAODMCHeader.cxx AliAODPWG4Particle.cxx AliAODPWG4ParticleCorrelation.cxx AliAODDimuon.cxx AliAODpidUtil.cxx AliAODCentrality.cxx AliAODBranchReplicator.cxx AliAODVZERO.cxx)
+
 # -*- mode: CMake -*-
 
+else(MFT_UPGRADE)
+set ( SRCS  AliAODEvent.cxx AliAODHeader.cxx AliAODTrack.cxx AliAODPid.cxx AliAODVertex.cxx AliAODCluster.cxx AliAODCaloCluster.cxx AliAODPmdCluster.cxx AliAODFmdCluster.cxx AliAODJet.cxx AliAODJetEventBackground.cxx AliAODPhoton.cxx AliAODRedCov.cxx AliAODRecoDecay.cxx AliAODExtension.cxx AliAODHandler.cxx AliAODTracklets.cxx AliAODTagCreator.cxx AliAODv0.cxx AliAODcascade.cxx AliAODCaloCells.cxx AliAODInputHandler.cxx AliAODDiJet.cxx AliAODMCParticle.cxx AliAODMCHeader.cxx AliAODPWG4Particle.cxx AliAODPWG4ParticleCorrelation.cxx AliAODDimuon.cxx AliAODpidUtil.cxx AliAODCentrality.cxx AliAODBranchReplicator.cxx AliAODVZERO.cxx)
+endif(MFT_UPGRADE)
+
 set ( SRCS  
     AOD/AliAODEvent.cxx 
     AOD/AliAODHeader.cxx 
index d4870ad2d931a9ab959542ae245060e3f3c29ca7..c8e66957faf678858c16fc713485816b32c66c0e 100644 (file)
@@ -1,4 +1,12 @@
+set(MFT_UPGRADE $ENV{MFT_UPGRADE})
+
+if(MFT_UPGRADE)
+set ( SRCS  AliESDEvent.cxx AliESDInputHandler.cxx AliESDInputHandlerRP.cxx AliESDfriend.cxx AliESD.cxx AliESDtrack.cxx AliESDfriendTrack.cxx AliESDMuonTrack.cxx AliESDPmdTrack.cxx AliESDTrdTrack.cxx AliESDHLTtrack.cxx AliESDv0.cxx AliESDcascade.cxx AliVertex.cxx AliESDVertex.cxx AliESDpid.cxx AliESDkink.cxx AliESDCaloCluster.cxx AliESDMuonCluster.cxx AliESDMuonPad.cxx AliKFParticleBase.cxx AliKFParticle.cxx AliKFVertex.cxx AliKalmanTrack.cxx AliVertexerTracks.cxx AliStrLine.cxx AliESDV0Params.cxx AliTrackPointArray.cxx AliESDFMD.cxx AliFMDMap.cxx AliFMDFloatMap.cxx AliESDMultITS.cxx AliESDVZERO.cxx AliMultiplicity.cxx AliSelector.cxx AliESDRun.cxx AliESDHeader.cxx AliESDHLTDecision.cxx AliESDZDC.cxx AliESDTZERO.cxx AliESDTZEROfriend.cxx AliESDCaloTrigger.cxx AliRawDataErrorLog.cxx AliMeanVertex.cxx AliESDCaloCells.cxx AliESDACORDE.cxx AliTriggerIR.cxx AliESDVZEROfriend.cxx AliTriggerScalersESD.cxx AliTriggerScalersRecordESD.cxx AliESDHandler.cxx AliTrackerBase.cxx  AliTOFHeader.cxx AliESDUtils.cxx)
+
 # -*- mode: CMake -*-
+else(MFT_UPGRADE)
+set ( SRCS  AliESDEvent.cxx AliESDInputHandler.cxx AliESDInputHandlerRP.cxx AliESDfriend.cxx AliESD.cxx AliESDtrack.cxx AliESDfriendTrack.cxx AliESDMuonTrack.cxx AliESDPmdTrack.cxx AliESDTrdTrack.cxx AliESDHLTtrack.cxx AliESDv0.cxx AliESDcascade.cxx AliVertex.cxx AliESDVertex.cxx AliESDpid.cxx AliESDkink.cxx AliESDCaloCluster.cxx AliESDMuonCluster.cxx AliESDMuonPad.cxx AliKFParticleBase.cxx AliKFParticle.cxx AliKFVertex.cxx AliKalmanTrack.cxx AliVertexerTracks.cxx AliStrLine.cxx AliESDV0Params.cxx AliTrackPointArray.cxx AliESDFMD.cxx AliFMDMap.cxx AliFMDFloatMap.cxx AliESDMultITS.cxx AliESDVZERO.cxx AliMultiplicity.cxx AliSelector.cxx AliESDRun.cxx AliESDHeader.cxx AliESDHLTDecision.cxx AliESDZDC.cxx AliESDTZERO.cxx AliESDTZEROfriend.cxx AliESDCaloTrigger.cxx AliRawDataErrorLog.cxx AliMeanVertex.cxx AliESDCaloCells.cxx AliESDACORDE.cxx AliTriggerIR.cxx AliESDVZEROfriend.cxx AliTriggerScalersESD.cxx AliTriggerScalersRecordESD.cxx AliESDHandler.cxx AliTrackerBase.cxx  AliTOFHeader.cxx AliESDUtils.cxx)
+endif(MFT_UPGRADE)
 
 set ( SRCS  
     ESD/AliESDEvent.cxx 
index 20e516762f7fd31d2e611be02afd297d692c5b7f..a2347023be02cce6a2a6730dcc7fecef0e22f391 100644 (file)
@@ -74,6 +74,7 @@ set ( SRCS
     STEERBase/AliOADBContainer.cxx     
     STEERBase/AliMathBase.cxx 
     STEERBase/TTreeStream.cxx 
+    STEERBase/AliVMFT.cxx
     )
 
 string(REPLACE ".cxx" ".h" HDRS  "${SRCS}")
index a4a37f4de3fa1d444a96d8e0f4765ac931b39cfe..c88e5598ea715867270e2588e2562080074cb82f 100644 (file)
@@ -75,6 +75,9 @@ AliESD::AliESD():
   fESDVZERO(0x0),
   fESDACORDE(0x0),
   fErrorLogs("AliRawDataErrorLog",5)
+  #ifdef MFT_UPGRADE
+ // ,fESDMFT(0x0)
+  #endif
 {
   // 
   // Standar constructor
@@ -138,6 +141,9 @@ AliESD::AliESD(const AliESD& esd):
   fESDVZERO(esd.fESDVZERO),
   fESDACORDE(esd.fESDACORDE),
   fErrorLogs(*((TClonesArray*)esd.fErrorLogs.Clone()))
+  #ifdef MFT_UPGRADE
+  //, fESDMFT(esd.fESDMFT)
+  #endif
 {
   // 
   // copy constructor
@@ -174,7 +180,9 @@ AliESD::~AliESD()
   delete fPHOSTriggerPosition;
   delete fPHOSTriggerAmplitudes;
   delete fESDACORDE;
-
+  #ifdef MFT_UPGRADE
+//  delete fESDMFT;
+  #endif
   fErrorLogs.Delete();
 
 }
@@ -254,7 +262,14 @@ void AliESD::Reset()
   if (fESDACORDE){
       fESDACORDE->~AliESDACORDE();
       new (fESDACORDE) AliESDACORDE(); 
-  }
+  }    
+//
+  #ifdef MFT_UPGRADE
+ // if (fESDMFT){
+//       fESDMFT->~AliESDMFT();
+//       new (fESDMFT) AliESDMFT();    
+//  }
+  #endif
 //
   fErrorLogs.Delete();
 }
@@ -577,6 +592,9 @@ void AliESD::Print(Option_t *) const
   printf("                 emcal     %d\n", GetNumberOfEMCALClusters());
   printf("                 FMD       %s\n", (fESDFMD ? "yes" : "no"));
   printf("                 VZERO     %s\n", (fESDVZERO ? "yes" : "no"));
+  #ifdef MFT_UPGRADE
+ // printf("                 MFT       %s\n", (fESDMFT ? "yes" : "no"));
+  #endif
 }
 
 void AliESD::SetESDfriend(const AliESDfriend *ev) {
index df5481ab82409edf0d70bba54fca66c3436eabf9..86dc6b4f4cb591766e4eb29290aaec51f8b0f504 100644 (file)
@@ -33,6 +33,9 @@
 #include "AliMultiplicity.h"
 #include "AliRawDataErrorLog.h"
 #include "AliESDACORDE.h"
+#ifdef MFT_UPGRADE
+//#include "AliESDMFT.h"
+#endif
 
 class AliESDfriend;
 
@@ -237,6 +240,10 @@ public:
    
   void SetVZEROData(AliESDVZERO * obj) { fESDVZERO = new AliESDVZERO(*obj); }
   AliESDVZERO *GetVZEROData(){ return fESDVZERO; }
+  #ifdef MFT_UPGRADE
+  //void SetMFTData(AliESDMFT * obj) { fESDMFT = new AliESDMFT(*obj); }
+ //AliESDMFT *GetMFTData(){ return fESDMFT; }
+  #endif
   void SetACORDEData(AliESDACORDE * obj){ fESDACORDE = new AliESDACORDE(*obj); } 
   AliESDACORDE *GetACORDEDAta(){ return fESDACORDE; }
   AliRawDataErrorLog *GetErrorLog(Int_t i) const {
@@ -310,7 +317,9 @@ protected:
   AliESDFMD   *fESDFMD;   // FMD object containing rough multiplicity
   AliESDVZERO *fESDVZERO; // VZERO object containing rough multiplicity
   AliESDACORDE *fESDACORDE; // ACORDE ESD object containing bit pattern
-
+  #ifdef MFT_UPGRADE
+  //AliESDMFT *fESDMFT; // MFT object containing rough multiplicity
+  #endif
   TClonesArray fErrorLogs;        // Raw-data reading error messages
 
   ClassDef(AliESD,23)  //ESD class 
index 3ec223e1f7a1d415ab1e7f37d84d202dc3cdc71d..d4494a30444821c38de520a9c7a0b2902e2a803b 100644 (file)
 #include "AliESDACORDE.h"
 #include "AliESDHLTDecision.h"
 #include "AliCentrality.h"
+#ifdef MFT_UPGRADE
+#include "AliESDMFT.h"
+#endif
 #include "AliEventplane.h"
 
+
 ClassImp(AliESDEvent)
 
 
@@ -105,7 +109,11 @@ ClassImp(AliESDEvent)
                                                        "PHOSCells",
                                                        "AliRawDataErrorLogs",
                                                        "AliESDACORDE",
-                                                       "AliTOFHeader"};
+                                                       "AliTOFHeader"
+                               #ifdef MFT_UPGRADE
+//                             , "AliESDMFT"
+                                                       #endif
+  };
 
 //______________________________________________________________________________
 AliESDEvent::AliESDEvent():
@@ -145,6 +153,9 @@ AliESDEvent::AliESDEvent():
   fTOFHeader(0),
   fCentrality(0),
   fEventplane(0)
+  #ifdef MFT_UPGRADE
+//  , fESDMFT(0)
+  #endif
 {
 }
 //______________________________________________________________________________
@@ -186,7 +197,13 @@ AliESDEvent::AliESDEvent(const AliESDEvent& esd):
   fTOFHeader(new AliTOFHeader(*esd.fTOFHeader)),
   fCentrality(new AliCentrality(*esd.fCentrality)),
   fEventplane(new AliEventplane(*esd.fEventplane))
+  #ifdef MFT_UPGRADE
+//  , fESDMFT(new AliESDMFT(*esd.fESDMFT))
+  #endif
+
+
 {
+  printf("copying ESD event...\n");   // AU
   // CKB init in the constructor list and only add here ...
   AddObject(fESDRun);
   AddObject(fHeader);
@@ -217,7 +234,9 @@ AliESDEvent::AliESDEvent(const AliESDEvent& esd):
   AddObject(fErrorLogs);
   AddObject(fESDACORDE);
   AddObject(fTOFHeader);
-
+  #ifdef MFT_UPGRADE
+//  AddObject(fESDMFT);
+  #endif
   GetStdContent();
 
 }
@@ -461,6 +480,13 @@ void AliESDEvent::ResetStdContent()
     fTrdTrigger->~AliESDTrdTrigger();
     new (fTrdTrigger) AliESDTrdTrigger();
   }
+  #ifdef MFT_UPGRADE
+  //if(fESDMFT){
+//     fESDMFT->~AliESDMFT();
+//     new (fESDMFT) AliESDMFT();
+ // }  
+  #endif
+       
   if(fPHOSTrigger)fPHOSTrigger->DeAllocate(); 
   if(fEMCALTrigger)fEMCALTrigger->DeAllocate(); 
   if(fSPDPileupVertices)fSPDPileupVertices->Delete();
@@ -538,6 +564,11 @@ void AliESDEvent::Print(Option_t *) const
   printf("                 CaloClusters %d\n", GetNumberOfCaloClusters());
   printf("                 FMD       %s\n", (fESDFMD ? "yes" : "no"));
   printf("                 VZERO     %s\n", (fESDVZERO ? "yes" : "no"));
+  #ifdef MFT_UPGRADE
+  //printf("                 MFT     %s\n", (fESDMFT ? "yes" : "no"));
+  #endif
+       
+       
   TObject* pHLTDecision=GetHLTTriggerDecision();
   printf("HLT trigger decision: %s\n", pHLTDecision?pHLTDecision->GetOption():"not available");
   if (pHLTDecision) pHLTDecision->Print("compact");
@@ -1109,6 +1140,14 @@ void AliESDEvent::SetTZEROData(AliESDTZERO * obj)
     *fESDTZERO = *obj;
 }
 
+#ifdef MFT_UPGRADE
+//void AliESDEvent::SetMFTData(AliESDMFT * obj)
+//{ 
+//  if(fESDMFT)
+//     *fESDMFT = *obj;
+//}
+#endif
+
 void AliESDEvent::SetACORDEData(AliESDACORDE * obj)
 {
   if(fESDACORDE)
@@ -1182,6 +1221,9 @@ void AliESDEvent::GetStdContent()
   fErrorLogs = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kErrorLogs]);
   fESDACORDE = (AliESDACORDE*)fESDObjects->FindObject(fgkESDListName[kESDACORDE]);
   fTOFHeader = (AliTOFHeader*)fESDObjects->FindObject(fgkESDListName[kTOFHeader]);
+  #ifdef MFT_UPGRADE
+ // fESDMFT = (AliESDMFT*)fESDObjects->FindObject(fgkESDListName[kESDMFT]);
+  #endif
 }
 
 void AliESDEvent::SetStdNames(){
@@ -1243,7 +1285,10 @@ void AliESDEvent::CreateStdContent()
   AddObject(new TClonesArray("AliRawDataErrorLog",0));
   AddObject(new AliESDACORDE()); 
   AddObject(new AliTOFHeader());
-
+  #ifdef MFT_UPGRADE
+  //AddObject(new AliESDMFT());
+  #endif
+       
   // check the order of the indices against enum...
 
   // set names
@@ -1608,6 +1653,11 @@ void AliESDEvent::CopyFromOldESD()
     for(int i = 0;i<fESDOld->GetNumberOfCaloClusters();i++){
       AddCaloCluster(fESDOld->GetCaloCluster(i));
     }
+         
+       #ifdef MFT_UPGRADE  
+       // MFT
+//     if (fESDOld->GetMFTData()) SetMFTData(fESDOld->GetMFTData());
+    #endif
 
   }// if fesdold
 }
index e74f556c129d7daabb94a4335dc1a04c3b7f75c9..50e7d1fb49bae6abe6f1444f4f8349ba4d38de12 100644 (file)
@@ -42,6 +42,9 @@
 #include "AliTOFHeader.h"
 
 #include "AliESDVZERO.h"
+#ifdef MFT_UPGRADE
+//#include "AliESDMFT.h"
+#endif
 
 class AliESDfriend;
 class AliESDHLTtrack;
@@ -103,6 +106,9 @@ public:
                        kESDACORDE,
                       kTOFHeader,
                       kESDListN
+                  #ifdef MFT_UPGRADE
+       //           , kESDMFT
+                  #endif
   };
 
   AliESDEvent();
@@ -236,7 +242,13 @@ public:
   // VZERO 
   AliESDVZERO *GetVZEROData() const { return fESDVZERO; }
   void SetVZEROData(AliESDVZERO * obj);
-
+       
+  #ifdef MFT_UPGRADE
+  // MFT 
+//  AliESDMFT *GetMFTData() const { return fESDMFT; }
+//  void SetMFTData(AliESDMFT * obj);
+  #endif
+       
  // ACORDE
   AliESDACORDE *GetACORDEData() const { return fESDACORDE;}
   void SetACORDEData(AliESDACORDE * obj);
index 6235ebdc83f11fc8d5fb13ac3477585a1fc0d4ed..598e57f1094d3429d0f2c6cd74f098cd1a2be90d 100644 (file)
 
 ClassImp( AliTriggerInput )
 
-Bool_t AliTriggerInput::fgkIsTriggerDetector[AliDAQ::kNDetectors] = {1,0,0,1,1,1,0,1,0,0,0,1,0,1,1,1,1,1,1,1,0};
+Bool_t AliTriggerInput::fgkIsTriggerDetector[AliDAQ::kNDetectors] = {1,0,0,1,1,1,0,1,0,0,0,1,0,1,1,1,1,1,1,1,0
+// #ifdef MFT_UPGRADE
+//                                                                  ,0 
+// #endif
+                                                                    ,0     // AU
+};
 const char* AliTriggerInput::fgkCTPDetectorName[AliDAQ::kNDetectors] = {
   "SPD",
   "SDD",
@@ -67,6 +72,10 @@ const char* AliTriggerInput::fgkCTPDetectorName[AliDAQ::kNDetectors] = {
   "EMCal",
   "DAQ_TEST",
   "HLT"
+//   #ifdef MFT_UPGRADE
+//   , "MFT"
+//   #endif    
+  , "MFT"    // AU
 };
 
 //_____________________________________________________________________________
index 98e16d5ee8821b20cd99d8a67195ab6c073f79cf..6ca7d3280aec8bdb542606dbc27c5fc6195f052e 100644 (file)
@@ -73,7 +73,9 @@
 #pragma link C++ class  AliESDVZERO+;
 #pragma link C++ class  AliESDTZERO+;
 #pragma link C++ class  AliESDACORDE+;
-
+#ifdef MFT_UPGRADE
+//#pragma link C++ class  AliESDMFT+;
+#endif
 
 #pragma link C++ class  AliESDMultITS+;
 #pragma link C++ class  AliMultiplicity+;
index 19de27e812740bede57fc2ef4a690a03f24a04c5..650db5f35316c986c120606a00fb25e6cfa30fe5 100644 (file)
@@ -395,12 +395,14 @@ void AliGRPObject::ReadValuesFromMap(const TMap* mapGRP){
        }
        if(mapGRP->GetValue("fNumberOfDetectors")){
                SetNumberOfDetectors((Char_t)(((TObjString*)(mapGRP->GetValue("fNumberOfDetectors")))->GetString()).Atoi()); 
+               AliDebug(1, Form("fNumberOfDetectors = %d", fNumberOfDetectors));
        }
        else { 
                AliError(Form("No fNumberOfDetectors value found in GRP map!"));
        }
        if(mapGRP->GetValue("fDetectorMask")){
                SetDetectorMask((UInt_t)(((TObjString*)(mapGRP->GetValue("fDetectorMask")))->GetString()).Atoi());  
+               AliDebug(1, Form("fDetectorMask = %d",fDetectorMask));
        }
        else { 
                AliError(Form("No fDetectorMask value found in GRP map!"));
index 37c44fa7eb871548742e059688c563bf77a17aa5..cd38af6ed59dd8d06bfd29012b9382cd4e127160 100644 (file)
@@ -98,9 +98,18 @@ AliAlignObj** AliGeomManager::fgAlignObjs[kLastLayer - kFirstLayer] = {
   0x0
 };
 
-const char* AliGeomManager::fgkDetectorName[AliGeomManager::fgkNDetectors] = {"GRP","ITS","TPC","TRD","TOF","PHOS","HMPID","EMCAL","MUON","FMD","ZDC","PMD","T0","VZERO","ACORDE"};
-Int_t AliGeomManager::fgNalignable[fgkNDetectors] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
+const char* AliGeomManager::fgkDetectorName[AliGeomManager::fgkNDetectors] = {"GRP","ITS","TPC","TRD","TOF","PHOS","HMPID","EMCAL","MUON","FMD","ZDC","PMD","T0","VZERO","ACORDE"
+                                                                             // #ifdef MFT_UPGRADE     
+                                                                             //  ,"MFT"
+                                                                             // #endif 
+                                                                             ,"MFT"   // AU
+};
+Int_t AliGeomManager::fgNalignable[fgkNDetectors] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+// #ifdef MFT_UPGRADE
+//                                                  , 0
+// #endif 
+                                                    , 0    // AU
+};
 
 TGeoManager* AliGeomManager::fgGeometry = 0x0;
 
index 63b62078af15a26e71f15bc16f9ae3d7a8711c1c..ffe5242a879016752500e8a427bf52fc473f8bd0 100644 (file)
@@ -123,7 +123,12 @@ public:
   static const char* fgLayerName[kLastLayer - kFirstLayer]; // Name of layers
   static TGeoPNEntry** fgPNEntry[kLastLayer - kFirstLayer]; // TGeoPNEntries
   static AliAlignObj** fgAlignObjs[kLastLayer - kFirstLayer]; // Alignment objects
-  static const Int_t   fgkNDetectors = 15;              // number of detectors
+//   #ifdef MFT_UPGRADE
+//   static const Int_t   fgkNDetectors = 16;              // number of detectors
+//   #else
+//   static const Int_t   fgkNDetectors = 15;              // number of detectors
+//   #endif
+  static const Int_t   fgkNDetectors = 16;              // number of detectors    // AU
   static const char *  fgkDetectorName[fgkNDetectors] ; // name of detectors
   static Int_t       fgNalignable[fgkNDetectors];
 
index e55ac3726688fb10121af01c901320d383ff2f1d..7a4b757e3629d84876d9bc8efb6ddd8ddc110ad2 100644 (file)
@@ -57,7 +57,11 @@ TFile    *     AliQAv1::fgQAResultFile         = 0x0 ;
 TString        AliQAv1::fgQAResultDirName      = "" ;  
 TString        AliQAv1::fgQAResultFileName     = "QA.root" ; 
 TString        AliQAv1::fgDetNames[]           = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD",
-                                                  "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT", "Global", "CORR"} ;   
+                                                  "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT", "Global", "CORR"
+                                                                                                 #ifdef MFT_UPGRADE
+                                                                                                 , "MFT" 
+                                                                                                 #endif 
+                                                                                                 } ;   
 TString        AliQAv1::fgGRPPath              = "GRP/GRP/Data" ; 
 TString        AliQAv1::fgTaskNames[]          = {"Raws", "Hits", "SDigits", "Digits", "DigitsR", "RecPoints", "TrackSegments", "RecParticles", "ESDs"} ;   
 TString        AliQAv1::fgModeNames[]          = {"", "Sim", "Rec", "QA"} ;   
index 8e805910af4b5ed278366a79c229905cf2f6adb9..d30c739f73e1a4b98b11993d588c15f751696370 100644 (file)
@@ -22,7 +22,11 @@ public:
   
   enum DETECTORINDEX_t {
     kNULLDET=-1, kITS, kTPC, kTRD, kTOF, kPHOS, kHMPID, kEMCAL, kMUON, kFMD,
-    kZDC, kPMD, kT0, kVZERO, kACORDE, kHLT, kGLOBAL, kCORR, kNDET};
+    kZDC, kPMD, kT0, kVZERO, kACORDE, kHLT, kGLOBAL, kCORR, kNDET
+    #ifdef MFT_UPGRADE
+    , kMFT
+    #endif 
+    };
   enum ALITASK_t {
     kNULLTASK=-1, kRAW, kSIM, kREC, kESD, kANA, kNTASK };
   enum QABIT_t {
index deff2f39f361c6820090004df370159f6de3b96d..477cab6c80b493c2511bfb2d6bb2101fda33ac08 100644 (file)
@@ -29,7 +29,12 @@ class AliRecoParam : public TObject
   //
   enum {
     kNSpecies = 5,   // number of event species
-    kNDetectors = 16 // number of detectors (last one is GRP!)
+// #ifdef MFT_UPGRADE  
+//     kNDetectors = 17 // number of detectors (last one is MFT!)
+// #else
+//     kNDetectors = 16 // number of detectors (last one is GRP!)
+// #endif
+    kNDetectors = 17 // number of detectors (last one is MFT!)   // AU
   };
   enum EventSpecie_t {kDefault = 1,
                      kLowMult = 2,
index 58c14abf7d2224c72d6e3ba5ac477fd50eca3667..5b8449e6b0d895d608eead78e2c33ab62fd55833 100644 (file)
 ClassImp(AliReconstruction)
 
 //_____________________________________________________________________________
-const char* AliReconstruction::fgkDetectorName[AliReconstruction::kNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT"};
+const char* AliReconstruction::fgkDetectorName[AliReconstruction::kNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE"
+// #ifdef MFT_UPGRADE
+//                                                                                   , "MFT"
+// #endif 
+                                                                                  , "MFT"    // AU
+                                                                                 , "HLT"
+};
 
 //_____________________________________________________________________________
 AliReconstruction::AliReconstruction(const char* gAliceFilename) :
@@ -1076,6 +1082,7 @@ Bool_t AliReconstruction::InitGRP() {
     AliError("GRP/GRP/Data entry:  missing value for the detector mask ! Using 1074790399");
     activeDetectors = 1074790399;
   }
+  AliDebug(1, Form("activeDetectors = %d", activeDetectors));
 
   fRunInfo = new AliRunInfo(lhcState, beamType, beamEnergy, runType, activeDetectors);
   fRunInfo->Dump();
@@ -1084,7 +1091,9 @@ Bool_t AliReconstruction::InitGRP() {
   // Process the list of active detectors
   if (activeDetectors) {
     UInt_t detMask = activeDetectors;
+    AliDebug(1, Form("Detector List = %s", fRunLocalReconstruction.Data()));
     fRunLocalReconstruction = MatchDetectorList(fRunLocalReconstruction,detMask);
+    AliDebug(1, Form("Detector List = %s", fRunLocalReconstruction.Data()));
     fRunTracking = MatchDetectorList(fRunTracking,detMask);
     fFillESD = MatchDetectorList(fFillESD,detMask);
     fQADetectors = MatchDetectorList(fQADetectors,detMask);
@@ -2470,15 +2479,22 @@ Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
       // https://savannah.cern.ch/bugs/?35473
       AliInfo("running reconstruction for HLT");
       if (fRawReader) {
+       AliInfo("reconstructor->Reconstruct(fRawReader, NULL)");
         reconstructor->Reconstruct(fRawReader, NULL);
-      } else {
+      } 
+      else {
+       AliInfo("reconstructor->Reconstruct(dummy, NULL)");
         TTree* dummy=NULL;
         reconstructor->Reconstruct(dummy, NULL);
       }
     }
   }
+
+  AliInfo(Form("kNDetectors = %d",kNDetectors));
+
   for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
+    AliDebug(1, Form("Detector: %s", fgkDetectorName[iDet]));
     AliReconstructor* reconstructor = GetReconstructor(iDet);
     if (!reconstructor) continue;
     AliLoader* loader = fLoader[iDet];
@@ -2503,20 +2519,28 @@ Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
     // local reconstruction
     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
     //AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]),0);
+    AliDebug(1, "Loading Rec Points");
     loader->LoadRecPoints("update");
+    AliDebug(1, "Cleaning Rec Points");
     loader->CleanRecPoints();
+    AliDebug(1, "Making Rec Points Container");
     loader->MakeRecPointsContainer();
     TTree* clustersTree = loader->TreeR();
     if (fRawReader && !reconstructor->HasDigitConversion()) {
       reconstructor->Reconstruct(fRawReader, clustersTree);
-    } else {
+    } 
+    else {
+      AliDebug(1, "Loading Digits");
       loader->LoadDigits("read");
       TTree* digitsTree = loader->TreeD();
+      AliDebug(1, Form("Digits Tree = %p",digitsTree));
       if (!digitsTree) {
         AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
         if (fStopOnError) 
           return kFALSE;
-      } else {
+      } 
+      else {
+       AliDebug(1, "Digits -> Clusters");
         reconstructor->Reconstruct(digitsTree, clustersTree);
         if (fRunQA && IsInTasks(AliQAv1::kDIGITSR)) {
           AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
index eabb81600aa80bab8bf039ecc625bb42cece6462..03f7e86164bb112a264c9c4e0226596a1c9dd797 100644 (file)
@@ -163,7 +163,12 @@ public:
   void    SetRunPlaneEff(Bool_t flag=kFALSE)  {fRunPlaneEff = flag;}
 
   enum {
-    kNDetectors = 15   // number of detectors
+// #ifdef MFT_UPGRADE 
+//     kNDetectors = 16   // number of detectors
+// #else
+//     kNDetectors = 15   // number of detectors
+// #endif 
+    kNDetectors = 16   // number of detectors    // AU
   };
   static Int_t   GetDetIndex(const char * detector);
 
index 5b37cb76194e2972390ab6dac129bb38f7b8dacc..0f51a828fda425014477d9a9ee6c7426b808c054 100644 (file)
 
 ClassImp(AliReconstructor)
 
-const AliDetectorRecoParam* AliReconstructor::fgRecoParam[AliReconstruction::kNDetectors] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+const AliDetectorRecoParam* AliReconstructor::fgRecoParam[AliReconstruction::kNDetectors] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+// #ifdef MFT_UPGRADE
+//                                                                                          ,NULL
+// #endif      
+                                                                                            ,NULL    // AU
+};
 
 //_____________________________________________________________________________
 void AliReconstructor::ConvertDigits(AliRawReader* /*rawReader*/, 
index 54c99d692779e91d4dc2505f7b0c674e3fb889e3..d04b9eb86bb1753272ac4ffe15655779c97c211e 100644 (file)
@@ -347,6 +347,8 @@ Int_t AliRunLoader::SetEventNumber(Int_t evno)
 AliCDBEntry* AliRunLoader::GetCDBEntry(const char* name) const
 {
 //Get an AliCDBEntry from the run data storage
+  
+  AliDebug(1, Form("Getting CDBEntry with name %s",name));
 
   if ( !(AliCDBManager::Instance()->IsDefaultStorageSet()) ) {
     AliError("No run data storage defined!");
index 995ada631ca7ee5a17b84373f52ecdb35232b53e..bb493bd5f5ffe6188b810ec296f53b317a2ea082 100644 (file)
 ClassImp(AliSimulation)
 
 AliSimulation *AliSimulation::fgInstance = 0;
-const char* AliSimulation::fgkDetectorName[AliSimulation::fgkNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT"};
+const char* AliSimulation::fgkDetectorName[AliSimulation::fgkNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE"
+// #ifdef MFT_UPGRADE
+//                                                                             ,"MFT"
+// #endif 
+                                                                            ,"MFT"    // AU
+                                                                           ,"HLT"
+};
 
 //_____________________________________________________________________________
 AliSimulation::AliSimulation(const char* configFileName,
@@ -2336,6 +2342,7 @@ void AliSimulation::WriteGRPEntry()
   TObjArray *detArray = gAlice->Detectors();
   for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors-1; iDet++) {
     if (detArray->FindObject(AliDAQ::OfflineModuleName(iDet))) {
+      AliDebug(1, Form("Detector #%d found: %s", iDet, AliDAQ::OfflineModuleName(iDet)));
       detectorPattern |= (1 << iDet);
       nDets++;
     }
index 76e49415ba3cc31e3e267e27e4229065ed804506..e3d67681dd84bf1935e43388e2cb51c2f4ac2c17 100644 (file)
@@ -199,7 +199,12 @@ private:
   time_t          fTimeEnd;            // EOR time-stamp
   
   //QA stuff
-  static const Int_t   fgkNDetectors = 15 ;             // number of detectors
+//   #ifdef MFT_UPGRADE
+//   static const Int_t   fgkNDetectors = 16 ;             // number of detectors
+//   #else
+//   static const Int_t   fgkNDetectors = 15 ;             // number of detectors
+//   #endif
+  static const Int_t   fgkNDetectors = 16 ;             // number of detectors    // AU
   static const char *  fgkDetectorName[fgkNDetectors] ; // names of detectors
   TString              fQADetectors ;                   // list of detectors to be QA'ed       
   TString              fQATasks ;                       // list of QA tasks to be performed    
index 814fd226115704394bd63921eff3b8e26115f11c..35acc84dbc310cd64cd9ad3035a9ba53653989e1 100644 (file)
@@ -63,8 +63,9 @@ const char* AliDAQ::fgkDetectorName[AliDAQ::kNDetectors] = {
   "ACORDE",
   "TRG",
   "EMCAL",
-  "DAQ_TEST",
-  "HLT"
+  "DAQ_TEST"
+  , "MFT"   // AU
+  , "HLT"
 };
 
 Int_t AliDAQ::fgkNumberOfDdls[AliDAQ::kNDetectors] = {
@@ -88,6 +89,7 @@ Int_t AliDAQ::fgkNumberOfDdls[AliDAQ::kNDetectors] = {
   1,
   46,
   1,
+  1,
   28
 };
 
@@ -112,6 +114,7 @@ Float_t AliDAQ::fgkNumberOfLdcs[AliDAQ::kNDetectors] = {
   1,
   8,
   1,
+  1,
   7
 };
 
@@ -135,8 +138,10 @@ const char* AliDAQ::fgkOfflineModuleName[AliDAQ::kNDetectors] = {
   "ACORDE",
   "CTP",
   "EMCAL",
-  "",
-  "HLT"
+  ""
+  , "MFT"    // AU
+  ,  "HLT"
 };
 
 const char* AliDAQ::fgkOnlineName[AliDAQ::kNDetectors] = {
@@ -159,8 +164,9 @@ const char* AliDAQ::fgkOnlineName[AliDAQ::kNDetectors] = {
   "ACO",
   "TRI",
   "EMC",
-  "TST",
-  "HLT"
+  "TST"
+  , "MFT"   // AU
+  , "HLT"
 };
 
 AliDAQ::AliDAQ(const AliDAQ& source) :
index dc85cc07e7ed8d93e2bda56bf607ad92511ee30c..366854c8207b6a8ba52da1f270ff461d0072c3dc 100644 (file)
@@ -69,19 +69,29 @@ class AliDAQ: public TObject {
   static const char *OnlineName(Int_t detectorID);
 
   enum {
-    kNDetectors = 21,    // Number of detectors
+// #ifdef MFT_UPGRADE
+//     kNDetectors = 22,    // Number of detectors
+// #else
+//     kNDetectors = 21,    // Number of detectors
+// #endif
+    kNDetectors = 22,    // Number of detectors   // AU
     kHLTId = 30          // HLT detector index
   };
-
+  
   enum DetectorBits {kSPD = 0x0001, kSDD = 0x0002, kSSD = 0x0004, kITS = 0x0007, 
                     kTPC = 0x0008, kTRD = 0x0010, kTOF = 0x0020, kHMPID = 0x0040, 
                     kPHOS = 0x0080, kCPV = 0x0100, kPMD = 0x0200, kMUONTRK = 0x0400,
                     kMUONTRG = 0x0800, kMUON = 0x0c00, kFMD = 0x1000, kT0 = 0x2000, kVZERO = 0x4000,
                     kZDC = 0x8000, kACORDE = 0x10000, kTRG = 0x20000, kEMCAL = 0x40000,
-                    kDAQTEST = 0x80000, kHLT = 0x40000000 };
-
- private:
-
+                    kDAQTEST = 0x80000, kHLT = 0x40000000
+// #ifdef MFT_UPGRADE
+//                  ,kMFT = 0x80000000
+// #endif
+                    ,kMFT = 0x80000000     // AU
+  };
+  
+private:
+  
   static const char *fgkDetectorName[kNDetectors]; // Detector names
   static Int_t       fgkNumberOfDdls[kNDetectors]; // Number of DDLs per detector
   static Float_t     fgkNumberOfLdcs[kNDetectors]; // Number of LDCs per detector (not fixed - used only for the raw data simulation)
index 67dc5f3e5e70b253d79f97d0ac42e87fd7ddad78..403ce4cf129b01d2beccddac3dbde48f2fda0395 100644 (file)
@@ -60,7 +60,10 @@ class AliDetectorTag : public TObject {
   Bool_t GetVZERO()  const {return fMaskDAQ & AliDAQ::kVZERO;}
   Bool_t GetZDC()    const {return fMaskDAQ & AliDAQ::kZDC;}
   Bool_t GetEMCAL()  const {return fMaskDAQ & AliDAQ::kEMCAL;}
-  
+//   #ifdef MFT_UPGRADE
+//   Bool_t GetMFT()    const {return fMaskDAQ & AliDAQ::kMFT;}
+//   #endif
+  Bool_t GetMFT()    const {return fMaskDAQ & AliDAQ::kMFT;}   // AU
   //____________________________________________________//
  private:
   //  void Int2Bin();
@@ -81,7 +84,11 @@ class AliDetectorTag : public TObject {
   void SetVZERO()  {fMaskDAQ |= AliDAQ::kVZERO;}
   void SetZDC()    {fMaskDAQ |= AliDAQ::kZDC  ;}
   void SetEMCAL()  {fMaskDAQ |= AliDAQ::kEMCAL;}
-  
+//   #ifdef MFT_UPGRADE
+//   void SetMFT()    {fMaskDAQ |= AliDAQ::kMFT;}
+//   #endif
+  void SetMFT()    {fMaskDAQ |= AliDAQ::kMFT;}   // AU
+       
   //   TObjArray *fDetectorArray; //detectors' names - active
   UInt_t     fMaskDAQ;          //detector mask in DAQ
   UInt_t     fMaskReco;         //detector mask in Reco
index de14ac70ca08322680d939a6f8069acefd4fd1a4..be083ba2adbabd76dc309124edd287701c6f56cd 100644 (file)
@@ -142,6 +142,11 @@ public:
   virtual AliVVZERO    *GetVZEROData() const {return 0;}
   virtual AliVZDC      *GetZDCData()   const {return 0;}
     
+//   #ifdef MFT_UPGRADE
+//   virtual AliVMFT *GetMFTData() const {return 0;}
+//   #endif
+  virtual AliVMFT *GetMFTData() const {return 0;}    // AU
+       
 private:
     virtual void      ReorderAndExpandTreeTR();
     virtual Int_t     FindIndexAndEvent(Int_t oldidx, AliMCEvent*& event) const;
index f752402294be2968da905854bd1cdafd4933d8ee..4310fd62e69825c3c0a3a5717a41c5eb6a4913ad 100644 (file)
@@ -57,7 +57,11 @@ TFile    * AliQA::fgQAResultFile         = 0x0 ;
 TString    AliQA::fgQAResultDirName      = "" ;  
 TString    AliQA::fgQAResultFileName     = "QA.root" ; 
 TString    AliQA::fgDetNames[]           = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD",
-                                            "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT", "Global", "CORR"} ;   
+                                            "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT", "Global", "CORR"
+                                                                                       #ifdef MFT_UPGRADE
+                                               , "MFT"
+                                                                                       #endif 
+                                                                                       };   
 TString    AliQA::fgGRPPath              = "GRP/GRP/Data" ; 
 TString    AliQA::fgRTNames[]            = {"UNKNOWN", "AUTO_TEST", "CALIBRATION", "CALIBRATION_PULSER", "CHANNEL_DELAY_TUNING", "COSMIC", 
                                                                                                                                                                                "COSMICS", "DAQ_FO_UNIF_SCAN", "DAQ_GEN_DAC_SCAN", "DAQ_MEAN_TH_SCAN", "DAQ_MIN_TH_SCAN", 
index d74057ed3b1c81508447b40b8b64f4bfcb19b436..2a17ae3741e9dd731da45a08a5918d74b758e779 100644 (file)
@@ -19,7 +19,11 @@ public:
   
        enum DETECTORINDEX_t {
     kNULLDET=-1, kITS, kTPC, kTRD, kTOF, kPHOS, kHMPID, kEMCAL, kMUON, kFMD,
-    kZDC, kPMD, kT0, kVZERO, kACORDE, kHLT, kGLOBAL, kCORR, kNDET};
+    kZDC, kPMD, kT0, kVZERO, kACORDE, kHLT, kGLOBAL, kCORR, kNDET
+       #ifdef MFT_UPGRADE
+       , kMFT
+       #endif 
+       };
        enum ALITASK_t {
     kNULLTASK=-1, kRAW, kSIM, kREC, kESD, kANA, kNTASK };
        enum QABIT_t {
index 76042a3384444c51d284a54a7adb7b7af1b6838f..0ed841244c65ca2f5441437c5f25074ff94bc5a4 100644 (file)
@@ -29,7 +29,8 @@ public:
                    kEMCAL = 8,
                    kPMD   = 10,
                    kFMD   = 12,
-                   kVZERO = 14
+                   kVZERO = 14,
+                   kMFT   = 16
     };
   AliTrackReference();
   AliTrackReference(Int_t label, Int_t id = -999);
index cfbe5f468ed874d4cd4798e24788412e6beead50..8445513e182313c3d187e3a5ed6c0ca7f62c2967 100644 (file)
@@ -26,6 +26,7 @@ class AliCentrality;
 class AliEventplane;
 class AliVVZERO;
 class AliVZDC;
+class AliVMFT;   // AU
 
 class AliVEvent : public TObject {
 
diff --git a/STEER/STEERBase/AliVMFT.cxx b/STEER/STEERBase/AliVMFT.cxx
new file mode 100644 (file)
index 0000000..5ebb687
--- /dev/null
@@ -0,0 +1,42 @@
+/**************************************************************************
+ * Copyright(c) 1998-2007, 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.                  *
+ **************************************************************************/
+
+//-------------------------------------------------------------------------
+//     Base class for ESD and AOD MFT data
+//     Author: Cvetan Cheshkov
+//     cvetan.cheshkov@cern.ch 2/02/2011
+//-------------------------------------------------------------------------
+
+#include "AliVMFT.h"
+#include "AliLog.h"
+
+ClassImp(AliVMFT)
+
+//__________________________________________________________________________
+AliVMFT::AliVMFT(const AliVMFT& source) :
+  TObject(source) { } // Copy constructor
+
+//__________________________________________________________________________
+AliVMFT& AliVMFT::operator=(const AliVMFT& source)
+{
+  // Assignment operator
+  //
+  if (this!=&source) { 
+    TObject::operator=(source); 
+  }
+  
+  return *this; 
+}
+
diff --git a/STEER/STEERBase/AliVMFT.h b/STEER/STEERBase/AliVMFT.h
new file mode 100644 (file)
index 0000000..ade7e16
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef ALIVMFT_H
+#define ALIVMFT_H
+
+//-------------------------------------------------------------------------
+//     Base class for ESD and AOD MFT data
+//     Author: Cvetan Cheshkov
+//     cvetan.cheshkov@cern.ch 2/02/2011
+//-------------------------------------------------------------------------
+
+#include "TObject.h"
+
+class AliVMFT : public TObject 
+{
+public:
+  AliVMFT() { }
+  AliVMFT(const AliVMFT& source);
+  AliVMFT &operator=(const AliVMFT& source);
+
+  virtual ~AliVMFT() { }
+
+
+protected:  
+
+    
+  ClassDef(AliVMFT,1)
+};
+
+#endif
index 8710cba474da34b1bb08cc134b2030e16ea9b572..250d171be7be65157af05711632709e728022f2e 100644 (file)
 #pragma link C++ class  TTreeStream+;
 #pragma link C++ class  TTreeSRedirector+;
 
+#pragma link C++ class AliVMFT+;
 
 #endif
diff --git a/STRUCT/AliPIPEv4.cxx b/STRUCT/AliPIPEv4.cxx
new file mode 100644 (file)
index 0000000..c20f43d
--- /dev/null
@@ -0,0 +1,2989 @@
+
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
+//-------------------------------------------------------------------------
+//  Beam pipe class
+//  This version uses TGeo
+//  Author: A.Morsch
+//-------------------------------------------------------------------------
+
+
+#include <Riostream.h>
+
+#include <TSystem.h>
+#include <TVirtualMC.h>
+#include <TGeoManager.h>
+#include <TGeoMatrix.h>
+#include <TGeoVolume.h>
+#include <TGeoTorus.h>
+#include <TGeoTube.h>
+#include <TGeoCone.h>
+#include <TGeoPcon.h>
+#include <TGeoBBox.h>
+#include <TGeoXtru.h>
+#include <TGeoCompositeShape.h>
+#include <TGeoGlobalMagField.h>
+
+#include "AliConst.h"
+#include "AliMagF.h"
+#include "AliPIPEv4.h"
+#include "AliRun.h"
+#include "AliLog.h"
+ClassImp(AliPIPEv4)
+//_____________________________________________________________________________
+AliPIPEv4::AliPIPEv4():
+    ftheta_cone(6.00),  // angle of conical beam pipe, if angle < 3 --> cylindrical beam pipe
+    frmin1(2.00),       // internal radius of Be beam pipe
+    fepaisseur(0.08),   // width of Be beam pipe
+    fsigmaz(8.00),      // dispersion of z location (1 sigma) of beam impact position
+    fz_chambre(-40.0),  // first pixel chamber location, closest to the IP
+    fzdebut1(50.),      // beginning of beam pipe z location (A side)
+    fzfin4(-82.)        // end of beamp pipe z location (C side)
+{
+  // Constructor
+}
+
+//_____________________________________________________________________________
+AliPIPEv4::AliPIPEv4(const char *name, const char *title)
+  : AliPIPE(name,title),
+    ftheta_cone(6.00),  // angle of conical beam pipe, if angle < 3 --> cylindrical beam pipe
+    frmin1(2.00),       // internal radius of Be beam pipe
+    fepaisseur(0.08),   // width of Be beam pipe
+    fsigmaz(8.00),      // dispersion of z location (1 sigma) of beam impact position
+    fz_chambre(-40.0),  // first pixel chamber location, closest to the IP
+    fzdebut1(50.),      // beginning of beam pipe z location (A side)
+    fzfin4(-82.)        // end of beamp pipe z location (C side)
+{
+  // Constructor
+}
+
+
+//_____________________________________________________________________________
+AliPIPEv4::AliPIPEv4(const char *name, const char *title, const Float_t theta_cone,  const Float_t rmin1, const Float_t epaisseur, 
+                    const Float_t sigmaz, const Float_t z_chambre)
+  : AliPIPE(name,title),
+    ftheta_cone(theta_cone), // angle of conical beam pipe, if angle < 3 --> cylindrical beam pipe
+    frmin1(rmin1),           // internal radius of Be beam pipe 
+    fepaisseur(epaisseur),   // width of Be beam pipe 
+    fsigmaz(sigmaz),         // dispersion of z location (1 sigma) of beam impact position
+    fz_chambre(z_chambre),   // first pixel chamber location, closest to the IP
+    fzdebut1(50.),           // beginning of beam pipe z location (A side)
+    fzfin4(-82.)             // end of beamp pipe z location (C side)
+{
+  // Constructor
+
+}
+
+//___________________________________________
+void AliPIPEv4::CreateGeometry()
+{
+  AliDebug(1,"Create PIPEv4 geometry");
+  //
+  //  Class describing the beam pipe geometry
+  //
+  Float_t lolo = 0.9;   //1.3 minimum pour que le premier anneau soit dans l'acceptance du spectro
+  Float_t dz, z, zsh, z0;
+  //
+  // Rotation Matrices
+  //
+  const Float_t  kDegRad = TMath::Pi() / 180.;
+  // Rotation by 180 deg
+  TGeoRotation* rot180        = new TGeoRotation("rot180", 90., 180.,  90.,  90., 180.,   0.);
+  TGeoRotation* rotyz         = new TGeoRotation("rotyz",  90., 180.,   0., 180.,  90.,  90.);
+  TGeoRotation* rotxz         = new TGeoRotation("rotxz",   0.,   0.,  90.,  90.,  90., 180.);
+  TGeoRotation* rot045        = new TGeoRotation("rot045", 90.,  45.,  90., 135.,   0.,   0.);
+  TGeoRotation* rot135        = new TGeoRotation("rot135", 90. ,135.,  90., 225.,   0.,   0.);
+  TGeoRotation* rot225        = new TGeoRotation("rot225", 90. ,225.,  90., 315.,   0.,   0.);
+  TGeoRotation* rot315        = new TGeoRotation("rot315", 90. ,315.,  90.,  45.,   0.,   0.);    
+  //
+  // Media
+  const TGeoMedium* kMedAir     =  gGeoManager->GetMedium("PIPE_AIR");
+  const TGeoMedium* kMedAirHigh =  gGeoManager->GetMedium("PIPE_AIR_HIGH");
+  const TGeoMedium* kMedVac     =  gGeoManager->GetMedium("PIPE_VACUUM");    
+  const TGeoMedium* kMedInsu    =  gGeoManager->GetMedium("PIPE_INS_C0");    
+  const TGeoMedium* kMedSteel   =  gGeoManager->GetMedium("PIPE_INOX");        
+  const TGeoMedium* kMedBe      =  gGeoManager->GetMedium("PIPE_BE");       
+  const TGeoMedium* kMedCu      =  gGeoManager->GetMedium("PIPE_CU");        
+  //const TGeoMedium* kMedKapton  =  gGeoManager->GetMedium("PIPE_KAPTON");        
+  const TGeoMedium* kMedAco     =  gGeoManager->GetMedium("PIPE_ANTICORODAL");        
+  //const TGeoMedium* kMedNEG     =  gGeoManager->GetMedium("PIPE_NEG COATING"); 
+       
+  // Top volume
+  TGeoVolume* top    = gGeoManager->GetVolume("ALIC");
+  //
+  //
+  ////////////////////////////////////////////////////////////////////////////////     
+  //                                                                            //
+  //                                  The Central Vacuum system                 // 
+  //                                                                            //
+  ////////////////////////////////////////////////////////////////////////////////
+  //
+  //
+  //  The ALICE central beam-pipe according to drawing         LHCVC2C_0001 
+  //  Drawings of sub-elements:
+  //  
+  //  Pos 7 - Minimised Flange:                                LHCVFX_P0025
+  //  Pos 6 - Standard Flange:                                 STDVFUHV0009
+  //  Pos 8 - Bellow:                                          LHCVBX__0001
+  //
+  //  Absolute z-coordinates -82.0 - 400.0 cm 
+  //  Total length:                                          482.0 cm
+  //  It consists of 3 main parts:
+  //  CP/2 The flange on the non-absorber side:               36.5 cm  
+  //  CP/1 The central Be pipe:                              405.0 cm 
+  //  CP/3 The double-bellow and flange on the absorber side: 40.5 cm 
+  //
+  //
+
+  //
+  //
+  //  Starting position in z
+  const Float_t kCPz0      = -400.0;
+  //  Length of the CP/1 section
+  const Float_t kCP1Length =  405.0;    
+  //  Length of the CP/2 section    
+  const Float_t kCP2Length =   36.5;
+  //  Length of the CP/3 section    
+  const Float_t kCP3Length =   40.5;
+  //  Position of the CP/2 section    
+  //    const Float_t kCP2pos    = kCPz0 + kCP2Length / 2.;
+  //  Position of the CP/3 section
+  const Float_t kCP3pos    = kCPz0 + kCP2Length + kCP1Length + kCP3Length/2.;
+
+
+
+  ///////////////////////////////// NEW GEOMETRY /////////////////////////////////////////////
+  
+  Float_t zfin1= fsigmaz - frmin1/TMath::Tan(ftheta_cone/ 180. * TMath::Pi());
+  Float_t zdebut2=zfin1;
+  Float_t rmax2= TMath::Tan(ftheta_cone/ 180. * TMath::Pi())*(fsigmaz+TMath::Abs(fz_chambre));
+  Float_t zfin2=-(TMath::Abs(fz_chambre)-1);
+  Float_t zdebut3=zfin2;
+  Float_t zfin3=zfin2+(-fepaisseur);
+  Float_t zdebut4=zfin3;
+  //---------------- Conical beam pipe ---------------
+  if(ftheta_cone>3){                             
+    TGeoPcon* CONE_VIDE = new TGeoPcon(0., 360., 8);
+    CONE_VIDE->DefineSection(0,fzdebut1, 0.,frmin1);
+    CONE_VIDE->DefineSection(1,zfin1, 0.,frmin1);
+    CONE_VIDE->DefineSection(2,zdebut2, 0.,frmin1);
+    CONE_VIDE->DefineSection(3,zfin2, 0.,rmax2);
+    CONE_VIDE->DefineSection(4,zdebut3, 0.,frmin1);
+    CONE_VIDE->DefineSection(5,zfin3, 0.,frmin1);
+    CONE_VIDE->DefineSection(6,zdebut4, 0.,frmin1);
+    CONE_VIDE->DefineSection(7,fzfin4, 0.,frmin1);
+    TGeoVolume* voCONE_VIDE = new TGeoVolume("CONE_VIDE",CONE_VIDE,kMedVac);            
+    voCONE_VIDE->SetLineColor(kOrange);
+    top->AddNode(voCONE_VIDE,1,new TGeoTranslation(0., 0., 0.));
+
+    TGeoPcon* CONE_BE = new TGeoPcon(0., 360., 8);
+    CONE_BE->DefineSection(0,fzdebut1,frmin1,frmin1+fepaisseur);
+    CONE_BE->DefineSection(1,zfin1,frmin1,frmin1+fepaisseur);
+    CONE_BE->DefineSection(2,zdebut2,frmin1,frmin1+fepaisseur);
+    CONE_BE->DefineSection(3,zfin2,rmax2,rmax2+fepaisseur);
+    CONE_BE->DefineSection(4,zdebut3,frmin1,rmax2+fepaisseur);
+    CONE_BE->DefineSection(5,zfin3,frmin1,rmax2+fepaisseur);
+    CONE_BE->DefineSection(6,zdebut4,frmin1,frmin1+fepaisseur);
+    CONE_BE->DefineSection(7,fzfin4,frmin1,frmin1+fepaisseur);
+    TGeoVolume* voCONE_BE = new TGeoVolume("CONE_BE",CONE_BE,kMedBe);           
+    voCONE_BE->SetLineColor(kRed);
+  }
+  //--------------- Cylindrical beam pipe -------------
+  if(ftheta_cone<3){
+    TGeoPcon* TUBE_VIDE = new TGeoPcon(0., 360., 2);
+    TUBE_VIDE->DefineSection(0,fzdebut1, 0.,frmin1);
+    TUBE_VIDE->DefineSection(1,fzfin4, 0.,frmin1);
+    TGeoVolume* voTUBE_VIDE = new TGeoVolume("TUBE_VIDE",TUBE_VIDE,kMedVac);
+    voTUBE_VIDE->SetLineColor(kOrange);    
+    top->AddNode(voTUBE_VIDE,1,new TGeoTranslation(0., 0., 0.));
+
+    TGeoPcon* TUBE_BE = new TGeoPcon(0., 360., 2);
+    TUBE_BE->DefineSection(0,fzdebut1,frmin1,frmin1+fepaisseur);
+    TUBE_BE->DefineSection(1,fzfin4,frmin1,frmin1+fepaisseur);
+    TGeoVolume* voTUBE_BE = new TGeoVolume("TUBE_BE",TUBE_BE,kMedBe);
+    voTUBE_BE->SetLineColor(kRed);    
+    top->AddNode(voTUBE_BE,1,new TGeoTranslation(0., 0., 0.));
+  }
+  /////////////////////// END NEW GEOMETRY /////////////////////////////
+    
+
+
+  //
+  ///////////////////
+  //      CP/2     //
+  ///////////////////
+  //
+  // Fixed Point tube [Pos 5]
+  //
+  // Inner and outer radii of the Stainless Steel pipe    
+  const Float_t kCP2StRi               =      2.90-lolo;
+  const Float_t kCP2StRo               =      2.98-lolo;
+  //  
+  // Transition to central Be-pipe (Bulge)   
+  // Length
+  const Float_t kCP2BulgeLength        =      0.80;
+  //     
+  // Bulge outer radius
+  const Float_t kCP2BulgeRo            =      3.05-lolo;
+  //
+  // Fixed Point at z = 391.7 (IP)
+  //
+  // Position of fixed point
+  const Float_t kCP2FixedPointZ        =      8.30;
+  //
+  // Outer radius of fixed point
+  const Float_t kCP2FixedPointRo       =      3.50-lolo;
+  //
+  // Length of fixed point
+  const Float_t kCP2FixedPointLength   =      0.60;
+  //
+  // Fixed Flange [Pos 6]    
+  //
+  // Fixed flange outer radius
+  const Float_t kCP2FixedFlangeRo      =      7.60;
+  //
+  // Fixed flange inner radius
+  const Float_t kCP2FixedFlangeRi      =      3.00;
+  // Fixed flange inner radius bulge
+  const Float_t kCP2FixedFlangeBulgeRi =      2.90;
+  // Fixed flange lengths of sections at inner radius
+  const Float_t kCP2FixedFlangeRecessLengths[3] ={1., 0.08, 0.9};
+  // Fixed flange length
+  const Float_t kCP2FixedFlangeLength =       1.98;
+  //
+  // Fixed flange bulge
+  // Outer radius
+  const Float_t kCP2FixedFlangeBulgeRo =     3.00-lolo;
+  //
+  // Length    
+  const Float_t kCP2FixedFlangeBulgeLength = 2.00;
+
+  //
+  // CP/2 Mother Volume
+  //
+  TGeoPcon* shCp2Mo = new TGeoPcon(0., 360., 14);
+  //  Flange
+  z = - kCP2Length / 2.;
+  shCp2Mo->DefineSection( 0, z, kCP2FixedFlangeRi, kCP2FixedFlangeRo);
+  z +=  kCP2FixedFlangeRecessLengths[0];
+  shCp2Mo->DefineSection( 1, z, kCP2FixedFlangeRi, kCP2FixedFlangeRo);
+  shCp2Mo->DefineSection( 2, z, 0.,                kCP2FixedFlangeRo);
+  z +=  (kCP2FixedFlangeRecessLengths[1] + kCP2FixedFlangeRecessLengths[2]) ;
+  shCp2Mo->DefineSection( 3, z, 0., kCP2FixedFlangeRo);
+  //  Straight section between Flange and Fixed Point
+  shCp2Mo->DefineSection( 4, z, 0., kCP2FixedFlangeBulgeRo);
+  z += kCP2FixedFlangeBulgeLength;
+  shCp2Mo->DefineSection( 5, z, 0., kCP2FixedFlangeBulgeRo);
+  shCp2Mo->DefineSection( 6, z, 0., kCP2StRo);
+  z =  - kCP2Length / 2 +  kCP2FixedPointZ - kCP2FixedPointLength / 2.;
+  shCp2Mo->DefineSection( 7, z, 0., kCP2StRo);
+  //  Fixed Point
+  shCp2Mo->DefineSection( 8, z, 0., kCP2FixedPointRo);
+  z +=  kCP2FixedPointLength;
+  shCp2Mo->DefineSection( 9, z, 0., kCP2FixedPointRo);
+  //  Straight section between Fixed Point and transition bulge
+  shCp2Mo->DefineSection(10, z, 0., kCP2StRo);
+  z  =  kCP2Length / 2. - kCP2BulgeLength;
+  shCp2Mo->DefineSection(11, z, 0., kCP2StRo);
+  shCp2Mo->DefineSection(12, z, 0., kCP2BulgeRo);
+  z = kCP2Length / 2.;
+  shCp2Mo->DefineSection(13, z, 0., kCP2BulgeRo);
+    
+  TGeoVolume* voCp2Mo = new TGeoVolume("CP2MO", shCp2Mo, kMedAir);
+  voCp2Mo->SetVisibility(0);
+  //
+  // CP/1 Vacuum
+  TGeoTube*   shCp2Va = new TGeoTube(0., kCP2StRi, (kCP2Length - kCP2FixedFlangeRecessLengths[0])/2.);
+  TGeoVolume* voCp2Va = new TGeoVolume("CP2VA", shCp2Va, kMedVac);
+    
+  voCp2Mo->AddNode(voCp2Va, 1, new TGeoTranslation(0., 0., kCP2FixedFlangeRecessLengths[0]/2.));
+    
+  /////////////////////////////////////////////
+  //  CP/2 Fixed Flange [Pos 6]              //
+  /////////////////////////////////////////////
+
+  TGeoPcon* shCp2Fl = new TGeoPcon(0., 360., 6);
+  z = - kCP2FixedFlangeLength / 2.;
+  shCp2Fl->DefineSection(0, z, kCP2FixedFlangeRi,      kCP2FixedFlangeRo);
+  z +=  kCP2FixedFlangeRecessLengths[0];
+  shCp2Fl->DefineSection(1, z, kCP2FixedFlangeRi,      kCP2FixedFlangeRo);
+  shCp2Fl->DefineSection(2, z, kCP2FixedFlangeBulgeRi, kCP2FixedFlangeRo);
+  z +=  kCP2FixedFlangeRecessLengths[1];
+  shCp2Fl->DefineSection(3, z, kCP2FixedFlangeBulgeRi, kCP2FixedFlangeRo);
+  shCp2Fl->DefineSection(4, z, kCP2FixedFlangeRi,      kCP2FixedFlangeRo);
+  z = kCP2FixedFlangeLength / 2.;
+  shCp2Fl->DefineSection(5, z, kCP2FixedFlangeRi,      kCP2FixedFlangeRo);
+  TGeoVolume* voCp2Fl = new TGeoVolume("CP2FL", shCp2Fl, kMedSteel);
+  // 
+  dz =  - kCP2Length / 2. +  kCP2FixedFlangeLength / 2.;
+  voCp2Mo->AddNode(voCp2Fl, 1, new TGeoTranslation(0., 0., dz));
+
+
+  /////////////////////////////////////////////////////////////
+  //  CP/2 Beam pipe with fixed point and transition bulges  //
+  /////////////////////////////////////////////////////////////
+  TGeoPcon* shCp2Pi = new TGeoPcon(0., 360., 10);
+  //  Bulge at transition to flange 
+  z =  - (kCP2Length -  kCP2FixedFlangeRecessLengths[0] - kCP2FixedFlangeRecessLengths[1]) / 2.;
+  z0 = z;
+  shCp2Pi->DefineSection(0, z, kCP2StRi, kCP2FixedFlangeBulgeRo);
+  z += kCP2FixedFlangeBulgeLength;
+  shCp2Pi->DefineSection(1, z, kCP2StRi, kCP2FixedFlangeBulgeRo);
+  //  Straight section between Bulge and Fixed Point
+  shCp2Pi->DefineSection(2, z, kCP2StRi, kCP2StRo);
+  z  += (kCP2FixedPointZ - kCP2FixedPointLength / 2. - kCP2FixedFlangeRecessLengths[0]
+        - kCP2FixedFlangeRecessLengths[1] - 
+        kCP2FixedFlangeBulgeLength);
+  shCp2Pi->DefineSection(3, z, kCP2StRi, kCP2StRo);
+  //  Fixed Point
+  shCp2Pi->DefineSection(4, z, kCP2StRi, kCP2FixedPointRo);
+  z +=  kCP2FixedPointLength;
+  shCp2Pi->DefineSection(5, z, kCP2StRi, kCP2FixedPointRo);
+  //  Straight section between Fixed Point and transition bulge
+  shCp2Pi->DefineSection(6, z, kCP2StRi, kCP2StRo);
+  z = - shCp2Pi->GetZ(0) - kCP2BulgeLength;
+  shCp2Pi->DefineSection(7, z, kCP2StRi, kCP2StRo);
+  //  Bulge at transition to Be pipe
+  shCp2Pi->DefineSection(8, z, kCP2StRi, kCP2BulgeRo);
+  z = - shCp2Pi->GetZ(0);
+  shCp2Pi->DefineSection(9, z, kCP2StRi, kCP2BulgeRo);
+
+  TGeoVolume* voCp2Pi = new TGeoVolume("CP2PI", shCp2Pi, kMedSteel);
+  dz = (kCP2FixedFlangeRecessLengths[0] + kCP2FixedFlangeRecessLengths[1]) / 2.;
+  voCp2Mo->AddNode(voCp2Pi, 1, new TGeoTranslation(0., 0., dz));
+
+  //
+  //  Central beam pipe support collars
+  //  LHCVC2C_0019
+  //  Position at z = -46., 40., 150.
+  //TGeoVolume* voCpSupC = new TGeoVolume("CpSupC", new TGeoTube(3.051, 4.00, 0.35), kMedAco);
+  //voCp1->AddNode(voCpSupC, 1, new TGeoTranslation(0., 0.,  kCP1Length / 2. - 98.2)); 
+  //voCp1->AddNode(voCpSupC, 2, new TGeoTranslation(0., 0.,  kCP1Length / 2.- 191.5)); 
+
+  TGeoVolume* voCpSupClolo = new TGeoVolume("CpSupC", new TGeoTube(3.051-lolo, 4.0-lolo, 0.35), kMedAco);   
+  //  Beam Pipe Protection Tube
+  //
+  //  ALIFWDA_0025
+  //    
+  //  Plaque de Centrage  ALIFWDA_0019
+  const Float_t kFwdaBPPTXL = 3.;
+  TGeoXtru* shFwdaBPPTX = new TGeoXtru(2);
+  Double_t xBPPTX[8] = {12.5,  7.5, -7.5, -12.5, -12.5,  -7.5,   7.5, 12.5};
+  Double_t yBPPTX[8] = { 7.0, 12.0, 12.0,  7.0, -7.0, -12.0, -12.0,  -7.0};
+  shFwdaBPPTX->DefinePolygon(8, xBPPTX, yBPPTX);
+  shFwdaBPPTX->DefineSection(0, 0.,         0., 0., 1.);
+  shFwdaBPPTX->DefineSection(1, kFwdaBPPTXL, 0., 0., 1.);
+  shFwdaBPPTX->SetName("FwdaBPPTX");
+  TGeoTube* shFwdaBPPTY = new TGeoTube(0., 8.5, 3.2);
+  shFwdaBPPTY->SetName("FwdaBPPTY");
+  TGeoCompositeShape*  shFwdaBPPTPC = new TGeoCompositeShape("shFwdaBPPTPC", "FwdaBPPTX-FwdaBPPTY");
+  TGeoVolume* voFwdaBPPTPC =  new TGeoVolume("FwdaBPPTPC", shFwdaBPPTPC, kMedAco);
+  //    
+  //  Tube  ALIFWDA_0020  
+  //    const Float_t kFwdaBPPTTL = 48.;
+  const Float_t kFwdaBPPTTL = 35.;
+  TGeoVolume* voFwdaBPPTT =  new TGeoVolume("FwdaBPPTT", new TGeoTube(8.85, 9.0, kFwdaBPPTTL/2.), kMedAco);
+  TGeoVolumeAssembly* voFwdaBPPT = new TGeoVolumeAssembly("FwdaBPPT");
+  voFwdaBPPT->AddNode(voFwdaBPPTPC, 1, gGeoIdentity);
+  voFwdaBPPT->AddNode(voFwdaBPPTT,  1, new TGeoTranslation(0., 0., kFwdaBPPTTL/2. + kFwdaBPPTXL));
+
+    
+  //  BeamPipe and T0A Support
+  //
+  //  ALIFWDA_0033
+  //    
+  //  Support  Plate ALIFWDA_0026
+  const Float_t kFwdaBPSPL = 4.0;
+  TGeoXtru* shFwdaBPSPX = new TGeoXtru(2);
+  Double_t xBPSPX[8] = {10.0,  6.0 , -6.0, -10.0, -10.0,  -6.0,   6.0, 10.0};
+  Double_t yBPSPX[8] = { 6.0, 10.0,  10.0,   6.0, - 6.0, -10.0, -10.0, -6.0};
+  shFwdaBPSPX->DefinePolygon(8, xBPSPX, yBPSPX);
+  shFwdaBPSPX->DefineSection(0, 0.,         0., 0., 1.);
+  shFwdaBPSPX->DefineSection(1, kFwdaBPSPL, 0., 0., 1.);
+  shFwdaBPSPX->SetName("FwdaBPSPX");
+  TGeoPcon* shFwdaBPSPY = new TGeoPcon(0., 360., 6);
+  shFwdaBPSPY->DefineSection(0, -1.00, 0., 5.5);
+  shFwdaBPSPY->DefineSection(1,  3.50, 0., 5.5);    
+  shFwdaBPSPY->DefineSection(2,  3.50, 0., 5.0);    
+  shFwdaBPSPY->DefineSection(3,  3.86, 0., 5.0);    
+  shFwdaBPSPY->DefineSection(4,  3.86, 0., 5.5);    
+  shFwdaBPSPY->DefineSection(5,  5.00, 0., 5.5);    
+  shFwdaBPSPY->SetName("FwdaBPSPY");
+  TGeoCompositeShape*  shFwdaBPSP = new TGeoCompositeShape("shFwdaBPSP", "FwdaBPSPX-FwdaBPSPY");
+  TGeoVolume* voFwdaBPSP =  new TGeoVolume("FwdaBPSP", shFwdaBPSP, kMedAco);
+  //    
+  //  Flasque  ALIFWDA_00027
+
+
+  const Float_t kFwdaBPSTTRi  =  7.6/2.;
+  const Float_t kFwdaBPSTTRo1 = 13.9/2.;
+  const Float_t kFwdaBPSTTRo2 =  8.2/2.;
+  const Float_t kFwdaBPSTTRo3 =  9.4/2.;
+    
+  TGeoPcon* shFwdaBPSFL = new TGeoPcon(0., 360., 8);
+  z = 0., 
+    shFwdaBPSFL->DefineSection(0, z, kFwdaBPSTTRi, kFwdaBPSTTRo1);
+  z += 0.64;
+  shFwdaBPSFL->DefineSection(1, z, kFwdaBPSTTRi, kFwdaBPSTTRo1);
+  shFwdaBPSFL->DefineSection(2, z, kFwdaBPSTTRi, kFwdaBPSTTRo2);
+  z += 2.55;
+  shFwdaBPSFL->DefineSection(3, z, kFwdaBPSTTRi, kFwdaBPSTTRo2);
+  shFwdaBPSFL->DefineSection(4, z, kFwdaBPSTTRi, kFwdaBPSTTRo3);
+  z += 0.4;
+  shFwdaBPSFL->DefineSection(5, z, kFwdaBPSTTRi, kFwdaBPSTTRo3);
+  shFwdaBPSFL->DefineSection(6, z, kFwdaBPSTTRi, kFwdaBPSTTRo2);
+  z += 1.2;
+  shFwdaBPSFL->DefineSection(7, z, kFwdaBPSTTRi, kFwdaBPSTTRo2);
+
+  TGeoVolume* voFwdaBPSFL =  new TGeoVolume("FwdaBPSFL", shFwdaBPSFL, kMedAco);
+
+    
+  //
+  // Cable support 
+  TGeoBBox* shFwdaBPSCSa = new TGeoBBox(3.0, 8.75, 0.5);
+  shFwdaBPSCSa->SetName("FwdaBPSCSa");
+  TGeoBBox* shFwdaBPSCSb = new TGeoBBox(1.25, 4.00, 1.0);
+  shFwdaBPSCSb->SetName("FwdaBPSCSb");   
+  TGeoTranslation* tFwdaBPSCSb = new TGeoTranslation(0., 5.25 - 8.75, 0.);
+  tFwdaBPSCSb->SetName("tFwdaBPSCSb");
+  tFwdaBPSCSb->RegisterYourself();
+  TGeoBBox* shFwdaBPSCSc = new TGeoBBox(3.0, 0.50, 0.70);
+  shFwdaBPSCSc->SetName("FwdaBPSCSc");
+  TGeoTranslation* tFwdaBPSCSc = new TGeoTranslation(0., 0.5 - 8.75, 1.2);
+  tFwdaBPSCSc->SetName("tFwdaBPSCSc");
+  tFwdaBPSCSc->RegisterYourself();
+  TGeoCompositeShape* shFwdaBPSCS = new TGeoCompositeShape("shFwdaBPSCS", "(FwdaBPSCSa-FwdaBPSCSb:tFwdaBPSCSb)+FwdaBPSCSc:tFwdaBPSCSc");
+  TGeoVolume* voFwdaBPSCS = new TGeoVolume("FwdaBPSCS", shFwdaBPSCS, kMedAco);
+    
+    
+  // Assembling the beam pipe support  
+  TGeoVolumeAssembly* voFwdaBPS = new TGeoVolumeAssembly("FwdaBPS");
+  voFwdaBPS->AddNode(voFwdaBPSP,   1,  new TGeoCombiTrans(0., 0., 0., rot045));
+  voFwdaBPS->AddNode(voFwdaBPSFL,  1,  new TGeoTranslation(0., 0., kFwdaBPSPL));
+  const Float_t kFwdaBPSCSdy = 18.75/TMath::Sqrt(2.);
+    
+  voFwdaBPS->AddNode(voFwdaBPSCS,  1,  new TGeoCombiTrans(- kFwdaBPSCSdy,   kFwdaBPSCSdy, 2., rot045));
+  voFwdaBPS->AddNode(voFwdaBPSCS,  2,  new TGeoCombiTrans(- kFwdaBPSCSdy, - kFwdaBPSCSdy, 2., rot135));
+  voFwdaBPS->AddNode(voFwdaBPSCS,  3,  new TGeoCombiTrans(  kFwdaBPSCSdy, - kFwdaBPSCSdy, 2., rot225));
+  voFwdaBPS->AddNode(voFwdaBPSCS,  4,  new TGeoCombiTrans(  kFwdaBPSCSdy,   kFwdaBPSCSdy, 2., rot315));
+
+  TGeoVolumeAssembly* voCp2 = new TGeoVolumeAssembly("CP2");
+  voCp2->AddNode(voCp2Mo, 1, gGeoIdentity);
+  voCp2->AddNode(voFwdaBPPT, 1, new TGeoTranslation(0., 0., -kCP2Length / 2. + 13.8));
+  voCp2->AddNode(voFwdaBPS,  1, new TGeoTranslation(0., 0., -kCP2Length / 2. +  5.1));
+
+  //
+  ///////////////////
+  //      CP/3     //
+  ///////////////////
+  //
+  // Adaptor tube [Pos 4]
+  // 
+  // Adaptor tube length 
+  const Float_t  kCP3AdaptorTubeLength            =  5.50;
+  //
+  // Inner and outer radii
+  const Float_t kCP3AdaptorTubeRi                =  2.92-lolo;
+  const Float_t kCP3AdaptorTubeRo                =  3.00-lolo;
+  //
+  // Bulge at transition point
+  // Inner and outer radii
+  const Float_t kCP3AdaptorTubeBulgeRi           =  2.90-lolo;
+  const Float_t kCP3AdaptorTubeBulgeRo           =  3.05-lolo;    
+  //
+  // Length of bulge
+  const Float_t  kCP3AdaptorTubeBulgeLength       =  0.80;
+  //
+  // Bellow [Pos 8]
+  //
+  //  Total length    
+  const Float_t kCP3BellowLength                  = 13.00;
+  //  Outer Radius
+  const Float_t kCP3BellowRo                      =  3.6-lolo; //-1?
+  //  Inner Radius 
+  const Float_t kCP3BellowRi                      =  2.8-lolo;
+  //  Number of plies
+  const Int_t   kCP3NumberOfPlies                 = 18;
+  //  Length of undulated region
+  const Float_t kCP3BellowUndulatedLength         =  8.30; 
+  //  Plie thickness
+  const Float_t kCP3PlieThickness                 =  0.02;   
+  //  Connection Plie radies (at transition been undulated region and beam pipe)
+  const Float_t kCP3ConnectionPlieR               =  0.21;
+  //  Plie radius
+  //  const Float_t kCP3PlieR = 0.118286;
+  const Float_t kCP3PlieR = 
+    (kCP3BellowUndulatedLength - 4. *  kCP3ConnectionPlieR + 2. * kCP3PlieThickness + 
+     (2. *  kCP3NumberOfPlies - 2.) * kCP3PlieThickness) / (4. * kCP3NumberOfPlies - 2.);
+  //  Length of connection pipe
+  const Float_t kCP3BellowConnectionLength        =  2.35;
+  //
+  //  Tube between bellows [Pos 3]  
+  //    
+  //  Length of tube
+  const Float_t kCP3TubeLength                    =  4.00;
+  //
+  //  Minimised fixed flange [Pos 7]
+  //  
+  //  Length of flange connection tube
+  const Float_t kCP3FlangeConnectorLength         =  5.0 - 1.4;
+  //  Length of Flange
+  const Float_t kCP3FlangeLength                  =  1.40;
+  //  Outer radius    
+  const Float_t kCP3FlangeRo                      =  4.30-lolo-1.;
+
+  //
+  // CP/3 Mother volume
+  //
+  TGeoPcon* shCp3Mo = new TGeoPcon(0., 360., 12);
+  //  From transition to first bellow
+  z = - kCP3Length / 2.;
+  shCp3Mo->DefineSection( 0, z, 0., kCP3AdaptorTubeBulgeRo);
+  z += kCP3BellowConnectionLength + kCP3AdaptorTubeLength;
+  shCp3Mo->DefineSection( 1, z, 0., kCP3AdaptorTubeBulgeRo);
+  //  First Bellow
+  shCp3Mo->DefineSection( 2, z, 0., kCP3BellowRo);
+  z +=  kCP3BellowUndulatedLength;
+  shCp3Mo->DefineSection( 3, z, 0., kCP3BellowRo);
+  //  Connection between the two bellows
+  shCp3Mo->DefineSection( 4, z, 0., kCP3AdaptorTubeBulgeRo);
+  z +=  2. * kCP3BellowConnectionLength + kCP3TubeLength;
+  shCp3Mo->DefineSection( 5, z, 0., kCP3AdaptorTubeBulgeRo);
+  //  Second bellow
+  shCp3Mo->DefineSection( 6, z, 0., kCP3BellowRo);
+  z += kCP3BellowUndulatedLength;
+  shCp3Mo->DefineSection( 7, z, 0., kCP3BellowRo);
+  //  Pipe between second Bellow and Flange
+  shCp3Mo->DefineSection( 8, z, 0., kCP3AdaptorTubeBulgeRo);
+  z +=  kCP3BellowConnectionLength +  kCP3FlangeConnectorLength;
+  shCp3Mo->DefineSection( 9, z, 0., kCP3AdaptorTubeBulgeRo);
+  //  Flange 
+  shCp3Mo->DefineSection(10, z, 0., kCP3FlangeRo);
+  z = -shCp3Mo->GetZ(0);
+  shCp3Mo->DefineSection(11, z, 0., kCP3FlangeRo);
+  //
+  TGeoVolume* voCp3Mo = new TGeoVolume("CP3MO", shCp3Mo, kMedAir);
+  voCp3Mo->SetVisibility(0);
+  TGeoVolumeAssembly* voCp3 = new TGeoVolumeAssembly("Cp3");
+  voCp3->AddNode(voCp3Mo,  1, gGeoIdentity);
+  //  voCp3->AddNode(voCpSupC, 3, new TGeoTranslation(0., 0., - kCP3Length / 2. + 4.6));
+  voCp3->AddNode(voCpSupClolo, 3, new TGeoTranslation(0., 0., - kCP3Length / 2. + 4.6));
+  dz = kCP3pos;
+
+  //////////////////////////////////////////////
+  // CP/3 Adaptor tube                        // 
+  //////////////////////////////////////////////
+  TGeoPcon* shCp3AtV = new TGeoPcon(0., 360., 4);
+  //  Bulge at transition
+  z =  - kCP3AdaptorTubeLength / 2.;
+  shCp3AtV->DefineSection(0, z, 0., kCP3AdaptorTubeBulgeRo);
+  z += kCP3AdaptorTubeBulgeLength;
+  shCp3AtV->DefineSection(1, z, 0., kCP3AdaptorTubeBulgeRo);
+  //  Tube
+  shCp3AtV->DefineSection(2, z, 0., kCP3AdaptorTubeRo);
+  z =  + kCP3AdaptorTubeLength / 2.;
+  shCp3AtV->DefineSection(3, z, 0., kCP3AdaptorTubeRo);
+
+  TGeoVolume* voCp3AtV = new TGeoVolume("CP3ATV", shCp3AtV, kMedVac);
+
+  TGeoPcon* shCp3AtS = new TGeoPcon(0., 360., 4);
+  //  Bulge at transition
+  shCp3AtS->DefineSection(0, shCp3AtV->GetZ(0), kCP3AdaptorTubeBulgeRi, kCP3AdaptorTubeBulgeRo);
+  shCp3AtS->DefineSection(1, shCp3AtV->GetZ(1), kCP3AdaptorTubeBulgeRi, kCP3AdaptorTubeBulgeRo);
+  //  Tube
+  shCp3AtS->DefineSection(2, shCp3AtV->GetZ(2), kCP3AdaptorTubeRi,      kCP3AdaptorTubeRo);
+  shCp3AtS->DefineSection(3, shCp3AtV->GetZ(3), kCP3AdaptorTubeRi ,     kCP3AdaptorTubeRo);
+  TGeoVolume* voCp3AtS = new TGeoVolume("CP3ATS", shCp3AtS, kMedSteel);
+
+  voCp3AtV->AddNode(voCp3AtS, 1, gGeoIdentity);
+  dz = - kCP3Length / 2. +  kCP3AdaptorTubeLength / 2.;
+  voCp3Mo->AddNode(voCp3AtV, 1, new TGeoTranslation(0., 0., dz));
+
+  /////////////////////////////////
+  // CP/3 Bellow section         //
+  /////////////////////////////////
+
+  //
+  //  Upper part of the undulation
+  TGeoTorus* plieTorusUO =  new TGeoTorus(kCP3BellowRo - kCP3PlieR, 0. , kCP3PlieR);
+  plieTorusUO->SetName("TorusUO");
+  TGeoTorus* plieTorusUI =  new TGeoTorus(kCP3BellowRo - kCP3PlieR, kCP3PlieR - kCP3PlieThickness, kCP3PlieR);
+  plieTorusUI->SetName("TorusUI");
+  TGeoTube*  plieTubeU   =  new TGeoTube (kCP3BellowRo - kCP3PlieR, kCP3BellowRo, kCP3PlieR);
+  plieTubeU->SetName("TubeU");
+    
+  TGeoCompositeShape*  shUpperPlieO = new TGeoCompositeShape("upperPlieO", "TorusUO*TubeU");
+  TGeoCompositeShape*  shUpperPlieI = new TGeoCompositeShape("upperPlieI", "TorusUI*TubeU");
+  TGeoVolume* voWiggleUO = new TGeoVolume("CP3WUO", shUpperPlieO, kMedVac);
+  TGeoVolume* voWiggleUI = new TGeoVolume("CP3WUI", shUpperPlieI, kMedSteel);
+  voWiggleUO->AddNode(voWiggleUI, 1,  gGeoIdentity);    
+  //
+  // Lower part of the undulation
+  TGeoTorus* plieTorusLO =  new TGeoTorus(kCP3BellowRi + kCP3PlieR, 0. , kCP3PlieR);
+  plieTorusLO->SetName("TorusLO");
+  TGeoTorus* plieTorusLI =  new TGeoTorus(kCP3BellowRi + kCP3PlieR, kCP3PlieR - kCP3PlieThickness, kCP3PlieR);
+  plieTorusLI->SetName("TorusLI");
+  TGeoTube*  plieTubeL   =  new TGeoTube (kCP3BellowRi, kCP3BellowRi + kCP3PlieR, kCP3PlieR);
+  plieTubeL->SetName("TubeL");
+
+  TGeoCompositeShape*  shLowerPlieO = new TGeoCompositeShape("lowerPlieO", "TorusLO*TubeL");
+  TGeoCompositeShape*  shLowerPlieI = new TGeoCompositeShape("lowerPlieI", "TorusLI*TubeL");
+
+  TGeoVolume* voWiggleLO = new TGeoVolume("CP3WLO", shLowerPlieO, kMedVac);
+  TGeoVolume* voWiggleLI = new TGeoVolume("CP3WLI", shLowerPlieI, kMedSteel);
+  voWiggleLO->AddNode(voWiggleLI, 1,  gGeoIdentity);    
+
+  //
+  // Connection between upper and lower part of undulation
+  TGeoVolume* voWiggleC1 = new TGeoVolume("Q3WCO1",  
+                                         new TGeoTube(kCP3BellowRi + kCP3PlieR, kCP3BellowRo - kCP3PlieR, kCP3PlieThickness / 2.),
+                                         kMedSteel);
+  TGeoVolume* voWiggleC2 = new TGeoVolume("Q3WCO2",  
+                                         new TGeoTube(kCP3BellowRi + kCP3ConnectionPlieR, kCP3BellowRo - kCP3PlieR, kCP3PlieThickness / 2.),
+                                         kMedSteel);
+  //
+  // Conncetion between undulated section and beam pipe
+  TGeoTorus* plieTorusCO =  new TGeoTorus(kCP3BellowRi + kCP3ConnectionPlieR, 0. , kCP3ConnectionPlieR);
+  plieTorusCO->SetName("TorusCO");
+  TGeoTorus* plieTorusCI =  new TGeoTorus(kCP3BellowRi + kCP3ConnectionPlieR, kCP3ConnectionPlieR - kCP3PlieThickness, kCP3ConnectionPlieR);
+  plieTorusCI->SetName("TorusCI");
+  TGeoTube*  plieTubeC   =  new TGeoTube (kCP3BellowRi, kCP3BellowRi + kCP3ConnectionPlieR, kCP3ConnectionPlieR);
+  plieTubeC->SetName("TubeC");
+
+  TGeoCompositeShape*  shConnectionPlieO = new TGeoCompositeShape("connectionPlieO", "TorusCO*TubeC");
+  TGeoCompositeShape*  shConnectionPlieI = new TGeoCompositeShape("connectionPlieI", "TorusCI*TubeC");
+
+  TGeoVolume* voConnectionPO = new TGeoVolume("CP3CPO", shConnectionPlieO, kMedVac);
+  TGeoVolume* voConnectionPI = new TGeoVolume("CP3CPI", shConnectionPlieI, kMedSteel);
+  voConnectionPO->AddNode(voConnectionPI, 1,  gGeoIdentity);    
+  //
+  // Connecting pipes
+  TGeoVolume* voConnectionPipeO = new TGeoVolume("CP3BECO",  
+                                                new TGeoTube(0., kCP3AdaptorTubeRo, kCP3BellowConnectionLength / 2.),
+                                                kMedVac);
+  TGeoVolume* voConnectionPipeI = new TGeoVolume("CP3BECI",  
+                                                new TGeoTube(kCP3AdaptorTubeRi, kCP3AdaptorTubeRo, kCP3BellowConnectionLength / 2.),
+                                                kMedSteel);
+    
+  voConnectionPipeO->AddNode(voConnectionPipeI, 1,  gGeoIdentity);
+    
+  //
+  // Bellow mother
+  TGeoPcon* shBellowMotherPC = new TGeoPcon(0., 360., 6);
+  dz =  - kCP3BellowLength / 2;
+  shBellowMotherPC->DefineSection(0, dz, 0.,  kCP3AdaptorTubeRo);
+  dz +=  kCP3BellowConnectionLength;
+  shBellowMotherPC->DefineSection(1, dz, 0.,  kCP3AdaptorTubeRo);
+  shBellowMotherPC->DefineSection(2, dz, 0.,  kCP3BellowRo);
+  dz =  kCP3BellowLength /2. -  kCP3BellowConnectionLength;;
+  shBellowMotherPC->DefineSection(3, dz, 0.,  kCP3BellowRo);
+  shBellowMotherPC->DefineSection(4, dz, 0.,  kCP3AdaptorTubeRo);
+  dz +=  kCP3BellowConnectionLength;
+  shBellowMotherPC->DefineSection(5, dz, 0.,  kCP3AdaptorTubeRo);
+
+  TGeoVolume* voBellowMother = new TGeoVolume("CP3BeMO", shBellowMotherPC, kMedVac);
+  voBellowMother->SetVisibility(0);
+    
+  //
+  // Add undulations
+  z0   =  - kCP3BellowLength / 2. +  kCP3BellowConnectionLength + 2. * kCP3ConnectionPlieR - kCP3PlieThickness;
+  zsh  = 4. *  kCP3PlieR -  2. * kCP3PlieThickness;
+  for (Int_t iw = 0; iw < 18; iw++) {
+    Float_t zpos =  z0 + iw * zsh;     
+    if (iw > 0) 
+      voBellowMother->AddNode(voWiggleC1,  iw + 1 , new TGeoTranslation(0., 0., zpos + kCP3PlieThickness / 2.));       
+    else
+      voBellowMother->AddNode(voWiggleC2,  iw + 1 , new TGeoTranslation(0., 0., zpos + kCP3PlieThickness / 2.));       
+
+    zpos += kCP3PlieR;
+    voBellowMother->AddNode(voWiggleUO, iw + 1,  new TGeoTranslation(0., 0., zpos));   
+
+    zpos += kCP3PlieR;
+    if (iw < 17) 
+      voBellowMother->AddNode(voWiggleC1,  iw + 19, new TGeoTranslation(0., 0., zpos - kCP3PlieThickness / 2.));
+    else
+      voBellowMother->AddNode(voWiggleC2,  iw + 19, new TGeoTranslation(0., 0., zpos - kCP3PlieThickness / 2.));
+
+    if (iw < 17) {
+      zpos += kCP3PlieR;
+      voBellowMother->AddNode(voWiggleLO, iw + 1, new TGeoTranslation(0., 0., zpos -  kCP3PlieThickness));
+    }
+  }
+  //
+  // Add connecting undulation between bellow and connecting pipe
+  dz = - kCP3BellowUndulatedLength / 2. + kCP3ConnectionPlieR;
+  voBellowMother->AddNode(voConnectionPO, 1,  new TGeoTranslation(0., 0.,  dz));
+  voBellowMother->AddNode(voConnectionPO, 2,  new TGeoTranslation(0., 0., -dz));
+  //
+  // Add connecting pipe
+  dz =  - kCP3BellowLength / 2. +  kCP3BellowConnectionLength / 2.;
+  voBellowMother->AddNode(voConnectionPipeO, 1,  new TGeoTranslation(0., 0.,   dz));
+  voBellowMother->AddNode(voConnectionPipeO, 2,  new TGeoTranslation(0., 0.,  -dz));
+  //
+  // Add bellow to CP/3 mother    
+  dz = - kCP3Length / 2. +  kCP3AdaptorTubeLength +  kCP3BellowLength / 2.;
+  voCp3Mo->AddNode(voBellowMother, 1,  new TGeoTranslation(0., 0., dz));
+  dz += (kCP3BellowLength +  kCP3TubeLength);
+  voCp3Mo->AddNode(voBellowMother, 2,  new TGeoTranslation(0., 0., dz));
+
+
+  ///////////////////////////////////////////
+  // Beam pipe section between bellows     //
+  ///////////////////////////////////////////
+
+  TGeoVolume* voCp3Bco = new TGeoVolume("CP3BCO",
+                                       new TGeoTube(0.,  kCP3AdaptorTubeRo,  kCP3TubeLength / 2.),
+                                       kMedVac);
+   
+  TGeoVolume* voCp3Bci = new TGeoVolume("CP3BCI",
+                                       new TGeoTube(kCP3AdaptorTubeRi, kCP3AdaptorTubeRo, kCP3TubeLength / 2.), 
+                                       kMedSteel);
+    
+  voCp3Bco->AddNode(voCp3Bci, 1, gGeoIdentity);
+  dz = - kCP3Length / 2. +   kCP3AdaptorTubeLength +  kCP3BellowLength +  kCP3TubeLength / 2.;
+  voCp3Mo->AddNode(voCp3Bco, 1, new TGeoTranslation(0., 0., dz));
+
+
+  ///////////////////////////////////////////            
+  // CP3 Minimised Flange                  //
+  ///////////////////////////////////////////
+
+  TGeoPcon* shCp3mfo = new TGeoPcon(0., 360., 4);
+  z = - (kCP3FlangeConnectorLength + kCP3FlangeLength) / 2.;
+  //  Connection Tube
+  shCp3mfo->DefineSection(0, z, 0., kCP3AdaptorTubeRo);
+  z +=  kCP3FlangeConnectorLength;
+  shCp3mfo->DefineSection(1, z, 0., kCP3AdaptorTubeRo);
+  //  Flange
+  shCp3mfo->DefineSection(2, z, 0., kCP3FlangeRo);
+  z = - shCp3mfo->GetZ(0);
+  shCp3mfo->DefineSection(3, z, 0., kCP3FlangeRo);
+
+  TGeoVolume* voCp3mfo = new TGeoVolume("CP3MFO", shCp3mfo, kMedVac);
+
+
+  TGeoPcon* shCp3mfi = new TGeoPcon(0., 360., 4);
+  //  Connection Tube
+  shCp3mfi->DefineSection(0, shCp3mfo->GetZ(0), kCP3AdaptorTubeRi, kCP3AdaptorTubeRo);
+  shCp3mfi->DefineSection(1, shCp3mfo->GetZ(1), kCP3AdaptorTubeRi, kCP3AdaptorTubeRo);
+  //  Flange
+  shCp3mfi->DefineSection(2, shCp3mfo->GetZ(2), kCP3AdaptorTubeRi, kCP3FlangeRo);
+  shCp3mfi->DefineSection(3, shCp3mfo->GetZ(3), kCP3AdaptorTubeRi, kCP3FlangeRo);
+
+  TGeoVolume* voCp3mfi = new TGeoVolume("CP3MFI", shCp3mfi, kMedSteel);
+
+  voCp3mfo->AddNode(voCp3mfi, 1, gGeoIdentity);
+  dz =  kCP3Length / 2. - (kCP3FlangeConnectorLength + kCP3FlangeLength) / 2.;
+  voCp3Mo->AddNode(voCp3mfo, 1, new TGeoTranslation(0., 0., dz));
+
+
+  /*
+  //
+  //  Assemble the central beam pipe
+  //
+  TGeoVolumeAssembly* asCP = new TGeoVolumeAssembly("CP");
+  z = 0.;
+  // asCP->AddNode(voCp2,   1, gGeoIdentity);
+  z +=  kCP2Length / 2. + kCP1Length / 2.;
+  //asCP->AddNode(voCp1, 1, new TGeoTranslation(0., 0., z));
+  
+  asCP->AddNode(voCp1, 1, new TGeoTranslation(0., 0., 0.));
+    
+  z +=  kCP1Length / 2.  + kCP3Length / 2.;
+  // asCP->AddNode(voCp3, 1, new TGeoTranslation(0., 0., z));
+  top->AddNode(asCP, 1,  new TGeoCombiTrans(0., 0., 400. -  kCP2Length / 2, rot180));
+
+  */
+
+
+  ////////////////////////////////////////////////////////////////////////////////     
+  //                                                                            //
+  //                                  RB24/1                                    // 
+  //                                                                            //
+  ////////////////////////////////////////////////////////////////////////////////
+  //
+  //
+  // Drawing LHCVC2U_0001
+  // Copper Tube RB24/1      393.5 cm 
+  // Warm module VMACA        18.0 cm
+  // Annular Ion Pump         35.0 cm
+  // Valve                     7.5 cm
+  // Warm module VMABC        28.0 cm
+  // ================================
+  //                         462.0 cm
+  //
+
+    
+  // Copper Tube RB24/1
+  const Float_t  kRB24CuTubeL   = 393.5;
+  const Float_t  kRB24CuTubeRi  = 8.0/2.;
+  const Float_t  kRB24CuTubeRo  = 8.4/2.;
+  const Float_t  kRB24CuTubeFRo = 7.6;
+  const Float_t  kRB24CuTubeFL  = 1.86;
+
+  TGeoVolume* voRB24CuTubeM = new TGeoVolume("voRB24CuTubeM", 
+                                            new TGeoTube(0., kRB24CuTubeRo, kRB24CuTubeL/2.), kMedVac);
+  voRB24CuTubeM->SetVisibility(0);
+  TGeoVolume* voRB24CuTube  = new TGeoVolume("voRB24CuTube", 
+                                            new TGeoTube(kRB24CuTubeRi, kRB24CuTubeRo, kRB24CuTubeL/2.), kMedCu);
+  voRB24CuTubeM->AddNode(voRB24CuTube, 1, gGeoIdentity);
+  // Air outside tube with higher transport cuts
+  TGeoVolume* voRB24CuTubeA  = new TGeoVolume("voRB24CuTubeA", 
+                                             new TGeoTube(25., 100., kRB24CuTubeL/2.), kMedAirHigh);
+  voRB24CuTubeA->SetVisibility(0);
+  // Simplified DN 100 Flange
+  TGeoVolume* voRB24CuTubeF = new TGeoVolume("voRB24CuTubeF", 
+                                            new TGeoTube(kRB24CuTubeRo, kRB24CuTubeFRo, kRB24CuTubeFL/2.), kMedSteel);
+
+  // Warm Module Type VMACA
+  // LHCVMACA_0002
+  // 
+  // Pos 1 Warm Bellows DN100       LHCVBU__0012
+  // Pos 2 RF Contact   D80         LHCVSR__0005
+  // Pos 3 Trans. Tube Flange       LHCVSR__0065
+  // [Pos 4 Hex. Countersunk Screw   Bossard BN4719]
+  // [Pos 5 Tension spring           LHCVSR__0011]
+  //
+  //
+  //
+  // Pos1    Warm Bellows DN100
+  // Pos1.1  Bellows                  LHCVBU__0006
+  //
+  //
+  // Connection Tubes    
+  // Connection tube inner r
+  const Float_t kRB24B1ConTubeRin        = 10.0/2.;
+  // Connection tube outer r
+  const Float_t kRB24B1ConTubeRou        = 10.3/2.;
+  // Connection tube length
+  const Float_t kRB24B1ConTubeL          =  2.5;
+  // 
+  const Float_t kRB24B1CompL             = 16.00;    // Length of the compensator
+  const Float_t kRB24B1BellowRi          = 10.25/2.; // Bellow inner radius        
+  const Float_t kRB24B1BellowRo          = 11.40/2.; // Bellow outer radius        
+  const Int_t   kRB24B1NumberOfPlies     = 27;       // Number of plies            
+  const Float_t kRB24B1BellowUndL        = 11.00;    // Length of undulated region 
+  const Float_t kRB24B1PlieThickness     =  0.015;   // Plie thickness             
+
+  const Float_t kRB24B1PlieRadius = 
+    (kRB24B1BellowUndL + (2. *  kRB24B1NumberOfPlies - 2.) * kRB24B1PlieThickness) / (4. * kRB24B1NumberOfPlies);
+    
+  const Float_t kRB24B1ProtTubeThickness = 0.02;     // Thickness of the protection tube
+  const Float_t kRB24B1ProtTubeLength    = 4.2;      // Length of the protection tube
+
+  const Float_t kRB24B1RFlangeL          = 1.86;     // Length of the flanges
+  const Float_t kRB24B1RFlangeLO         = 0.26;     // Flange overlap
+  const Float_t kRB24B1RFlangeRO         = 11.18/2;  // Inner radius at Flange overlap    
+  const Float_t kRB24B1RFlangeRou        = 15.20/2.; // Outer radius of flange
+  const Float_t kRB24B1RFlangeRecess     = 0.98;     // Flange recess
+  const Float_t kRB24B1L                 = kRB24B1CompL +  2. * (kRB24B1RFlangeL - kRB24B1RFlangeRecess);
+    
+  ///      
+  //
+  // Bellow mother volume
+  TGeoPcon* shRB24B1BellowM = new TGeoPcon(0., 360., 14);
+  // Connection Tube and Flange
+  z = 0.;
+  shRB24B1BellowM->DefineSection( 0, z, 0.,               kRB24B1RFlangeRou);
+  z += kRB24B1RFlangeLO;
+  shRB24B1BellowM->DefineSection( 1, z, 0.,               kRB24B1RFlangeRou);
+  shRB24B1BellowM->DefineSection( 2, z, 0.,               kRB24B1RFlangeRou);    
+  z = kRB24B1RFlangeL;
+  shRB24B1BellowM->DefineSection( 3, z, 0.,               kRB24B1RFlangeRou);    
+  shRB24B1BellowM->DefineSection( 4, z, 0.,               kRB24B1ConTubeRou);
+  z = kRB24B1ConTubeL +  kRB24B1RFlangeL - kRB24B1RFlangeRecess;
+  shRB24B1BellowM->DefineSection( 5, z, 0.,               kRB24B1ConTubeRou);
+  // Plie
+  shRB24B1BellowM->DefineSection( 6, z, 0.,               kRB24B1BellowRo + kRB24B1ProtTubeThickness);
+  z += kRB24B1BellowUndL;
+  shRB24B1BellowM->DefineSection( 7, z, 0.,               kRB24B1BellowRo + kRB24B1ProtTubeThickness);
+  shRB24B1BellowM->DefineSection( 8, z, 0.,               kRB24B1ConTubeRou);
+  // Connection Tube and Flange
+  z = kRB24B1L - shRB24B1BellowM->GetZ(3);
+  shRB24B1BellowM->DefineSection( 9, z, 0.,               kRB24B1ConTubeRou);
+  shRB24B1BellowM->DefineSection(10, z, 0.,               kRB24B1RFlangeRou);
+  z = kRB24B1L - shRB24B1BellowM->GetZ(1);
+  shRB24B1BellowM->DefineSection(11, z, 0.,               kRB24B1RFlangeRou);
+  shRB24B1BellowM->DefineSection(12, z, 0.,               kRB24B1RFlangeRou);
+  z = kRB24B1L - shRB24B1BellowM->GetZ(0);
+  shRB24B1BellowM->DefineSection(13, z, 0.,               kRB24B1RFlangeRou);
+
+  TGeoVolume* voRB24B1BellowM = new TGeoVolume("RB24B1BellowM", shRB24B1BellowM, kMedVac);
+  voRB24B1BellowM->SetVisibility(0);
+  //
+  // Bellow Section    
+  TGeoVolume* voRB24B1Bellow 
+    = MakeBellow("RB24B1", kRB24B1NumberOfPlies, kRB24B1BellowRi, kRB24B1BellowRo, 
+                kRB24B1BellowUndL, kRB24B1PlieRadius ,kRB24B1PlieThickness);
+  voRB24B1Bellow->SetVisibility(0);
+    
+  //
+  // End Parts (connection tube)
+  TGeoVolume* voRB24B1CT = new TGeoVolume("RB24B1CT", new TGeoTube(kRB24B1ConTubeRin, kRB24B1ConTubeRou,  kRB24B1ConTubeL/2.), kMedSteel); 
+  //
+  // Protection Tube      
+  TGeoVolume* voRB24B1PT = new TGeoVolume("RB24B1PT", new TGeoTube(kRB24B1BellowRo, kRB24B1BellowRo + kRB24B1ProtTubeThickness,  
+                                                                  kRB24B1ProtTubeLength / 2.), kMedSteel);
+    
+  z = kRB24B1ConTubeL/2. +  (kRB24B1RFlangeL - kRB24B1RFlangeRecess);
+    
+  voRB24B1BellowM->AddNode(voRB24B1CT, 1, new TGeoTranslation(0., 0., z));
+  z += (kRB24B1ConTubeL/2.+ kRB24B1BellowUndL/2.);
+  voRB24B1BellowM->AddNode(voRB24B1Bellow, 1, new TGeoTranslation(0., 0., z));
+  z += (kRB24B1BellowUndL/2. + kRB24B1ConTubeL/2);
+  voRB24B1BellowM->AddNode(voRB24B1CT, 2, new TGeoTranslation(0., 0., z));
+  z =  kRB24B1ConTubeL +  kRB24B1ProtTubeLength / 2. + 1. + kRB24B1RFlangeLO;
+  voRB24B1BellowM->AddNode(voRB24B1PT, 1, new TGeoTranslation(0., 0., z));
+  z +=  kRB24B1ProtTubeLength + 0.6;
+  voRB24B1BellowM->AddNode(voRB24B1PT, 2, new TGeoTranslation(0., 0., z));
+
+                 
+
+  // Pos 1/2 Rotatable Flange         LHCVBU__0013
+  // Pos 1/3 Flange DN100/103         LHCVBU__0018
+  // The two flanges can be represented by the same volume
+  // Outer Radius (including the outer movable ring).
+  // The inner ring has a diameter of 12.04 cm
+
+  
+  TGeoPcon* shRB24B1RFlange = new TGeoPcon(0., 360., 10);
+  z = 0.;
+  shRB24B1RFlange->DefineSection(0, z, 10.30/2., kRB24B1RFlangeRou);
+  z += 0.55;  // 5.5 mm added for outer ring
+  z += 0.43;
+  shRB24B1RFlange->DefineSection(1, z, 10.30/2., kRB24B1RFlangeRou);
+  shRB24B1RFlange->DefineSection(2, z, 10.06/2., kRB24B1RFlangeRou);    
+  z += 0.15;
+  shRB24B1RFlange->DefineSection(3, z, 10.06/2., kRB24B1RFlangeRou);    
+  // In reality this part is rounded
+  shRB24B1RFlange->DefineSection(4, z, 10.91/2., kRB24B1RFlangeRou);    
+  z += 0.15;
+  shRB24B1RFlange->DefineSection(5, z, 10.91/2., kRB24B1RFlangeRou);    
+  shRB24B1RFlange->DefineSection(6, z, 10.06/2., kRB24B1RFlangeRou);    
+  z += 0.32;
+  shRB24B1RFlange->DefineSection(7, z, 10.06/2., kRB24B1RFlangeRou);    
+  shRB24B1RFlange->DefineSection(8, z, kRB24B1RFlangeRO, kRB24B1RFlangeRou);    
+  z += kRB24B1RFlangeLO;
+  shRB24B1RFlange->DefineSection(9, z, kRB24B1RFlangeRO, kRB24B1RFlangeRou);    
+    
+  TGeoVolume* voRB24B1RFlange = new TGeoVolume("RB24B1RFlange", shRB24B1RFlange, kMedSteel);
+
+    
+  z = kRB24B1L - kRB24B1RFlangeL;
+  voRB24B1BellowM->AddNode(voRB24B1RFlange, 1, new TGeoTranslation(0., 0., z));
+  z = kRB24B1RFlangeL;
+  voRB24B1BellowM->AddNode(voRB24B1RFlange, 2, new TGeoCombiTrans(0., 0., z, rot180));
+  //
+  // Pos 2 RF Contact   D80         LHCVSR__0005
+  //
+  // Pos 2.1 RF Contact Flange      LHCVSR__0003
+  //
+  TGeoPcon* shRB24B1RCTFlange = new TGeoPcon(0., 360., 6);
+  const Float_t kRB24B1RCTFlangeRin  = 8.06/2. + 0.05;  // Inner radius
+  const Float_t kRB24B1RCTFlangeL    = 1.45;            // Length
+    
+  z = 0.;
+  shRB24B1RCTFlange->DefineSection(0, z, kRB24B1RCTFlangeRin,  8.20/2.);
+  z += 0.15;
+  shRB24B1RCTFlange->DefineSection(1, z, kRB24B1RCTFlangeRin,  8.20/2.);
+  shRB24B1RCTFlange->DefineSection(2, z, kRB24B1RCTFlangeRin,  8.60/2.);
+  z += 1.05;
+  shRB24B1RCTFlange->DefineSection(3, z, kRB24B1RCTFlangeRin,  8.60/2.);
+  shRB24B1RCTFlange->DefineSection(4, z, kRB24B1RCTFlangeRin, 11.16/2.);
+  z += 0.25;
+  shRB24B1RCTFlange->DefineSection(5, z, kRB24B1RCTFlangeRin, 11.16/2.);
+  TGeoVolume* voRB24B1RCTFlange = new TGeoVolume("RB24B1RCTFlange", shRB24B1RCTFlange, kMedCu);
+  z = kRB24B1L - kRB24B1RCTFlangeL;
+    
+  voRB24B1BellowM->AddNode(voRB24B1RCTFlange, 1, new TGeoTranslation(0., 0., z));
+  //
+  // Pos 2.2 RF-Contact        LHCVSR__0004
+  //
+  TGeoPcon* shRB24B1RCT = new TGeoPcon(0., 360., 3);
+  const Float_t kRB24B1RCTRin  = 8.00/2.;        // Inner radius
+  const Float_t kRB24B1RCTCRin = 8.99/2.;        // Max. inner radius conical section
+  const Float_t kRB24B1RCTL    = 11.78;          // Length
+  const Float_t kRB24B1RCTSL   = 10.48;          // Length of straight section
+  const Float_t kRB24B1RCTd    =  0.03;          // Thickness
+    
+  z = 0;
+  shRB24B1RCT->DefineSection(0, z,  kRB24B1RCTCRin,  kRB24B1RCTCRin + kRB24B1RCTd);
+  z =  kRB24B1RCTL -  kRB24B1RCTSL;
+  // In the (VSR0004) this section is straight in (LHCVC2U_0001) it is conical ????
+  shRB24B1RCT->DefineSection(1, z,  kRB24B1RCTRin + 0.35,  kRB24B1RCTRin + 0.35 + kRB24B1RCTd);
+  z = kRB24B1RCTL - 0.03;
+  shRB24B1RCT->DefineSection(2, z,  kRB24B1RCTRin,  kRB24B1RCTRin + kRB24B1RCTd);
+
+  TGeoVolume* voRB24B1RCT = new TGeoVolume("RB24B1RCT", shRB24B1RCT, kMedCu);
+  z = kRB24B1L - kRB24B1RCTL - 0.45;
+  voRB24B1BellowM->AddNode(voRB24B1RCT, 1, new TGeoTranslation(0., 0., z));    
+
+  //
+  // Pos 3 Trans. Tube Flange       LHCVSR__0065
+  //
+  // Pos 3.1 Transition Tube D53    LHCVSR__0064
+  // Pos 3.2 Transition Flange      LHCVSR__0060
+  // Pos 3.3 Transition Tube        LHCVSR__0058
+  TGeoPcon* shRB24B1TTF = new TGeoPcon(0., 360., 7);
+  // Flange
+  z = 0.;
+  shRB24B1TTF->DefineSection(0, z,  6.30/2., 11.16/2.);
+  z += 0.25;
+  shRB24B1TTF->DefineSection(1, z,  6.30/2., 11.16/2.);
+  shRB24B1TTF->DefineSection(2, z,  6.30/2.,  9.3/2.);
+  z += 0.55;
+  shRB24B1TTF->DefineSection(3, z,  6.30/2.,  9.3/2.);
+  // Tube
+  shRB24B1TTF->DefineSection(4, z,  6.30/2.,  6.7/2.);
+  z += 5.80;
+  shRB24B1TTF->DefineSection(5, z,  6.30/2.,  6.7/2.);
+  // Transition Tube
+  z += 3.75;
+  shRB24B1TTF->DefineSection(6, z,  8.05/2.,  8.45/2.);
+  TGeoVolume* voRB24B1TTF = new TGeoVolume("RB24B1TTF", shRB24B1TTF, kMedSteel);
+  z =  0.;
+  voRB24B1BellowM->AddNode(voRB24B1TTF, 1, new TGeoTranslation(0., 0., z));    
+
+  // Annular Ion Pump        
+  // LHCVC2U_0003
+  //
+  // Pos  1 Rotable Flange         LHCVFX__0031
+  // Pos  2 RF Screen Tube         LHCVC2U_0005
+  // Pos  3 Shell                  LHCVC2U_0007
+  // Pos  4 Extruded Shell         LHCVC2U_0006
+  // Pos  5 Feedthrough Tube       LHCVC2U_0004
+  // Pos  6 Tubulated Flange       STDVFUHV0021
+  // Pos  7 Fixed Flange           LHCVFX__0032
+  // Pos  8 Pumping Elements
+
+  //
+  // Pos 1 Rotable Flange          LHCVFX__0031
+  // pos 7 Fixed Flange            LHCVFX__0032
+  //
+  //  Mother volume
+  const Float_t kRB24AIpML = 35.;
+    
+  TGeoVolume* voRB24AIpM = new TGeoVolume("voRB24AIpM", new TGeoTube(0., 10., kRB24AIpML/2.), kMedAir);
+  voRB24AIpM->SetVisibility(0);
+    
+  //
+  // Length 35 cm
+  // Flange 2 x 1.98 =   3.96
+  // Tube            =  32.84
+  //==========================
+  //                    36.80
+  // Overlap 2 * 0.90 =  1.80
+                        
+  const Float_t kRB24IpRFD1     =  0.68;    // Length of section 1
+  const Float_t kRB24IpRFD2     =  0.30;    // Length of section 2                                                  
+  const Float_t kRB24IpRFD3     =  0.10;    // Length of section 3                                                        
+  const Float_t kRB24IpRFD4     =  0.35;    // Length of section 4                                                        
+  const Float_t kRB24IpRFD5     =  0.55;    // Length of section 5                                                        
+    
+  const Float_t kRB24IpRFRo     = 15.20/2.; // Flange outer radius 
+  const Float_t kRB24IpRFRi1    =  6.30/2.; // Flange inner radius section 1
+  const Float_t kRB24IpRFRi2    =  6.00/2.; // Flange inner radius section 2
+  const Float_t kRB24IpRFRi3    =  5.84/2.; // Flange inner radius section 3    
+  const Float_t kRB24IpRFRi4    =  6.00/2.; // Flange inner radius section 1
+  const Float_t kRB24IpRFRi5    = 10.50/2.; // Flange inner radius section 2
+
+  TGeoPcon* shRB24IpRF = new TGeoPcon(0., 360., 9);
+  z0 = 0.;
+  shRB24IpRF->DefineSection(0, z0, kRB24IpRFRi1, kRB24IpRFRo);
+  z0 += kRB24IpRFD1;
+  shRB24IpRF->DefineSection(1, z0, kRB24IpRFRi2, kRB24IpRFRo);
+  z0 += kRB24IpRFD2;
+  shRB24IpRF->DefineSection(2, z0, kRB24IpRFRi2, kRB24IpRFRo);
+  shRB24IpRF->DefineSection(3, z0, kRB24IpRFRi3, kRB24IpRFRo);
+  z0 += kRB24IpRFD3;
+  shRB24IpRF->DefineSection(4, z0, kRB24IpRFRi3, kRB24IpRFRo);
+  shRB24IpRF->DefineSection(5, z0, kRB24IpRFRi4, kRB24IpRFRo);
+  z0 += kRB24IpRFD4;
+  shRB24IpRF->DefineSection(6, z0, kRB24IpRFRi4, kRB24IpRFRo);
+  shRB24IpRF->DefineSection(7, z0, kRB24IpRFRi5, kRB24IpRFRo);
+  z0 += kRB24IpRFD5;
+  shRB24IpRF->DefineSection(8, z0, kRB24IpRFRi5, kRB24IpRFRo);
+
+  TGeoVolume* voRB24IpRF = new TGeoVolume("RB24IpRF", shRB24IpRF, kMedSteel);
+    
+  //
+  // Pos  2 RF Screen Tube         LHCVC2U_0005
+  //
+
+  //
+  // Tube
+  Float_t kRB24IpSTTL  = 32.84;            // Total length of the tube
+  Float_t kRB24IpSTTRi =  5.80/2.;         // Inner Radius
+  Float_t kRB24IpSTTRo =  6.00/2.;         // Outer Radius
+  TGeoVolume* voRB24IpSTT = new TGeoVolume("RB24IpSTT", new TGeoTube(kRB24IpSTTRi, kRB24IpSTTRo, kRB24IpSTTL/2.), kMedSteel);
+  // Screen
+  Float_t kRB24IpSTCL  =  0.4;             // Lenth of the crochet detail
+  // Length of the screen 
+  Float_t kRB24IpSTSL  =  9.00 - 2. * kRB24IpSTCL; 
+  // Rel. position of the screen 
+  Float_t kRB24IpSTSZ  =  7.00 + kRB24IpSTCL; 
+  TGeoVolume* voRB24IpSTS = new TGeoVolume("RB24IpSTS", new TGeoTube(kRB24IpSTTRi, kRB24IpSTTRo, kRB24IpSTSL/2.), kMedSteel);
+  // Vacuum
+  TGeoVolume* voRB24IpSTV = new TGeoVolume("RB24IpSTV", new TGeoTube(0., kRB24IpSTTRi, kRB24AIpML/2.), kMedVac);
+  //
+  voRB24IpSTT->AddNode(voRB24IpSTS, 1, new TGeoTranslation(0., 0., kRB24IpSTSZ -  kRB24IpSTTL/2. +  kRB24IpSTSL/2.));
+    
+  // Crochets
+  // Inner radius
+  Float_t kRB24IpSTCRi  = kRB24IpSTTRo + 0.25;
+  // Outer radius
+  Float_t kRB24IpSTCRo  = kRB24IpSTTRo + 0.35;
+  // Length of 1stsection
+  Float_t kRB24IpSTCL1  = 0.15;
+  // Length of 2nd section
+  Float_t kRB24IpSTCL2  = 0.15;
+  // Length of 3rd section
+  Float_t kRB24IpSTCL3  = 0.10;
+  // Rel. position of 1st Crochet
+
+
+  TGeoPcon* shRB24IpSTC = new TGeoPcon(0., 360., 5);
+  z0 = 0;
+  shRB24IpSTC->DefineSection(0, z0, kRB24IpSTCRi, kRB24IpSTCRo);
+  z0 += kRB24IpSTCL1;
+  shRB24IpSTC->DefineSection(1, z0, kRB24IpSTCRi, kRB24IpSTCRo);
+  shRB24IpSTC->DefineSection(2, z0, kRB24IpSTTRo, kRB24IpSTCRo);
+  z0 += kRB24IpSTCL2;
+  shRB24IpSTC->DefineSection(3, z0, kRB24IpSTTRo, kRB24IpSTCRo);
+  z0 += kRB24IpSTCL3;
+  shRB24IpSTC->DefineSection(4, z0, kRB24IpSTTRo, kRB24IpSTTRo + 0.001);
+  TGeoVolume* voRB24IpSTC = new TGeoVolume("RB24IpSTC", shRB24IpSTC, kMedSteel);
+
+  // Pos  3 Shell                  LHCVC2U_0007
+  // Pos  4 Extruded Shell         LHCVC2U_0006
+  Float_t kRB24IpShellL     =  4.45;    // Length of the Shell
+  Float_t kRB24IpShellD     =  0.10;    // Wall thickness of the shell
+  Float_t kRB24IpShellCTRi  =  6.70/2.; // Inner radius of the connection tube
+  Float_t kRB24IpShellCTL   =  1.56;    // Length of the connection tube
+  Float_t kRB24IpShellCARi  = 17.80/2.; // Inner radius of the cavity
+  Float_t kRB24IpShellCCRo  = 18.20/2.; // Inner radius at the centre
+
+  TGeoPcon* shRB24IpShell = new TGeoPcon(0., 360., 7);
+  z0 = 0;
+  shRB24IpShell->DefineSection(0, z0, kRB24IpShellCTRi, kRB24IpShellCTRi + kRB24IpShellD);
+  z0 +=  kRB24IpShellCTL;
+  shRB24IpShell->DefineSection(1, z0, kRB24IpShellCTRi, kRB24IpShellCTRi + kRB24IpShellD);
+  shRB24IpShell->DefineSection(2, z0, kRB24IpShellCTRi, kRB24IpShellCARi + kRB24IpShellD);
+  z0 += kRB24IpShellD;
+  shRB24IpShell->DefineSection(3, z0, kRB24IpShellCARi, kRB24IpShellCARi + kRB24IpShellD);
+  z0 = kRB24IpShellL - kRB24IpShellD;
+  shRB24IpShell->DefineSection(4, z0, kRB24IpShellCARi, kRB24IpShellCARi + kRB24IpShellD);
+  shRB24IpShell->DefineSection(5, z0, kRB24IpShellCARi, kRB24IpShellCCRo);
+  z0 = kRB24IpShellL;
+  shRB24IpShell->DefineSection(6, z0, kRB24IpShellCARi, kRB24IpShellCCRo);
+  TGeoVolume* voRB24IpShell = new TGeoVolume("RB24IpShell", shRB24IpShell, kMedSteel);
+    
+  TGeoPcon* shRB24IpShellM   = MakeMotherFromTemplate(shRB24IpShell, 0, 6, kRB24IpShellCTRi , 13);
+    
+    
+  for (Int_t i = 0; i < 6; i++) {
+    z = 2. * kRB24IpShellL  - shRB24IpShellM->GetZ(5-i);
+    Float_t rmin = shRB24IpShellM->GetRmin(5-i);
+    Float_t rmax = shRB24IpShellM->GetRmax(5-i);
+    shRB24IpShellM->DefineSection(7+i, z, rmin, rmax);
+  }
+    
+  TGeoVolume* voRB24IpShellM = new TGeoVolume("RB24IpShellM", shRB24IpShellM, kMedVac);
+  voRB24IpShellM->SetVisibility(0);
+  voRB24IpShellM->AddNode(voRB24IpShell, 1, gGeoIdentity);
+  voRB24IpShellM->AddNode(voRB24IpShell, 2, new TGeoCombiTrans(0., 0., 2. * kRB24IpShellL, rot180));
+  //
+  // Pos  8 Pumping Elements
+  //
+  //  Anode array
+  TGeoVolume* voRB24IpPE = new TGeoVolume("voRB24IpPE", new TGeoTube(0.9, 1., 2.54/2.), kMedSteel);
+  Float_t kRB24IpPEAR = 5.5;
+    
+  for (Int_t i = 0; i < 15; i++) {
+    Float_t phi = Float_t(i) * 24.;
+    Float_t x   =  kRB24IpPEAR * TMath::Cos(kDegRad * phi);
+    Float_t y   =  kRB24IpPEAR * TMath::Sin(kDegRad * phi);
+    voRB24IpShellM->AddNode(voRB24IpPE, i+1, new TGeoTranslation(x, y, kRB24IpShellL));
+  }
+    
+    
+  //
+  //  Cathodes
+  //
+  // Here we could add some Ti strips
+
+  // Postioning of elements
+  voRB24AIpM->AddNode(voRB24IpRF,     1, new TGeoTranslation(0., 0., -kRB24AIpML/2.));
+  voRB24AIpM->AddNode(voRB24IpRF,     2, new TGeoCombiTrans (0., 0., +kRB24AIpML/2., rot180));
+  voRB24AIpM->AddNode(voRB24IpSTT,    1, new TGeoTranslation(0., 0., 0.));
+  voRB24AIpM->AddNode(voRB24IpSTV,    1, new TGeoTranslation(0., 0., 0.));
+  voRB24AIpM->AddNode(voRB24IpShellM, 1, new TGeoTranslation(0., 0., -kRB24AIpML/2. +  8.13));
+  voRB24AIpM->AddNode(voRB24IpSTC,    1, new TGeoTranslation(0., 0., 8.13 - kRB24AIpML/2.));
+  voRB24AIpM->AddNode(voRB24IpSTC,    2, new TGeoCombiTrans (0., 0., 8.14 + 8.9 - kRB24AIpML/2., rot180));
+    
+  //
+  // Valve
+  // VAC Series 47 DN 63 with manual actuator
+  //
+  const Float_t kRB24ValveWz = 7.5;
+  const Float_t kRB24ValveDN = 10.0/2.;
+  //
+  //  Body containing the valve plate
+  //
+  const Float_t kRB24ValveBoWx =  15.6;
+  const Float_t kRB24ValveBoWy = (21.5 + 23.1 - 5.);
+  const Float_t kRB24ValveBoWz =  4.6;
+  const Float_t kRB24ValveBoD  =  0.5;
+
+  TGeoVolume* voRB24ValveBoM =
+    new TGeoVolume("RB24ValveBoM", 
+                  new TGeoBBox( kRB24ValveBoWx/2.,  kRB24ValveBoWy/2., kRB24ValveBoWz/2.), kMedAir);
+  voRB24ValveBoM->SetVisibility(0);
+  TGeoVolume* voRB24ValveBo =
+    new TGeoVolume("RB24ValveBo", 
+                  new TGeoBBox( kRB24ValveBoWx/2.,  kRB24ValveBoWy/2., kRB24ValveBoWz/2.), kMedSteel);
+  voRB24ValveBoM->AddNode(voRB24ValveBo, 1, gGeoIdentity);
+  //
+  // Inner volume
+  //
+  TGeoVolume* voRB24ValveBoI = new TGeoVolume("RB24ValveBoI", 
+                                             new TGeoBBox( kRB24ValveBoWx/2. -  kRB24ValveBoD,  
+                                                           kRB24ValveBoWy/2. -  kRB24ValveBoD/2., 
+                                                           kRB24ValveBoWz/2. -  kRB24ValveBoD), 
+                                             kMedVac);
+  voRB24ValveBo->AddNode(voRB24ValveBoI, 1, new TGeoTranslation(0., kRB24ValveBoD/2., 0.));
+  //
+  // Opening and Flanges
+  const Float_t  kRB24ValveFlRo = 18./2.;
+  const Float_t  kRB24ValveFlD  = 1.45;    
+  TGeoVolume* voRB24ValveBoA = new TGeoVolume("RB24ValveBoA", 
+                                             new TGeoTube(0., kRB24ValveDN/2., kRB24ValveBoD/2.), kMedVac);
+  voRB24ValveBo->AddNode(voRB24ValveBoA, 1, new TGeoTranslation(0., - kRB24ValveBoWy/2. + 21.5, -kRB24ValveBoWz/2. +  kRB24ValveBoD/2.));
+  voRB24ValveBo->AddNode(voRB24ValveBoA, 2, new TGeoTranslation(0., - kRB24ValveBoWy/2. + 21.5, +kRB24ValveBoWz/2. -  kRB24ValveBoD/2.));
+  TGeoVolume* voRB24ValveFl  = new TGeoVolume("RB24ValveFl",  new TGeoTube(kRB24ValveDN/2.,  kRB24ValveFlRo, kRB24ValveFlD/2.), kMedSteel);
+  TGeoVolume* voRB24ValveFlI = new TGeoVolume("RB24ValveFlI", new TGeoTube(0.,               kRB24ValveFlRo, kRB24ValveFlD/2.), kMedVac);
+  voRB24ValveFlI->AddNode(voRB24ValveFl, 1, gGeoIdentity);
+    
+  //
+  // Actuator Flange
+  const Float_t kRB24ValveAFlWx =  18.9;
+  const Float_t kRB24ValveAFlWy =   5.0;
+  const Float_t kRB24ValveAFlWz =   7.7;
+  TGeoVolume* voRB24ValveAFl = new TGeoVolume("RB24ValveAFl", new TGeoBBox(kRB24ValveAFlWx/2., kRB24ValveAFlWy/2., kRB24ValveAFlWz/2.), kMedSteel);
+  //
+  // Actuator Tube
+  const Float_t kRB24ValveATRo = 9.7/2.;
+  const Float_t kRB24ValveATH  = 16.6;
+  TGeoVolume* voRB24ValveAT = new TGeoVolume("RB24ValveAT", new TGeoTube(kRB24ValveATRo -  2. * kRB24ValveBoD,kRB24ValveATRo,  kRB24ValveATH/2.), 
+                                            kMedSteel);
+  //
+  // Manual Actuator (my best guess)
+  TGeoVolume* voRB24ValveMA1 = new TGeoVolume("RB24ValveMA1", new TGeoCone(2.5/2., 0., 0.5, 4.5, 5.), kMedSteel);
+  TGeoVolume* voRB24ValveMA2 = new TGeoVolume("RB24ValveMA2", new TGeoTorus(5., 0., 1.25), kMedSteel);
+  TGeoVolume* voRB24ValveMA3 = new TGeoVolume("RB24ValveMA3", new TGeoTube (0., 1.25, 2.5), kMedSteel);
+    
+
+  //
+  // Position all volumes
+  Float_t y0;
+  TGeoVolumeAssembly*  voRB24ValveMo = new TGeoVolumeAssembly("RB24ValveMo");
+  voRB24ValveMo->AddNode(voRB24ValveFl,  1, new TGeoTranslation(0., 0., - 7.5/2. + kRB24ValveFlD/2.));
+  voRB24ValveMo->AddNode(voRB24ValveFl,  2, new TGeoTranslation(0., 0., + 7.5/2. - kRB24ValveFlD/2.));
+  y0 = -21.5;
+  voRB24ValveMo->AddNode(voRB24ValveBoM, 1, new TGeoTranslation(0., y0 + kRB24ValveBoWy/2.,   0.));
+  y0 +=  kRB24ValveBoWy;
+  voRB24ValveMo->AddNode(voRB24ValveAFl, 1, new TGeoTranslation(0., y0 +  kRB24ValveAFlWy/2., 0.));
+  y0 +=  kRB24ValveAFlWy;
+  voRB24ValveMo->AddNode(voRB24ValveAT,  1, new TGeoCombiTrans(0.,  y0 + kRB24ValveATH/2.,    0., rotyz));
+  y0 += kRB24ValveATH;
+  voRB24ValveMo->AddNode(voRB24ValveMA1, 1, new TGeoCombiTrans(0.,  y0 + 2.5/2.,    0., rotyz));
+  y0 += 2.5;
+  voRB24ValveMo->AddNode(voRB24ValveMA2, 1, new TGeoCombiTrans(0.,  y0 + 2.5/2.,    0., rotyz));
+  y0 += 2.5;
+  voRB24ValveMo->AddNode(voRB24ValveMA3, 1, new TGeoCombiTrans(5./TMath::Sqrt(2.),  y0 + 5.0/2., 5./TMath::Sqrt(2.), rotyz));
+  //
+  // Warm Module Type VMABC
+  // LHCVMABC_0002
+  // 
+  //
+  //
+  // Flange                  1.00
+  // Central Piece          11.50
+  // Bellow                 14.50
+  // End Flange              1.00
+  //===================================
+  // Total                  28.00 
+  //                        
+  // Pos 1 Warm Bellows DN100       LHCVBU__0016
+  // Pos 2 Trans. Tube Flange       LHCVSR__0062
+  // Pos 3 RF Contact   D63         LHCVSR__0057
+  // [Pos 4 Hex. Countersunk Screw   Bossard BN4719]
+  // [Pos 5 Tension spring           LHCVSR__00239]
+  //
+
+  // Pos 1 Warm Bellows DN100                   LHCVBU__0016
+  // Pos 1.1 Right Body 2 Ports with Support    LHCVBU__0014
+  //
+  // Tube 1
+  const Float_t kRB24VMABCRBT1Ri = 10.0/2.;
+  const Float_t kRB24VMABCRBT1Ro = 10.3/2.;
+  const Float_t kRB24VMABCRBT1L  = 11.5;   
+  const Float_t kRB24VMABCRBT1L2 = 8.;
+  const Float_t kRB24VMABCL      = 28.;
+    
+  TGeoTube* shRB24VMABCRBT1 = new TGeoTube(kRB24VMABCRBT1Ri, kRB24VMABCRBT1Ro, kRB24VMABCRBT1L/2.);
+  shRB24VMABCRBT1->SetName("RB24VMABCRBT1");
+  TGeoTube* shRB24VMABCRBT1o = new TGeoTube(0., kRB24VMABCRBT1Ro,  kRB24VMABCRBT1L/2.);
+  shRB24VMABCRBT1o->SetName("RB24VMABCRBT1o");
+  TGeoTube* shRB24VMABCRBT1o2 = new TGeoTube(0., kRB24VMABCRBT1Ro + 0.3, kRB24VMABCRBT1L/2.);
+  shRB24VMABCRBT1o2->SetName("RB24VMABCRBT1o2");
+  // Lower inforcement 
+  TGeoVolume*  voRB24VMABCRBT12  = new TGeoVolume("RB24VMABCRBT12", 
+                                                 new TGeoTubeSeg(kRB24VMABCRBT1Ro, kRB24VMABCRBT1Ro + 0.3, kRB24VMABCRBT1L2/2., 220., 320.)
+                                                 , kMedSteel);
+  //
+  // Tube 2
+  const Float_t kRB24VMABCRBT2Ri =   6.0/2.;
+  const Float_t kRB24VMABCRBT2Ro =   6.3/2.;
+  const Float_t kRB24VMABCRBF2Ro =  11.4/2.;
+  const Float_t kRB24VMABCRBT2L  =   5.95 + 2.; // 2. cm added for welding    
+  const Float_t kRB24VMABCRBF2L  =   1.75;
+  TGeoTube* shRB24VMABCRBT2 = new TGeoTube(kRB24VMABCRBT2Ri, kRB24VMABCRBT2Ro,  kRB24VMABCRBT2L/2.);
+  shRB24VMABCRBT2->SetName("RB24VMABCRBT2");
+  TGeoTube* shRB24VMABCRBT2i = new TGeoTube(0., kRB24VMABCRBT2Ri, kRB24VMABCRBT2L/2. + 2.);
+  shRB24VMABCRBT2i->SetName("RB24VMABCRBT2i");
+  TGeoCombiTrans* tRBT2 = new TGeoCombiTrans(-11.5 + kRB24VMABCRBT2L/2., 0., 7.2 - kRB24VMABCRBT1L/2.  , rotxz);
+  tRBT2->SetName("tRBT2");
+  tRBT2->RegisterYourself();
+  TGeoCompositeShape* shRB24VMABCRBT2c =  new TGeoCompositeShape("shRB24VMABCRBT2c","RB24VMABCRBT2:tRBT2-RB24VMABCRBT1o");
+  TGeoVolume* voRB24VMABCRBT2 = new TGeoVolume("shRB24VMABCRBT2", shRB24VMABCRBT2c, kMedSteel);
+  // Flange
+  // Pos 1.4 Flange DN63                        LHCVBU__0008
+  TGeoVolume* voRB24VMABCRBF2 = new TGeoVolume("RB24VMABCRBF2", 
+                                              new TGeoTube(kRB24VMABCRBT2Ro, kRB24VMABCRBF2Ro, kRB24VMABCRBF2L/2.), kMedSteel);
+  // DN63 Blank Flange (my best guess)
+  TGeoVolume* voRB24VMABCRBF2B = new TGeoVolume("RB24VMABCRBF2B", 
+                                               new TGeoTube(0., kRB24VMABCRBF2Ro, kRB24VMABCRBF2L/2.), kMedSteel);
+  //
+  // Tube 3
+  const Float_t kRB24VMABCRBT3Ri =  3.5/2.;
+  const Float_t kRB24VMABCRBT3Ro =  3.8/2.;
+  const Float_t kRB24VMABCRBF3Ro =  7.0/2.;
+  const Float_t kRB24VMABCRBT3L  =  4.95 + 2.; // 2. cm added for welding    
+  const Float_t kRB24VMABCRBF3L  =  1.27;
+  TGeoTube* shRB24VMABCRBT3 = new TGeoTube(kRB24VMABCRBT3Ri, kRB24VMABCRBT3Ro,  kRB24VMABCRBT3L/2);
+  shRB24VMABCRBT3->SetName("RB24VMABCRBT3");
+  TGeoTube* shRB24VMABCRBT3i = new TGeoTube(0., kRB24VMABCRBT3Ri, kRB24VMABCRBT3L/2. + 2.);
+  shRB24VMABCRBT3i->SetName("RB24VMABCRBT3i");
+  TGeoCombiTrans* tRBT3 = new TGeoCombiTrans(0., 10.5 - kRB24VMABCRBT3L/2., 7.2 - kRB24VMABCRBT1L/2.  , rotyz);
+  tRBT3->SetName("tRBT3");
+  tRBT3->RegisterYourself();
+  TGeoCompositeShape* shRB24VMABCRBT3c =  new TGeoCompositeShape("shRB24VMABCRBT3c","RB24VMABCRBT3:tRBT3-RB24VMABCRBT1o");
+  TGeoVolume* voRB24VMABCRBT3 = new TGeoVolume("shRB24VMABCRBT3", shRB24VMABCRBT3c, kMedSteel);
+  // Flange
+  // Pos 1.4 Flange DN35                        LHCVBU__0007
+  TGeoVolume* voRB24VMABCRBF3 = new TGeoVolume("RB24VMABCRBF3", 
+                                              new TGeoTube(kRB24VMABCRBT3Ro, kRB24VMABCRBF3Ro, kRB24VMABCRBF3L/2.), kMedSteel);
+  //
+  // Tube 4
+  const Float_t kRB24VMABCRBT4Ri =  6.0/2.;
+  const Float_t kRB24VMABCRBT4Ro =  6.4/2.;
+  const Float_t kRB24VMABCRBT4L  =  6.6;    
+  TGeoTube* shRB24VMABCRBT4 = new TGeoTube(kRB24VMABCRBT4Ri, kRB24VMABCRBT4Ro,  kRB24VMABCRBT4L/2.);
+  shRB24VMABCRBT4->SetName("RB24VMABCRBT4");
+  TGeoCombiTrans* tRBT4 = new TGeoCombiTrans(0.,-11.+kRB24VMABCRBT4L/2., 7.2 - kRB24VMABCRBT1L/2.  , rotyz);
+  tRBT4->SetName("tRBT4");
+  tRBT4->RegisterYourself();
+  TGeoCompositeShape* shRB24VMABCRBT4c =  new TGeoCompositeShape("shRB24VMABCRBT4c","RB24VMABCRBT4:tRBT4-RB24VMABCRBT1o2");
+  TGeoVolume* voRB24VMABCRBT4 = new TGeoVolume("shRB24VMABCRBT4", shRB24VMABCRBT4c, kMedSteel);
+  TGeoCompositeShape* shRB24VMABCRB = new TGeoCompositeShape("shRB24VMABCRB", "RB24VMABCRBT1-(RB24VMABCRBT2i:tRBT2+RB24VMABCRBT3i:tRBT3)");
+  TGeoVolume* voRB24VMABCRBI = new TGeoVolume("RB24VMABCRBI", shRB24VMABCRB, kMedSteel);
+  //
+  // Plate
+  const Float_t kRB24VMABCRBBx = 16.0;
+  const Float_t kRB24VMABCRBBy =  1.5;
+  const Float_t kRB24VMABCRBBz = 15.0;
+    
+  // Relative position of tubes
+  const Float_t  kRB24VMABCTz =   7.2;
+  // Relative position of plate
+  const Float_t  kRB24VMABCPz =   3.6;
+  const Float_t  kRB24VMABCPy = -12.5;
+    
+  TGeoVolume* voRB24VMABCRBP = new TGeoVolume("RB24VMABCRBP", new TGeoBBox(kRB24VMABCRBBx/2., kRB24VMABCRBBy/2., kRB24VMABCRBBz/2.), kMedSteel);
+  //
+  // Pirani Gauge (my best guess)
+  //
+  TGeoPcon* shRB24VMABCPirani = new TGeoPcon(0., 360., 15);
+  // DN35/16 Coupling
+  z = 0;
+  shRB24VMABCPirani->DefineSection( 0, z,  0.8 , kRB24VMABCRBF3Ro);
+  z += kRB24VMABCRBF3L; // 1.3
+  shRB24VMABCPirani->DefineSection( 1, z,  0.8 , kRB24VMABCRBF3Ro);
+  shRB24VMABCPirani->DefineSection( 2, z,  0.8 , 1.0);
+  // Pipe
+  z += 2.8;
+  shRB24VMABCPirani->DefineSection( 3, z,  0.8 , 1.0);
+  // Flange
+  shRB24VMABCPirani->DefineSection( 4, z,  0.8 , 1.75);
+  z += 1.6;
+  shRB24VMABCPirani->DefineSection( 5, z,  0.8 , 1.75);
+  shRB24VMABCPirani->DefineSection( 6, z,  0.8 , 1.0);
+  z += 5.2;
+  shRB24VMABCPirani->DefineSection( 7, z,  0.8 , 1.0);
+  shRB24VMABCPirani->DefineSection( 8, z,  0.8 , 2.5);    
+  z += 2.0;
+  shRB24VMABCPirani->DefineSection( 9, z,  0.80, 2.50);    
+  shRB24VMABCPirani->DefineSection(10, z,  1.55, 1.75);    
+  z += 5.7;
+  shRB24VMABCPirani->DefineSection(11, z,  1.55, 1.75);    
+  shRB24VMABCPirani->DefineSection(11, z,  0.00, 1.75);    
+  z += 0.2;
+  shRB24VMABCPirani->DefineSection(12, z,  0.00, 1.75);    
+  shRB24VMABCPirani->DefineSection(13, z,  0.00, 0.75);    
+  z += 0.5;
+  shRB24VMABCPirani->DefineSection(14, z,  0.00, 0.75);  
+  TGeoVolume* voRB24VMABCPirani = new TGeoVolume("RB24VMABCPirani", shRB24VMABCPirani, kMedSteel);
+  //
+  //
+  // 
+    
+    
+  //
+  // Positioning of elements
+  TGeoVolumeAssembly* voRB24VMABCRB = new TGeoVolumeAssembly("RB24VMABCRB");
+  //
+  voRB24VMABCRB->AddNode(voRB24VMABCRBI,   1, gGeoIdentity);
+  // Plate
+  voRB24VMABCRB->AddNode(voRB24VMABCRBP,   1, new TGeoTranslation(0., kRB24VMABCPy +  kRB24VMABCRBBy /2., 
+                                                                 kRB24VMABCRBBz/2. - kRB24VMABCRBT1L/2. +  kRB24VMABCPz));
+  // Tube 2
+  voRB24VMABCRB->AddNode(voRB24VMABCRBT2,  1, gGeoIdentity);
+  // Flange Tube 2
+  voRB24VMABCRB->AddNode(voRB24VMABCRBF2,  1, new TGeoCombiTrans(kRB24VMABCPy + kRB24VMABCRBF2L/2., 0.,  kRB24VMABCTz - kRB24VMABCRBT1L/2., rotxz));
+  // Blank Flange Tube 2
+  voRB24VMABCRB->AddNode(voRB24VMABCRBF2B, 1, new TGeoCombiTrans(kRB24VMABCPy- kRB24VMABCRBF2L/2., 0.,  kRB24VMABCTz - kRB24VMABCRBT1L/2., rotxz));    
+  // Tube 3
+  voRB24VMABCRB->AddNode(voRB24VMABCRBT3,  1, gGeoIdentity);
+  // Flange Tube 3
+  voRB24VMABCRB->AddNode(voRB24VMABCRBF3,  1, new TGeoCombiTrans(0.,   11.2 - kRB24VMABCRBF3L/2.,  kRB24VMABCTz - kRB24VMABCRBT1L/2., rotyz));
+  // Pirani Gauge
+  voRB24VMABCRB->AddNode(voRB24VMABCPirani, 1, new  TGeoCombiTrans(0., 11.2,  kRB24VMABCTz - kRB24VMABCRBT1L/2., rotyz));
+  // Tube 4
+  voRB24VMABCRB->AddNode(voRB24VMABCRBT4,  1, gGeoIdentity);
+  // Inforcement 
+  voRB24VMABCRB->AddNode(voRB24VMABCRBT12, 1, new TGeoTranslation(0., 0., kRB24VMABCRBT1L2/2. - kRB24VMABCRBT1L/2. + 2.8));
+    
+
+  // Pos 1.3 Bellows with end part              LHCVBU__0002
+  //
+  // Connection Tube    
+  // Connection tube inner r
+  const Float_t kRB24VMABBEConTubeRin        = 10.0/2.;
+  // Connection tube outer r
+  const Float_t kRB24VMABBEConTubeRou        = 10.3/2.;
+  // Connection tube length
+  const Float_t kRB24VMABBEConTubeL1         =  0.9;
+  const Float_t kRB24VMABBEConTubeL2         =  2.6;
+  //  const Float_t RB24VMABBEBellowL            =  kRB24VMABBEConTubeL1 + kRB24VMABBEConTubeL2 + kRB24B1BellowUndL;
+    
+  // Mother volume
+  TGeoPcon* shRB24VMABBEBellowM = new TGeoPcon(0., 360., 6);
+  // Connection Tube and Flange
+  z = 0.;
+  shRB24VMABBEBellowM->DefineSection( 0, z, kRB24VMABBEConTubeRin,  kRB24VMABBEConTubeRou);
+  z += kRB24VMABBEConTubeL1;
+  shRB24VMABBEBellowM->DefineSection( 1, z, kRB24VMABBEConTubeRin, kRB24VMABBEConTubeRou);
+  shRB24VMABBEBellowM->DefineSection( 2, z, kRB24B1BellowRi,       kRB24B1BellowRo + kRB24B1ProtTubeThickness);
+  z += kRB24B1BellowUndL;
+  shRB24VMABBEBellowM->DefineSection( 3, z, kRB24B1BellowRi,       kRB24B1BellowRo + kRB24B1ProtTubeThickness);
+  shRB24VMABBEBellowM->DefineSection( 4, z, kRB24VMABBEConTubeRin,  kRB24VMABBEConTubeRou);
+  z += kRB24VMABBEConTubeL2;
+  shRB24VMABBEBellowM->DefineSection( 5, z, kRB24VMABBEConTubeRin,  kRB24VMABBEConTubeRou);
+  TGeoVolume* voRB24VMABBEBellowM = new TGeoVolume("RB24VMABBEBellowM", shRB24VMABBEBellowM, kMedVac);
+  voRB24VMABBEBellowM->SetVisibility(0);
+    
+  //  Connection tube left
+  TGeoVolume* voRB24VMABBECT1 = new TGeoVolume("RB24VMABBECT1", 
+                                              new TGeoTube(kRB24VMABBEConTubeRin, kRB24VMABBEConTubeRou,kRB24VMABBEConTubeL1/2.),
+                                              kMedSteel);
+  //  Connection tube right
+  TGeoVolume* voRB24VMABBECT2 = new TGeoVolume("RB24VMABBECT2", 
+                                              new TGeoTube(kRB24VMABBEConTubeRin, kRB24VMABBEConTubeRou,kRB24VMABBEConTubeL2/2.),
+                                              kMedSteel);
+  z = kRB24VMABBEConTubeL1/2.;
+  voRB24VMABBEBellowM->AddNode(voRB24VMABBECT1, 1, new TGeoTranslation(0., 0., z));
+  z += kRB24VMABBEConTubeL1/2.;
+  z += kRB24B1BellowUndL/2.;
+  voRB24VMABBEBellowM->AddNode(voRB24B1Bellow, 2, new TGeoTranslation(0., 0., z));
+  z += kRB24B1BellowUndL/2.;
+  z += kRB24VMABBEConTubeL2/2.;
+  voRB24VMABBEBellowM->AddNode(voRB24VMABBECT2, 1, new TGeoTranslation(0., 0., z));
+  z += kRB24VMABBEConTubeL2/2.;
+
+  voRB24VMABCRB->AddNode(voRB24VMABBEBellowM, 1, new TGeoTranslation(0., 0., kRB24VMABCRBT1L/2.));
+
+  // Pos 1.2 Rotable flange                     LHCVBU__0013[*]
+  // Front
+  voRB24VMABCRB->AddNode(voRB24B1RFlange,  3, new TGeoCombiTrans(0., 0., - kRB24VMABCRBT1L/2. + 0.86, rot180));
+  // End
+  z =  kRB24VMABCRBT1L/2. + kRB24B1BellowUndL +kRB24VMABBEConTubeL1 +  kRB24VMABBEConTubeL2;
+  voRB24VMABCRB->AddNode(voRB24B1RFlange,  4, new TGeoTranslation(0., 0., z - 0.86));
+
+
+  // Pos 2    Trans. Tube Flange       LHCVSR__0062
+  // Pos 2.1  Transition Tube          LHCVSR__0063
+  // Pos 2.2  Transition Flange        LHCVSR__0060
+  //
+  // Transition Tube with Flange
+  TGeoPcon* shRB24VMABCTT = new TGeoPcon(0., 360., 7);
+  z = 0.;
+  shRB24VMABCTT->DefineSection(0, z, 6.3/2., 11.16/2.);
+  z += 0.25;
+  shRB24VMABCTT->DefineSection(1, z, 6.3/2., 11.16/2.);
+  shRB24VMABCTT->DefineSection(2, z, 6.3/2.,  9.30/2.);
+  z += 0.25;
+  shRB24VMABCTT->DefineSection(3, z, 6.3/2.,  9.30/2.);
+  shRB24VMABCTT->DefineSection(4, z, 6.3/2.,  6.70/2.);
+  z += (20.35 - 0.63);
+  shRB24VMABCTT->DefineSection(5, z, 6.3/2.,  6.7/2.);
+  z += 0.63;
+  shRB24VMABCTT->DefineSection(6, z, 6.3/2.,  6.7/2.);
+  TGeoVolume* voRB24VMABCTT = new TGeoVolume("RB24VMABCTT", shRB24VMABCTT, kMedSteel);
+  voRB24VMABCRB->AddNode(voRB24VMABCTT, 1, new TGeoTranslation(0., 0., - kRB24VMABCRBT1L/2.-1.));
+
+  // Pos 3   RF Contact   D63         LHCVSR__0057
+  // Pos 3.1 RF Contact Flange        LHCVSR__0017
+  //
+  TGeoPcon* shRB24VMABCCTFlange = new TGeoPcon(0., 360., 6);
+  const Float_t kRB24VMABCCTFlangeRin  = 6.36/2.;  // Inner radius
+  const Float_t kRB24VMABCCTFlangeL    = 1.30;     // Length
+    
+  z = 0.;
+  shRB24VMABCCTFlange->DefineSection(0, z, kRB24VMABCCTFlangeRin,  6.5/2.);
+  z += 0.15;
+  shRB24VMABCCTFlange->DefineSection(1, z, kRB24VMABCCTFlangeRin,  6.5/2.);
+  shRB24VMABCCTFlange->DefineSection(2, z, kRB24VMABCCTFlangeRin,  6.9/2.);
+  z += 0.9;
+  shRB24VMABCCTFlange->DefineSection(3, z, kRB24VMABCCTFlangeRin,  6.9/2.);
+  shRB24VMABCCTFlange->DefineSection(4, z, kRB24VMABCCTFlangeRin, 11.16/2.);
+  z += 0.25;
+  shRB24VMABCCTFlange->DefineSection(5, z, kRB24VMABCCTFlangeRin, 11.16/2.);
+  TGeoVolume* voRB24VMABCCTFlange = new TGeoVolume("RB24VMABCCTFlange", shRB24VMABCCTFlange, kMedCu);
+  //
+  // Pos 3.2 RF-Contact        LHCVSR__0056
+  //
+  TGeoPcon* shRB24VMABCCT = new TGeoPcon(0., 360., 4);
+  const Float_t kRB24VMABCCTRin  = 6.30/2.;        // Inner radius
+  const Float_t kRB24VMABCCTCRin = 7.29/2.;        // Max. inner radius conical section
+  const Float_t kRB24VMABCCTL    = 11.88;          // Length
+  const Float_t kRB24VMABCCTSL   = 10.48;          // Length of straight section
+  const Float_t kRB24VMABCCTd    =  0.03;          // Thickness
+  z = 0;
+  shRB24VMABCCT->DefineSection(0, z,  kRB24VMABCCTCRin,  kRB24VMABCCTCRin + kRB24VMABCCTd);
+  z =  kRB24VMABCCTL -  kRB24VMABCCTSL;
+  shRB24VMABCCT->DefineSection(1, z,  kRB24VMABCCTRin + 0.35,  kRB24VMABCCTRin + 0.35 + kRB24VMABCCTd);
+  z = kRB24VMABCCTL  -  kRB24VMABCCTFlangeL;
+  shRB24VMABCCT->DefineSection(2, z,  kRB24VMABCCTRin,  kRB24VMABCCTRin + kRB24VMABCCTd);
+  z = kRB24VMABCCTL;
+  shRB24VMABCCT->DefineSection(3, z,  kRB24VMABCCTRin,  kRB24VMABCCTRin + kRB24VMABCCTd);
+
+  TGeoVolume* voRB24VMABCCT = new TGeoVolume("RB24VMABCCT", shRB24VMABCCT, kMedCu);
+    
+  TGeoVolumeAssembly* voRB24VMABRFCT = new TGeoVolumeAssembly("RB24VMABRFCT");
+  voRB24VMABRFCT->AddNode(voRB24VMABCCT,        1, gGeoIdentity);
+  voRB24VMABRFCT->AddNode( voRB24VMABCCTFlange, 1, new TGeoTranslation(0., 0.,  kRB24VMABCCTL - kRB24VMABCCTFlangeL));
+
+  z =  kRB24VMABCRBT1L/2. + kRB24B1BellowUndL + kRB24VMABBEConTubeL1 +  kRB24VMABBEConTubeL2 - kRB24VMABCCTL + 1.;    
+  voRB24VMABCRB->AddNode(voRB24VMABRFCT, 1, new TGeoTranslation(0., 0., z));
+
+
+  //
+  // Assembling RB24/1
+  //    
+  TGeoVolumeAssembly* voRB24 = new TGeoVolumeAssembly("RB24");
+  // Cu Tube with two simplified flanges
+  voRB24->AddNode(voRB24CuTubeM, 1, gGeoIdentity);
+  voRB24->AddNode(voRB24CuTubeA, 1, gGeoIdentity);
+  z = - kRB24CuTubeL/2 + kRB24CuTubeFL/2.;
+  voRB24->AddNode(voRB24CuTubeF, 1, new TGeoTranslation(0., 0., z));
+  z = + kRB24CuTubeL/2 - kRB24CuTubeFL/2.;
+  voRB24->AddNode(voRB24CuTubeF, 2, new TGeoTranslation(0., 0., z));
+  // VMABC close to compensator magnet
+  z = - kRB24CuTubeL/2. -  (kRB24VMABCL - kRB24VMABCRBT1L/2) + 1.;
+    
+  voRB24->AddNode(voRB24VMABCRB, 2, new TGeoTranslation(0., 0., z));
+  // Bellow
+  z =  kRB24CuTubeL/2;
+  voRB24->AddNode(voRB24B1BellowM, 1, new TGeoTranslation(0., 0., z));
+  z +=  (kRB24B1L +  kRB24AIpML/2.);
+  // Annular ion pump
+  voRB24->AddNode(voRB24AIpM, 1, new TGeoTranslation(0., 0., z));
+  z +=  (kRB24AIpML/2. +  kRB24ValveWz/2.);
+  // Valve
+  voRB24->AddNode(voRB24ValveMo, 1, new TGeoTranslation(0., 0., z));
+  z += (kRB24ValveWz/2.+ kRB24VMABCRBT1L/2. + 1.);
+  // VMABC close to forward detectors
+  voRB24->AddNode(voRB24VMABCRB, 3, new TGeoTranslation(0., 0., z));
+  //
+  //   RB24/2
+  //     
+  // Copper Tube RB24/2
+  const Float_t  kRB242CuTubeL  = 330.0;
+    
+  TGeoVolume* voRB242CuTubeM = new TGeoVolume("voRB242CuTubeM", 
+                                             new TGeoTube(0., kRB24CuTubeRo, kRB242CuTubeL/2.), kMedVac);
+  voRB24CuTubeM->SetVisibility(0);
+  TGeoVolume* voRB242CuTube = new TGeoVolume("voRB242CuTube", 
+                                            new TGeoTube(kRB24CuTubeRi, kRB24CuTubeRo, kRB242CuTubeL/2.), kMedCu);
+  voRB242CuTubeM->AddNode(voRB242CuTube, 1, gGeoIdentity);
+    
+
+  TGeoVolumeAssembly* voRB242 = new TGeoVolumeAssembly("RB242");
+  voRB242->AddNode(voRB242CuTube, 1, gGeoIdentity);
+  z = - kRB242CuTubeL/2 + kRB24CuTubeFL/2.;
+  voRB242->AddNode(voRB24CuTubeF, 3, new TGeoTranslation(0., 0., z));
+  z = + kRB242CuTubeL/2 - kRB24CuTubeFL/2.;
+  voRB242->AddNode(voRB24CuTubeF, 4, new TGeoTranslation(0., 0., z));
+  z = - kRB24CuTubeL/2 - kRB24VMABCL - kRB242CuTubeL/2.;
+  voRB24->AddNode(voRB242, 1, new TGeoTranslation(0., 0., z));
+  //
+  //   RB24/3
+  //     
+  // Copper Tube RB24/3
+  const Float_t  kRB243CuTubeL  = 303.35;
+    
+  TGeoVolume* voRB243CuTubeM = new TGeoVolume("voRB243CuTubeM", 
+                                             new TGeoTube(0., kRB24CuTubeRo, kRB243CuTubeL/2.), kMedVac);
+  voRB24CuTubeM->SetVisibility(0);
+  TGeoVolume* voRB243CuTube = new TGeoVolume("voRB243CuTube", 
+                                            new TGeoTube(kRB24CuTubeRi, kRB24CuTubeRo, kRB243CuTubeL/2.), kMedCu);
+  voRB243CuTubeM->AddNode(voRB243CuTube, 1, gGeoIdentity);
+    
+
+  TGeoVolumeAssembly* voRB243  = new TGeoVolumeAssembly("RB243");
+  TGeoVolumeAssembly* voRB243A = new TGeoVolumeAssembly("RB243A");
+    
+  voRB243A->AddNode(voRB243CuTube, 1, gGeoIdentity);
+  z = - kRB243CuTubeL/2 + kRB24CuTubeFL/2.;
+  voRB243A->AddNode(voRB24CuTubeF, 5, new TGeoTranslation(0., 0., z));
+  z = + kRB243CuTubeL/2 - kRB24CuTubeFL/2.;
+  voRB243A->AddNode(voRB24CuTubeF,    6, new TGeoTranslation(0., 0., z));
+  z = + kRB243CuTubeL/2;
+  voRB243A->AddNode(voRB24B1BellowM,  2, new TGeoTranslation(0., 0., z));    
+
+  z = - kRB243CuTubeL/2.  - kRB24B1L;
+  voRB243->AddNode(voRB243A, 1, new TGeoTranslation(0., 0., z));    
+  z = - (1.5 * kRB243CuTubeL + 2. * kRB24B1L);
+  voRB243->AddNode(voRB243A, 2, new TGeoTranslation(0., 0., z));    
+
+  z = - 2. * (kRB243CuTubeL + kRB24B1L) - (kRB24VMABCL - kRB24VMABCRBT1L/2) + 1.;
+  voRB243->AddNode(voRB24VMABCRB, 3, new TGeoTranslation(0., 0., z));    
+    
+  z = - kRB24CuTubeL/2 - kRB24VMABCL - kRB242CuTubeL;
+  voRB24->AddNode(voRB243, 1, new TGeoTranslation(0., 0., z));
+
+
+  //
+  //
+  top->AddNode(voRB24, 1, new TGeoCombiTrans(0., 0., kRB24CuTubeL/2 + 88.5 + 400., rot180));
+
+
+  // 
+  ////////////////////////////////////////////////////////////////////////////////     
+  //                                                                            //
+  //                                  The Absorber Vacuum system                // 
+  //                                                                            //
+  ////////////////////////////////////////////////////////////////////////////////
+  //
+  //    Rotable Flange starts at:            82.00 cm from IP      
+  //    Length of rotable flange section:    10.68 cm             
+  //    Weld                                  0.08 cm                  
+  //    Length of straight section          207.21 cm
+  //    =======================================================================
+  //                                        299.97 cm  [0.03 cm missing ?]
+  //    Length of opening cone              252.09 cm
+  //    Weld                                  0.15 cm                
+  //    Length of compensator                30.54 cm
+  //    Weld                                  0.15 cm                
+  //    Length of fixed flange  2.13 - 0.97   1.16 cm
+  //    ======================================================================= 
+  //                                        584.06 cm [584.80 installed] [0.74 cm missing]
+  //    RB26/3
+  //    Length of split flange  2.13 - 1.2    0.93 cm
+  //    Weld                                  0.15 cm                
+  //    Length of fixed point section        16.07 cm               
+  //    Weld                                  0.15 cm                
+  //    Length of opening cone              629.20 cm
+  //    Weld                                  0.30 cm                
+  //    Kength of the compensator            41.70 cm
+  //    Weld                                  0.30 cm                
+  //    Length of fixed flange  2.99 - 1.72   1.27 cm
+  // =================================================
+  //    Length of RB26/3                    690.07 cm [689.20 installed] [0.87 cm too much] 
+  //
+  //    RB26/4-5
+  //    Length of split flange  2.13 - 1.2    0.93 cm
+  //    Weld                                  0.15 cm                
+  //    Length of fixed point section        16.07 cm               
+  //    Weld                                  0.15 cm                
+  //    Length of opening cone              629.20 cm
+  //    Weld                                  0.30 cm                
+  //    Length of closing cone
+  //    Weld
+  //    Lenth of straight section 
+  //    Kength of the compensator            41.70 cm
+  //    Weld                                  0.30 cm                
+  //    Length of fixed flange  2.99 - 1.72   1.27 cm
+  // =================================================
+  //    Length of RB26/3                    690.07 cm [689.20 installed] [0.87 cm too much] 
+      
+  ///////////////////////////////////////////
+  //                                       //
+  //    RB26/1-2                           //  
+  //    Drawing LHCV2a_0050 [as installed] //
+  //    Drawing LHCV2a_0008                //
+  //    Drawing LHCV2a_0001                //
+  ///////////////////////////////////////////
+  //    Pos1 Vacuum Tubes   LHCVC2A__0010
+  //    Pos2 Compensator    LHCVC2A__0064
+  //    Pos3 Rotable Flange LHCVFX___0016
+  //    Pos4 Fixed Flange   LHCVFX___0006
+  //    Pos5 Bellow Tooling LHCVFX___0003
+  //
+  //             
+  //
+  ///////////////////////////////////
+  //    RB26/1-2 Vacuum Tubes      //
+  //    Drawing  LHCVC2a_0010      //
+  ///////////////////////////////////
+  const Float_t kRB26s12TubeL = 459.45; // 0.15 cm added for welding       
+  //
+  // Add 1 cm on outer diameter for insulation
+  //
+  TGeoPcon* shRB26s12Tube = new TGeoPcon(0., 360., 5);
+  // Section 1: straight section
+  shRB26s12Tube->DefineSection(0,   0.00,         5.84/2.,  6.00/2.);
+  shRB26s12Tube->DefineSection(1, 207.21,         5.84/2.,  6.00/2.);      
+  // Section 2: 0.72 deg opening cone
+  shRB26s12Tube->DefineSection(2, 207.21,         5.84/2.,  6.14/2.);      
+  shRB26s12Tube->DefineSection(3, 452.30,        12.00/2., 12.30/2.);      
+  shRB26s12Tube->DefineSection(4, kRB26s12TubeL, 12.00/2., 12.30/2.); 
+  TGeoVolume* voRB26s12Tube  = new TGeoVolume("RB26s12Tube", shRB26s12Tube, kMedSteel);
+  // Add the insulation layer    
+  TGeoVolume* voRB26s12TubeIns = new TGeoVolume("RB26s12TubeIns", MakeInsulationFromTemplate(shRB26s12Tube), kMedInsu); 
+  voRB26s12Tube->AddNode(voRB26s12TubeIns, 1, gGeoIdentity);
+
+  TGeoVolume* voRB26s12TubeM  = new TGeoVolume("RB26s12TubeM", MakeMotherFromTemplate(shRB26s12Tube), kMedVac);
+  voRB26s12TubeM->AddNode(voRB26s12Tube, 1, gGeoIdentity);
+      
+
+      
+  ///////////////////////////////////
+  //    RB26/2   Axial Compensator //
+  //    Drawing  LHCVC2a_0064      //
+  ///////////////////////////////////
+  const Float_t kRB26s2CompL             = 30.65;    // Length of the compensator
+  const Float_t kRB26s2BellowRo          = 14.38/2.; // Bellow outer radius        [Pos 1]
+  const Float_t kRB26s2BellowRi          = 12.12/2.; // Bellow inner radius        [Pos 1] 
+  const Int_t   kRB26s2NumberOfPlies     = 14;       // Number of plies            [Pos 1] 
+  const Float_t kRB26s2BellowUndL        = 10.00;    // Length of undulated region [Pos 1]  [+10 mm installed including pretension ?] 
+  const Float_t kRB26s2PlieThickness     =  0.025;   // Plie thickness             [Pos 1]
+  const Float_t kRB26s2ConnectionPlieR   =  0.21;    // Connection plie radius     [Pos 1] 
+  //  Plie radius
+  const Float_t kRB26s2PlieR = 
+    (kRB26s2BellowUndL - 4. *  kRB26s2ConnectionPlieR + 2. * kRB26s2PlieThickness + 
+     (2. *  kRB26s2NumberOfPlies - 2.) * kRB26s2PlieThickness) / (4. * kRB26s2NumberOfPlies - 2.);
+  const Float_t kRB26s2CompTubeInnerR    = 12.00/2.;  // Connection tubes inner radius     [Pos 2 + 3]
+  const Float_t kRB26s2CompTubeOuterR    = 12.30/2.;  // Connection tubes outer radius     [Pos 2 + 3]
+  const Float_t kRB26s2WeldingTubeLeftL  =  9.00/2.;  // Left connection tube half length  [Pos 2]
+  const Float_t kRB26s2WeldingTubeRightL = 11.65/2.;  // Right connection tube half length [Pos 3]  [+ 0.15 cm for welding]
+  const Float_t kRB26s2RingOuterR        = 18.10/2.;  // Ring inner radius                 [Pos 4]
+  const Float_t kRB26s2RingL             =  0.40/2.;  // Ring half length                  [Pos 4]
+  const Float_t kRB26s2RingZ             =  6.50   ;  // Ring z-position                   [Pos 4]
+  const Float_t kRB26s2ProtOuterR        = 18.20/2.;  // Protection tube outer radius      [Pos 5]
+  const Float_t kRB26s2ProtL             = 15.00/2.;  // Protection tube half length       [Pos 5]
+  const Float_t kRB26s2ProtZ             =  6.70   ;  // Protection tube z-position        [Pos 5]
+   
+      
+  // Mother volume
+  //
+  TGeoPcon* shRB26s2Compensator  = new TGeoPcon(0., 360., 6);
+  shRB26s2Compensator->DefineSection( 0,   0.0, 0., kRB26s2CompTubeOuterR);
+  shRB26s2Compensator->DefineSection( 1,   kRB26s2RingZ, 0., kRB26s2CompTubeOuterR);      
+  shRB26s2Compensator->DefineSection( 2,   kRB26s2RingZ, 0., kRB26s2ProtOuterR);      
+  shRB26s2Compensator->DefineSection( 3,   kRB26s2ProtZ + 2. * kRB26s2ProtL, 0., kRB26s2ProtOuterR);            
+  shRB26s2Compensator->DefineSection( 4,   kRB26s2ProtZ + 2. * kRB26s2ProtL, 0., kRB26s2CompTubeOuterR);
+  shRB26s2Compensator->DefineSection( 5,   kRB26s2CompL                    , 0., kRB26s2CompTubeOuterR);            
+  TGeoVolume* voRB26s2Compensator  = new TGeoVolume("RB26s2Compensator", shRB26s2Compensator, kMedVac);
+            
+  //
+  // [Pos 1] Bellow
+  //      
+  //
+  TGeoVolume* voRB26s2Bellow = new TGeoVolume("RB26s2Bellow", new TGeoTube(kRB26s2BellowRi, kRB26s2BellowRo, kRB26s2BellowUndL/2.), kMedVac);
+  //      
+  //  Upper part of the undulation
+  //
+  TGeoTorus* shRB26s2PlieTorusU  =  new TGeoTorus(kRB26s2BellowRo - kRB26s2PlieR, kRB26s2PlieR - kRB26s2PlieThickness, kRB26s2PlieR);
+  shRB26s2PlieTorusU->SetName("RB26s2TorusU");
+  TGeoTube*  shRB26s2PlieTubeU   =  new TGeoTube (kRB26s2BellowRo - kRB26s2PlieR, kRB26s2BellowRo, kRB26s2PlieR);
+  shRB26s2PlieTubeU->SetName("RB26s2TubeU");
+  TGeoCompositeShape*  shRB26s2UpperPlie = new TGeoCompositeShape("RB26s2UpperPlie", "RB26s2TorusU*RB26s2TubeU");
+  TGeoVolume* voRB26s2WiggleU = new TGeoVolume("RB26s2UpperPlie", shRB26s2UpperPlie, kMedSteel);
+  //
+  // Lower part of the undulation
+  TGeoTorus* shRB26s2PlieTorusL =  new TGeoTorus(kRB26s2BellowRi + kRB26s2PlieR, kRB26s2PlieR - kRB26s2PlieThickness, kRB26s2PlieR);
+  shRB26s2PlieTorusL->SetName("RB26s2TorusL");
+  TGeoTube*  shRB26s2PlieTubeL   =  new TGeoTube (kRB26s2BellowRi, kRB26s2BellowRi + kRB26s2PlieR, kRB26s2PlieR);
+  shRB26s2PlieTubeL->SetName("RB26s2TubeL");
+  TGeoCompositeShape*  shRB26s2LowerPlie = new TGeoCompositeShape("RB26s2LowerPlie", "RB26s2TorusL*RB26s2TubeL");
+      
+  TGeoVolume* voRB26s2WiggleL = new TGeoVolume("RB26s2LowerPlie", shRB26s2LowerPlie, kMedSteel); 
+
+  //
+  // Connection between upper and lower part of undulation
+  TGeoVolume* voRB26s2WiggleC1 = new TGeoVolume("RB26s2PlieConn1",  
+                                               new TGeoTube(kRB26s2BellowRi + kRB26s2PlieR, 
+                                                            kRB26s2BellowRo - kRB26s2PlieR, kRB26s2PlieThickness / 2.), kMedSteel);
+  //
+  // One wiggle
+  TGeoVolumeAssembly* voRB26s2Wiggle = new TGeoVolumeAssembly("RB26s2Wiggle");
+  z0 =  -  kRB26s2PlieThickness / 2.;
+  voRB26s2Wiggle->AddNode(voRB26s2WiggleC1,  1 , new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s2PlieR -  kRB26s2PlieThickness / 2.;
+  voRB26s2Wiggle->AddNode(voRB26s2WiggleU,   1 , new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s2PlieR -  kRB26s2PlieThickness / 2.;
+  voRB26s2Wiggle->AddNode(voRB26s2WiggleC1,  2 , new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s2PlieR -  kRB26s2PlieThickness;
+  voRB26s2Wiggle->AddNode(voRB26s2WiggleL ,  1 , new TGeoTranslation(0., 0., z0));
+  // Positioning of the volumes
+  z0   = - kRB26s2BellowUndL/2.+ kRB26s2ConnectionPlieR;
+  voRB26s2Bellow->AddNode(voRB26s2WiggleL, 1, new TGeoTranslation(0., 0., z0));
+  z0  +=  kRB26s2ConnectionPlieR;
+  zsh  = 4. *  kRB26s2PlieR -  2. * kRB26s2PlieThickness;
+  for (Int_t iw = 0; iw < kRB26s2NumberOfPlies; iw++) {
+    Float_t zpos =  z0 + iw * zsh;     
+    voRB26s2Bellow->AddNode(voRB26s2Wiggle,  iw + 1, new TGeoTranslation(0., 0., zpos -  kRB26s2PlieThickness));       
+  }
+
+  voRB26s2Compensator->AddNode(voRB26s2Bellow, 1,  new TGeoTranslation(0., 0., 2. * kRB26s2WeldingTubeLeftL + kRB26s2BellowUndL/2.));
+      
+  //
+  // [Pos 2] Left Welding Tube
+  //      
+  TGeoTube* shRB26s2CompLeftTube = new TGeoTube(kRB26s2CompTubeInnerR, kRB26s2CompTubeOuterR, kRB26s2WeldingTubeLeftL);
+  TGeoVolume* voRB26s2CompLeftTube = new TGeoVolume("RB26s2CompLeftTube", shRB26s2CompLeftTube, kMedSteel);
+  voRB26s2Compensator->AddNode(voRB26s2CompLeftTube, 1,  new TGeoTranslation(0., 0., kRB26s2WeldingTubeLeftL));
+  //
+  // [Pos 3] Right Welding Tube
+  //      
+  TGeoTube* shRB26s2CompRightTube = new TGeoTube(kRB26s2CompTubeInnerR, kRB26s2CompTubeOuterR, kRB26s2WeldingTubeRightL);
+  TGeoVolume* voRB26s2CompRightTube = new TGeoVolume("RB26s2CompRightTube", shRB26s2CompRightTube, kMedSteel);
+  voRB26s2Compensator->AddNode(voRB26s2CompRightTube,  1, new TGeoTranslation(0., 0.,  kRB26s2CompL - kRB26s2WeldingTubeRightL));
+  //
+  // [Pos 4] Ring
+  //      
+  TGeoTube* shRB26s2CompRing = new TGeoTube(kRB26s2CompTubeOuterR, kRB26s2RingOuterR, kRB26s2RingL);
+  TGeoVolume* voRB26s2CompRing = new TGeoVolume("RB26s2CompRing", shRB26s2CompRing, kMedSteel);
+  voRB26s2Compensator->AddNode(voRB26s2CompRing,  1, new TGeoTranslation(0., 0., kRB26s2RingZ + kRB26s2RingL));
+
+  //
+  // [Pos 5] Outer Protecting Tube
+  //      
+  TGeoTube* shRB26s2CompProtTube = new TGeoTube(kRB26s2RingOuterR, kRB26s2ProtOuterR, kRB26s2ProtL);
+  TGeoVolume* voRB26s2CompProtTube = new TGeoVolume("RB26s2CompProtTube", shRB26s2CompProtTube, kMedSteel);
+  voRB26s2Compensator->AddNode(voRB26s2CompProtTube, 1,  new TGeoTranslation(0., 0., kRB26s2ProtZ + kRB26s2ProtL));
+      
+  ///////////////////////////////////
+  //    Rotable Flange             //
+  //    Drawing  LHCVFX_0016       //
+  /////////////////////////////////// 
+  const Float_t kRB26s1RFlangeTubeRi    = 5.84/2.-lolo ;  // Tube inner radius
+  const Float_t kRB26s1RFlangeTubeRo    = 6.00/2.-lolo ;  // Tube outer radius
+
+  // Pos 1 Clamp Ring          LHCVFX__0015
+  const Float_t kRB26s1RFlangeCrL       = 1.40     ; // Lenth of the clamp ring
+  const Float_t kRB26s1RFlangeCrRi1     = 6.72/2.-lolo-1. ; // Ring inner radius section 1
+  const Float_t kRB26s1RFlangeCrRi2     = 6.06/2.-lolo-1.  ; // Ring inner radius section 2
+  const Float_t kRB26s1RFlangeCrRo      = 8.60/2.-lolo-1.  ; // Ring outer radius 
+  const Float_t kRB26s1RFlangeCrD       = 0.800    ; // Width section 1
+      
+  TGeoPcon* shRB26s1RFlangeCr = new TGeoPcon(0., 360., 4);
+  z0 = 0.;
+  shRB26s1RFlangeCr->DefineSection(0, z0, kRB26s1RFlangeCrRi1, kRB26s1RFlangeCrRo);
+  z0 += kRB26s1RFlangeCrD;
+  shRB26s1RFlangeCr->DefineSection(1, z0, kRB26s1RFlangeCrRi1, kRB26s1RFlangeCrRo);
+  shRB26s1RFlangeCr->DefineSection(2, z0, kRB26s1RFlangeCrRi2, kRB26s1RFlangeCrRo);      
+  z0 = kRB26s1RFlangeCrL;
+  shRB26s1RFlangeCr->DefineSection(3, z0, kRB26s1RFlangeCrRi2, kRB26s1RFlangeCrRo);
+  TGeoVolume* voRB26s1RFlangeCr =  
+    new TGeoVolume("RB26s1RFlangeCr", shRB26s1RFlangeCr, kMedSteel);
+
+  // Pos 2 Insert              LHCVFX__0015
+  const Float_t kRB26s1RFlangeIsL       = 4.88     ; // Lenth of the insert
+  const Float_t kRB26s1RFlangeIsR       = 6.70/2.-lolo  ; // Ring radius
+  const Float_t kRB26s1RFlangeIsD       = 0.80     ; // Ring Width
+
+  TGeoPcon* shRB26s1RFlangeIs = new TGeoPcon(0., 360., 4);
+  z0 = 0.;
+  shRB26s1RFlangeIs->DefineSection(0, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeIsR);
+  z0 += kRB26s1RFlangeIsD;
+  shRB26s1RFlangeIs->DefineSection(1, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeIsR);
+  shRB26s1RFlangeIs->DefineSection(2, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeTubeRo);      
+  z0 = kRB26s1RFlangeIsL;
+  shRB26s1RFlangeIs->DefineSection(3, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeTubeRo);
+  TGeoVolume* voRB26s1RFlangeIs =  
+    new TGeoVolume("RB26s1RFlangeIs", shRB26s1RFlangeIs, kMedSteel);
+  // 4.88 + 3.7 = 8.58 (8.7 to avoid overlap)
+  // Pos 3 Fixed Point Section LHCVC2A_0021
+  const Float_t kRB26s1RFlangeFpL       = 5.88     ; // Length of the fixed point section (0.08 cm added for welding)
+  const Float_t kRB26s1RFlangeFpZ       = 3.82     ; // Position of the ring
+  const Float_t kRB26s1RFlangeFpD       = 0.59     ; // Width of the ring
+  const Float_t kRB26s1RFlangeFpR       = 7.00/2.-lolo  ; // Radius of the ring
+      
+  TGeoPcon* shRB26s1RFlangeFp = new TGeoPcon(0., 360., 6);
+  z0 = 0.;
+  shRB26s1RFlangeFp->DefineSection(0, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeTubeRo);
+  z0 += kRB26s1RFlangeFpZ;
+  shRB26s1RFlangeFp->DefineSection(1, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeTubeRo);      
+  shRB26s1RFlangeFp->DefineSection(2, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeFpR);              
+  z0 += kRB26s1RFlangeFpD;
+  shRB26s1RFlangeFp->DefineSection(3, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeFpR);              
+  shRB26s1RFlangeFp->DefineSection(4, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeTubeRo);
+  z0 = kRB26s1RFlangeFpL;
+  shRB26s1RFlangeFp->DefineSection(5, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeTubeRo);
+  TGeoVolume* voRB26s1RFlangeFp = new TGeoVolume("RB26s1RFlangeFp", shRB26s1RFlangeFp, kMedSteel);
+            
+  // Put everything in a mother volume
+  TGeoPcon* shRB26s1RFlange = new TGeoPcon(0., 360., 8);
+  z0 =  0.;
+  shRB26s1RFlange->DefineSection(0, z0, 0., kRB26s1RFlangeCrRo);
+  z0 += kRB26s1RFlangeCrL;
+  shRB26s1RFlange->DefineSection(1, z0, 0., kRB26s1RFlangeCrRo);
+  shRB26s1RFlange->DefineSection(2, z0, 0., kRB26s1RFlangeTubeRo);
+  z0 = kRB26s1RFlangeIsL + kRB26s1RFlangeFpZ;
+  shRB26s1RFlange->DefineSection(3, z0, 0., kRB26s1RFlangeTubeRo);      
+  shRB26s1RFlange->DefineSection(4, z0, 0., kRB26s1RFlangeFpR);
+  z0 += kRB26s1RFlangeFpD;
+  shRB26s1RFlange->DefineSection(5, z0, 0., kRB26s1RFlangeFpR);          
+  shRB26s1RFlange->DefineSection(6, z0, 0., kRB26s1RFlangeTubeRo);
+  z0 = kRB26s1RFlangeIsL + kRB26s1RFlangeFpL;
+  shRB26s1RFlange->DefineSection(7, z0, 0., kRB26s1RFlangeTubeRo);
+  TGeoVolume* voRB26s1RFlange = new TGeoVolume("RB26s1RFlange", shRB26s1RFlange, kMedVac);
+
+  voRB26s1RFlange->AddNode(voRB26s1RFlangeIs, 1, gGeoIdentity);
+  voRB26s1RFlange->AddNode(voRB26s1RFlangeCr, 1, gGeoIdentity);
+  voRB26s1RFlange->AddNode(voRB26s1RFlangeFp, 1, new TGeoTranslation(0., 0., kRB26s1RFlangeIsL));
+      
+  ///////////////////////////////////
+  //    Fixed Flange               //
+  //    Drawing  LHCVFX_0006       //
+  /////////////////////////////////// 
+  const Float_t kRB26s2FFlangeL      =  2.13;    // Length of the flange
+  const Float_t kRB26s2FFlangeD1     =  0.97;    // Length of section 1
+  const Float_t kRB26s2FFlangeD2     =  0.29;    // Length of section 2                                                     
+  const Float_t kRB26s2FFlangeD3     =  0.87;    // Length of section 3                                                           
+  const Float_t kRB26s2FFlangeRo     = 17.15/2.; // Flange outer radius 
+  const Float_t kRB26s2FFlangeRi1    = 12.30/2.; // Flange inner radius section 1
+  const Float_t kRB26s2FFlangeRi2    = 12.00/2.; // Flange inner radius section 2
+  const Float_t kRB26s2FFlangeRi3    = 12.30/2.; // Flange inner radius section 3
+  z0 = 0;
+  TGeoPcon* shRB26s2FFlange = new TGeoPcon(0., 360., 6);
+  z0 = 0.;
+  shRB26s2FFlange->DefineSection(0, z0, kRB26s2FFlangeRi1, kRB26s2FFlangeRo);
+  z0 += kRB26s2FFlangeD1;
+  shRB26s2FFlange->DefineSection(1, z0, kRB26s2FFlangeRi1, kRB26s2FFlangeRo);
+  shRB26s2FFlange->DefineSection(2, z0, kRB26s2FFlangeRi2, kRB26s2FFlangeRo);
+  z0 += kRB26s2FFlangeD2;
+  shRB26s2FFlange->DefineSection(3, z0, kRB26s2FFlangeRi2, kRB26s2FFlangeRo);
+  shRB26s2FFlange->DefineSection(4, z0, kRB26s2FFlangeRi3, kRB26s2FFlangeRo);
+  z0 += kRB26s2FFlangeD3;
+  shRB26s2FFlange->DefineSection(5, z0, kRB26s2FFlangeRi3, kRB26s2FFlangeRo);
+  TGeoVolume* voRB26s2FFlange = new TGeoVolume("RB26s2FFlange", shRB26s2FFlange, kMedSteel);
+
+  TGeoVolume* voRB26s2FFlangeM = new TGeoVolume("RB26s2FFlangeM", MakeMotherFromTemplate(shRB26s2FFlange, 2, 5), kMedVac);
+  voRB26s2FFlangeM->AddNode(voRB26s2FFlange, 1, gGeoIdentity);
+      
+      
+
+  ////////////////////////////////////////
+  //                                    //
+  //    RB26/3                          //  
+  //    Drawing LHCV2a_0048             //
+  //    Drawing LHCV2a_0002             //
+  ////////////////////////////////////////    
+  //
+  //    Pos 1 Vacuum Tubes      LHCVC2A__0003
+  //    Pos 2 Fixed Point       LHCVFX___0005
+  //    Pos 3 Split Flange      LHCVFX___0007
+  //    Pos 4 Fixed Flange      LHCVFX___0004
+  //    Pos 5 Axial Compensator LHCVC2A__0065
+  //
+  //
+  //
+  //
+  ///////////////////////////////////
+  //    Vacuum Tube                //
+  //    Drawing  LHCVC2A_0003      //
+  /////////////////////////////////// 
+  const Float_t kRB26s3TubeL  = 629.35 + 0.3; // 0.3 cm added for welding
+  const Float_t kRB26s3TubeR1 =  12./2.;
+  const Float_t kRB26s3TubeR2 =  kRB26s3TubeR1 + 215.8 * TMath::Tan(0.829 / 180. * TMath::Pi());
+      
+      
+  TGeoPcon* shRB26s3Tube = new TGeoPcon(0., 360., 7);
+  // Section 1: straight section
+  shRB26s3Tube->DefineSection(0,   0.00, kRB26s3TubeR1, kRB26s3TubeR1 + 0.15);
+  shRB26s3Tube->DefineSection(1,   2.00, kRB26s3TubeR1, kRB26s3TubeR1 + 0.15);      
+  // Section 2: 0.829 deg opening cone
+  shRB26s3Tube->DefineSection(2,   2.00, kRB26s3TubeR1, kRB26s3TubeR1 + 0.20);
+      
+  shRB26s3Tube->DefineSection(3, 217.80, kRB26s3TubeR2, kRB26s3TubeR2 + 0.20);
+  shRB26s3Tube->DefineSection(4, 217.80, kRB26s3TubeR2, kRB26s3TubeR2 + 0.30);      
+
+  shRB26s3Tube->DefineSection(5, 622.20,       30.00/2., 30.60/2.);      
+  shRB26s3Tube->DefineSection(6, kRB26s3TubeL, 30.00/2., 30.60/2.); 
+
+  TGeoVolume* voRB26s3Tube = new TGeoVolume("RB26s3Tube", shRB26s3Tube, kMedSteel);
+  //    Add the insulation layer
+  TGeoVolume* voRB26s3TubeIns = new TGeoVolume("RB26s3TubeIns", MakeInsulationFromTemplate(shRB26s3Tube), kMedInsu); 
+  voRB26s3Tube->AddNode(voRB26s3TubeIns, 1, gGeoIdentity);
+
+  TGeoVolume* voRB26s3TubeM  = new TGeoVolume("RB26s3TubeM", MakeMotherFromTemplate(shRB26s3Tube), kMedVac);
+  voRB26s3TubeM->AddNode(voRB26s3Tube, 1, gGeoIdentity);
+
+      
+
+  ///////////////////////////////////
+  //    Fixed Point                //
+  //    Drawing  LHCVFX_0005       //
+  /////////////////////////////////// 
+  const Float_t kRB26s3FixedPointL       = 16.37     ; // Length of the fixed point section (0.3 cm added for welding)
+  const Float_t kRB26s3FixedPointZ       =  9.72     ; // Position of the ring (0.15 cm added for welding)
+  const Float_t kRB26s3FixedPointD       =  0.595    ; // Width of the ring
+  const Float_t kRB26s3FixedPointR       = 13.30/2.  ; // Radius of the ring
+  const Float_t kRB26s3FixedPointRi      = 12.00/2.  ; // Inner radius of the tube
+  const Float_t kRB26s3FixedPointRo1     = 12.30/2.  ; // Outer radius of the tube (in)
+  const Float_t kRB26s3FixedPointRo2     = 12.40/2.  ; // Outer radius of the tube (out)
+  const Float_t kRB26s3FixedPointDs      =  1.5      ; // Width of straight section behind ring
+  const Float_t kRB26s3FixedPointDc      =  3.15     ; // Width of conical  section behind ring (0.15 cm added for welding)      
+      
+  TGeoPcon* shRB26s3FixedPoint = new TGeoPcon(0., 360., 8);
+  z0 = 0.;
+  shRB26s3FixedPoint->DefineSection(0, z0, kRB26s3FixedPointRi, kRB26s3FixedPointRo1);
+  z0 += kRB26s3FixedPointZ;
+  shRB26s3FixedPoint->DefineSection(1, z0, kRB26s3FixedPointRi, kRB26s3FixedPointRo1);      
+  shRB26s3FixedPoint->DefineSection(2, z0, kRB26s3FixedPointRi, kRB26s3FixedPointR);             
+  z0 += kRB26s3FixedPointD;
+  shRB26s3FixedPoint->DefineSection(3, z0, kRB26s3FixedPointRi, kRB26s3FixedPointR);             
+  shRB26s3FixedPoint->DefineSection(4, z0, kRB26s3FixedPointRi, kRB26s3FixedPointRo1);
+  z0 += kRB26s3FixedPointDs;
+  shRB26s3FixedPoint->DefineSection(5, z0, kRB26s3FixedPointRi, kRB26s3FixedPointRo1);
+  z0 += kRB26s3FixedPointDc;
+  shRB26s3FixedPoint->DefineSection(6, z0, kRB26s3FixedPointRi, kRB26s3FixedPointRo2);
+  z0 = kRB26s3FixedPointL;
+  shRB26s3FixedPoint->DefineSection(7, z0, kRB26s3FixedPointRi, kRB26s3FixedPointRo2);
+  TGeoVolume* voRB26s3FixedPoint = new TGeoVolume("RB26s3FixedPoint", shRB26s3FixedPoint, kMedSteel);
+
+  TGeoVolume* voRB26s3FixedPointM = new TGeoVolume("RB26s3FixedPointM", MakeMotherFromTemplate(shRB26s3FixedPoint), kMedVac);
+  voRB26s3FixedPointM->AddNode(voRB26s3FixedPoint, 1, gGeoIdentity);
+      
+  ///////////////////////////////////
+  //    Split Flange               //
+  //    Drawing  LHCVFX_0005       //
+  /////////////////////////////////// 
+  const Float_t kRB26s3SFlangeL      =  2.13;        // Length of the flange
+  const Float_t kRB26s3SFlangeD1     =  0.57;        // Length of section 1
+  const Float_t kRB26s3SFlangeD2     =  0.36;        // Length of section 2                                                 
+  const Float_t kRB26s3SFlangeD3     =  0.50 + 0.70; // Length of section 3                                                       
+  const Float_t kRB26s3SFlangeRo     = 17.15/2.;     // Flange outer radius 
+  const Float_t kRB26s3SFlangeRi1    = 12.30/2.;     // Flange inner radius section 1
+  const Float_t kRB26s3SFlangeRi2    = 12.00/2.;     // Flange inner radius section 2
+  const Float_t kRB26s3SFlangeRi3    = 12.30/2.;     // Flange inner radius section 3
+  z0 = 0;
+  TGeoPcon* shRB26s3SFlange = new TGeoPcon(0., 360., 6);
+  z0 = 0.;
+  shRB26s3SFlange->DefineSection(0, z0, kRB26s3SFlangeRi1, kRB26s3SFlangeRo);
+  z0 += kRB26s3SFlangeD1;
+  shRB26s3SFlange->DefineSection(1, z0, kRB26s3SFlangeRi1, kRB26s3SFlangeRo);
+  shRB26s3SFlange->DefineSection(2, z0, kRB26s3SFlangeRi2, kRB26s3SFlangeRo);
+  z0 += kRB26s3SFlangeD2;
+  shRB26s3SFlange->DefineSection(3, z0, kRB26s3SFlangeRi2, kRB26s3SFlangeRo);
+  shRB26s3SFlange->DefineSection(4, z0, kRB26s3SFlangeRi3, kRB26s3SFlangeRo);
+  z0 += kRB26s3SFlangeD3;
+  shRB26s3SFlange->DefineSection(5, z0, kRB26s3SFlangeRi3, kRB26s3SFlangeRo);
+  TGeoVolume* voRB26s3SFlange = new TGeoVolume("RB26s3SFlange", shRB26s3SFlange, kMedSteel);
+
+  TGeoVolume* voRB26s3SFlangeM = new TGeoVolume("RB26s3SFlangeM", MakeMotherFromTemplate(shRB26s3SFlange, 0, 3), kMedVac);
+  voRB26s3SFlangeM->AddNode(voRB26s3SFlange, 1, gGeoIdentity);
+        
+  ///////////////////////////////////
+  //    RB26/3   Fixed Flange      //
+  //    Drawing  LHCVFX___0004     //
+  /////////////////////////////////// 
+  const Float_t kRB26s3FFlangeL      =  2.99;    // Length of the flange
+  const Float_t kRB26s3FFlangeD1     =  1.72;    // Length of section 1
+  const Float_t kRB26s3FFlangeD2     =  0.30;    // Length of section 2                                                     
+  const Float_t kRB26s3FFlangeD3     =  0.97;    // Length of section 3                                                           
+  const Float_t kRB26s3FFlangeRo     = 36.20/2.; // Flange outer radius 
+  const Float_t kRB26s3FFlangeRi1    = 30.60/2.; // Flange inner radius section 1
+  const Float_t kRB26s3FFlangeRi2    = 30.00/2.; // Flange inner radius section 2
+  const Float_t kRB26s3FFlangeRi3    = 30.60/2.; // Flange inner radius section 3
+  z0 = 0;
+  TGeoPcon* shRB26s3FFlange = new TGeoPcon(0., 360., 6);
+  z0 = 0.;
+  shRB26s3FFlange->DefineSection(0, z0, kRB26s3FFlangeRi1, kRB26s3FFlangeRo);
+  z0 += kRB26s3FFlangeD1;
+  shRB26s3FFlange->DefineSection(1, z0, kRB26s3FFlangeRi1, kRB26s3FFlangeRo);
+  shRB26s3FFlange->DefineSection(2, z0, kRB26s3FFlangeRi2, kRB26s3FFlangeRo);
+  z0 += kRB26s3FFlangeD2;
+  shRB26s3FFlange->DefineSection(3, z0, kRB26s3FFlangeRi2, kRB26s3FFlangeRo);
+  shRB26s3FFlange->DefineSection(4, z0, kRB26s3FFlangeRi3, kRB26s3FFlangeRo);
+  z0 += kRB26s3FFlangeD3;
+  shRB26s3FFlange->DefineSection(5, z0, kRB26s3FFlangeRi3, kRB26s3FFlangeRo);
+  TGeoVolume* voRB26s3FFlange = new TGeoVolume("RB26s3FFlange", shRB26s3FFlange, kMedSteel);
+      
+  TGeoVolume* voRB26s3FFlangeM = new TGeoVolume("RB26s3FFlangeM", MakeMotherFromTemplate(shRB26s3FFlange, 2, 5), kMedVac);
+  voRB26s3FFlangeM->AddNode(voRB26s3FFlange, 1, gGeoIdentity);
+            
+
+
+  ///////////////////////////////////
+  //    RB26/3   Axial Compensator //
+  //    Drawing  LHCVC2a_0065      //
+  /////////////////////////////////// 
+  const Float_t kRB26s3CompL              = 42.0;     // Length of the compensator (0.3 cm added for welding)
+  const Float_t kRB26s3BellowRo           = 34.00/2.; // Bellow outer radius        [Pos 1]
+  const Float_t kRB26s3BellowRi           = 30.10/2.; // Bellow inner radius        [Pos 1] 
+  const Int_t   kRB26s3NumberOfPlies      = 13;       // Number of plies            [Pos 1] 
+  const Float_t kRB26s3BellowUndL         = 17.70;    // Length of undulated region [Pos 1] 
+  const Float_t kRB26s3PlieThickness      =  0.06;    // Plie thickness             [Pos 1]
+  const Float_t kRB26s3ConnectionPlieR    =  0.21;    // Connection plie radius     [Pos 1] 
+  //  Plie radius
+  const Float_t kRB26s3PlieR = 
+    (kRB26s3BellowUndL - 4. *  kRB26s3ConnectionPlieR + 2. * kRB26s3PlieThickness + 
+     (2. *  kRB26s3NumberOfPlies - 2.) * kRB26s3PlieThickness) / (4. * kRB26s3NumberOfPlies - 2.);
+
+  //
+  // The welding tubes have 3 sections with different radii and 2 transition regions.
+  // Section 1: connection to the outside
+  // Section 2: commection to the bellow
+  // Section 3: between 1 and 2
+  const Float_t kRB26s3CompTubeInnerR1    = 30.0/2.;  // Outer Connection tubes inner radius     [Pos 4 + 3]
+  const Float_t kRB26s3CompTubeOuterR1    = 30.6/2.;  // Outer Connection tubes outer radius     [Pos 4 + 3]
+  const Float_t kRB26s3CompTubeInnerR2    = 29.4/2.;  // Connection tubes inner radius           [Pos 4 + 3]
+  const Float_t kRB26s3CompTubeOuterR2    = 30.0/2.;  // Connection tubes outer radius           [Pos 4 + 3]
+  const Float_t kRB26s3CompTubeInnerR3    = 30.6/2.;  // Connection tubes inner radius at bellow [Pos 4 + 3]
+  const Float_t kRB26s3CompTubeOuterR3    = 32.2/2.;  // Connection tubes outer radius at bellow [Pos 4 + 3]
+  const Float_t kRB26s3WeldingTubeLeftL1  =  2.0;     // Left connection tube length             [Pos 4]
+  const Float_t kRB26s3WeldingTubeLeftL2  =  3.4;     // Left connection tube length             [Pos 4]
+  const Float_t kRB26s3WeldingTubeLeftL   =  7.0;     // Left connection tube total length       [Pos 4]
+  const Float_t kRB26s3WeldingTubeRightL1 =  2.3;     // Right connection tube length            [Pos 3] (0.3 cm added for welding)
+  const Float_t kRB26s3WeldingTubeRightL2 = 13.4;     // Right connection tube length            [Pos 3]
+
+  const Float_t kRB26s3WeldingTubeT1      =  0.6;     // Length of first r-transition            [Pos 4 + 3]
+  const Float_t kRB26s3WeldingTubeT2      =  1.0;     // Length of 2nd   r-transition            [Pos 4 + 3]       
+
+      
+      
+  const Float_t kRB26s3RingOuterR         = 36.1/2.;  // Ring inner radius                       [Pos 4]
+  const Float_t kRB26s3RingL              =  0.8/2.;  // Ring half length                        [Pos 4]
+  const Float_t kRB26s3RingZ              =  3.7   ;  // Ring z-position                         [Pos 4]
+  const Float_t kRB26s3ProtOuterR         = 36.2/2.;  // Protection tube outer radius            [Pos 2]
+  const Float_t kRB26s3ProtL              = 27.0/2.;  // Protection tube half length             [Pos 2]
+  const Float_t kRB26s3ProtZ              =  4.0   ;  // Protection tube z-position              [Pos 2]
+   
+      
+  // Mother volume
+  //
+  TGeoPcon* shRB26s3Compensator  = new TGeoPcon(0., 360., 6);
+  shRB26s3Compensator->DefineSection( 0,   0.0, 0., kRB26s3CompTubeOuterR1);
+  shRB26s3Compensator->DefineSection( 1,   kRB26s3RingZ, 0., kRB26s3CompTubeOuterR1);      
+  shRB26s3Compensator->DefineSection( 2,   kRB26s3RingZ, 0., kRB26s3ProtOuterR);      
+  shRB26s3Compensator->DefineSection( 3,   kRB26s3ProtZ + 2. * kRB26s3ProtL, 0., kRB26s3ProtOuterR);            
+  shRB26s3Compensator->DefineSection( 4,   kRB26s3ProtZ + 2. * kRB26s3ProtL, 0., kRB26s3CompTubeOuterR1);
+  shRB26s3Compensator->DefineSection( 5,   kRB26s3CompL                    , 0., kRB26s3CompTubeOuterR1);            
+  TGeoVolume* voRB26s3Compensator  =  
+    new TGeoVolume("RB26s3Compensator", shRB26s3Compensator, kMedVac);
+            
+  //
+  // [Pos 1] Bellow
+  //      
+  //
+  TGeoVolume* voRB26s3Bellow = new TGeoVolume("RB26s3Bellow", 
+                                             new TGeoTube(kRB26s3BellowRi, kRB26s3BellowRo, kRB26s3BellowUndL/2.), kMedVac);
+  //      
+  //  Upper part of the undulation
+  //
+  TGeoTorus* shRB26s3PlieTorusU  =  new TGeoTorus(kRB26s3BellowRo - kRB26s3PlieR, kRB26s3PlieR - kRB26s3PlieThickness, kRB26s3PlieR);
+  shRB26s3PlieTorusU->SetName("RB26s3TorusU");
+  TGeoTube*  shRB26s3PlieTubeU   =  new TGeoTube (kRB26s3BellowRo - kRB26s3PlieR, kRB26s3BellowRo, kRB26s3PlieR);
+  shRB26s3PlieTubeU->SetName("RB26s3TubeU");
+  TGeoCompositeShape*  shRB26s3UpperPlie = new TGeoCompositeShape("RB26s3UpperPlie", "RB26s3TorusU*RB26s3TubeU");
+  TGeoVolume* voRB26s3WiggleU = new TGeoVolume("RB26s3UpperPlie", shRB26s3UpperPlie, kMedSteel);
+  //
+  // Lower part of the undulation
+  TGeoTorus* shRB26s3PlieTorusL =  new TGeoTorus(kRB26s3BellowRi + kRB26s3PlieR, kRB26s3PlieR - kRB26s3PlieThickness, kRB26s3PlieR);
+  shRB26s3PlieTorusL->SetName("RB26s3TorusL");
+  TGeoTube*  shRB26s3PlieTubeL   =  new TGeoTube (kRB26s3BellowRi, kRB26s3BellowRi + kRB26s3PlieR, kRB26s3PlieR);
+  shRB26s3PlieTubeL->SetName("RB26s3TubeL");
+  TGeoCompositeShape*  shRB26s3LowerPlie = new TGeoCompositeShape("RB26s3LowerPlie", "RB26s3TorusL*RB26s3TubeL");
+      
+  TGeoVolume* voRB26s3WiggleL = new TGeoVolume("RB26s3LowerPlie", shRB26s3LowerPlie, kMedSteel); 
+
+  //
+  // Connection between upper and lower part of undulation
+  TGeoVolume* voRB26s3WiggleC1 = new TGeoVolume("RB26s3PlieConn1",  
+                                               new TGeoTube(kRB26s3BellowRi + kRB26s3PlieR, 
+                                                            kRB26s3BellowRo - kRB26s3PlieR, kRB26s3PlieThickness / 2.), kMedSteel);
+  //
+  // One wiggle
+  TGeoVolumeAssembly* voRB26s3Wiggle = new TGeoVolumeAssembly("RB26s3Wiggle");
+  z0 =  -  kRB26s3PlieThickness / 2.;
+  voRB26s3Wiggle->AddNode(voRB26s3WiggleC1,  1 , new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s3PlieR -  kRB26s3PlieThickness / 2.;
+  voRB26s3Wiggle->AddNode(voRB26s3WiggleU,   1 , new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s3PlieR -  kRB26s3PlieThickness / 2.;
+  voRB26s3Wiggle->AddNode(voRB26s3WiggleC1,  2 , new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s3PlieR -  kRB26s3PlieThickness;
+  voRB26s3Wiggle->AddNode(voRB26s3WiggleL,  1 , new TGeoTranslation(0., 0., z0));
+  // Positioning of the volumes
+  z0   = - kRB26s3BellowUndL/2.+ kRB26s3ConnectionPlieR;
+  voRB26s3Bellow->AddNode(voRB26s3WiggleL, 1, new TGeoTranslation(0., 0., z0));
+  z0  +=  kRB26s3ConnectionPlieR;
+  zsh  = 4. *  kRB26s3PlieR -  2. * kRB26s3PlieThickness;
+  for (Int_t iw = 0; iw < kRB26s3NumberOfPlies; iw++) {
+    Float_t zpos =  z0 + iw * zsh;     
+    voRB26s3Bellow->AddNode(voRB26s3Wiggle,  iw + 1, new TGeoTranslation(0., 0., zpos -  kRB26s3PlieThickness));       
+  }
+
+  voRB26s3Compensator->AddNode(voRB26s3Bellow, 1,  new TGeoTranslation(0., 0., kRB26s3WeldingTubeLeftL + kRB26s3BellowUndL/2.));
+
+
+  //
+  // [Pos 2] Outer Protecting Tube
+  //      
+  TGeoTube* shRB26s3CompProtTube = new TGeoTube(kRB26s3RingOuterR, kRB26s3ProtOuterR, kRB26s3ProtL);
+  TGeoVolume* voRB26s3CompProtTube =  
+    new TGeoVolume("RB26s3CompProtTube", shRB26s3CompProtTube, kMedSteel);
+  voRB26s3Compensator->AddNode(voRB26s3CompProtTube, 1,  new TGeoTranslation(0., 0., kRB26s3ProtZ + kRB26s3ProtL));
+      
+
+  //
+  // [Pos 3] Right Welding Tube
+  //      
+  TGeoPcon* shRB26s3CompRightTube = new TGeoPcon(0., 360., 5);
+  z0 = 0.;
+  shRB26s3CompRightTube->DefineSection(0, z0,  kRB26s3CompTubeInnerR3, kRB26s3CompTubeOuterR3);
+  z0 += kRB26s3WeldingTubeT2;
+  shRB26s3CompRightTube->DefineSection(1, z0,  kRB26s3CompTubeInnerR2, kRB26s3CompTubeOuterR2);
+  z0 += kRB26s3WeldingTubeRightL2;
+  shRB26s3CompRightTube->DefineSection(2, z0,  kRB26s3CompTubeInnerR2, kRB26s3CompTubeOuterR2);
+  z0 += kRB26s3WeldingTubeT1;
+  shRB26s3CompRightTube->DefineSection(3, z0,  kRB26s3CompTubeInnerR1, kRB26s3CompTubeOuterR1);
+  z0 += kRB26s3WeldingTubeRightL1;
+  shRB26s3CompRightTube->DefineSection(4, z0,  kRB26s3CompTubeInnerR1, kRB26s3CompTubeOuterR1);
+      
+  TGeoVolume* voRB26s3CompRightTube =  
+    new TGeoVolume("RB26s3CompRightTube", shRB26s3CompRightTube, kMedSteel);
+  voRB26s3Compensator->AddNode(voRB26s3CompRightTube,  1, new TGeoTranslation(0., 0.,  kRB26s3CompL - z0));
+
+  //
+  // [Pos 4] Left Welding Tube
+  //      
+  TGeoPcon* shRB26s3CompLeftTube = new TGeoPcon(0., 360., 5);
+  z0 = 0.;
+  shRB26s3CompLeftTube->DefineSection(0, z0,  kRB26s3CompTubeInnerR1, kRB26s3CompTubeOuterR1);
+  z0 += kRB26s3WeldingTubeLeftL1;
+  shRB26s3CompLeftTube->DefineSection(1, z0,  kRB26s3CompTubeInnerR1, kRB26s3CompTubeOuterR1);
+  z0 += kRB26s3WeldingTubeT1;
+  shRB26s3CompLeftTube->DefineSection(2, z0,  kRB26s3CompTubeInnerR2, kRB26s3CompTubeOuterR2);
+  z0 += kRB26s3WeldingTubeLeftL2;
+  shRB26s3CompLeftTube->DefineSection(3, z0,  kRB26s3CompTubeInnerR2, kRB26s3CompTubeOuterR2);
+  z0 += kRB26s3WeldingTubeT2;
+  shRB26s3CompLeftTube->DefineSection(4, z0,  kRB26s3CompTubeInnerR3, kRB26s3CompTubeOuterR3);
+
+  TGeoVolume* voRB26s3CompLeftTube =  
+    new TGeoVolume("RB26s3CompLeftTube", shRB26s3CompLeftTube, kMedSteel);
+  voRB26s3Compensator->AddNode(voRB26s3CompLeftTube, 1,  gGeoIdentity);
+  //
+  // [Pos 5] Ring
+  //      
+  TGeoTube* shRB26s3CompRing = new TGeoTube(kRB26s3CompTubeOuterR2, kRB26s3RingOuterR, kRB26s3RingL);
+  TGeoVolume* voRB26s3CompRing =  
+    new TGeoVolume("RB26s3CompRing", shRB26s3CompRing, kMedSteel);
+  voRB26s3Compensator->AddNode(voRB26s3CompRing,  1, new TGeoTranslation(0., 0., kRB26s3RingZ + kRB26s3RingL));
+
+
+
+  ///////////////////////////////////////////
+  //                                       //
+  //    RB26/4-5                           //  
+  //    Drawing LHCV2a_0012 [as installed] //
+  ////////////////////////////////////////////
+  //    Pos1 Vacuum Tubes        LHCVC2A__0014
+  //    Pos2 Compensator         LHCVC2A__0066
+  //    Pos3 Fixed Point Section LHCVC2A__0016
+  //    Pos4 Split Flange        LHCVFX___0005
+  //    Pos5 RotableFlange       LHCVFX___0009
+  ////////////////////////////////////////////
+
+  ///////////////////////////////////
+  //    RB26/4-5 Vacuum Tubes      //
+  //    Drawing  LHCVC2a_0014      //
+  /////////////////////////////////// 
+  const Float_t kRB26s45TubeL = 593.12 + 0.3; // 0.3 cm added for welding
+      
+  TGeoPcon* shRB26s45Tube = new TGeoPcon(0., 360., 11);
+  // Section 1: straight section
+  shRB26s45Tube->DefineSection( 0,   0.00, 30.00/2., 30.60/2.);
+  shRB26s45Tube->DefineSection( 1,   1.20, 30.00/2., 30.60/2.);
+  shRB26s45Tube->DefineSection( 2,   1.20, 30.00/2., 30.80/2.);
+  shRB26s45Tube->DefineSection( 3,  25.10, 30.00/2., 30.80/2.);      
+  // Section 2: 0.932 deg opening cone
+  shRB26s45Tube->DefineSection( 4, 486.10, 45.00/2., 45.80/2.);      
+  // Section 3: straight section 4 mm 
+  shRB26s45Tube->DefineSection( 5, 512.10, 45.00/2., 45.80/2.);
+  // Section 4: straight section 3 mm
+  shRB26s45Tube->DefineSection( 6, 512.10, 45.00/2., 45.60/2.);
+  shRB26s45Tube->DefineSection( 7, 527.70, 45.00/2., 45.60/2.);
+  // Section 4: closing cone 
+  shRB26s45Tube->DefineSection( 8, 591.30, 10.00/2., 10.60/2.);      
+  shRB26s45Tube->DefineSection( 9, 591.89, 10.00/2., 10.30/2.);      
+
+  shRB26s45Tube->DefineSection(10, kRB26s45TubeL, 10.00/2., 10.30/2.);      
+  TGeoVolume* voRB26s45Tube  =  
+    new TGeoVolume("RB26s45Tube", shRB26s45Tube, kMedSteel);
+
+  TGeoVolume* voRB26s45TubeM  = new TGeoVolume("RB26s45TubeM", MakeMotherFromTemplate(shRB26s45Tube), kMedVac);
+  voRB26s45TubeM->AddNode(voRB26s45Tube, 1, gGeoIdentity);
+            
+      
+
+  ///////////////////////////////////
+  //    RB26/5   Axial Compensator //
+  //    Drawing  LHCVC2a_0066      //
+  /////////////////////////////////// 
+  const Float_t kRB26s5CompL             = 27.60;    // Length of the compensator (0.30 cm added for welding)
+  const Float_t kRB26s5BellowRo          = 12.48/2.; // Bellow outer radius        [Pos 1]
+  const Float_t kRB26s5BellowRi          = 10.32/2.; // Bellow inner radius        [Pos 1] 
+  const Int_t   kRB26s5NumberOfPlies     = 15;       // Number of plies            [Pos 1] 
+  const Float_t kRB26s5BellowUndL        = 10.50;    // Length of undulated region [Pos 1] 
+  const Float_t kRB26s5PlieThickness     =  0.025;   // Plie thickness             [Pos 1]
+  const Float_t kRB26s5ConnectionPlieR   =  0.21;    // Connection plie radius     [Pos 1] 
+  const Float_t kRB26s5ConnectionR       = 11.2/2.;  // Bellow connection radius   [Pos 1] 
+  //  Plie radius
+  const Float_t kRB26s5PlieR = 
+    (kRB26s5BellowUndL - 4. *  kRB26s5ConnectionPlieR + 2. * kRB26s5PlieThickness + 
+     (2. *  kRB26s5NumberOfPlies - 2.) * kRB26s5PlieThickness) / (4. * kRB26s5NumberOfPlies - 2.);
+  const Float_t kRB26s5CompTubeInnerR    = 10.00/2.;  // Connection tubes inner radius     [Pos 2 + 3]
+  const Float_t kRB26s5CompTubeOuterR    = 10.30/2.;  // Connection tubes outer radius     [Pos 2 + 3]
+  const Float_t kRB26s5WeldingTubeLeftL  =  3.70/2.;  // Left connection tube half length  [Pos 2]
+  const Float_t kRB26s5WeldingTubeRightL = 13.40/2.;  // Right connection tube half length [Pos 3]   (0.3 cm added for welding)
+  const Float_t kRB26s5RingInnerR        = 11.2/2.;   // Ring inner radius                 [Pos 4]
+  const Float_t kRB26s5RingOuterR        = 16.0/2.;   // Ring inner radius                 [Pos 4]
+  const Float_t kRB26s5RingL             =  0.4/2.;   // Ring half length                  [Pos 4]
+  const Float_t kRB26s5RingZ             = 14.97;     // Ring z-position                   [Pos 4]
+  const Float_t kRB26s5ProtOuterR        = 16.2/2.;   // Protection tube outer radius      [Pos 5]
+  const Float_t kRB26s5ProtL             = 13.0/2.;   // Protection tube half length       [Pos 5]
+  const Float_t kRB26s5ProtZ             =  2.17;     // Protection tube z-position        [Pos 5]
+  const Float_t kRB26s5DetailZR          = 11.3/2.;   // Detail Z max radius
+      
+      
+  // Mother volume
+  //
+  TGeoPcon* shRB26s5Compensator  = new TGeoPcon(0., 360., 8);
+  shRB26s5Compensator->DefineSection( 0,   0.0,                                                  0., kRB26s5CompTubeOuterR);
+  shRB26s5Compensator->DefineSection( 1,   kRB26s5ProtZ,                                         0., kRB26s5CompTubeOuterR);      
+  shRB26s5Compensator->DefineSection( 2,   kRB26s5ProtZ,                                         0., kRB26s5ProtOuterR);
+  shRB26s5Compensator->DefineSection( 3,   kRB26s5ProtZ + 2. * kRB26s5ProtL + 2. * kRB26s5RingL, 0., kRB26s5ProtOuterR);      
+  shRB26s5Compensator->DefineSection( 4,   kRB26s5ProtZ + 2. * kRB26s5ProtL + 2. * kRB26s5RingL, 0., kRB26s5DetailZR);
+  shRB26s5Compensator->DefineSection( 5,   kRB26s5CompL - 8.,                                    0., kRB26s5DetailZR);
+  shRB26s5Compensator->DefineSection( 6,   kRB26s5CompL - 8.,                                    0., kRB26s5CompTubeOuterR);            
+  shRB26s5Compensator->DefineSection( 7,   kRB26s5CompL,                                         0., kRB26s5CompTubeOuterR);            
+  TGeoVolume* voRB26s5Compensator  = new TGeoVolume("RB26s5Compensator", shRB26s5Compensator, kMedVac);
+            
+  //
+  // [Pos 1] Bellow
+  //      
+  //
+  TGeoVolume* voRB26s5Bellow = new TGeoVolume("RB26s5Bellow", 
+                                             new TGeoTube(kRB26s5BellowRi, kRB26s5BellowRo, kRB26s5BellowUndL/2.), kMedVac);
+  //      
+  //  Upper part of the undulation
+  //
+  TGeoTorus* shRB26s5PlieTorusU  =  new TGeoTorus(kRB26s5BellowRo - kRB26s5PlieR, kRB26s5PlieR - kRB26s5PlieThickness, kRB26s5PlieR);
+  shRB26s5PlieTorusU->SetName("RB26s5TorusU");
+  TGeoTube*  shRB26s5PlieTubeU   =  new TGeoTube (kRB26s5BellowRo - kRB26s5PlieR, kRB26s5BellowRo, kRB26s5PlieR);
+  shRB26s5PlieTubeU->SetName("RB26s5TubeU");
+  TGeoCompositeShape*  shRB26s5UpperPlie = new TGeoCompositeShape("RB26s5UpperPlie", "RB26s5TorusU*RB26s5TubeU");
+  TGeoVolume* voRB26s5WiggleU = new TGeoVolume("RB26s5UpperPlie", shRB26s5UpperPlie, kMedSteel);
+  //
+  // Lower part of the undulation
+  TGeoTorus* shRB26s5PlieTorusL =  new TGeoTorus(kRB26s5BellowRi + kRB26s5PlieR, kRB26s5PlieR - kRB26s5PlieThickness, kRB26s5PlieR);
+  shRB26s5PlieTorusL->SetName("RB26s5TorusL");
+  TGeoTube*  shRB26s5PlieTubeL   =  new TGeoTube (kRB26s5BellowRi, kRB26s5BellowRi + kRB26s5PlieR, kRB26s5PlieR);
+  shRB26s5PlieTubeL->SetName("RB26s5TubeL");
+  TGeoCompositeShape*  shRB26s5LowerPlie = new TGeoCompositeShape("RB26s5LowerPlie", "RB26s5TorusL*RB26s5TubeL");
+      
+  TGeoVolume* voRB26s5WiggleL = new TGeoVolume("RB26s5LowerPlie", shRB26s5LowerPlie, kMedSteel); 
+
+  //
+  // Connection between upper and lower part of undulation
+  TGeoVolume* voRB26s5WiggleC1 = new TGeoVolume("RB26s5PlieConn1",  
+                                               new TGeoTube(kRB26s5BellowRi + kRB26s5PlieR, 
+                                                            kRB26s5BellowRo - kRB26s5PlieR, kRB26s5PlieThickness / 2.), kMedSteel);
+  //
+  // One wiggle
+  TGeoVolumeAssembly* voRB26s5Wiggle = new TGeoVolumeAssembly("RB26s5Wiggle");
+  z0 =  -  kRB26s5PlieThickness / 2.;
+  voRB26s5Wiggle->AddNode(voRB26s5WiggleC1,  1 , new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s5PlieR -  kRB26s5PlieThickness / 2.;
+  voRB26s5Wiggle->AddNode(voRB26s5WiggleU,   1 , new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s5PlieR -  kRB26s5PlieThickness / 2.;
+  voRB26s5Wiggle->AddNode(voRB26s5WiggleC1,  2 , new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s5PlieR -  kRB26s5PlieThickness;
+  voRB26s5Wiggle->AddNode(voRB26s5WiggleL ,  1 , new TGeoTranslation(0., 0., z0));
+  // Positioning of the volumes
+  z0   = - kRB26s5BellowUndL/2.+ kRB26s5ConnectionPlieR;
+  voRB26s5Bellow->AddNode(voRB26s5WiggleL, 1, new TGeoTranslation(0., 0., z0));
+  z0  +=  kRB26s5ConnectionPlieR;
+  zsh  = 4. *  kRB26s5PlieR -  2. * kRB26s5PlieThickness;
+  for (Int_t iw = 0; iw < kRB26s5NumberOfPlies; iw++) {
+    Float_t zpos =  z0 + iw * zsh;     
+    voRB26s5Bellow->AddNode(voRB26s5Wiggle,  iw + 1, new TGeoTranslation(0., 0., zpos -  kRB26s5PlieThickness));       
+  }
+
+  voRB26s5Compensator->AddNode(voRB26s5Bellow, 1,  new TGeoTranslation(0., 0., 2. * kRB26s5WeldingTubeLeftL + kRB26s5BellowUndL/2.));
+      
+  //
+  // [Pos 2] Left Welding Tube
+  //      
+  TGeoPcon* shRB26s5CompLeftTube = new TGeoPcon(0., 360., 3);
+  z0 = 0;
+  shRB26s5CompLeftTube->DefineSection(0, z0, kRB26s5CompTubeInnerR, kRB26s5CompTubeOuterR);
+  z0 += 2 * kRB26s5WeldingTubeLeftL - ( kRB26s5ConnectionR - kRB26s5CompTubeOuterR);
+  shRB26s5CompLeftTube->DefineSection(1, z0, kRB26s5CompTubeInnerR, kRB26s5CompTubeOuterR);
+  z0 += ( kRB26s5ConnectionR - kRB26s5CompTubeOuterR);
+  shRB26s5CompLeftTube->DefineSection(2, z0, kRB26s5ConnectionR - 0.15, kRB26s5ConnectionR);
+  TGeoVolume* voRB26s5CompLeftTube = new TGeoVolume("RB26s5CompLeftTube", shRB26s5CompLeftTube, kMedSteel);
+  voRB26s5Compensator->AddNode(voRB26s5CompLeftTube, 1,  gGeoIdentity);
+  //
+  // [Pos 3] Right Welding Tube
+  //      
+  TGeoPcon* shRB26s5CompRightTube = new TGeoPcon(0., 360., 11);
+  // Detail Z
+  shRB26s5CompRightTube->DefineSection( 0, 0.  , kRB26s5CompTubeInnerR + 0.22, 11.2/2.);
+  shRB26s5CompRightTube->DefineSection( 1, 0.05, kRB26s5CompTubeInnerR + 0.18, 11.2/2.);
+  shRB26s5CompRightTube->DefineSection( 2, 0.22, kRB26s5CompTubeInnerR       , 11.2/2. - 0.22);
+  shRB26s5CompRightTube->DefineSection( 3, 0.44, kRB26s5CompTubeInnerR       , 11.2/2.);
+  shRB26s5CompRightTube->DefineSection( 4, 1.70, kRB26s5CompTubeInnerR       , 11.2/2.);
+  shRB26s5CompRightTube->DefineSection( 5, 2.10, kRB26s5CompTubeInnerR       , kRB26s5CompTubeOuterR);
+  shRB26s5CompRightTube->DefineSection( 6, 2.80, kRB26s5CompTubeInnerR       , kRB26s5CompTubeOuterR);
+  shRB26s5CompRightTube->DefineSection( 7, 2.80, kRB26s5CompTubeInnerR       , 11.3/2.);
+  shRB26s5CompRightTube->DefineSection( 8, 3.40, kRB26s5CompTubeInnerR       , 11.3/2.);
+  // Normal pipe
+  shRB26s5CompRightTube->DefineSection( 9, 3.50, kRB26s5CompTubeInnerR       , kRB26s5CompTubeOuterR);
+  shRB26s5CompRightTube->DefineSection(10, 2. * kRB26s5WeldingTubeRightL, kRB26s5CompTubeInnerR, kRB26s5CompTubeOuterR);
+      
+  TGeoVolume* voRB26s5CompRightTube =  
+    new TGeoVolume("RB26s5CompRightTube", shRB26s5CompRightTube, kMedSteel);
+  voRB26s5Compensator->AddNode(voRB26s5CompRightTube,  1, 
+                              new TGeoTranslation(0., 0.,  kRB26s5CompL - 2. * kRB26s5WeldingTubeRightL));
+  //
+  // [Pos 4] Ring
+  //      
+  TGeoTube* shRB26s5CompRing = new TGeoTube(kRB26s5RingInnerR, kRB26s5RingOuterR, kRB26s5RingL);
+  TGeoVolume* voRB26s5CompRing =  
+    new TGeoVolume("RB26s5CompRing", shRB26s5CompRing, kMedSteel);
+  voRB26s5Compensator->AddNode(voRB26s5CompRing,  1, new TGeoTranslation(0., 0., kRB26s5RingZ + kRB26s5RingL));
+
+  //
+  // [Pos 5] Outer Protecting Tube
+  //      
+  TGeoTube* shRB26s5CompProtTube = new TGeoTube(kRB26s5RingOuterR, kRB26s5ProtOuterR, kRB26s5ProtL);
+  TGeoVolume* voRB26s5CompProtTube =  
+    new TGeoVolume("RB26s5CompProtTube", shRB26s5CompProtTube, kMedSteel);
+  voRB26s5Compensator->AddNode(voRB26s5CompProtTube, 1,  new TGeoTranslation(0., 0., kRB26s5ProtZ + kRB26s5ProtL));
+
+  ///////////////////////////////////////
+  //    RB26/4   Fixed Point Section   //
+  //    Drawing  LHCVC2a_0016          //
+  /////////////////////////////////////// 
+  const Float_t kRB26s4TubeRi            =  30.30/2. ; // Tube inner radius  (0.3 cm added for welding)
+  const Float_t kRB26s4TubeRo            =  30.60/2. ; // Tube outer radius      
+  const Float_t kRB26s4FixedPointL       =  12.63    ; // Length of the fixed point section
+  const Float_t kRB26s4FixedPointZ       =  10.53    ; // Position of the ring (0.15 added for welding)
+  const Float_t kRB26s4FixedPointD       =   0.595   ; // Width of the ring
+  const Float_t kRB26s4FixedPointR       =  31.60/2. ; // Radius of the ring
+      
+  TGeoPcon* shRB26s4FixedPoint = new TGeoPcon(0., 360., 6);
+  z0 = 0.;
+  shRB26s4FixedPoint->DefineSection(0, z0, kRB26s4TubeRi, kRB26s4TubeRo);
+  z0 += kRB26s4FixedPointZ;
+  shRB26s4FixedPoint->DefineSection(1, z0, kRB26s4TubeRi, kRB26s4TubeRo);      
+  shRB26s4FixedPoint->DefineSection(2, z0, kRB26s4TubeRi, kRB26s4FixedPointR);           
+  z0 += kRB26s4FixedPointD;
+  shRB26s4FixedPoint->DefineSection(3, z0, kRB26s4TubeRi, kRB26s4FixedPointR);           
+  shRB26s4FixedPoint->DefineSection(4, z0, kRB26s4TubeRi, kRB26s4TubeRo);
+  z0 = kRB26s4FixedPointL;
+  shRB26s4FixedPoint->DefineSection(5, z0, kRB26s4TubeRi, kRB26s4TubeRo);
+  TGeoVolume* voRB26s4FixedPoint = new TGeoVolume("RB26s4FixedPoint", shRB26s4FixedPoint, kMedSteel);
+      
+  TGeoVolume* voRB26s4FixedPointM = new TGeoVolume("RB26s4FixedPointM", MakeMotherFromTemplate(shRB26s4FixedPoint), kMedVac);
+  voRB26s4FixedPointM->AddNode(voRB26s4FixedPoint, 1, gGeoIdentity);
+            
+
+  ///////////////////////////////////////
+  //    RB26/4   Split Flange          //
+  //    Drawing  LHCVFX__0005          //
+  /////////////////////////////////////// 
+  const Float_t kRB26s4SFlangeL      =  2.99;        // Length of the flange
+  const Float_t kRB26s4SFlangeD1     =  0.85;        // Length of section 1
+  const Float_t kRB26s4SFlangeD2     =  0.36;        // Length of section 2                                                 
+  const Float_t kRB26s4SFlangeD3     =  0.73 + 1.05; // Length of section 3                                                       
+  const Float_t kRB26s4SFlangeRo     = 36.20/2.;     // Flange outer radius 
+  const Float_t kRB26s4SFlangeRi1    = 30.60/2.;     // Flange inner radius section 1
+  const Float_t kRB26s4SFlangeRi2    = 30.00/2.;     // Flange inner radius section 2
+  const Float_t kRB26s4SFlangeRi3    = 30.60/2.;     // Flange inner radius section 3
+  z0 = 0;
+  TGeoPcon* shRB26s4SFlange = new TGeoPcon(0., 360., 6);
+  z0 = 0.;
+  shRB26s4SFlange->DefineSection(0, z0, kRB26s4SFlangeRi1, kRB26s4SFlangeRo);
+  z0 += kRB26s4SFlangeD1;
+  shRB26s4SFlange->DefineSection(1, z0, kRB26s4SFlangeRi1, kRB26s4SFlangeRo);
+  shRB26s4SFlange->DefineSection(2, z0, kRB26s4SFlangeRi2, kRB26s4SFlangeRo);
+  z0 += kRB26s4SFlangeD2;
+  shRB26s4SFlange->DefineSection(3, z0, kRB26s4SFlangeRi2, kRB26s4SFlangeRo);
+  shRB26s4SFlange->DefineSection(4, z0, kRB26s4SFlangeRi3, kRB26s4SFlangeRo);
+  z0 += kRB26s4SFlangeD3;
+  shRB26s4SFlange->DefineSection(5, z0, kRB26s4SFlangeRi3, kRB26s4SFlangeRo);
+  TGeoVolume* voRB26s4SFlange = new TGeoVolume("RB26s4SFlange", shRB26s4SFlange, kMedSteel);
+
+  TGeoVolume* voRB26s4SFlangeM = new TGeoVolume("RB26s4SFlangeM", MakeMotherFromTemplate(shRB26s4SFlange, 0, 3), kMedVac);
+  voRB26s4SFlangeM->AddNode(voRB26s4SFlange, 1, gGeoIdentity);
+      
+  ///////////////////////////////////////
+  //    RB26/5   Rotable Flange        //
+  //    Drawing  LHCVFX__0009          //
+  /////////////////////////////////////// 
+  const Float_t kRB26s5RFlangeL      =  1.86;    // Length of the flange
+  const Float_t kRB26s5RFlangeD1     =  0.61;    // Length of section 1
+  const Float_t kRB26s5RFlangeD2     =  0.15;    // Length of section 2                                                     
+  const Float_t kRB26s5RFlangeD3     =  0.60;    // Length of section 3                                                           
+  const Float_t kRB26s5RFlangeD4     =  0.50;    // Length of section 4                                                           
+  const Float_t kRB26s5RFlangeRo     = 15.20/2.; // Flange outer radius 
+  const Float_t kRB26s5RFlangeRi1    = 10.30/2.; // Flange inner radius section 1
+  const Float_t kRB26s5RFlangeRi2    = 10.00/2.; // Flange inner radius section 2
+  const Float_t kRB26s5RFlangeRi3    = 10.30/2.; // Flange inner radius section 3
+  const Float_t kRB26s5RFlangeRi4    = 10.50/2.; // Flange inner radius section 4
+
+  z0 = 0;
+  TGeoPcon* shRB26s5RFlange = new TGeoPcon(0., 360., 8);
+  z0 = 0.;
+  shRB26s5RFlange->DefineSection(0, z0, kRB26s5RFlangeRi4, kRB26s5RFlangeRo);
+  z0 += kRB26s5RFlangeD4;
+  shRB26s5RFlange->DefineSection(1, z0, kRB26s5RFlangeRi4, kRB26s5RFlangeRo);
+  shRB26s5RFlange->DefineSection(2, z0, kRB26s5RFlangeRi3, kRB26s5RFlangeRo);
+  z0 += kRB26s5RFlangeD3;
+  shRB26s5RFlange->DefineSection(3, z0, kRB26s5RFlangeRi3, kRB26s5RFlangeRo);
+  shRB26s5RFlange->DefineSection(4, z0, kRB26s5RFlangeRi2, kRB26s5RFlangeRo);
+  z0 += kRB26s5RFlangeD2;
+  shRB26s5RFlange->DefineSection(5, z0, kRB26s5RFlangeRi2, kRB26s5RFlangeRo);
+  shRB26s5RFlange->DefineSection(6, z0, kRB26s5RFlangeRi1, kRB26s5RFlangeRo);
+  z0 += kRB26s5RFlangeD1;
+  shRB26s5RFlange->DefineSection(7, z0, kRB26s5RFlangeRi1, kRB26s5RFlangeRo);
+  TGeoVolume* voRB26s5RFlange = new TGeoVolume("RB26s5RFlange", shRB26s5RFlange, kMedSteel);
+
+  TGeoVolume* voRB26s5RFlangeM = new TGeoVolume("RB26s5RFlangeM", MakeMotherFromTemplate(shRB26s5RFlange, 4, 7), kMedVac);
+  voRB26s5RFlangeM->AddNode(voRB26s5RFlange, 1, gGeoIdentity);
+
+  //      
+  // Assemble RB26/1-2
+  //
+  TGeoVolumeAssembly* asRB26s12 = new TGeoVolumeAssembly("RB26s12"); 
+  z0 = 0.;
+  asRB26s12->AddNode(voRB26s1RFlange,       1, gGeoIdentity);
+  z0 += kRB26s1RFlangeIsL + kRB26s1RFlangeFpL;
+  asRB26s12->AddNode(voRB26s12TubeM,         1, new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s12TubeL;
+  asRB26s12->AddNode(voRB26s2Compensator,   1, new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s2CompL;
+  z0 -= kRB26s2FFlangeD1;
+  asRB26s12->AddNode(voRB26s2FFlangeM,       1, new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s2FFlangeL;
+  const Float_t kRB26s12L = z0;
+
+  //
+  // Assemble RB26/3
+  //
+  TGeoVolumeAssembly* asRB26s3 = new TGeoVolumeAssembly("RB26s3"); 
+  z0 = 0.;
+  asRB26s3->AddNode(voRB26s3SFlangeM,      1, gGeoIdentity);
+  z0 +=  kRB26s3SFlangeL;
+  z0 -=  kRB26s3SFlangeD3;
+  asRB26s3->AddNode(voRB26s3FixedPointM,   1, new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s3FixedPointL;
+  asRB26s3->AddNode(voRB26s3TubeM,         1, new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s3TubeL;
+  asRB26s3->AddNode(voRB26s3Compensator,   1, new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s3CompL;
+  z0 -= kRB26s3FFlangeD1;
+  asRB26s3->AddNode(voRB26s3FFlangeM,      1, new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s3FFlangeL;
+  const Float_t kRB26s3L = z0;
+      
+
+  //
+  // Assemble RB26/4-5
+  //
+  TGeoVolumeAssembly* asRB26s45 = new TGeoVolumeAssembly("RB26s45"); 
+  z0 = 0.;
+  asRB26s45->AddNode(voRB26s4SFlangeM,       1, gGeoIdentity);
+  z0 +=  kRB26s4SFlangeL;
+  z0 -=  kRB26s4SFlangeD3;
+  asRB26s45->AddNode(voRB26s4FixedPointM,    1, new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s4FixedPointL;
+  asRB26s45->AddNode(voRB26s45TubeM,         1, new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s45TubeL;
+  asRB26s45->AddNode(voRB26s5Compensator,    1, new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s5CompL;
+  z0 -= kRB26s5RFlangeD3;
+  z0 -= kRB26s5RFlangeD4;
+  asRB26s45->AddNode(voRB26s5RFlangeM,       1, new TGeoTranslation(0., 0., z0));
+  z0 += kRB26s5RFlangeL;
+  const Float_t kRB26s45L = z0;
+      
+  //
+  // Assemble RB26
+  //
+  TGeoVolumeAssembly* asRB26Pipe = new TGeoVolumeAssembly("RB26Pipe"); 
+  z0 = 0.;
+  asRB26Pipe->AddNode(asRB26s12,       1, new TGeoTranslation(0., 0., z0));
+  z0 +=  kRB26s12L;
+  asRB26Pipe->AddNode(asRB26s3,        1, new TGeoTranslation(0., 0., z0));
+  z0 +=  kRB26s3L;
+  asRB26Pipe->AddNode(asRB26s45,       1, new TGeoTranslation(0., 0., z0));
+  z0 +=  kRB26s45L;
+  top->AddNode(asRB26Pipe, 1, new TGeoCombiTrans(0., 0., -82., rot180));
+}
+
+
+
+//___________________________________________
+void AliPIPEv4::CreateMaterials()
+{
+  //
+  // Define materials for beam pipe
+  //
+
+  AliDebugClass(1,"Create PIPEv4 materials");
+  Int_t   isxfld = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();
+  Float_t sxmgmx = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();
+  // Steel (Inox)  
+  Float_t asteel[4] = { 55.847,51.9961,58.6934,28.0855 };
+  Float_t zsteel[4] = { 26.,24.,28.,14. };
+  Float_t wsteel[4] = { .715,.18,.1,.005 };
+  // AlBe - alloy 
+  Float_t aAlBe[2] = { 26.98, 9.01};
+  Float_t zAlBe[2] = { 13.00, 4.00};
+  Float_t wAlBe[2] = { 0.4, 0.6};
+  //
+  // Polyamid
+  Float_t aPA[4] = {16., 14., 12.,  1.};
+  Float_t zPA[4] = { 8.,  7.,  6.,  1.};
+  Float_t wPA[4] = { 1.,  1.,  6., 11.};
+  //
+  // Air 
+  //
+  Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
+  Float_t zAir[4]={6.,7.,8.,18.};
+  Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
+  Float_t dAir = 1.20479E-3;
+  Float_t dAir1 = 1.20479E-10;
+  //
+  // Insulation powder
+  //                    Si         O       Ti     Al
+  Float_t ains[4] ={28.0855, 15.9994, 47.867,  26.982};
+  Float_t zins[4] ={14.,      8.    , 22.   ,  13.   };
+  Float_t wins[4] ={ 0.3019,  0.4887,  0.1914,  0.018};
+  //
+  //
+  // Anticorodal
+  //
+  // Al Si7 Mg 0.6
+  //
+  Float_t aaco[3] ={26.982, 28.0855, 24.035};
+  Float_t zaco[3] ={13.,    14.    , 12.   };
+  Float_t waco[3] ={ 0.924,  0.07,  0.006};
+  // Kapton
+  //
+  Float_t aKapton[4]={1.00794,12.0107, 14.010,15.9994};
+  Float_t zKapton[4]={1.,6.,7.,8.};
+  Float_t wKapton[4]={0.026362,0.69113,0.07327,0.209235};
+  Float_t dKapton = 1.42;
+  // NEG coating
+  //                  Ti     V      Zr
+  Float_t aNEG[4] = {47.87, 50.94, 91.24};
+  Float_t zNEG[4] = {22.00, 23.00, 40.00};
+  Float_t wNEG[4] = {1./3., 1./3., 1./3.};  
+  Float_t dNEG = 5.6; // ?
+
+  //
+  //
+  //     Berillium 
+  AliMaterial(5, "BERILLIUM$", 9.01, 4., 1.848, 35.3, 36.7);
+  //
+  //     Carbon 
+  AliMaterial(6,  "CARBON$   ", 12.01, 6., 2.265, 18.8, 49.9);
+  //
+  //     Aluminum 
+  AliMaterial(9,  "ALUMINIUM$", 26.98, 13., 2.7, 8.9, 37.2);
+  //
+  //     Copper 
+  AliMaterial(10, "COPPER", 63.55, 29, 8.96, 1.43, 85.6/8.96);
+  //
+  //     Air 
+  AliMixture(15, "AIR$      ", aAir, zAir, dAir, 4, wAir);
+  AliMixture(35, "AIR_HIGH$ ", aAir, zAir, dAir, 4, wAir);
+  //
+  //     Vacuum 
+  AliMixture(16, "VACUUM$ ", aAir, zAir, dAir1, 4, wAir);
+  //
+  //     stainless Steel 
+  AliMixture(19, "STAINLESS STEEL$", asteel, zsteel, 7.88, 4, wsteel);
+  //
+  //     reduced density steel to approximate pump getter material
+  AliMixture(20, "GETTER$", asteel, zsteel, 1.00, 4, wsteel);
+  //     Al-Be alloy
+  //     
+  AliMixture(21, "AlBe$", aAlBe, zAlBe, 2.07, 2, wAlBe);
+  //     Polyamid
+  //   
+  AliMixture(22, "PA$", aPA, zPA, 1.14, -4, wPA);
+  //
+  //     Kapton
+  AliMixture(23, "KAPTON", aKapton, zKapton, dKapton, 4, wKapton);
+  // Anticorodal 
+  AliMixture(24, "ANTICORODAL", aaco, zaco, 2.66, 3, waco);
+  
+  //
+  //     Insulation powder 
+  AliMixture(14, "INSULATION0$", ains, zins, 0.41, 4, wins);
+  AliMixture(34, "INSULATION1$", ains, zins, 0.41, 4, wins);
+  AliMixture(54, "INSULATION2$", ains, zins, 0.41, 4, wins);
+
+  //    NEG
+  AliMixture(25, "NEG COATING", aNEG, zNEG, dNEG, -3, wNEG);
+   
+   
+  // **************** 
+  //     Defines tracking media parameters. 
+  //
+  Float_t epsil  = .001;    // Tracking precision, 
+  Float_t stemax = -0.01;   // Maximum displacement for multiple scat 
+  Float_t tmaxfd = -20.;    // Maximum angle due to field deflection 
+  Float_t deemax = -.3;     // Maximum fractional energy loss, DLS 
+  Float_t stmin  = -.8;
+  // *************** 
+  //
+  //    Beryllium 
+  
+  AliMedium(5, "BE",       5, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+
+  //    Carbon 
+  AliMedium(6, "C",        6, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+  //
+  //    Aluminum 
+  AliMedium(9, "ALU",      9, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+  //    Copper 
+  AliMedium(10, "CU",      10, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+  //
+  //    Air 
+  AliMedium(15, "AIR",     15, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+  AliMedium(35, "AIR_HIGH",35, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+  //
+  //    Vacuum 
+  AliMedium(16, "VACUUM", 16, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+  //
+  //    Steel 
+  AliMedium(19, "INOX",   19, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+  //
+  //    Getter 
+  AliMedium(20, "GETTER", 20, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+  //
+  //   AlBe - Aloy 
+  AliMedium(21, "AlBe"  , 21, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+  //
+  //   Polyamid
+  AliMedium(22, "PA"  ,   22, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+  //   Antocorodal
+  AliMedium(24, "ANTICORODAL",   24, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+  //    Insulation Powder 
+  AliMedium(14, "INS_C0          ", 14, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+  AliMedium(34, "INS_C1          ", 34, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+  AliMedium(54, "INS_C2          ", 54, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+  //
+  //   KAPTON
+  AliMedium(23, "KAPTON", 23, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+
+  //
+  //   NEG
+  AliMedium(25, "NEG COATING", 25, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+}
+
+
+TGeoPcon* AliPIPEv4::MakeMotherFromTemplate(TGeoPcon* shape, Int_t imin, Int_t imax, Float_t r0, Int_t nz)
+{
+  //
+  //  Create a mother shape from a template setting some min radii to 0
+  //
+  Int_t nz0 = shape->GetNz();
+  // if nz > -1 the number of planes is given by nz
+  if (nz != -1) nz0 = nz;
+  TGeoPcon* mother = new TGeoPcon(0., 360., nz0);
+
+  if (imin == -1 || imax == -1) {
+    imin = 0;
+    imax = shape->GetNz();
+  } else if (imax >= nz0) {
+    imax = nz0 - 1;
+    printf("Warning: imax reset to nz-1 %5d %5d %5d %5d\n", imin, imax, nz, nz0);
+  }
+    
+
+    
+  for (Int_t i = 0;  i < shape->GetNz(); i++) {
+    Double_t rmin = shape->GetRmin(i);
+    if ((i >= imin) && (i <= imax) ) rmin = r0;
+    Double_t rmax = shape->GetRmax(i);
+    Double_t    z = shape->GetZ(i);
+    mother->DefineSection(i, z, rmin, rmax);
+  }
+  return mother;
+    
+}
+
+TGeoPcon* AliPIPEv4::MakeInsulationFromTemplate(TGeoPcon* shape)
+{
+  //
+  //  Create an beam pipe insulation layer shape from a template
+  //
+  Int_t nz = shape->GetNz();
+  TGeoPcon* insu = new TGeoPcon(0., 360., nz);
+    
+  for (Int_t i = 0;  i < nz; i++) {
+    Double_t    z = shape->GetZ(i);
+    Double_t rmin = shape->GetRmin(i);
+    Double_t rmax = shape->GetRmax(i);
+    rmax += 0.5;
+    shape->DefineSection(i, z, rmin, rmax);    
+    rmin  = rmax - 0.5;
+    insu->DefineSection(i, z, rmin, rmax);     
+  }
+  return insu;
+    
+}
+
+
+TGeoVolume* AliPIPEv4::MakeBellow(const char* ext, Int_t nc, Float_t rMin, Float_t rMax, Float_t dU, Float_t rPlie, Float_t dPlie)
+{
+  // nc     Number of convolution
+  // rMin   Inner radius of the bellow
+  // rMax   Outer radius of the bellow
+  // dU     Undulation length
+  // rPlie  Plie radius
+  // dPlie  Plie thickness
+  const TGeoMedium* kMedVac    =  gGeoManager->GetMedium("PIPE_VACUUM");    
+  const TGeoMedium* kMedSteel  =  gGeoManager->GetMedium("PIPE_INOX");   
+
+  char name[64], nameA[64], nameB[64], bools[64];
+  sprintf(name, "%sBellowUS", ext);
+  TGeoVolume* voBellow = new TGeoVolume(name, new TGeoTube(rMin, rMax, dU/2.), kMedVac);
+  //      
+  //  Upper part of the undulation
+  //
+  TGeoTorus* shPlieTorusU  =  new TGeoTorus(rMax - rPlie, rPlie - dPlie, rPlie);
+  sprintf(nameA, "%sTorusU", ext);
+  shPlieTorusU->SetName(nameA);
+  TGeoTube*  shPlieTubeU   =  new TGeoTube (rMax - rPlie, rMax, rPlie);
+  sprintf(nameB, "%sTubeU", ext);
+  shPlieTubeU->SetName(nameB);
+  sprintf(name, "%sUpperPlie", ext);
+  sprintf(bools, "%s*%s", nameA, nameB);
+  TGeoCompositeShape*  shUpperPlie = new TGeoCompositeShape(name, bools);
+    
+  TGeoVolume* voWiggleU = new TGeoVolume(name, shUpperPlie, kMedSteel);
+  //
+  // Lower part of the undulation
+  TGeoTorus* shPlieTorusL =  new TGeoTorus(rMin + rPlie, rPlie - dPlie, rPlie);
+  sprintf(nameA, "%sTorusL", ext);
+  shPlieTorusL->SetName(nameA);
+  TGeoTube*  shPlieTubeL  =  new TGeoTube (rMin, rMin + rPlie, rPlie);
+  sprintf(nameB, "%sTubeL", ext);
+  shPlieTubeL->SetName(nameB);
+  sprintf(name, "%sLowerPlie", ext);
+  sprintf(bools, "%s*%s", nameA, nameB);
+  TGeoCompositeShape*  shLowerPlie = new TGeoCompositeShape(name, bools);
+    
+  TGeoVolume* voWiggleL = new TGeoVolume(name, shLowerPlie, kMedSteel); 
+    
+  //
+  // Connection between upper and lower part of undulation
+  sprintf(name, "%sPlieConn1", ext);
+  TGeoVolume* voWiggleC1 = new TGeoVolume(name, new TGeoTube(rMin + rPlie, rMax - rPlie, dPlie/2.), kMedSteel);
+  //
+  // One wiggle
+  Float_t dz = rPlie -  dPlie / 2.;
+  Float_t z0 = -  dPlie / 2.;
+  sprintf(name, "%sWiggle", ext);
+  TGeoVolumeAssembly* asWiggle = new TGeoVolumeAssembly(name);
+  asWiggle->AddNode(voWiggleC1,  1 , new TGeoTranslation(0., 0., z0));
+  z0 += dz;
+  asWiggle->AddNode(voWiggleU,   1 , new TGeoTranslation(0., 0., z0));
+  z0 += dz;
+  asWiggle->AddNode(voWiggleC1,  2 , new TGeoTranslation(0., 0., z0));
+  z0 += dz;
+  asWiggle->AddNode(voWiggleL ,  1 , new TGeoTranslation(0., 0., z0));
+  // Positioning of the volumes
+  z0   = - dU / 2.+ rPlie;
+  voBellow->AddNode(voWiggleL, 2, new TGeoTranslation(0., 0., z0));
+  z0  +=  rPlie;
+  Float_t zsh  = 4. *  rPlie -  2. * dPlie;
+  for (Int_t iw = 0; iw < nc; iw++) {
+    Float_t zpos =  z0 + iw * zsh;     
+    voBellow->AddNode(asWiggle,  iw + 1, new TGeoTranslation(0., 0., zpos - dPlie));   
+  }
+  return voBellow;
+}
+
+
+
+
diff --git a/STRUCT/AliPIPEv4.h b/STRUCT/AliPIPEv4.h
new file mode 100644 (file)
index 0000000..ad220e6
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef ALIPIPEVGEO4_H
+#define ALIPIPEVGEO4_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$*/
+
+/////////////////////////////////////////////////////////
+// ALICE beam pipe geometry                            //
+// This version uses TGeo.                             //
+// Author:                                             //
+// Andreas Morsch                                      //
+// e-mail: andreas.morsch@cern.ch                      // 
+/////////////////////////////////////////////////////////
+#include "AliPIPE.h"
+class TGeoPcon;
+class TGeoVolume;
+
+
+class AliPIPEv4 : public AliPIPE {
+    
+ public:
+    enum constants {kC=6, kAlu=9, kInox=19, kGetter=20, kBe=5, kVac=16,
+         kAir=15, kAlBe=21, kPA = 22};
+       
+  AliPIPEv4();
+  AliPIPEv4(const char *name, const char *title);
+  AliPIPEv4(const char *name, const char *title, const Float_t theta_cone,  const Float_t rmin1, 
+           const Float_t epaisseur, const Float_t sigmaz, const Float_t z_chambre);
+  virtual       ~AliPIPEv4() {};
+  virtual void   CreateGeometry();
+  virtual void   CreateMaterials();
+  virtual Int_t  IsVersion() const {return 0;}
+ private:
+  virtual TGeoPcon*   MakeMotherFromTemplate(TGeoPcon* shape, Int_t imin = -1, Int_t imax = -1, Float_t r0 = 0., Int_t nz =-1);
+  virtual TGeoPcon*   MakeInsulationFromTemplate(TGeoPcon* shape);
+  virtual TGeoVolume* MakeBellow(const char* ext, Int_t nc, Float_t rMin, Float_t rMax, Float_t dU, Float_t rPlie, Float_t dPlie);
+
+  Float_t   ftheta_cone; // angle of conical beam pipe, if angle < 3 --> cylindrical beam pipe
+  Float_t   frmin1;      // internal radius of Be beam pipe
+  Float_t   fepaisseur;  // width of Be beam pipe
+  Float_t   fsigmaz;     // dispersion of z location (1 sigma) of beam impact position
+  Float_t   fz_chambre;  // first pixel chamber location, closest to the IP
+  Float_t   fzdebut1;    // beginning of beam pipe z location (A side)
+  Float_t   fzfin4;      // end of beamp pipe z location (C side)
+
+
+ protected:
+  ClassDef(AliPIPEv4,1)  //Class for PIPE version using TGeo
+};
+#endif
index 484f7a79954af2bc6c23be51662374a615570179..9051faea4b23470003d9ed2585c8bf8c9b1090db 100644 (file)
@@ -43,6 +43,7 @@ set ( SRCS
     AliPIPE.cxx 
     AliPIPEv0.cxx 
     AliPIPEv3.cxx 
+    AliPIPEv4.cxx 
     AliBODY.cxx 
     AliSHILv2.cxx 
     AliSHILv3.cxx
index 4d7e0e4690d200a71509cf3ae8ef58ad2d0c13b1..d47e8ba0c704084a9065558801ae0e9640727264 100644 (file)
@@ -23,6 +23,7 @@
 #pragma link C++ class  AliPIPE+;
 #pragma link C++ class  AliPIPEv0+;
 #pragma link C++ class  AliPIPEv3+;
+#pragma link C++ class  AliPIPEv4+;
 #pragma link C++ class  AliSHIL+;
 #pragma link C++ class  AliSHILv0+;
 #pragma link C++ class  AliSHILv2+;
index ea4d16557ab74a8f10299b3c5944cebe0d71acc7..bbd1ff3c4c708220c0e42d2f2676b6fdf15cfad7 100644 (file)
@@ -11,7 +11,7 @@ cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR)
 
 #list of detectors 
 #set(ONLINEDETECTORS T00)
-set(ONLINEDETECTORS SPD SDD SSD ACO GRP TST HLT EMC TRI T00 PMD CPV PHS FMD TPC TRD ZDC V00 MTR MCH HMP TOF)
+set(ONLINEDETECTORS SPD SDD SSD ACO GRP TST HLT EMC TRI T00 PMD CPV PHS FMD TPC TRD ZDC V00 MTR MCH HMP TOF MFT)
 function(expand output input)
     string(REGEX MATCH "\\\${[^}]*}" m "${input}")
     while(m)
@@ -25,7 +25,7 @@ endfunction()
 #function to get module for detector
 function (detector_module _module detector)
   #Map of online detectors to DA in pairs of ONLINEDETECTORNAME DAMODULE
-  set (DETECTORMODULEMAP SPD ITS SDD ITS SSD ITS HMP HMPID PHS PHOS CPV PHOS MCH MUON MTR MUON T00 T0 V00 VZERO ACO ACORDE EMC EMCAL)
+  set (DETECTORMODULEMAP SPD ITS SDD ITS SSD ITS HMP HMPID PHS PHOS CPV PHOS MCH MUON MTR MUON T00 T0 V00 VZERO ACO ACORDE EMC EMCAL MFT)
   list(FIND DETECTORMODULEMAP ${detector} _index)
   if(_index STREQUAL "-1")
     set(${_module} "${detector}" PARENT_SCOPE)
index 2183033c9f0f39d1be966ded562e3a88855bed41..b4c33f7faf72b04b31101b002d8572a370cd0c6a 100644 (file)
@@ -102,6 +102,13 @@ Int_t loadlibs ()
   if ( gSystem->Load("libHLTinterface") < 0 ) return ret; ret--;
   if ( gSystem->Load("libHLTsim") < 0 ) return ret; ret--;
   if ( gSystem->Load("libHLTrec") < 0 )  return ret; ret--;
+       
+  #ifdef MFT_UPGRADE
+  if ( gSystem->Load("libMFTbase") < 0 ) return ret; ret--;
+  if ( gSystem->Load("libMFTrec") < 0 ) return ret; ret--;
+  if ( gSystem->Load("libMFTsim") < 0 ) return ret; ret--;
+  #endif
+       
 
   return 0;
 
index c945bd58b1f5c38f6a2a6507ffd658a9f6a2f95f..2db79a0bbb8684d1f218068e68feed532e59523c 100644 (file)
@@ -83,7 +83,11 @@ Int_t loadlibsrec ()
   if ( gSystem->Load("libTOFbase") < 0 ) return ret; ret--;
   if ( gSystem->Load("libTOFrec") < 0 ) return ret; ret--;
   if ( gSystem->Load("libTOFsim") < 0 ) return ret; ret--;
-
+  #ifdef MFT_UPGRADE
+  if ( gSystem->Load("libMFTbase") < 0 ) return ret; ret--;
+  if ( gSystem->Load("libMFTrec") < 0 ) return ret; ret--;
+  if ( gSystem->Load("libMFTsim") < 0 ) return ret; ret--;
+  #endif
   if ( gSystem->Load("libHLTbase") < 0 ) return ret; ret--;
   
   return 0;
index 41f155de6ae5e6c3d29eb03c53f74f83bbe7c3c8..ae1b6ca9a3e2a77872570dc3f4cf86d7ae54d3b1 100644 (file)
@@ -96,6 +96,13 @@ Int_t loadlibssim ()
   if ( gSystem->Load("libHLTinterface") < 0 ) return ret; ret--;
   if ( gSystem->Load("libHLTsim") < 0 ) return ret; ret--;
   if ( gSystem->Load("libHLTrec") < 0 ) return ret; ret--;
-  
+
+  #ifdef MFT_UPGRADE 
+  if ( gSystem->Load("libMFTbase") < 0 ) return ret; ret--;
+  if ( gSystem->Load("libMFTrec") < 0 ) return ret; ret--;
+  if ( gSystem->Load("libMFTsim") < 0 ) return ret; ret--;
+  #endif
+       
+       
   return 0;
 }