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 cf7a6bf..49a7991 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 bb55c0e..c8d7ae1 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 8ae3812..a542c3f 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 a810aa8..ecdcf55 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 829154b..32531d8 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 f05becb..a2fbfb4 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 65dbf72..6f9b7c0 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 fe36ca9..a0a2693 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 8de36a9..d3f046c 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 437eaac..fb8b56b 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 40bf087..a346090 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 16ae16e..835b6a1 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 d4870ad..c8e6695 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 20e5167..a234702 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 a4a37f4..c88e559 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 df5481a..86dc6b4 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 3ec223e..d4494a3 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 e74f556..50e7d1f 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 6235ebd..598e57f 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 98e16d5..6ca7d32 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 19de27e..650db5f 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 37c44fa..cd38af6 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 63b6207..ffe5242 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 e55ac37..7a4b757 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 8e80591..d30c739 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 deff2f3..477cab6 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 58c14ab..5b8449e 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 eabb816..03f7e86 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 5b37cb7..0f51a82 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 54c99d6..d04b9eb 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 995ada6..bb493bd 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 76e4941..e3d6768 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 814fd22..35acc84 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 dc85cc0..366854c 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 67dc5f3..403ce4c 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 de14ac7..be083ba 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 f752402..4310fd6 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 d74057e..2a17ae3 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 76042a3..0ed8412 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 cfbe5f4..8445513 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 8710cba..250d171 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 fixe