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)
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})
# 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")
# 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)
# 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
}
// 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] =
{
"EMCAL",
"DAQ_TEST",
"HLT"
+ #ifndef MFT_UPGRADE
+ , "MFT"
+ #endif
};
void AliHLTModulePreprocessor::SetShuttleInterface(AliHLTShuttleInterface* pInterface)
--- /dev/null
+/**************************************************************************
+ * 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);
+
+}
+
+//====================================================================================================================================================
--- /dev/null
+#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
--- /dev/null
+// **************************************************************************
+// * 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);
+
+}
+
+//====================================================================================================================================================
--- /dev/null
+#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
+
--- /dev/null
+/**************************************************************************
+* 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;
+
+}
+
+//====================================================================================================================================================
--- /dev/null
+#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
+
--- /dev/null
+/**************************************************************************
+ * 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");
+ }
+
+}
+
+//====================================================================================================================================================
--- /dev/null
+/* 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
--- /dev/null
+//================================================================================================================================
+
+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();
+
+}
+
+//================================================================================================================================
+
--- /dev/null
+#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();
+
+}
+
+//====================================================================================================================================================
--- /dev/null
+#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
+
+
--- /dev/null
+/**************************************************************************
+ * 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;
+
+}
+
+//====================================================================================================================================================
--- /dev/null
+#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
+
+
+
--- /dev/null
+/**************************************************************************
+ * 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));
+
+}
+
+//====================================================================================================================================================
+
--- /dev/null
+#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
+
+
--- /dev/null
+/**************************************************************************
+ * 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());
+
+}
+
+//====================================================================================================================================================
--- /dev/null
+#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
--- /dev/null
+/**************************************************************************
+* 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");
+ }
+
+ }
+
+}
+
+//====================================================================================================================================================
+
--- /dev/null
+#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
+
--- /dev/null
+/**************************************************************************
+ * 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();
+ }
+
+}
+
+//====================================================================================================================================================
--- /dev/null
+#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
--- /dev/null
+/**************************************************************************
+ * 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;
+
+}
+
+//====================================================================================================================================================
+
--- /dev/null
+#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
+
--- /dev/null
+/**************************************************************************
+ * 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);
+
+}
+
+//====================================================================================================================================================
+
--- /dev/null
+#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
+
+
+
--- /dev/null
+//================================================================================================================================
+
+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();
+
+}
+
+//================================================================================================================================
+
--- /dev/null
+// 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(¤tParamFront, 0.);
+ AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(¤tParamBack, 0.);
+ AliMUONTrackExtrap::ExtrapToVertex(¤tParamForResearchFront, 0., 0., gRandom->Gaus(0,fGaussianBlurZVert), fExtrapOriginTransvError, fExtrapOriginTransvError);
+ AliMUONTrackExtrap::ExtrapToVertex(¤tParamForResearchBack, 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(¤tParamFront, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
+ fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/radLengthSi,-1.);
+ AliMUONTrackExtrap::AddMCSEffect(¤tParamForResearchFront,(fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
+ fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/radLengthSi,-1.);
+ AliMUONTrackExtrap::AddMCSEffect(¤tParamBack, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
+ fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/radLengthSi,-1.);
+ AliMUONTrackExtrap::AddMCSEffect(¤tParamForResearchBack, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
+ fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/radLengthSi,-1.);
+ }
+ // for all planes: extrapolation to the Z of the plane
+ AliMUONTrackExtrap::ExtrapToZCov(¤tParamFront, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveFront());
+ AliMUONTrackExtrap::ExtrapToZCov(¤tParamForResearchFront, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveFront());
+ AliMUONTrackExtrap::ExtrapToZCov(¤tParamBack, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveBack());
+ AliMUONTrackExtrap::ExtrapToZCov(¤tParamForResearchBack, -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(¤tParamFront, 0.);
+ AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(¤tParamBack, 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(¤tParamFront, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
+ fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeFront())/radLengthSi,-1.);
+ AliMUONTrackExtrap::AddMCSEffect(¤tParamBack, (fSegmentation->GetPlane(planeId+1)->GetEquivalentSilicon()+
+ fSegmentation->GetPlane(planeId)->GetEquivalentSiliconBeforeBack())/radLengthSi,-1.);
+ }
+ // for all planes: linear extrapolation to the Z of the plane
+ AliMUONTrackExtrap::ExtrapToZCov(¤tParamFront, -1.*fSegmentation->GetPlane(planeId)->GetZCenterActiveFront());
+ AliMUONTrackExtrap::ExtrapToZCov(¤tParamBack, -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;
+
+}
+
+//====================================================================================================================================================
+
--- /dev/null
+#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
+
+
--- /dev/null
+/**************************************************************************
+ * 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();
+
+}
+
+//====================================================================================================================================================
+
+
+
+
+
+
+
+
--- /dev/null
+#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
+
+
+
--- /dev/null
+#--------------------------------------------------------------------------------#
+# 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")
--- /dev/null
+#--------------------------------------------------------------------------------#
+# 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")
--- /dev/null
+#--------------------------------------------------------------------------------#
+# 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")
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+//==========================================================================================================================================
+
+// 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();
+
+}
+
+//==========================================================================================================================================
}
// 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;
}
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
CheckLoadLibrary("libTOFbase");
CheckLoadLibrary("libTOFrec");
CheckLoadLibrary("libTOFsim");
-
+ #ifdef MFT_UPGRADE
+ CheckLoadLibrary("libMFTbase");
+ CheckLoadLibrary("libMFTrec");
+ CheckLoadLibrary("libMFTsim");
+ #endif
CheckLoadLibrary("libPWG1");
}
"dimuons",
"AliAODVZERO",
"AliAODZDC"
+#ifdef MFT_UPGRADE
+ ,"AliAODMFT"
+#endif
};
//______________________________________________________________________________
fDimuons(0),
fAODVZERO(0),
fAODZDC(0)
+#ifdef MFT_UPGRADE
+ ,fAODMFT(0)
+#endif
{
// default constructor
}
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);
AddObject(fDimuons);
AddObject(fAODVZERO);
AddObject(fAODZDC);
+#ifdef MFT_UPGRADE
+ AddObject(fAODVZERO);
+#endif
fConnected = aod.fConnected;
GetStdContent();
CreateStdFolders();
AddObject(new TClonesArray("AliAODDimuon", 0));
AddObject(new AliAODVZERO());
AddObject(new AliAODZDC());
+#ifdef MFT_UPGRADE
+ AddObject(new AliAODMFT());
+#endif
// set names
SetStdNames();
fDimuons = (TClonesArray*)fAODObjects->FindObject("dimuons");
fAODVZERO = (AliAODVZERO*)fAODObjects->FindObject("AliAODVZERO");
fAODZDC = (AliAODZDC*)fAODObjects->FindObject("AliAODZDC");
+#ifdef MFT_UPGRADE
+ fAODMFT = (AliAODMFT*)fAODObjects->FindObject("AliAODMFT");
+#endif
}
//______________________________________________________________________________
#include "AliAODDimuon.h"
#include "AliAODVZERO.h"
#include "AliAODZDC.h"
+#ifdef MFT_UPGRADE
+#include "AliAODMFT.h"
+#endif
class TTree;
class TFolder;
kAODVZERO,
kAODZDC,
kAODListN
+ #ifdef MFT_UPGRADE
+ ,kAODVZERO
+ #endif
};
AliAODEvent();
//ZDC
AliAODZDC *GetZDCData() const { return fAODZDC; }
+#ifdef MFT_UPGRADE
+ // MFT
+ AliAODMFT *GetMFTData() const { return fAODMFT; }
+#endif
+
private :
TList *fAODObjects; // list of AODObjects
TClonesArray *fDimuons; //! dimuons
AliAODVZERO *fAODVZERO; //! VZERO AOD
AliAODZDC *fAODZDC; //! ZDC AOD
+#ifdef MFT_UPGRADE
+ AliAODMFT *fAODMFT; //! VZERO AOD
+#endif
static const char* fAODListName[kAODListN]; //!
{
// 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) {
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()));
// 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");
{
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;
+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
+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
STEERBase/AliOADBContainer.cxx
STEERBase/AliMathBase.cxx
STEERBase/TTreeStream.cxx
+ STEERBase/AliVMFT.cxx
)
string(REPLACE ".cxx" ".h" HDRS "${SRCS}")
fESDVZERO(0x0),
fESDACORDE(0x0),
fErrorLogs("AliRawDataErrorLog",5)
+ #ifdef MFT_UPGRADE
+ // ,fESDMFT(0x0)
+ #endif
{
//
// Standar constructor
fESDVZERO(esd.fESDVZERO),
fESDACORDE(esd.fESDACORDE),
fErrorLogs(*((TClonesArray*)esd.fErrorLogs.Clone()))
+ #ifdef MFT_UPGRADE
+ //, fESDMFT(esd.fESDMFT)
+ #endif
{
//
// copy constructor
delete fPHOSTriggerPosition;
delete fPHOSTriggerAmplitudes;
delete fESDACORDE;
-
+ #ifdef MFT_UPGRADE
+// delete fESDMFT;
+ #endif
fErrorLogs.Delete();
}
if (fESDACORDE){
fESDACORDE->~AliESDACORDE();
new (fESDACORDE) AliESDACORDE();
- }
+ }
+//
+ #ifdef MFT_UPGRADE
+ // if (fESDMFT){
+// fESDMFT->~AliESDMFT();
+// new (fESDMFT) AliESDMFT();
+// }
+ #endif
//
fErrorLogs.Delete();
}
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) {
#include "AliMultiplicity.h"
#include "AliRawDataErrorLog.h"
#include "AliESDACORDE.h"
+#ifdef MFT_UPGRADE
+//#include "AliESDMFT.h"
+#endif
class AliESDfriend;
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 {
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
#include "AliESDACORDE.h"
#include "AliESDHLTDecision.h"
#include "AliCentrality.h"
+#ifdef MFT_UPGRADE
+#include "AliESDMFT.h"
+#endif
#include "AliEventplane.h"
+
ClassImp(AliESDEvent)
"PHOSCells",
"AliRawDataErrorLogs",
"AliESDACORDE",
- "AliTOFHeader"};
+ "AliTOFHeader"
+ #ifdef MFT_UPGRADE
+// , "AliESDMFT"
+ #endif
+ };
//______________________________________________________________________________
AliESDEvent::AliESDEvent():
fTOFHeader(0),
fCentrality(0),
fEventplane(0)
+ #ifdef MFT_UPGRADE
+// , fESDMFT(0)
+ #endif
{
}
//______________________________________________________________________________
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);
AddObject(fErrorLogs);
AddObject(fESDACORDE);
AddObject(fTOFHeader);
-
+ #ifdef MFT_UPGRADE
+// AddObject(fESDMFT);
+ #endif
GetStdContent();
}
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();
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");
*fESDTZERO = *obj;
}
+#ifdef MFT_UPGRADE
+//void AliESDEvent::SetMFTData(AliESDMFT * obj)
+//{
+// if(fESDMFT)
+// *fESDMFT = *obj;
+//}
+#endif
+
void AliESDEvent::SetACORDEData(AliESDACORDE * obj)
{
if(fESDACORDE)
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(){
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
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
}
#include "AliTOFHeader.h"
#include "AliESDVZERO.h"
+#ifdef MFT_UPGRADE
+//#include "AliESDMFT.h"
+#endif
class AliESDfriend;
class AliESDHLTtrack;
kESDACORDE,
kTOFHeader,
kESDListN
+ #ifdef MFT_UPGRADE
+ // , kESDMFT
+ #endif
};
AliESDEvent();
// 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);
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",
"EMCal",
"DAQ_TEST",
"HLT"
+// #ifdef MFT_UPGRADE
+// , "MFT"
+// #endif
+ , "MFT" // AU
};
//_____________________________________________________________________________
#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+;
}
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!"));
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;
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];
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"} ;
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 {
//
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,
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) :
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();
// 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);
// 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];
// 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()) ;
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);
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*/,
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!");
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,
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++;
}
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
"ACORDE",
"TRG",
"EMCAL",
- "DAQ_TEST",
- "HLT"
+ "DAQ_TEST"
+ , "MFT" // AU
+ , "HLT"
};
Int_t AliDAQ::fgkNumberOfDdls[AliDAQ::kNDetectors] = {
1,
46,
1,
+ 1,
28
};
1,
8,
1,
+ 1,
7
};
"ACORDE",
"CTP",
"EMCAL",
- "",
- "HLT"
+ ""
+ , "MFT" // AU
+ , "HLT"
+
};
const char* AliDAQ::fgkOnlineName[AliDAQ::kNDetectors] = {
"ACO",
"TRI",
"EMC",
- "TST",
- "HLT"
+ "TST"
+ , "MFT" // AU
+ , "HLT"
};
AliDAQ::AliDAQ(const AliDAQ& source) :
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)
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();
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
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;
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",
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 {
kEMCAL = 8,
kPMD = 10,
kFMD = 12,
- kVZERO = 14
+ kVZERO = 14,
+ kMFT = 16
};
AliTrackReference();
AliTrackReference(Int_t label, Int_t id = -999);
class AliEventplane;
class AliVVZERO;
class AliVZDC;
+class AliVMFT; // AU
class AliVEvent : public TObject {
--- /dev/null
+/**************************************************************************
+ * 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;
+}
+
--- /dev/null
+#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
#pragma link C++ class TTreeStream+;
#pragma link C++ class TTreeSRedirector+;
+#pragma link C++ class AliVMFT+;
#endif
--- /dev/null
+
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+//-------------------------------------------------------------------------
+// Beam pipe class
+// This version uses TGeo
+// Author: A.Morsch
+//-------------------------------------------------------------------------
+
+
+#include <Riostream.h>
+
+#include <TSystem.h>
+#include <TVirtualMC.h>
+#include <TGeoManager.h>
+#include <TGeoMatrix.h>
+#include <TGeoVolume.h>
+#include <TGeoTorus.h>
+#include <TGeoTube.h>
+#include <TGeoCone.h>
+#include <TGeoPcon.h>
+#include <TGeoBBox.h>
+#include <TGeoXtru.h>
+#include <TGeoCompositeShape.h>
+#include <TGeoGlobalMagField.h>
+
+#include "AliConst.h"
+#include "AliMagF.h"
+#include "AliPIPEv4.h"
+#include "AliRun.h"
+#include "AliLog.h"
+
+ClassImp(AliPIPEv4)
+
+//_____________________________________________________________________________
+AliPIPEv4::AliPIPEv4():
+ ftheta_cone(6.00), // angle of conical beam pipe, if angle < 3 --> cylindrical beam pipe
+ frmin1(2.00), // internal radius of Be beam pipe
+ fepaisseur(0.08), // width of Be beam pipe
+ fsigmaz(8.00), // dispersion of z location (1 sigma) of beam impact position
+ fz_chambre(-40.0), // first pixel chamber location, closest to the IP
+ fzdebut1(50.), // beginning of beam pipe z location (A side)
+ fzfin4(-82.) // end of beamp pipe z location (C side)
+{
+ // Constructor
+}
+
+//_____________________________________________________________________________
+AliPIPEv4::AliPIPEv4(const char *name, const char *title)
+ : AliPIPE(name,title),
+ ftheta_cone(6.00), // angle of conical beam pipe, if angle < 3 --> cylindrical beam pipe
+ frmin1(2.00), // internal radius of Be beam pipe
+ fepaisseur(0.08), // width of Be beam pipe
+ fsigmaz(8.00), // dispersion of z location (1 sigma) of beam impact position
+ fz_chambre(-40.0), // first pixel chamber location, closest to the IP
+ fzdebut1(50.), // beginning of beam pipe z location (A side)
+ fzfin4(-82.) // end of beamp pipe z location (C side)
+{
+ // Constructor
+}
+
+
+//_____________________________________________________________________________
+AliPIPEv4::AliPIPEv4(const char *name, const char *title, const Float_t theta_cone, const Float_t rmin1, const Float_t epaisseur,
+ const Float_t sigmaz, const Float_t z_chambre)
+ : AliPIPE(name,title),
+ ftheta_cone(theta_cone), // angle of conical beam pipe, if angle < 3 --> cylindrical beam pipe
+ frmin1(rmin1), // internal radius of Be beam pipe
+ fepaisseur(epaisseur), // width of Be beam pipe
+ fsigmaz(sigmaz), // dispersion of z location (1 sigma) of beam impact position
+ fz_chambre(z_chambre), // first pixel chamber location, closest to the IP
+ fzdebut1(50.), // beginning of beam pipe z location (A side)
+ fzfin4(-82.) // end of beamp pipe z location (C side)
+{
+ // Constructor
+
+}
+
+
+//___________________________________________
+void AliPIPEv4::CreateGeometry()
+{
+ AliDebug(1,"Create PIPEv4 geometry");
+ //
+ // Class describing the beam pipe geometry
+ //
+ Float_t lolo = 0.9; //1.3 minimum pour que le premier anneau soit dans l'acceptance du spectro
+ Float_t dz, z, zsh, z0;
+ //
+ // Rotation Matrices
+ //
+ const Float_t kDegRad = TMath::Pi() / 180.;
+ // Rotation by 180 deg
+ TGeoRotation* rot180 = new TGeoRotation("rot180", 90., 180., 90., 90., 180., 0.);
+ TGeoRotation* rotyz = new TGeoRotation("rotyz", 90., 180., 0., 180., 90., 90.);
+ TGeoRotation* rotxz = new TGeoRotation("rotxz", 0., 0., 90., 90., 90., 180.);
+ TGeoRotation* rot045 = new TGeoRotation("rot045", 90., 45., 90., 135., 0., 0.);
+ TGeoRotation* rot135 = new TGeoRotation("rot135", 90. ,135., 90., 225., 0., 0.);
+ TGeoRotation* rot225 = new TGeoRotation("rot225", 90. ,225., 90., 315., 0., 0.);
+ TGeoRotation* rot315 = new TGeoRotation("rot315", 90. ,315., 90., 45., 0., 0.);
+ //
+ // Media
+ const TGeoMedium* kMedAir = gGeoManager->GetMedium("PIPE_AIR");
+ const TGeoMedium* kMedAirHigh = gGeoManager->GetMedium("PIPE_AIR_HIGH");
+ const TGeoMedium* kMedVac = gGeoManager->GetMedium("PIPE_VACUUM");
+ const TGeoMedium* kMedInsu = gGeoManager->GetMedium("PIPE_INS_C0");
+ const TGeoMedium* kMedSteel = gGeoManager->GetMedium("PIPE_INOX");
+ const TGeoMedium* kMedBe = gGeoManager->GetMedium("PIPE_BE");
+ const TGeoMedium* kMedCu = gGeoManager->GetMedium("PIPE_CU");
+ //const TGeoMedium* kMedKapton = gGeoManager->GetMedium("PIPE_KAPTON");
+ const TGeoMedium* kMedAco = gGeoManager->GetMedium("PIPE_ANTICORODAL");
+ //const TGeoMedium* kMedNEG = gGeoManager->GetMedium("PIPE_NEG COATING");
+
+ // Top volume
+ TGeoVolume* top = gGeoManager->GetVolume("ALIC");
+ //
+ //
+ ////////////////////////////////////////////////////////////////////////////////
+ // //
+ // The Central Vacuum system //
+ // //
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ //
+ // The ALICE central beam-pipe according to drawing LHCVC2C_0001
+ // Drawings of sub-elements:
+ //
+ // Pos 7 - Minimised Flange: LHCVFX_P0025
+ // Pos 6 - Standard Flange: STDVFUHV0009
+ // Pos 8 - Bellow: LHCVBX__0001
+ //
+ // Absolute z-coordinates -82.0 - 400.0 cm
+ // Total length: 482.0 cm
+ // It consists of 3 main parts:
+ // CP/2 The flange on the non-absorber side: 36.5 cm
+ // CP/1 The central Be pipe: 405.0 cm
+ // CP/3 The double-bellow and flange on the absorber side: 40.5 cm
+ //
+ //
+
+ //
+ //
+ // Starting position in z
+ const Float_t kCPz0 = -400.0;
+ // Length of the CP/1 section
+ const Float_t kCP1Length = 405.0;
+ // Length of the CP/2 section
+ const Float_t kCP2Length = 36.5;
+ // Length of the CP/3 section
+ const Float_t kCP3Length = 40.5;
+ // Position of the CP/2 section
+ // const Float_t kCP2pos = kCPz0 + kCP2Length / 2.;
+ // Position of the CP/3 section
+ const Float_t kCP3pos = kCPz0 + kCP2Length + kCP1Length + kCP3Length/2.;
+
+
+
+ ///////////////////////////////// NEW GEOMETRY /////////////////////////////////////////////
+
+ Float_t zfin1= fsigmaz - frmin1/TMath::Tan(ftheta_cone/ 180. * TMath::Pi());
+ Float_t zdebut2=zfin1;
+ Float_t rmax2= TMath::Tan(ftheta_cone/ 180. * TMath::Pi())*(fsigmaz+TMath::Abs(fz_chambre));
+ Float_t zfin2=-(TMath::Abs(fz_chambre)-1);
+ Float_t zdebut3=zfin2;
+ Float_t zfin3=zfin2+(-fepaisseur);
+ Float_t zdebut4=zfin3;
+ //---------------- Conical beam pipe ---------------
+ if(ftheta_cone>3){
+ TGeoPcon* CONE_VIDE = new TGeoPcon(0., 360., 8);
+ CONE_VIDE->DefineSection(0,fzdebut1, 0.,frmin1);
+ CONE_VIDE->DefineSection(1,zfin1, 0.,frmin1);
+ CONE_VIDE->DefineSection(2,zdebut2, 0.,frmin1);
+ CONE_VIDE->DefineSection(3,zfin2, 0.,rmax2);
+ CONE_VIDE->DefineSection(4,zdebut3, 0.,frmin1);
+ CONE_VIDE->DefineSection(5,zfin3, 0.,frmin1);
+ CONE_VIDE->DefineSection(6,zdebut4, 0.,frmin1);
+ CONE_VIDE->DefineSection(7,fzfin4, 0.,frmin1);
+ TGeoVolume* voCONE_VIDE = new TGeoVolume("CONE_VIDE",CONE_VIDE,kMedVac);
+ voCONE_VIDE->SetLineColor(kOrange);
+ top->AddNode(voCONE_VIDE,1,new TGeoTranslation(0., 0., 0.));
+
+ TGeoPcon* CONE_BE = new TGeoPcon(0., 360., 8);
+ CONE_BE->DefineSection(0,fzdebut1,frmin1,frmin1+fepaisseur);
+ CONE_BE->DefineSection(1,zfin1,frmin1,frmin1+fepaisseur);
+ CONE_BE->DefineSection(2,zdebut2,frmin1,frmin1+fepaisseur);
+ CONE_BE->DefineSection(3,zfin2,rmax2,rmax2+fepaisseur);
+ CONE_BE->DefineSection(4,zdebut3,frmin1,rmax2+fepaisseur);
+ CONE_BE->DefineSection(5,zfin3,frmin1,rmax2+fepaisseur);
+ CONE_BE->DefineSection(6,zdebut4,frmin1,frmin1+fepaisseur);
+ CONE_BE->DefineSection(7,fzfin4,frmin1,frmin1+fepaisseur);
+ TGeoVolume* voCONE_BE = new TGeoVolume("CONE_BE",CONE_BE,kMedBe);
+ voCONE_BE->SetLineColor(kRed);
+ }
+ //--------------- Cylindrical beam pipe -------------
+ if(ftheta_cone<3){
+ TGeoPcon* TUBE_VIDE = new TGeoPcon(0., 360., 2);
+ TUBE_VIDE->DefineSection(0,fzdebut1, 0.,frmin1);
+ TUBE_VIDE->DefineSection(1,fzfin4, 0.,frmin1);
+ TGeoVolume* voTUBE_VIDE = new TGeoVolume("TUBE_VIDE",TUBE_VIDE,kMedVac);
+ voTUBE_VIDE->SetLineColor(kOrange);
+ top->AddNode(voTUBE_VIDE,1,new TGeoTranslation(0., 0., 0.));
+
+ TGeoPcon* TUBE_BE = new TGeoPcon(0., 360., 2);
+ TUBE_BE->DefineSection(0,fzdebut1,frmin1,frmin1+fepaisseur);
+ TUBE_BE->DefineSection(1,fzfin4,frmin1,frmin1+fepaisseur);
+ TGeoVolume* voTUBE_BE = new TGeoVolume("TUBE_BE",TUBE_BE,kMedBe);
+ voTUBE_BE->SetLineColor(kRed);
+ top->AddNode(voTUBE_BE,1,new TGeoTranslation(0., 0., 0.));
+ }
+
+ /////////////////////// END NEW GEOMETRY /////////////////////////////
+
+
+
+ //
+ ///////////////////
+ // CP/2 //
+ ///////////////////
+ //
+ // Fixed Point tube [Pos 5]
+ //
+ // Inner and outer radii of the Stainless Steel pipe
+ const Float_t kCP2StRi = 2.90-lolo;
+ const Float_t kCP2StRo = 2.98-lolo;
+ //
+ // Transition to central Be-pipe (Bulge)
+ // Length
+ const Float_t kCP2BulgeLength = 0.80;
+ //
+ // Bulge outer radius
+ const Float_t kCP2BulgeRo = 3.05-lolo;
+ //
+ // Fixed Point at z = 391.7 (IP)
+ //
+ // Position of fixed point
+ const Float_t kCP2FixedPointZ = 8.30;
+ //
+ // Outer radius of fixed point
+ const Float_t kCP2FixedPointRo = 3.50-lolo;
+ //
+ // Length of fixed point
+ const Float_t kCP2FixedPointLength = 0.60;
+ //
+ // Fixed Flange [Pos 6]
+ //
+ // Fixed flange outer radius
+ const Float_t kCP2FixedFlangeRo = 7.60;
+ //
+ // Fixed flange inner radius
+ const Float_t kCP2FixedFlangeRi = 3.00;
+ // Fixed flange inner radius bulge
+ const Float_t kCP2FixedFlangeBulgeRi = 2.90;
+ // Fixed flange lengths of sections at inner radius
+ const Float_t kCP2FixedFlangeRecessLengths[3] ={1., 0.08, 0.9};
+ // Fixed flange length
+ const Float_t kCP2FixedFlangeLength = 1.98;
+ //
+ // Fixed flange bulge
+ // Outer radius
+ const Float_t kCP2FixedFlangeBulgeRo = 3.00-lolo;
+ //
+ // Length
+ const Float_t kCP2FixedFlangeBulgeLength = 2.00;
+
+ //
+ // CP/2 Mother Volume
+ //
+ TGeoPcon* shCp2Mo = new TGeoPcon(0., 360., 14);
+ // Flange
+ z = - kCP2Length / 2.;
+ shCp2Mo->DefineSection( 0, z, kCP2FixedFlangeRi, kCP2FixedFlangeRo);
+ z += kCP2FixedFlangeRecessLengths[0];
+ shCp2Mo->DefineSection( 1, z, kCP2FixedFlangeRi, kCP2FixedFlangeRo);
+ shCp2Mo->DefineSection( 2, z, 0., kCP2FixedFlangeRo);
+ z += (kCP2FixedFlangeRecessLengths[1] + kCP2FixedFlangeRecessLengths[2]) ;
+ shCp2Mo->DefineSection( 3, z, 0., kCP2FixedFlangeRo);
+ // Straight section between Flange and Fixed Point
+ shCp2Mo->DefineSection( 4, z, 0., kCP2FixedFlangeBulgeRo);
+ z += kCP2FixedFlangeBulgeLength;
+ shCp2Mo->DefineSection( 5, z, 0., kCP2FixedFlangeBulgeRo);
+ shCp2Mo->DefineSection( 6, z, 0., kCP2StRo);
+ z = - kCP2Length / 2 + kCP2FixedPointZ - kCP2FixedPointLength / 2.;
+ shCp2Mo->DefineSection( 7, z, 0., kCP2StRo);
+ // Fixed Point
+ shCp2Mo->DefineSection( 8, z, 0., kCP2FixedPointRo);
+ z += kCP2FixedPointLength;
+ shCp2Mo->DefineSection( 9, z, 0., kCP2FixedPointRo);
+ // Straight section between Fixed Point and transition bulge
+ shCp2Mo->DefineSection(10, z, 0., kCP2StRo);
+ z = kCP2Length / 2. - kCP2BulgeLength;
+ shCp2Mo->DefineSection(11, z, 0., kCP2StRo);
+ shCp2Mo->DefineSection(12, z, 0., kCP2BulgeRo);
+ z = kCP2Length / 2.;
+ shCp2Mo->DefineSection(13, z, 0., kCP2BulgeRo);
+
+ TGeoVolume* voCp2Mo = new TGeoVolume("CP2MO", shCp2Mo, kMedAir);
+ voCp2Mo->SetVisibility(0);
+ //
+ // CP/1 Vacuum
+ TGeoTube* shCp2Va = new TGeoTube(0., kCP2StRi, (kCP2Length - kCP2FixedFlangeRecessLengths[0])/2.);
+ TGeoVolume* voCp2Va = new TGeoVolume("CP2VA", shCp2Va, kMedVac);
+
+ voCp2Mo->AddNode(voCp2Va, 1, new TGeoTranslation(0., 0., kCP2FixedFlangeRecessLengths[0]/2.));
+
+ /////////////////////////////////////////////
+ // CP/2 Fixed Flange [Pos 6] //
+ /////////////////////////////////////////////
+
+ TGeoPcon* shCp2Fl = new TGeoPcon(0., 360., 6);
+ z = - kCP2FixedFlangeLength / 2.;
+ shCp2Fl->DefineSection(0, z, kCP2FixedFlangeRi, kCP2FixedFlangeRo);
+ z += kCP2FixedFlangeRecessLengths[0];
+ shCp2Fl->DefineSection(1, z, kCP2FixedFlangeRi, kCP2FixedFlangeRo);
+ shCp2Fl->DefineSection(2, z, kCP2FixedFlangeBulgeRi, kCP2FixedFlangeRo);
+ z += kCP2FixedFlangeRecessLengths[1];
+ shCp2Fl->DefineSection(3, z, kCP2FixedFlangeBulgeRi, kCP2FixedFlangeRo);
+ shCp2Fl->DefineSection(4, z, kCP2FixedFlangeRi, kCP2FixedFlangeRo);
+ z = kCP2FixedFlangeLength / 2.;
+ shCp2Fl->DefineSection(5, z, kCP2FixedFlangeRi, kCP2FixedFlangeRo);
+ TGeoVolume* voCp2Fl = new TGeoVolume("CP2FL", shCp2Fl, kMedSteel);
+ //
+ dz = - kCP2Length / 2. + kCP2FixedFlangeLength / 2.;
+ voCp2Mo->AddNode(voCp2Fl, 1, new TGeoTranslation(0., 0., dz));
+
+
+ /////////////////////////////////////////////////////////////
+ // CP/2 Beam pipe with fixed point and transition bulges //
+ /////////////////////////////////////////////////////////////
+ TGeoPcon* shCp2Pi = new TGeoPcon(0., 360., 10);
+ // Bulge at transition to flange
+ z = - (kCP2Length - kCP2FixedFlangeRecessLengths[0] - kCP2FixedFlangeRecessLengths[1]) / 2.;
+ z0 = z;
+ shCp2Pi->DefineSection(0, z, kCP2StRi, kCP2FixedFlangeBulgeRo);
+ z += kCP2FixedFlangeBulgeLength;
+ shCp2Pi->DefineSection(1, z, kCP2StRi, kCP2FixedFlangeBulgeRo);
+ // Straight section between Bulge and Fixed Point
+ shCp2Pi->DefineSection(2, z, kCP2StRi, kCP2StRo);
+ z += (kCP2FixedPointZ - kCP2FixedPointLength / 2. - kCP2FixedFlangeRecessLengths[0]
+ - kCP2FixedFlangeRecessLengths[1] -
+ kCP2FixedFlangeBulgeLength);
+ shCp2Pi->DefineSection(3, z, kCP2StRi, kCP2StRo);
+ // Fixed Point
+ shCp2Pi->DefineSection(4, z, kCP2StRi, kCP2FixedPointRo);
+ z += kCP2FixedPointLength;
+ shCp2Pi->DefineSection(5, z, kCP2StRi, kCP2FixedPointRo);
+ // Straight section between Fixed Point and transition bulge
+ shCp2Pi->DefineSection(6, z, kCP2StRi, kCP2StRo);
+ z = - shCp2Pi->GetZ(0) - kCP2BulgeLength;
+ shCp2Pi->DefineSection(7, z, kCP2StRi, kCP2StRo);
+ // Bulge at transition to Be pipe
+ shCp2Pi->DefineSection(8, z, kCP2StRi, kCP2BulgeRo);
+ z = - shCp2Pi->GetZ(0);
+ shCp2Pi->DefineSection(9, z, kCP2StRi, kCP2BulgeRo);
+
+ TGeoVolume* voCp2Pi = new TGeoVolume("CP2PI", shCp2Pi, kMedSteel);
+ dz = (kCP2FixedFlangeRecessLengths[0] + kCP2FixedFlangeRecessLengths[1]) / 2.;
+ voCp2Mo->AddNode(voCp2Pi, 1, new TGeoTranslation(0., 0., dz));
+
+ //
+ // Central beam pipe support collars
+ // LHCVC2C_0019
+ // Position at z = -46., 40., 150.
+ //TGeoVolume* voCpSupC = new TGeoVolume("CpSupC", new TGeoTube(3.051, 4.00, 0.35), kMedAco);
+ //voCp1->AddNode(voCpSupC, 1, new TGeoTranslation(0., 0., kCP1Length / 2. - 98.2));
+ //voCp1->AddNode(voCpSupC, 2, new TGeoTranslation(0., 0., kCP1Length / 2.- 191.5));
+
+ TGeoVolume* voCpSupClolo = new TGeoVolume("CpSupC", new TGeoTube(3.051-lolo, 4.0-lolo, 0.35), kMedAco);
+ // Beam Pipe Protection Tube
+ //
+ // ALIFWDA_0025
+ //
+ // Plaque de Centrage ALIFWDA_0019
+ const Float_t kFwdaBPPTXL = 3.;
+ TGeoXtru* shFwdaBPPTX = new TGeoXtru(2);
+ Double_t xBPPTX[8] = {12.5, 7.5, -7.5, -12.5, -12.5, -7.5, 7.5, 12.5};
+ Double_t yBPPTX[8] = { 7.0, 12.0, 12.0, 7.0, -7.0, -12.0, -12.0, -7.0};
+ shFwdaBPPTX->DefinePolygon(8, xBPPTX, yBPPTX);
+ shFwdaBPPTX->DefineSection(0, 0., 0., 0., 1.);
+ shFwdaBPPTX->DefineSection(1, kFwdaBPPTXL, 0., 0., 1.);
+ shFwdaBPPTX->SetName("FwdaBPPTX");
+ TGeoTube* shFwdaBPPTY = new TGeoTube(0., 8.5, 3.2);
+ shFwdaBPPTY->SetName("FwdaBPPTY");
+ TGeoCompositeShape* shFwdaBPPTPC = new TGeoCompositeShape("shFwdaBPPTPC", "FwdaBPPTX-FwdaBPPTY");
+ TGeoVolume* voFwdaBPPTPC = new TGeoVolume("FwdaBPPTPC", shFwdaBPPTPC, kMedAco);
+ //
+ // Tube ALIFWDA_0020
+ // const Float_t kFwdaBPPTTL = 48.;
+ const Float_t kFwdaBPPTTL = 35.;
+ TGeoVolume* voFwdaBPPTT = new TGeoVolume("FwdaBPPTT", new TGeoTube(8.85, 9.0, kFwdaBPPTTL/2.), kMedAco);
+ TGeoVolumeAssembly* voFwdaBPPT = new TGeoVolumeAssembly("FwdaBPPT");
+ voFwdaBPPT->AddNode(voFwdaBPPTPC, 1, gGeoIdentity);
+ voFwdaBPPT->AddNode(voFwdaBPPTT, 1, new TGeoTranslation(0., 0., kFwdaBPPTTL/2. + kFwdaBPPTXL));
+
+
+ // BeamPipe and T0A Support
+ //
+ // ALIFWDA_0033
+ //
+ // Support Plate ALIFWDA_0026
+ const Float_t kFwdaBPSPL = 4.0;
+ TGeoXtru* shFwdaBPSPX = new TGeoXtru(2);
+ Double_t xBPSPX[8] = {10.0, 6.0 , -6.0, -10.0, -10.0, -6.0, 6.0, 10.0};
+ Double_t yBPSPX[8] = { 6.0, 10.0, 10.0, 6.0, - 6.0, -10.0, -10.0, -6.0};
+ shFwdaBPSPX->DefinePolygon(8, xBPSPX, yBPSPX);
+ shFwdaBPSPX->DefineSection(0, 0., 0., 0., 1.);
+ shFwdaBPSPX->DefineSection(1, kFwdaBPSPL, 0., 0., 1.);
+ shFwdaBPSPX->SetName("FwdaBPSPX");
+ TGeoPcon* shFwdaBPSPY = new TGeoPcon(0., 360., 6);
+ shFwdaBPSPY->DefineSection(0, -1.00, 0., 5.5);
+ shFwdaBPSPY->DefineSection(1, 3.50, 0., 5.5);
+ shFwdaBPSPY->DefineSection(2, 3.50, 0., 5.0);
+ shFwdaBPSPY->DefineSection(3, 3.86, 0., 5.0);
+ shFwdaBPSPY->DefineSection(4, 3.86, 0., 5.5);
+ shFwdaBPSPY->DefineSection(5, 5.00, 0., 5.5);
+ shFwdaBPSPY->SetName("FwdaBPSPY");
+ TGeoCompositeShape* shFwdaBPSP = new TGeoCompositeShape("shFwdaBPSP", "FwdaBPSPX-FwdaBPSPY");
+ TGeoVolume* voFwdaBPSP = new TGeoVolume("FwdaBPSP", shFwdaBPSP, kMedAco);
+ //
+ // Flasque ALIFWDA_00027
+
+
+ const Float_t kFwdaBPSTTRi = 7.6/2.;
+ const Float_t kFwdaBPSTTRo1 = 13.9/2.;
+ const Float_t kFwdaBPSTTRo2 = 8.2/2.;
+ const Float_t kFwdaBPSTTRo3 = 9.4/2.;
+
+ TGeoPcon* shFwdaBPSFL = new TGeoPcon(0., 360., 8);
+ z = 0.,
+ shFwdaBPSFL->DefineSection(0, z, kFwdaBPSTTRi, kFwdaBPSTTRo1);
+ z += 0.64;
+ shFwdaBPSFL->DefineSection(1, z, kFwdaBPSTTRi, kFwdaBPSTTRo1);
+ shFwdaBPSFL->DefineSection(2, z, kFwdaBPSTTRi, kFwdaBPSTTRo2);
+ z += 2.55;
+ shFwdaBPSFL->DefineSection(3, z, kFwdaBPSTTRi, kFwdaBPSTTRo2);
+ shFwdaBPSFL->DefineSection(4, z, kFwdaBPSTTRi, kFwdaBPSTTRo3);
+ z += 0.4;
+ shFwdaBPSFL->DefineSection(5, z, kFwdaBPSTTRi, kFwdaBPSTTRo3);
+ shFwdaBPSFL->DefineSection(6, z, kFwdaBPSTTRi, kFwdaBPSTTRo2);
+ z += 1.2;
+ shFwdaBPSFL->DefineSection(7, z, kFwdaBPSTTRi, kFwdaBPSTTRo2);
+
+ TGeoVolume* voFwdaBPSFL = new TGeoVolume("FwdaBPSFL", shFwdaBPSFL, kMedAco);
+
+
+ //
+ // Cable support
+ TGeoBBox* shFwdaBPSCSa = new TGeoBBox(3.0, 8.75, 0.5);
+ shFwdaBPSCSa->SetName("FwdaBPSCSa");
+ TGeoBBox* shFwdaBPSCSb = new TGeoBBox(1.25, 4.00, 1.0);
+ shFwdaBPSCSb->SetName("FwdaBPSCSb");
+ TGeoTranslation* tFwdaBPSCSb = new TGeoTranslation(0., 5.25 - 8.75, 0.);
+ tFwdaBPSCSb->SetName("tFwdaBPSCSb");
+ tFwdaBPSCSb->RegisterYourself();
+ TGeoBBox* shFwdaBPSCSc = new TGeoBBox(3.0, 0.50, 0.70);
+ shFwdaBPSCSc->SetName("FwdaBPSCSc");
+ TGeoTranslation* tFwdaBPSCSc = new TGeoTranslation(0., 0.5 - 8.75, 1.2);
+ tFwdaBPSCSc->SetName("tFwdaBPSCSc");
+ tFwdaBPSCSc->RegisterYourself();
+ TGeoCompositeShape* shFwdaBPSCS = new TGeoCompositeShape("shFwdaBPSCS", "(FwdaBPSCSa-FwdaBPSCSb:tFwdaBPSCSb)+FwdaBPSCSc:tFwdaBPSCSc");
+ TGeoVolume* voFwdaBPSCS = new TGeoVolume("FwdaBPSCS", shFwdaBPSCS, kMedAco);
+
+
+ // Assembling the beam pipe support
+ TGeoVolumeAssembly* voFwdaBPS = new TGeoVolumeAssembly("FwdaBPS");
+ voFwdaBPS->AddNode(voFwdaBPSP, 1, new TGeoCombiTrans(0., 0., 0., rot045));
+ voFwdaBPS->AddNode(voFwdaBPSFL, 1, new TGeoTranslation(0., 0., kFwdaBPSPL));
+ const Float_t kFwdaBPSCSdy = 18.75/TMath::Sqrt(2.);
+
+ voFwdaBPS->AddNode(voFwdaBPSCS, 1, new TGeoCombiTrans(- kFwdaBPSCSdy, kFwdaBPSCSdy, 2., rot045));
+ voFwdaBPS->AddNode(voFwdaBPSCS, 2, new TGeoCombiTrans(- kFwdaBPSCSdy, - kFwdaBPSCSdy, 2., rot135));
+ voFwdaBPS->AddNode(voFwdaBPSCS, 3, new TGeoCombiTrans( kFwdaBPSCSdy, - kFwdaBPSCSdy, 2., rot225));
+ voFwdaBPS->AddNode(voFwdaBPSCS, 4, new TGeoCombiTrans( kFwdaBPSCSdy, kFwdaBPSCSdy, 2., rot315));
+
+ TGeoVolumeAssembly* voCp2 = new TGeoVolumeAssembly("CP2");
+ voCp2->AddNode(voCp2Mo, 1, gGeoIdentity);
+ voCp2->AddNode(voFwdaBPPT, 1, new TGeoTranslation(0., 0., -kCP2Length / 2. + 13.8));
+ voCp2->AddNode(voFwdaBPS, 1, new TGeoTranslation(0., 0., -kCP2Length / 2. + 5.1));
+
+ //
+ ///////////////////
+ // CP/3 //
+ ///////////////////
+ //
+ // Adaptor tube [Pos 4]
+ //
+ // Adaptor tube length
+ const Float_t kCP3AdaptorTubeLength = 5.50;
+ //
+ // Inner and outer radii
+ const Float_t kCP3AdaptorTubeRi = 2.92-lolo;
+ const Float_t kCP3AdaptorTubeRo = 3.00-lolo;
+ //
+ // Bulge at transition point
+ // Inner and outer radii
+ const Float_t kCP3AdaptorTubeBulgeRi = 2.90-lolo;
+ const Float_t kCP3AdaptorTubeBulgeRo = 3.05-lolo;
+ //
+ // Length of bulge
+ const Float_t kCP3AdaptorTubeBulgeLength = 0.80;
+ //
+ // Bellow [Pos 8]
+ //
+ // Total length
+ const Float_t kCP3BellowLength = 13.00;
+ // Outer Radius
+ const Float_t kCP3BellowRo = 3.6-lolo; //-1?
+ // Inner Radius
+ const Float_t kCP3BellowRi = 2.8-lolo;
+ // Number of plies
+ const Int_t kCP3NumberOfPlies = 18;
+ // Length of undulated region
+ const Float_t kCP3BellowUndulatedLength = 8.30;
+ // Plie thickness
+ const Float_t kCP3PlieThickness = 0.02;
+ // Connection Plie radies (at transition been undulated region and beam pipe)
+ const Float_t kCP3ConnectionPlieR = 0.21;
+ // Plie radius
+ // const Float_t kCP3PlieR = 0.118286;
+ const Float_t kCP3PlieR =
+ (kCP3BellowUndulatedLength - 4. * kCP3ConnectionPlieR + 2. * kCP3PlieThickness +
+ (2. * kCP3NumberOfPlies - 2.) * kCP3PlieThickness) / (4. * kCP3NumberOfPlies - 2.);
+ // Length of connection pipe
+ const Float_t kCP3BellowConnectionLength = 2.35;
+ //
+ // Tube between bellows [Pos 3]
+ //
+ // Length of tube
+ const Float_t kCP3TubeLength = 4.00;
+ //
+ // Minimised fixed flange [Pos 7]
+ //
+ // Length of flange connection tube
+ const Float_t kCP3FlangeConnectorLength = 5.0 - 1.4;
+ // Length of Flange
+ const Float_t kCP3FlangeLength = 1.40;
+ // Outer radius
+ const Float_t kCP3FlangeRo = 4.30-lolo-1.;
+
+ //
+ // CP/3 Mother volume
+ //
+ TGeoPcon* shCp3Mo = new TGeoPcon(0., 360., 12);
+ // From transition to first bellow
+ z = - kCP3Length / 2.;
+ shCp3Mo->DefineSection( 0, z, 0., kCP3AdaptorTubeBulgeRo);
+ z += kCP3BellowConnectionLength + kCP3AdaptorTubeLength;
+ shCp3Mo->DefineSection( 1, z, 0., kCP3AdaptorTubeBulgeRo);
+ // First Bellow
+ shCp3Mo->DefineSection( 2, z, 0., kCP3BellowRo);
+ z += kCP3BellowUndulatedLength;
+ shCp3Mo->DefineSection( 3, z, 0., kCP3BellowRo);
+ // Connection between the two bellows
+ shCp3Mo->DefineSection( 4, z, 0., kCP3AdaptorTubeBulgeRo);
+ z += 2. * kCP3BellowConnectionLength + kCP3TubeLength;
+ shCp3Mo->DefineSection( 5, z, 0., kCP3AdaptorTubeBulgeRo);
+ // Second bellow
+ shCp3Mo->DefineSection( 6, z, 0., kCP3BellowRo);
+ z += kCP3BellowUndulatedLength;
+ shCp3Mo->DefineSection( 7, z, 0., kCP3BellowRo);
+ // Pipe between second Bellow and Flange
+ shCp3Mo->DefineSection( 8, z, 0., kCP3AdaptorTubeBulgeRo);
+ z += kCP3BellowConnectionLength + kCP3FlangeConnectorLength;
+ shCp3Mo->DefineSection( 9, z, 0., kCP3AdaptorTubeBulgeRo);
+ // Flange
+ shCp3Mo->DefineSection(10, z, 0., kCP3FlangeRo);
+ z = -shCp3Mo->GetZ(0);
+ shCp3Mo->DefineSection(11, z, 0., kCP3FlangeRo);
+ //
+ TGeoVolume* voCp3Mo = new TGeoVolume("CP3MO", shCp3Mo, kMedAir);
+ voCp3Mo->SetVisibility(0);
+ TGeoVolumeAssembly* voCp3 = new TGeoVolumeAssembly("Cp3");
+ voCp3->AddNode(voCp3Mo, 1, gGeoIdentity);
+ // voCp3->AddNode(voCpSupC, 3, new TGeoTranslation(0., 0., - kCP3Length / 2. + 4.6));
+ voCp3->AddNode(voCpSupClolo, 3, new TGeoTranslation(0., 0., - kCP3Length / 2. + 4.6));
+ dz = kCP3pos;
+
+ //////////////////////////////////////////////
+ // CP/3 Adaptor tube //
+ //////////////////////////////////////////////
+ TGeoPcon* shCp3AtV = new TGeoPcon(0., 360., 4);
+ // Bulge at transition
+ z = - kCP3AdaptorTubeLength / 2.;
+ shCp3AtV->DefineSection(0, z, 0., kCP3AdaptorTubeBulgeRo);
+ z += kCP3AdaptorTubeBulgeLength;
+ shCp3AtV->DefineSection(1, z, 0., kCP3AdaptorTubeBulgeRo);
+ // Tube
+ shCp3AtV->DefineSection(2, z, 0., kCP3AdaptorTubeRo);
+ z = + kCP3AdaptorTubeLength / 2.;
+ shCp3AtV->DefineSection(3, z, 0., kCP3AdaptorTubeRo);
+
+ TGeoVolume* voCp3AtV = new TGeoVolume("CP3ATV", shCp3AtV, kMedVac);
+
+ TGeoPcon* shCp3AtS = new TGeoPcon(0., 360., 4);
+ // Bulge at transition
+ shCp3AtS->DefineSection(0, shCp3AtV->GetZ(0), kCP3AdaptorTubeBulgeRi, kCP3AdaptorTubeBulgeRo);
+ shCp3AtS->DefineSection(1, shCp3AtV->GetZ(1), kCP3AdaptorTubeBulgeRi, kCP3AdaptorTubeBulgeRo);
+ // Tube
+ shCp3AtS->DefineSection(2, shCp3AtV->GetZ(2), kCP3AdaptorTubeRi, kCP3AdaptorTubeRo);
+ shCp3AtS->DefineSection(3, shCp3AtV->GetZ(3), kCP3AdaptorTubeRi , kCP3AdaptorTubeRo);
+ TGeoVolume* voCp3AtS = new TGeoVolume("CP3ATS", shCp3AtS, kMedSteel);
+
+ voCp3AtV->AddNode(voCp3AtS, 1, gGeoIdentity);
+ dz = - kCP3Length / 2. + kCP3AdaptorTubeLength / 2.;
+ voCp3Mo->AddNode(voCp3AtV, 1, new TGeoTranslation(0., 0., dz));
+
+ /////////////////////////////////
+ // CP/3 Bellow section //
+ /////////////////////////////////
+
+ //
+ // Upper part of the undulation
+ TGeoTorus* plieTorusUO = new TGeoTorus(kCP3BellowRo - kCP3PlieR, 0. , kCP3PlieR);
+ plieTorusUO->SetName("TorusUO");
+ TGeoTorus* plieTorusUI = new TGeoTorus(kCP3BellowRo - kCP3PlieR, kCP3PlieR - kCP3PlieThickness, kCP3PlieR);
+ plieTorusUI->SetName("TorusUI");
+ TGeoTube* plieTubeU = new TGeoTube (kCP3BellowRo - kCP3PlieR, kCP3BellowRo, kCP3PlieR);
+ plieTubeU->SetName("TubeU");
+
+ TGeoCompositeShape* shUpperPlieO = new TGeoCompositeShape("upperPlieO", "TorusUO*TubeU");
+ TGeoCompositeShape* shUpperPlieI = new TGeoCompositeShape("upperPlieI", "TorusUI*TubeU");
+
+ TGeoVolume* voWiggleUO = new TGeoVolume("CP3WUO", shUpperPlieO, kMedVac);
+ TGeoVolume* voWiggleUI = new TGeoVolume("CP3WUI", shUpperPlieI, kMedSteel);
+ voWiggleUO->AddNode(voWiggleUI, 1, gGeoIdentity);
+ //
+ // Lower part of the undulation
+ TGeoTorus* plieTorusLO = new TGeoTorus(kCP3BellowRi + kCP3PlieR, 0. , kCP3PlieR);
+ plieTorusLO->SetName("TorusLO");
+ TGeoTorus* plieTorusLI = new TGeoTorus(kCP3BellowRi + kCP3PlieR, kCP3PlieR - kCP3PlieThickness, kCP3PlieR);
+ plieTorusLI->SetName("TorusLI");
+ TGeoTube* plieTubeL = new TGeoTube (kCP3BellowRi, kCP3BellowRi + kCP3PlieR, kCP3PlieR);
+ plieTubeL->SetName("TubeL");
+
+ TGeoCompositeShape* shLowerPlieO = new TGeoCompositeShape("lowerPlieO", "TorusLO*TubeL");
+ TGeoCompositeShape* shLowerPlieI = new TGeoCompositeShape("lowerPlieI", "TorusLI*TubeL");
+
+ TGeoVolume* voWiggleLO = new TGeoVolume("CP3WLO", shLowerPlieO, kMedVac);
+ TGeoVolume* voWiggleLI = new TGeoVolume("CP3WLI", shLowerPlieI, kMedSteel);
+ voWiggleLO->AddNode(voWiggleLI, 1, gGeoIdentity);
+
+ //
+ // Connection between upper and lower part of undulation
+ TGeoVolume* voWiggleC1 = new TGeoVolume("Q3WCO1",
+ new TGeoTube(kCP3BellowRi + kCP3PlieR, kCP3BellowRo - kCP3PlieR, kCP3PlieThickness / 2.),
+ kMedSteel);
+ TGeoVolume* voWiggleC2 = new TGeoVolume("Q3WCO2",
+ new TGeoTube(kCP3BellowRi + kCP3ConnectionPlieR, kCP3BellowRo - kCP3PlieR, kCP3PlieThickness / 2.),
+ kMedSteel);
+ //
+ // Conncetion between undulated section and beam pipe
+ TGeoTorus* plieTorusCO = new TGeoTorus(kCP3BellowRi + kCP3ConnectionPlieR, 0. , kCP3ConnectionPlieR);
+ plieTorusCO->SetName("TorusCO");
+ TGeoTorus* plieTorusCI = new TGeoTorus(kCP3BellowRi + kCP3ConnectionPlieR, kCP3ConnectionPlieR - kCP3PlieThickness, kCP3ConnectionPlieR);
+ plieTorusCI->SetName("TorusCI");
+ TGeoTube* plieTubeC = new TGeoTube (kCP3BellowRi, kCP3BellowRi + kCP3ConnectionPlieR, kCP3ConnectionPlieR);
+ plieTubeC->SetName("TubeC");
+
+ TGeoCompositeShape* shConnectionPlieO = new TGeoCompositeShape("connectionPlieO", "TorusCO*TubeC");
+ TGeoCompositeShape* shConnectionPlieI = new TGeoCompositeShape("connectionPlieI", "TorusCI*TubeC");
+
+ TGeoVolume* voConnectionPO = new TGeoVolume("CP3CPO", shConnectionPlieO, kMedVac);
+ TGeoVolume* voConnectionPI = new TGeoVolume("CP3CPI", shConnectionPlieI, kMedSteel);
+ voConnectionPO->AddNode(voConnectionPI, 1, gGeoIdentity);
+ //
+ // Connecting pipes
+ TGeoVolume* voConnectionPipeO = new TGeoVolume("CP3BECO",
+ new TGeoTube(0., kCP3AdaptorTubeRo, kCP3BellowConnectionLength / 2.),
+ kMedVac);
+ TGeoVolume* voConnectionPipeI = new TGeoVolume("CP3BECI",
+ new TGeoTube(kCP3AdaptorTubeRi, kCP3AdaptorTubeRo, kCP3BellowConnectionLength / 2.),
+ kMedSteel);
+
+ voConnectionPipeO->AddNode(voConnectionPipeI, 1, gGeoIdentity);
+
+ //
+ // Bellow mother
+ TGeoPcon* shBellowMotherPC = new TGeoPcon(0., 360., 6);
+ dz = - kCP3BellowLength / 2;
+ shBellowMotherPC->DefineSection(0, dz, 0., kCP3AdaptorTubeRo);
+ dz += kCP3BellowConnectionLength;
+ shBellowMotherPC->DefineSection(1, dz, 0., kCP3AdaptorTubeRo);
+ shBellowMotherPC->DefineSection(2, dz, 0., kCP3BellowRo);
+ dz = kCP3BellowLength /2. - kCP3BellowConnectionLength;;
+ shBellowMotherPC->DefineSection(3, dz, 0., kCP3BellowRo);
+ shBellowMotherPC->DefineSection(4, dz, 0., kCP3AdaptorTubeRo);
+ dz += kCP3BellowConnectionLength;
+ shBellowMotherPC->DefineSection(5, dz, 0., kCP3AdaptorTubeRo);
+
+ TGeoVolume* voBellowMother = new TGeoVolume("CP3BeMO", shBellowMotherPC, kMedVac);
+ voBellowMother->SetVisibility(0);
+
+ //
+ // Add undulations
+ z0 = - kCP3BellowLength / 2. + kCP3BellowConnectionLength + 2. * kCP3ConnectionPlieR - kCP3PlieThickness;
+ zsh = 4. * kCP3PlieR - 2. * kCP3PlieThickness;
+ for (Int_t iw = 0; iw < 18; iw++) {
+ Float_t zpos = z0 + iw * zsh;
+ if (iw > 0)
+ voBellowMother->AddNode(voWiggleC1, iw + 1 , new TGeoTranslation(0., 0., zpos + kCP3PlieThickness / 2.));
+ else
+ voBellowMother->AddNode(voWiggleC2, iw + 1 , new TGeoTranslation(0., 0., zpos + kCP3PlieThickness / 2.));
+
+ zpos += kCP3PlieR;
+ voBellowMother->AddNode(voWiggleUO, iw + 1, new TGeoTranslation(0., 0., zpos));
+
+ zpos += kCP3PlieR;
+ if (iw < 17)
+ voBellowMother->AddNode(voWiggleC1, iw + 19, new TGeoTranslation(0., 0., zpos - kCP3PlieThickness / 2.));
+ else
+ voBellowMother->AddNode(voWiggleC2, iw + 19, new TGeoTranslation(0., 0., zpos - kCP3PlieThickness / 2.));
+
+ if (iw < 17) {
+ zpos += kCP3PlieR;
+ voBellowMother->AddNode(voWiggleLO, iw + 1, new TGeoTranslation(0., 0., zpos - kCP3PlieThickness));
+ }
+ }
+ //
+ // Add connecting undulation between bellow and connecting pipe
+ dz = - kCP3BellowUndulatedLength / 2. + kCP3ConnectionPlieR;
+ voBellowMother->AddNode(voConnectionPO, 1, new TGeoTranslation(0., 0., dz));
+ voBellowMother->AddNode(voConnectionPO, 2, new TGeoTranslation(0., 0., -dz));
+ //
+ // Add connecting pipe
+ dz = - kCP3BellowLength / 2. + kCP3BellowConnectionLength / 2.;
+ voBellowMother->AddNode(voConnectionPipeO, 1, new TGeoTranslation(0., 0., dz));
+ voBellowMother->AddNode(voConnectionPipeO, 2, new TGeoTranslation(0., 0., -dz));
+ //
+ // Add bellow to CP/3 mother
+ dz = - kCP3Length / 2. + kCP3AdaptorTubeLength + kCP3BellowLength / 2.;
+ voCp3Mo->AddNode(voBellowMother, 1, new TGeoTranslation(0., 0., dz));
+ dz += (kCP3BellowLength + kCP3TubeLength);
+ voCp3Mo->AddNode(voBellowMother, 2, new TGeoTranslation(0., 0., dz));
+
+
+ ///////////////////////////////////////////
+ // Beam pipe section between bellows //
+ ///////////////////////////////////////////
+
+ TGeoVolume* voCp3Bco = new TGeoVolume("CP3BCO",
+ new TGeoTube(0., kCP3AdaptorTubeRo, kCP3TubeLength / 2.),
+ kMedVac);
+
+ TGeoVolume* voCp3Bci = new TGeoVolume("CP3BCI",
+ new TGeoTube(kCP3AdaptorTubeRi, kCP3AdaptorTubeRo, kCP3TubeLength / 2.),
+ kMedSteel);
+
+ voCp3Bco->AddNode(voCp3Bci, 1, gGeoIdentity);
+ dz = - kCP3Length / 2. + kCP3AdaptorTubeLength + kCP3BellowLength + kCP3TubeLength / 2.;
+ voCp3Mo->AddNode(voCp3Bco, 1, new TGeoTranslation(0., 0., dz));
+
+
+ ///////////////////////////////////////////
+ // CP3 Minimised Flange //
+ ///////////////////////////////////////////
+
+ TGeoPcon* shCp3mfo = new TGeoPcon(0., 360., 4);
+ z = - (kCP3FlangeConnectorLength + kCP3FlangeLength) / 2.;
+ // Connection Tube
+ shCp3mfo->DefineSection(0, z, 0., kCP3AdaptorTubeRo);
+ z += kCP3FlangeConnectorLength;
+ shCp3mfo->DefineSection(1, z, 0., kCP3AdaptorTubeRo);
+ // Flange
+ shCp3mfo->DefineSection(2, z, 0., kCP3FlangeRo);
+ z = - shCp3mfo->GetZ(0);
+ shCp3mfo->DefineSection(3, z, 0., kCP3FlangeRo);
+
+ TGeoVolume* voCp3mfo = new TGeoVolume("CP3MFO", shCp3mfo, kMedVac);
+
+
+ TGeoPcon* shCp3mfi = new TGeoPcon(0., 360., 4);
+ // Connection Tube
+ shCp3mfi->DefineSection(0, shCp3mfo->GetZ(0), kCP3AdaptorTubeRi, kCP3AdaptorTubeRo);
+ shCp3mfi->DefineSection(1, shCp3mfo->GetZ(1), kCP3AdaptorTubeRi, kCP3AdaptorTubeRo);
+ // Flange
+ shCp3mfi->DefineSection(2, shCp3mfo->GetZ(2), kCP3AdaptorTubeRi, kCP3FlangeRo);
+ shCp3mfi->DefineSection(3, shCp3mfo->GetZ(3), kCP3AdaptorTubeRi, kCP3FlangeRo);
+
+ TGeoVolume* voCp3mfi = new TGeoVolume("CP3MFI", shCp3mfi, kMedSteel);
+
+ voCp3mfo->AddNode(voCp3mfi, 1, gGeoIdentity);
+ dz = kCP3Length / 2. - (kCP3FlangeConnectorLength + kCP3FlangeLength) / 2.;
+ voCp3Mo->AddNode(voCp3mfo, 1, new TGeoTranslation(0., 0., dz));
+
+
+ /*
+ //
+ // Assemble the central beam pipe
+ //
+ TGeoVolumeAssembly* asCP = new TGeoVolumeAssembly("CP");
+ z = 0.;
+ // asCP->AddNode(voCp2, 1, gGeoIdentity);
+ z += kCP2Length / 2. + kCP1Length / 2.;
+ //asCP->AddNode(voCp1, 1, new TGeoTranslation(0., 0., z));
+
+ asCP->AddNode(voCp1, 1, new TGeoTranslation(0., 0., 0.));
+
+ z += kCP1Length / 2. + kCP3Length / 2.;
+ // asCP->AddNode(voCp3, 1, new TGeoTranslation(0., 0., z));
+ top->AddNode(asCP, 1, new TGeoCombiTrans(0., 0., 400. - kCP2Length / 2, rot180));
+
+ */
+
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // //
+ // RB24/1 //
+ // //
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ //
+ // Drawing LHCVC2U_0001
+ // Copper Tube RB24/1 393.5 cm
+ // Warm module VMACA 18.0 cm
+ // Annular Ion Pump 35.0 cm
+ // Valve 7.5 cm
+ // Warm module VMABC 28.0 cm
+ // ================================
+ // 462.0 cm
+ //
+
+
+ // Copper Tube RB24/1
+ const Float_t kRB24CuTubeL = 393.5;
+ const Float_t kRB24CuTubeRi = 8.0/2.;
+ const Float_t kRB24CuTubeRo = 8.4/2.;
+ const Float_t kRB24CuTubeFRo = 7.6;
+ const Float_t kRB24CuTubeFL = 1.86;
+
+ TGeoVolume* voRB24CuTubeM = new TGeoVolume("voRB24CuTubeM",
+ new TGeoTube(0., kRB24CuTubeRo, kRB24CuTubeL/2.), kMedVac);
+ voRB24CuTubeM->SetVisibility(0);
+ TGeoVolume* voRB24CuTube = new TGeoVolume("voRB24CuTube",
+ new TGeoTube(kRB24CuTubeRi, kRB24CuTubeRo, kRB24CuTubeL/2.), kMedCu);
+ voRB24CuTubeM->AddNode(voRB24CuTube, 1, gGeoIdentity);
+ // Air outside tube with higher transport cuts
+ TGeoVolume* voRB24CuTubeA = new TGeoVolume("voRB24CuTubeA",
+ new TGeoTube(25., 100., kRB24CuTubeL/2.), kMedAirHigh);
+ voRB24CuTubeA->SetVisibility(0);
+ // Simplified DN 100 Flange
+ TGeoVolume* voRB24CuTubeF = new TGeoVolume("voRB24CuTubeF",
+ new TGeoTube(kRB24CuTubeRo, kRB24CuTubeFRo, kRB24CuTubeFL/2.), kMedSteel);
+
+ // Warm Module Type VMACA
+ // LHCVMACA_0002
+ //
+ // Pos 1 Warm Bellows DN100 LHCVBU__0012
+ // Pos 2 RF Contact D80 LHCVSR__0005
+ // Pos 3 Trans. Tube Flange LHCVSR__0065
+ // [Pos 4 Hex. Countersunk Screw Bossard BN4719]
+ // [Pos 5 Tension spring LHCVSR__0011]
+ //
+ //
+ //
+ // Pos1 Warm Bellows DN100
+ // Pos1.1 Bellows LHCVBU__0006
+ //
+ //
+ // Connection Tubes
+ // Connection tube inner r
+ const Float_t kRB24B1ConTubeRin = 10.0/2.;
+ // Connection tube outer r
+ const Float_t kRB24B1ConTubeRou = 10.3/2.;
+ // Connection tube length
+ const Float_t kRB24B1ConTubeL = 2.5;
+ //
+ const Float_t kRB24B1CompL = 16.00; // Length of the compensator
+ const Float_t kRB24B1BellowRi = 10.25/2.; // Bellow inner radius
+ const Float_t kRB24B1BellowRo = 11.40/2.; // Bellow outer radius
+ const Int_t kRB24B1NumberOfPlies = 27; // Number of plies
+ const Float_t kRB24B1BellowUndL = 11.00; // Length of undulated region
+ const Float_t kRB24B1PlieThickness = 0.015; // Plie thickness
+
+ const Float_t kRB24B1PlieRadius =
+ (kRB24B1BellowUndL + (2. * kRB24B1NumberOfPlies - 2.) * kRB24B1PlieThickness) / (4. * kRB24B1NumberOfPlies);
+
+ const Float_t kRB24B1ProtTubeThickness = 0.02; // Thickness of the protection tube
+ const Float_t kRB24B1ProtTubeLength = 4.2; // Length of the protection tube
+
+ const Float_t kRB24B1RFlangeL = 1.86; // Length of the flanges
+ const Float_t kRB24B1RFlangeLO = 0.26; // Flange overlap
+ const Float_t kRB24B1RFlangeRO = 11.18/2; // Inner radius at Flange overlap
+ const Float_t kRB24B1RFlangeRou = 15.20/2.; // Outer radius of flange
+ const Float_t kRB24B1RFlangeRecess = 0.98; // Flange recess
+ const Float_t kRB24B1L = kRB24B1CompL + 2. * (kRB24B1RFlangeL - kRB24B1RFlangeRecess);
+
+ ///
+ //
+ // Bellow mother volume
+ TGeoPcon* shRB24B1BellowM = new TGeoPcon(0., 360., 14);
+ // Connection Tube and Flange
+ z = 0.;
+ shRB24B1BellowM->DefineSection( 0, z, 0., kRB24B1RFlangeRou);
+ z += kRB24B1RFlangeLO;
+ shRB24B1BellowM->DefineSection( 1, z, 0., kRB24B1RFlangeRou);
+ shRB24B1BellowM->DefineSection( 2, z, 0., kRB24B1RFlangeRou);
+ z = kRB24B1RFlangeL;
+ shRB24B1BellowM->DefineSection( 3, z, 0., kRB24B1RFlangeRou);
+ shRB24B1BellowM->DefineSection( 4, z, 0., kRB24B1ConTubeRou);
+ z = kRB24B1ConTubeL + kRB24B1RFlangeL - kRB24B1RFlangeRecess;
+ shRB24B1BellowM->DefineSection( 5, z, 0., kRB24B1ConTubeRou);
+ // Plie
+ shRB24B1BellowM->DefineSection( 6, z, 0., kRB24B1BellowRo + kRB24B1ProtTubeThickness);
+ z += kRB24B1BellowUndL;
+ shRB24B1BellowM->DefineSection( 7, z, 0., kRB24B1BellowRo + kRB24B1ProtTubeThickness);
+ shRB24B1BellowM->DefineSection( 8, z, 0., kRB24B1ConTubeRou);
+ // Connection Tube and Flange
+ z = kRB24B1L - shRB24B1BellowM->GetZ(3);
+ shRB24B1BellowM->DefineSection( 9, z, 0., kRB24B1ConTubeRou);
+ shRB24B1BellowM->DefineSection(10, z, 0., kRB24B1RFlangeRou);
+ z = kRB24B1L - shRB24B1BellowM->GetZ(1);
+ shRB24B1BellowM->DefineSection(11, z, 0., kRB24B1RFlangeRou);
+ shRB24B1BellowM->DefineSection(12, z, 0., kRB24B1RFlangeRou);
+ z = kRB24B1L - shRB24B1BellowM->GetZ(0);
+ shRB24B1BellowM->DefineSection(13, z, 0., kRB24B1RFlangeRou);
+
+ TGeoVolume* voRB24B1BellowM = new TGeoVolume("RB24B1BellowM", shRB24B1BellowM, kMedVac);
+ voRB24B1BellowM->SetVisibility(0);
+ //
+ // Bellow Section
+ TGeoVolume* voRB24B1Bellow
+ = MakeBellow("RB24B1", kRB24B1NumberOfPlies, kRB24B1BellowRi, kRB24B1BellowRo,
+ kRB24B1BellowUndL, kRB24B1PlieRadius ,kRB24B1PlieThickness);
+ voRB24B1Bellow->SetVisibility(0);
+
+ //
+ // End Parts (connection tube)
+ TGeoVolume* voRB24B1CT = new TGeoVolume("RB24B1CT", new TGeoTube(kRB24B1ConTubeRin, kRB24B1ConTubeRou, kRB24B1ConTubeL/2.), kMedSteel);
+ //
+ // Protection Tube
+ TGeoVolume* voRB24B1PT = new TGeoVolume("RB24B1PT", new TGeoTube(kRB24B1BellowRo, kRB24B1BellowRo + kRB24B1ProtTubeThickness,
+ kRB24B1ProtTubeLength / 2.), kMedSteel);
+
+ z = kRB24B1ConTubeL/2. + (kRB24B1RFlangeL - kRB24B1RFlangeRecess);
+
+ voRB24B1BellowM->AddNode(voRB24B1CT, 1, new TGeoTranslation(0., 0., z));
+ z += (kRB24B1ConTubeL/2.+ kRB24B1BellowUndL/2.);
+ voRB24B1BellowM->AddNode(voRB24B1Bellow, 1, new TGeoTranslation(0., 0., z));
+ z += (kRB24B1BellowUndL/2. + kRB24B1ConTubeL/2);
+ voRB24B1BellowM->AddNode(voRB24B1CT, 2, new TGeoTranslation(0., 0., z));
+ z = kRB24B1ConTubeL + kRB24B1ProtTubeLength / 2. + 1. + kRB24B1RFlangeLO;
+ voRB24B1BellowM->AddNode(voRB24B1PT, 1, new TGeoTranslation(0., 0., z));
+ z += kRB24B1ProtTubeLength + 0.6;
+ voRB24B1BellowM->AddNode(voRB24B1PT, 2, new TGeoTranslation(0., 0., z));
+
+
+
+ // Pos 1/2 Rotatable Flange LHCVBU__0013
+ // Pos 1/3 Flange DN100/103 LHCVBU__0018
+ // The two flanges can be represented by the same volume
+ // Outer Radius (including the outer movable ring).
+ // The inner ring has a diameter of 12.04 cm
+
+
+ TGeoPcon* shRB24B1RFlange = new TGeoPcon(0., 360., 10);
+ z = 0.;
+ shRB24B1RFlange->DefineSection(0, z, 10.30/2., kRB24B1RFlangeRou);
+ z += 0.55; // 5.5 mm added for outer ring
+ z += 0.43;
+ shRB24B1RFlange->DefineSection(1, z, 10.30/2., kRB24B1RFlangeRou);
+ shRB24B1RFlange->DefineSection(2, z, 10.06/2., kRB24B1RFlangeRou);
+ z += 0.15;
+ shRB24B1RFlange->DefineSection(3, z, 10.06/2., kRB24B1RFlangeRou);
+ // In reality this part is rounded
+ shRB24B1RFlange->DefineSection(4, z, 10.91/2., kRB24B1RFlangeRou);
+ z += 0.15;
+ shRB24B1RFlange->DefineSection(5, z, 10.91/2., kRB24B1RFlangeRou);
+ shRB24B1RFlange->DefineSection(6, z, 10.06/2., kRB24B1RFlangeRou);
+ z += 0.32;
+ shRB24B1RFlange->DefineSection(7, z, 10.06/2., kRB24B1RFlangeRou);
+ shRB24B1RFlange->DefineSection(8, z, kRB24B1RFlangeRO, kRB24B1RFlangeRou);
+ z += kRB24B1RFlangeLO;
+ shRB24B1RFlange->DefineSection(9, z, kRB24B1RFlangeRO, kRB24B1RFlangeRou);
+
+ TGeoVolume* voRB24B1RFlange = new TGeoVolume("RB24B1RFlange", shRB24B1RFlange, kMedSteel);
+
+
+ z = kRB24B1L - kRB24B1RFlangeL;
+ voRB24B1BellowM->AddNode(voRB24B1RFlange, 1, new TGeoTranslation(0., 0., z));
+ z = kRB24B1RFlangeL;
+ voRB24B1BellowM->AddNode(voRB24B1RFlange, 2, new TGeoCombiTrans(0., 0., z, rot180));
+ //
+ // Pos 2 RF Contact D80 LHCVSR__0005
+ //
+ // Pos 2.1 RF Contact Flange LHCVSR__0003
+ //
+ TGeoPcon* shRB24B1RCTFlange = new TGeoPcon(0., 360., 6);
+ const Float_t kRB24B1RCTFlangeRin = 8.06/2. + 0.05; // Inner radius
+ const Float_t kRB24B1RCTFlangeL = 1.45; // Length
+
+ z = 0.;
+ shRB24B1RCTFlange->DefineSection(0, z, kRB24B1RCTFlangeRin, 8.20/2.);
+ z += 0.15;
+ shRB24B1RCTFlange->DefineSection(1, z, kRB24B1RCTFlangeRin, 8.20/2.);
+ shRB24B1RCTFlange->DefineSection(2, z, kRB24B1RCTFlangeRin, 8.60/2.);
+ z += 1.05;
+ shRB24B1RCTFlange->DefineSection(3, z, kRB24B1RCTFlangeRin, 8.60/2.);
+ shRB24B1RCTFlange->DefineSection(4, z, kRB24B1RCTFlangeRin, 11.16/2.);
+ z += 0.25;
+ shRB24B1RCTFlange->DefineSection(5, z, kRB24B1RCTFlangeRin, 11.16/2.);
+ TGeoVolume* voRB24B1RCTFlange = new TGeoVolume("RB24B1RCTFlange", shRB24B1RCTFlange, kMedCu);
+ z = kRB24B1L - kRB24B1RCTFlangeL;
+
+ voRB24B1BellowM->AddNode(voRB24B1RCTFlange, 1, new TGeoTranslation(0., 0., z));
+ //
+ // Pos 2.2 RF-Contact LHCVSR__0004
+ //
+ TGeoPcon* shRB24B1RCT = new TGeoPcon(0., 360., 3);
+ const Float_t kRB24B1RCTRin = 8.00/2.; // Inner radius
+ const Float_t kRB24B1RCTCRin = 8.99/2.; // Max. inner radius conical section
+ const Float_t kRB24B1RCTL = 11.78; // Length
+ const Float_t kRB24B1RCTSL = 10.48; // Length of straight section
+ const Float_t kRB24B1RCTd = 0.03; // Thickness
+
+ z = 0;
+ shRB24B1RCT->DefineSection(0, z, kRB24B1RCTCRin, kRB24B1RCTCRin + kRB24B1RCTd);
+ z = kRB24B1RCTL - kRB24B1RCTSL;
+ // In the (VSR0004) this section is straight in (LHCVC2U_0001) it is conical ????
+ shRB24B1RCT->DefineSection(1, z, kRB24B1RCTRin + 0.35, kRB24B1RCTRin + 0.35 + kRB24B1RCTd);
+ z = kRB24B1RCTL - 0.03;
+ shRB24B1RCT->DefineSection(2, z, kRB24B1RCTRin, kRB24B1RCTRin + kRB24B1RCTd);
+
+ TGeoVolume* voRB24B1RCT = new TGeoVolume("RB24B1RCT", shRB24B1RCT, kMedCu);
+ z = kRB24B1L - kRB24B1RCTL - 0.45;
+ voRB24B1BellowM->AddNode(voRB24B1RCT, 1, new TGeoTranslation(0., 0., z));
+
+ //
+ // Pos 3 Trans. Tube Flange LHCVSR__0065
+ //
+ // Pos 3.1 Transition Tube D53 LHCVSR__0064
+ // Pos 3.2 Transition Flange LHCVSR__0060
+ // Pos 3.3 Transition Tube LHCVSR__0058
+ TGeoPcon* shRB24B1TTF = new TGeoPcon(0., 360., 7);
+ // Flange
+ z = 0.;
+ shRB24B1TTF->DefineSection(0, z, 6.30/2., 11.16/2.);
+ z += 0.25;
+ shRB24B1TTF->DefineSection(1, z, 6.30/2., 11.16/2.);
+ shRB24B1TTF->DefineSection(2, z, 6.30/2., 9.3/2.);
+ z += 0.55;
+ shRB24B1TTF->DefineSection(3, z, 6.30/2., 9.3/2.);
+ // Tube
+ shRB24B1TTF->DefineSection(4, z, 6.30/2., 6.7/2.);
+ z += 5.80;
+ shRB24B1TTF->DefineSection(5, z, 6.30/2., 6.7/2.);
+ // Transition Tube
+ z += 3.75;
+ shRB24B1TTF->DefineSection(6, z, 8.05/2., 8.45/2.);
+ TGeoVolume* voRB24B1TTF = new TGeoVolume("RB24B1TTF", shRB24B1TTF, kMedSteel);
+ z = 0.;
+ voRB24B1BellowM->AddNode(voRB24B1TTF, 1, new TGeoTranslation(0., 0., z));
+
+ // Annular Ion Pump
+ // LHCVC2U_0003
+ //
+ // Pos 1 Rotable Flange LHCVFX__0031
+ // Pos 2 RF Screen Tube LHCVC2U_0005
+ // Pos 3 Shell LHCVC2U_0007
+ // Pos 4 Extruded Shell LHCVC2U_0006
+ // Pos 5 Feedthrough Tube LHCVC2U_0004
+ // Pos 6 Tubulated Flange STDVFUHV0021
+ // Pos 7 Fixed Flange LHCVFX__0032
+ // Pos 8 Pumping Elements
+
+ //
+ // Pos 1 Rotable Flange LHCVFX__0031
+ // pos 7 Fixed Flange LHCVFX__0032
+ //
+ // Mother volume
+ const Float_t kRB24AIpML = 35.;
+
+ TGeoVolume* voRB24AIpM = new TGeoVolume("voRB24AIpM", new TGeoTube(0., 10., kRB24AIpML/2.), kMedAir);
+ voRB24AIpM->SetVisibility(0);
+
+ //
+ // Length 35 cm
+ // Flange 2 x 1.98 = 3.96
+ // Tube = 32.84
+ //==========================
+ // 36.80
+ // Overlap 2 * 0.90 = 1.80
+
+ const Float_t kRB24IpRFD1 = 0.68; // Length of section 1
+ const Float_t kRB24IpRFD2 = 0.30; // Length of section 2
+ const Float_t kRB24IpRFD3 = 0.10; // Length of section 3
+ const Float_t kRB24IpRFD4 = 0.35; // Length of section 4
+ const Float_t kRB24IpRFD5 = 0.55; // Length of section 5
+
+ const Float_t kRB24IpRFRo = 15.20/2.; // Flange outer radius
+ const Float_t kRB24IpRFRi1 = 6.30/2.; // Flange inner radius section 1
+ const Float_t kRB24IpRFRi2 = 6.00/2.; // Flange inner radius section 2
+ const Float_t kRB24IpRFRi3 = 5.84/2.; // Flange inner radius section 3
+ const Float_t kRB24IpRFRi4 = 6.00/2.; // Flange inner radius section 1
+ const Float_t kRB24IpRFRi5 = 10.50/2.; // Flange inner radius section 2
+
+ TGeoPcon* shRB24IpRF = new TGeoPcon(0., 360., 9);
+ z0 = 0.;
+ shRB24IpRF->DefineSection(0, z0, kRB24IpRFRi1, kRB24IpRFRo);
+ z0 += kRB24IpRFD1;
+ shRB24IpRF->DefineSection(1, z0, kRB24IpRFRi2, kRB24IpRFRo);
+ z0 += kRB24IpRFD2;
+ shRB24IpRF->DefineSection(2, z0, kRB24IpRFRi2, kRB24IpRFRo);
+ shRB24IpRF->DefineSection(3, z0, kRB24IpRFRi3, kRB24IpRFRo);
+ z0 += kRB24IpRFD3;
+ shRB24IpRF->DefineSection(4, z0, kRB24IpRFRi3, kRB24IpRFRo);
+ shRB24IpRF->DefineSection(5, z0, kRB24IpRFRi4, kRB24IpRFRo);
+ z0 += kRB24IpRFD4;
+ shRB24IpRF->DefineSection(6, z0, kRB24IpRFRi4, kRB24IpRFRo);
+ shRB24IpRF->DefineSection(7, z0, kRB24IpRFRi5, kRB24IpRFRo);
+ z0 += kRB24IpRFD5;
+ shRB24IpRF->DefineSection(8, z0, kRB24IpRFRi5, kRB24IpRFRo);
+
+ TGeoVolume* voRB24IpRF = new TGeoVolume("RB24IpRF", shRB24IpRF, kMedSteel);
+
+ //
+ // Pos 2 RF Screen Tube LHCVC2U_0005
+ //
+
+ //
+ // Tube
+ Float_t kRB24IpSTTL = 32.84; // Total length of the tube
+ Float_t kRB24IpSTTRi = 5.80/2.; // Inner Radius
+ Float_t kRB24IpSTTRo = 6.00/2.; // Outer Radius
+ TGeoVolume* voRB24IpSTT = new TGeoVolume("RB24IpSTT", new TGeoTube(kRB24IpSTTRi, kRB24IpSTTRo, kRB24IpSTTL/2.), kMedSteel);
+ // Screen
+ Float_t kRB24IpSTCL = 0.4; // Lenth of the crochet detail
+ // Length of the screen
+ Float_t kRB24IpSTSL = 9.00 - 2. * kRB24IpSTCL;
+ // Rel. position of the screen
+ Float_t kRB24IpSTSZ = 7.00 + kRB24IpSTCL;
+ TGeoVolume* voRB24IpSTS = new TGeoVolume("RB24IpSTS", new TGeoTube(kRB24IpSTTRi, kRB24IpSTTRo, kRB24IpSTSL/2.), kMedSteel);
+ // Vacuum
+ TGeoVolume* voRB24IpSTV = new TGeoVolume("RB24IpSTV", new TGeoTube(0., kRB24IpSTTRi, kRB24AIpML/2.), kMedVac);
+ //
+ voRB24IpSTT->AddNode(voRB24IpSTS, 1, new TGeoTranslation(0., 0., kRB24IpSTSZ - kRB24IpSTTL/2. + kRB24IpSTSL/2.));
+
+ // Crochets
+ // Inner radius
+ Float_t kRB24IpSTCRi = kRB24IpSTTRo + 0.25;
+ // Outer radius
+ Float_t kRB24IpSTCRo = kRB24IpSTTRo + 0.35;
+ // Length of 1stsection
+ Float_t kRB24IpSTCL1 = 0.15;
+ // Length of 2nd section
+ Float_t kRB24IpSTCL2 = 0.15;
+ // Length of 3rd section
+ Float_t kRB24IpSTCL3 = 0.10;
+ // Rel. position of 1st Crochet
+
+
+ TGeoPcon* shRB24IpSTC = new TGeoPcon(0., 360., 5);
+ z0 = 0;
+ shRB24IpSTC->DefineSection(0, z0, kRB24IpSTCRi, kRB24IpSTCRo);
+ z0 += kRB24IpSTCL1;
+ shRB24IpSTC->DefineSection(1, z0, kRB24IpSTCRi, kRB24IpSTCRo);
+ shRB24IpSTC->DefineSection(2, z0, kRB24IpSTTRo, kRB24IpSTCRo);
+ z0 += kRB24IpSTCL2;
+ shRB24IpSTC->DefineSection(3, z0, kRB24IpSTTRo, kRB24IpSTCRo);
+ z0 += kRB24IpSTCL3;
+ shRB24IpSTC->DefineSection(4, z0, kRB24IpSTTRo, kRB24IpSTTRo + 0.001);
+ TGeoVolume* voRB24IpSTC = new TGeoVolume("RB24IpSTC", shRB24IpSTC, kMedSteel);
+
+ // Pos 3 Shell LHCVC2U_0007
+ // Pos 4 Extruded Shell LHCVC2U_0006
+ Float_t kRB24IpShellL = 4.45; // Length of the Shell
+ Float_t kRB24IpShellD = 0.10; // Wall thickness of the shell
+ Float_t kRB24IpShellCTRi = 6.70/2.; // Inner radius of the connection tube
+ Float_t kRB24IpShellCTL = 1.56; // Length of the connection tube
+ Float_t kRB24IpShellCARi = 17.80/2.; // Inner radius of the cavity
+ Float_t kRB24IpShellCCRo = 18.20/2.; // Inner radius at the centre
+
+ TGeoPcon* shRB24IpShell = new TGeoPcon(0., 360., 7);
+ z0 = 0;
+ shRB24IpShell->DefineSection(0, z0, kRB24IpShellCTRi, kRB24IpShellCTRi + kRB24IpShellD);
+ z0 += kRB24IpShellCTL;
+ shRB24IpShell->DefineSection(1, z0, kRB24IpShellCTRi, kRB24IpShellCTRi + kRB24IpShellD);
+ shRB24IpShell->DefineSection(2, z0, kRB24IpShellCTRi, kRB24IpShellCARi + kRB24IpShellD);
+ z0 += kRB24IpShellD;
+ shRB24IpShell->DefineSection(3, z0, kRB24IpShellCARi, kRB24IpShellCARi + kRB24IpShellD);
+ z0 = kRB24IpShellL - kRB24IpShellD;
+ shRB24IpShell->DefineSection(4, z0, kRB24IpShellCARi, kRB24IpShellCARi + kRB24IpShellD);
+ shRB24IpShell->DefineSection(5, z0, kRB24IpShellCARi, kRB24IpShellCCRo);
+ z0 = kRB24IpShellL;
+ shRB24IpShell->DefineSection(6, z0, kRB24IpShellCARi, kRB24IpShellCCRo);
+ TGeoVolume* voRB24IpShell = new TGeoVolume("RB24IpShell", shRB24IpShell, kMedSteel);
+
+ TGeoPcon* shRB24IpShellM = MakeMotherFromTemplate(shRB24IpShell, 0, 6, kRB24IpShellCTRi , 13);
+
+
+ for (Int_t i = 0; i < 6; i++) {
+ z = 2. * kRB24IpShellL - shRB24IpShellM->GetZ(5-i);
+ Float_t rmin = shRB24IpShellM->GetRmin(5-i);
+ Float_t rmax = shRB24IpShellM->GetRmax(5-i);
+ shRB24IpShellM->DefineSection(7+i, z, rmin, rmax);
+ }
+
+ TGeoVolume* voRB24IpShellM = new TGeoVolume("RB24IpShellM", shRB24IpShellM, kMedVac);
+ voRB24IpShellM->SetVisibility(0);
+ voRB24IpShellM->AddNode(voRB24IpShell, 1, gGeoIdentity);
+ voRB24IpShellM->AddNode(voRB24IpShell, 2, new TGeoCombiTrans(0., 0., 2. * kRB24IpShellL, rot180));
+ //
+ // Pos 8 Pumping Elements
+ //
+ // Anode array
+ TGeoVolume* voRB24IpPE = new TGeoVolume("voRB24IpPE", new TGeoTube(0.9, 1., 2.54/2.), kMedSteel);
+ Float_t kRB24IpPEAR = 5.5;
+
+ for (Int_t i = 0; i < 15; i++) {
+ Float_t phi = Float_t(i) * 24.;
+ Float_t x = kRB24IpPEAR * TMath::Cos(kDegRad * phi);
+ Float_t y = kRB24IpPEAR * TMath::Sin(kDegRad * phi);
+ voRB24IpShellM->AddNode(voRB24IpPE, i+1, new TGeoTranslation(x, y, kRB24IpShellL));
+ }
+
+
+ //
+ // Cathodes
+ //
+ // Here we could add some Ti strips
+
+ // Postioning of elements
+ voRB24AIpM->AddNode(voRB24IpRF, 1, new TGeoTranslation(0., 0., -kRB24AIpML/2.));
+ voRB24AIpM->AddNode(voRB24IpRF, 2, new TGeoCombiTrans (0., 0., +kRB24AIpML/2., rot180));
+ voRB24AIpM->AddNode(voRB24IpSTT, 1, new TGeoTranslation(0., 0., 0.));
+ voRB24AIpM->AddNode(voRB24IpSTV, 1, new TGeoTranslation(0., 0., 0.));
+ voRB24AIpM->AddNode(voRB24IpShellM, 1, new TGeoTranslation(0., 0., -kRB24AIpML/2. + 8.13));
+ voRB24AIpM->AddNode(voRB24IpSTC, 1, new TGeoTranslation(0., 0., 8.13 - kRB24AIpML/2.));
+ voRB24AIpM->AddNode(voRB24IpSTC, 2, new TGeoCombiTrans (0., 0., 8.14 + 8.9 - kRB24AIpML/2., rot180));
+
+ //
+ // Valve
+ // VAC Series 47 DN 63 with manual actuator
+ //
+ const Float_t kRB24ValveWz = 7.5;
+ const Float_t kRB24ValveDN = 10.0/2.;
+ //
+ // Body containing the valve plate
+ //
+ const Float_t kRB24ValveBoWx = 15.6;
+ const Float_t kRB24ValveBoWy = (21.5 + 23.1 - 5.);
+ const Float_t kRB24ValveBoWz = 4.6;
+ const Float_t kRB24ValveBoD = 0.5;
+
+ TGeoVolume* voRB24ValveBoM =
+ new TGeoVolume("RB24ValveBoM",
+ new TGeoBBox( kRB24ValveBoWx/2., kRB24ValveBoWy/2., kRB24ValveBoWz/2.), kMedAir);
+ voRB24ValveBoM->SetVisibility(0);
+ TGeoVolume* voRB24ValveBo =
+ new TGeoVolume("RB24ValveBo",
+ new TGeoBBox( kRB24ValveBoWx/2., kRB24ValveBoWy/2., kRB24ValveBoWz/2.), kMedSteel);
+ voRB24ValveBoM->AddNode(voRB24ValveBo, 1, gGeoIdentity);
+ //
+ // Inner volume
+ //
+ TGeoVolume* voRB24ValveBoI = new TGeoVolume("RB24ValveBoI",
+ new TGeoBBox( kRB24ValveBoWx/2. - kRB24ValveBoD,
+ kRB24ValveBoWy/2. - kRB24ValveBoD/2.,
+ kRB24ValveBoWz/2. - kRB24ValveBoD),
+ kMedVac);
+ voRB24ValveBo->AddNode(voRB24ValveBoI, 1, new TGeoTranslation(0., kRB24ValveBoD/2., 0.));
+ //
+ // Opening and Flanges
+ const Float_t kRB24ValveFlRo = 18./2.;
+ const Float_t kRB24ValveFlD = 1.45;
+ TGeoVolume* voRB24ValveBoA = new TGeoVolume("RB24ValveBoA",
+ new TGeoTube(0., kRB24ValveDN/2., kRB24ValveBoD/2.), kMedVac);
+ voRB24ValveBo->AddNode(voRB24ValveBoA, 1, new TGeoTranslation(0., - kRB24ValveBoWy/2. + 21.5, -kRB24ValveBoWz/2. + kRB24ValveBoD/2.));
+ voRB24ValveBo->AddNode(voRB24ValveBoA, 2, new TGeoTranslation(0., - kRB24ValveBoWy/2. + 21.5, +kRB24ValveBoWz/2. - kRB24ValveBoD/2.));
+
+ TGeoVolume* voRB24ValveFl = new TGeoVolume("RB24ValveFl", new TGeoTube(kRB24ValveDN/2., kRB24ValveFlRo, kRB24ValveFlD/2.), kMedSteel);
+ TGeoVolume* voRB24ValveFlI = new TGeoVolume("RB24ValveFlI", new TGeoTube(0., kRB24ValveFlRo, kRB24ValveFlD/2.), kMedVac);
+ voRB24ValveFlI->AddNode(voRB24ValveFl, 1, gGeoIdentity);
+
+ //
+ // Actuator Flange
+ const Float_t kRB24ValveAFlWx = 18.9;
+ const Float_t kRB24ValveAFlWy = 5.0;
+ const Float_t kRB24ValveAFlWz = 7.7;
+ TGeoVolume* voRB24ValveAFl = new TGeoVolume("RB24ValveAFl", new TGeoBBox(kRB24ValveAFlWx/2., kRB24ValveAFlWy/2., kRB24ValveAFlWz/2.), kMedSteel);
+ //
+ // Actuator Tube
+ const Float_t kRB24ValveATRo = 9.7/2.;
+ const Float_t kRB24ValveATH = 16.6;
+ TGeoVolume* voRB24ValveAT = new TGeoVolume("RB24ValveAT", new TGeoTube(kRB24ValveATRo - 2. * kRB24ValveBoD,kRB24ValveATRo, kRB24ValveATH/2.),
+ kMedSteel);
+ //
+ // Manual Actuator (my best guess)
+ TGeoVolume* voRB24ValveMA1 = new TGeoVolume("RB24ValveMA1", new TGeoCone(2.5/2., 0., 0.5, 4.5, 5.), kMedSteel);
+ TGeoVolume* voRB24ValveMA2 = new TGeoVolume("RB24ValveMA2", new TGeoTorus(5., 0., 1.25), kMedSteel);
+ TGeoVolume* voRB24ValveMA3 = new TGeoVolume("RB24ValveMA3", new TGeoTube (0., 1.25, 2.5), kMedSteel);
+
+
+ //
+ // Position all volumes
+ Float_t y0;
+ TGeoVolumeAssembly* voRB24ValveMo = new TGeoVolumeAssembly("RB24ValveMo");
+ voRB24ValveMo->AddNode(voRB24ValveFl, 1, new TGeoTranslation(0., 0., - 7.5/2. + kRB24ValveFlD/2.));
+ voRB24ValveMo->AddNode(voRB24ValveFl, 2, new TGeoTranslation(0., 0., + 7.5/2. - kRB24ValveFlD/2.));
+ y0 = -21.5;
+ voRB24ValveMo->AddNode(voRB24ValveBoM, 1, new TGeoTranslation(0., y0 + kRB24ValveBoWy/2., 0.));
+ y0 += kRB24ValveBoWy;
+ voRB24ValveMo->AddNode(voRB24ValveAFl, 1, new TGeoTranslation(0., y0 + kRB24ValveAFlWy/2., 0.));
+ y0 += kRB24ValveAFlWy;
+ voRB24ValveMo->AddNode(voRB24ValveAT, 1, new TGeoCombiTrans(0., y0 + kRB24ValveATH/2., 0., rotyz));
+ y0 += kRB24ValveATH;
+ voRB24ValveMo->AddNode(voRB24ValveMA1, 1, new TGeoCombiTrans(0., y0 + 2.5/2., 0., rotyz));
+ y0 += 2.5;
+ voRB24ValveMo->AddNode(voRB24ValveMA2, 1, new TGeoCombiTrans(0., y0 + 2.5/2., 0., rotyz));
+ y0 += 2.5;
+ voRB24ValveMo->AddNode(voRB24ValveMA3, 1, new TGeoCombiTrans(5./TMath::Sqrt(2.), y0 + 5.0/2., 5./TMath::Sqrt(2.), rotyz));
+ //
+ // Warm Module Type VMABC
+ // LHCVMABC_0002
+ //
+ //
+ //
+ // Flange 1.00
+ // Central Piece 11.50
+ // Bellow 14.50
+ // End Flange 1.00
+ //===================================
+ // Total 28.00
+ //
+ // Pos 1 Warm Bellows DN100 LHCVBU__0016
+ // Pos 2 Trans. Tube Flange LHCVSR__0062
+ // Pos 3 RF Contact D63 LHCVSR__0057
+ // [Pos 4 Hex. Countersunk Screw Bossard BN4719]
+ // [Pos 5 Tension spring LHCVSR__00239]
+ //
+
+ // Pos 1 Warm Bellows DN100 LHCVBU__0016
+ // Pos 1.1 Right Body 2 Ports with Support LHCVBU__0014
+ //
+ // Tube 1
+ const Float_t kRB24VMABCRBT1Ri = 10.0/2.;
+ const Float_t kRB24VMABCRBT1Ro = 10.3/2.;
+ const Float_t kRB24VMABCRBT1L = 11.5;
+ const Float_t kRB24VMABCRBT1L2 = 8.;
+ const Float_t kRB24VMABCL = 28.;
+
+ TGeoTube* shRB24VMABCRBT1 = new TGeoTube(kRB24VMABCRBT1Ri, kRB24VMABCRBT1Ro, kRB24VMABCRBT1L/2.);
+ shRB24VMABCRBT1->SetName("RB24VMABCRBT1");
+ TGeoTube* shRB24VMABCRBT1o = new TGeoTube(0., kRB24VMABCRBT1Ro, kRB24VMABCRBT1L/2.);
+ shRB24VMABCRBT1o->SetName("RB24VMABCRBT1o");
+ TGeoTube* shRB24VMABCRBT1o2 = new TGeoTube(0., kRB24VMABCRBT1Ro + 0.3, kRB24VMABCRBT1L/2.);
+ shRB24VMABCRBT1o2->SetName("RB24VMABCRBT1o2");
+ // Lower inforcement
+ TGeoVolume* voRB24VMABCRBT12 = new TGeoVolume("RB24VMABCRBT12",
+ new TGeoTubeSeg(kRB24VMABCRBT1Ro, kRB24VMABCRBT1Ro + 0.3, kRB24VMABCRBT1L2/2., 220., 320.)
+ , kMedSteel);
+ //
+ // Tube 2
+ const Float_t kRB24VMABCRBT2Ri = 6.0/2.;
+ const Float_t kRB24VMABCRBT2Ro = 6.3/2.;
+ const Float_t kRB24VMABCRBF2Ro = 11.4/2.;
+ const Float_t kRB24VMABCRBT2L = 5.95 + 2.; // 2. cm added for welding
+ const Float_t kRB24VMABCRBF2L = 1.75;
+ TGeoTube* shRB24VMABCRBT2 = new TGeoTube(kRB24VMABCRBT2Ri, kRB24VMABCRBT2Ro, kRB24VMABCRBT2L/2.);
+ shRB24VMABCRBT2->SetName("RB24VMABCRBT2");
+ TGeoTube* shRB24VMABCRBT2i = new TGeoTube(0., kRB24VMABCRBT2Ri, kRB24VMABCRBT2L/2. + 2.);
+ shRB24VMABCRBT2i->SetName("RB24VMABCRBT2i");
+ TGeoCombiTrans* tRBT2 = new TGeoCombiTrans(-11.5 + kRB24VMABCRBT2L/2., 0., 7.2 - kRB24VMABCRBT1L/2. , rotxz);
+ tRBT2->SetName("tRBT2");
+ tRBT2->RegisterYourself();
+ TGeoCompositeShape* shRB24VMABCRBT2c = new TGeoCompositeShape("shRB24VMABCRBT2c","RB24VMABCRBT2:tRBT2-RB24VMABCRBT1o");
+ TGeoVolume* voRB24VMABCRBT2 = new TGeoVolume("shRB24VMABCRBT2", shRB24VMABCRBT2c, kMedSteel);
+ // Flange
+ // Pos 1.4 Flange DN63 LHCVBU__0008
+ TGeoVolume* voRB24VMABCRBF2 = new TGeoVolume("RB24VMABCRBF2",
+ new TGeoTube(kRB24VMABCRBT2Ro, kRB24VMABCRBF2Ro, kRB24VMABCRBF2L/2.), kMedSteel);
+ // DN63 Blank Flange (my best guess)
+ TGeoVolume* voRB24VMABCRBF2B = new TGeoVolume("RB24VMABCRBF2B",
+ new TGeoTube(0., kRB24VMABCRBF2Ro, kRB24VMABCRBF2L/2.), kMedSteel);
+ //
+ // Tube 3
+ const Float_t kRB24VMABCRBT3Ri = 3.5/2.;
+ const Float_t kRB24VMABCRBT3Ro = 3.8/2.;
+ const Float_t kRB24VMABCRBF3Ro = 7.0/2.;
+ const Float_t kRB24VMABCRBT3L = 4.95 + 2.; // 2. cm added for welding
+ const Float_t kRB24VMABCRBF3L = 1.27;
+ TGeoTube* shRB24VMABCRBT3 = new TGeoTube(kRB24VMABCRBT3Ri, kRB24VMABCRBT3Ro, kRB24VMABCRBT3L/2);
+ shRB24VMABCRBT3->SetName("RB24VMABCRBT3");
+ TGeoTube* shRB24VMABCRBT3i = new TGeoTube(0., kRB24VMABCRBT3Ri, kRB24VMABCRBT3L/2. + 2.);
+ shRB24VMABCRBT3i->SetName("RB24VMABCRBT3i");
+ TGeoCombiTrans* tRBT3 = new TGeoCombiTrans(0., 10.5 - kRB24VMABCRBT3L/2., 7.2 - kRB24VMABCRBT1L/2. , rotyz);
+ tRBT3->SetName("tRBT3");
+ tRBT3->RegisterYourself();
+ TGeoCompositeShape* shRB24VMABCRBT3c = new TGeoCompositeShape("shRB24VMABCRBT3c","RB24VMABCRBT3:tRBT3-RB24VMABCRBT1o");
+ TGeoVolume* voRB24VMABCRBT3 = new TGeoVolume("shRB24VMABCRBT3", shRB24VMABCRBT3c, kMedSteel);
+ // Flange
+ // Pos 1.4 Flange DN35 LHCVBU__0007
+ TGeoVolume* voRB24VMABCRBF3 = new TGeoVolume("RB24VMABCRBF3",
+ new TGeoTube(kRB24VMABCRBT3Ro, kRB24VMABCRBF3Ro, kRB24VMABCRBF3L/2.), kMedSteel);
+ //
+ // Tube 4
+ const Float_t kRB24VMABCRBT4Ri = 6.0/2.;
+ const Float_t kRB24VMABCRBT4Ro = 6.4/2.;
+ const Float_t kRB24VMABCRBT4L = 6.6;
+ TGeoTube* shRB24VMABCRBT4 = new TGeoTube(kRB24VMABCRBT4Ri, kRB24VMABCRBT4Ro, kRB24VMABCRBT4L/2.);
+ shRB24VMABCRBT4->SetName("RB24VMABCRBT4");
+ TGeoCombiTrans* tRBT4 = new TGeoCombiTrans(0.,-11.+kRB24VMABCRBT4L/2., 7.2 - kRB24VMABCRBT1L/2. , rotyz);
+ tRBT4->SetName("tRBT4");
+ tRBT4->RegisterYourself();
+ TGeoCompositeShape* shRB24VMABCRBT4c = new TGeoCompositeShape("shRB24VMABCRBT4c","RB24VMABCRBT4:tRBT4-RB24VMABCRBT1o2");
+ TGeoVolume* voRB24VMABCRBT4 = new TGeoVolume("shRB24VMABCRBT4", shRB24VMABCRBT4c, kMedSteel);
+ TGeoCompositeShape* shRB24VMABCRB = new TGeoCompositeShape("shRB24VMABCRB", "RB24VMABCRBT1-(RB24VMABCRBT2i:tRBT2+RB24VMABCRBT3i:tRBT3)");
+ TGeoVolume* voRB24VMABCRBI = new TGeoVolume("RB24VMABCRBI", shRB24VMABCRB, kMedSteel);
+ //
+ // Plate
+ const Float_t kRB24VMABCRBBx = 16.0;
+ const Float_t kRB24VMABCRBBy = 1.5;
+ const Float_t kRB24VMABCRBBz = 15.0;
+
+ // Relative position of tubes
+ const Float_t kRB24VMABCTz = 7.2;
+ // Relative position of plate
+ const Float_t kRB24VMABCPz = 3.6;
+ const Float_t kRB24VMABCPy = -12.5;
+
+ TGeoVolume* voRB24VMABCRBP = new TGeoVolume("RB24VMABCRBP", new TGeoBBox(kRB24VMABCRBBx/2., kRB24VMABCRBBy/2., kRB24VMABCRBBz/2.), kMedSteel);
+ //
+ // Pirani Gauge (my best guess)
+ //
+ TGeoPcon* shRB24VMABCPirani = new TGeoPcon(0., 360., 15);
+ // DN35/16 Coupling
+ z = 0;
+ shRB24VMABCPirani->DefineSection( 0, z, 0.8 , kRB24VMABCRBF3Ro);
+ z += kRB24VMABCRBF3L; // 1.3
+ shRB24VMABCPirani->DefineSection( 1, z, 0.8 , kRB24VMABCRBF3Ro);
+ shRB24VMABCPirani->DefineSection( 2, z, 0.8 , 1.0);
+ // Pipe
+ z += 2.8;
+ shRB24VMABCPirani->DefineSection( 3, z, 0.8 , 1.0);
+ // Flange
+ shRB24VMABCPirani->DefineSection( 4, z, 0.8 , 1.75);
+ z += 1.6;
+ shRB24VMABCPirani->DefineSection( 5, z, 0.8 , 1.75);
+ shRB24VMABCPirani->DefineSection( 6, z, 0.8 , 1.0);
+ z += 5.2;
+ shRB24VMABCPirani->DefineSection( 7, z, 0.8 , 1.0);
+ shRB24VMABCPirani->DefineSection( 8, z, 0.8 , 2.5);
+ z += 2.0;
+ shRB24VMABCPirani->DefineSection( 9, z, 0.80, 2.50);
+ shRB24VMABCPirani->DefineSection(10, z, 1.55, 1.75);
+ z += 5.7;
+ shRB24VMABCPirani->DefineSection(11, z, 1.55, 1.75);
+ shRB24VMABCPirani->DefineSection(11, z, 0.00, 1.75);
+ z += 0.2;
+ shRB24VMABCPirani->DefineSection(12, z, 0.00, 1.75);
+ shRB24VMABCPirani->DefineSection(13, z, 0.00, 0.75);
+ z += 0.5;
+ shRB24VMABCPirani->DefineSection(14, z, 0.00, 0.75);
+ TGeoVolume* voRB24VMABCPirani = new TGeoVolume("RB24VMABCPirani", shRB24VMABCPirani, kMedSteel);
+ //
+ //
+ //
+
+
+ //
+ // Positioning of elements
+ TGeoVolumeAssembly* voRB24VMABCRB = new TGeoVolumeAssembly("RB24VMABCRB");
+ //
+ voRB24VMABCRB->AddNode(voRB24VMABCRBI, 1, gGeoIdentity);
+ // Plate
+ voRB24VMABCRB->AddNode(voRB24VMABCRBP, 1, new TGeoTranslation(0., kRB24VMABCPy + kRB24VMABCRBBy /2.,
+ kRB24VMABCRBBz/2. - kRB24VMABCRBT1L/2. + kRB24VMABCPz));
+ // Tube 2
+ voRB24VMABCRB->AddNode(voRB24VMABCRBT2, 1, gGeoIdentity);
+ // Flange Tube 2
+ voRB24VMABCRB->AddNode(voRB24VMABCRBF2, 1, new TGeoCombiTrans(kRB24VMABCPy + kRB24VMABCRBF2L/2., 0., kRB24VMABCTz - kRB24VMABCRBT1L/2., rotxz));
+ // Blank Flange Tube 2
+ voRB24VMABCRB->AddNode(voRB24VMABCRBF2B, 1, new TGeoCombiTrans(kRB24VMABCPy- kRB24VMABCRBF2L/2., 0., kRB24VMABCTz - kRB24VMABCRBT1L/2., rotxz));
+ // Tube 3
+ voRB24VMABCRB->AddNode(voRB24VMABCRBT3, 1, gGeoIdentity);
+ // Flange Tube 3
+ voRB24VMABCRB->AddNode(voRB24VMABCRBF3, 1, new TGeoCombiTrans(0., 11.2 - kRB24VMABCRBF3L/2., kRB24VMABCTz - kRB24VMABCRBT1L/2., rotyz));
+ // Pirani Gauge
+ voRB24VMABCRB->AddNode(voRB24VMABCPirani, 1, new TGeoCombiTrans(0., 11.2, kRB24VMABCTz - kRB24VMABCRBT1L/2., rotyz));
+ // Tube 4
+ voRB24VMABCRB->AddNode(voRB24VMABCRBT4, 1, gGeoIdentity);
+ // Inforcement
+ voRB24VMABCRB->AddNode(voRB24VMABCRBT12, 1, new TGeoTranslation(0., 0., kRB24VMABCRBT1L2/2. - kRB24VMABCRBT1L/2. + 2.8));
+
+
+ // Pos 1.3 Bellows with end part LHCVBU__0002
+ //
+ // Connection Tube
+ // Connection tube inner r
+ const Float_t kRB24VMABBEConTubeRin = 10.0/2.;
+ // Connection tube outer r
+ const Float_t kRB24VMABBEConTubeRou = 10.3/2.;
+ // Connection tube length
+ const Float_t kRB24VMABBEConTubeL1 = 0.9;
+ const Float_t kRB24VMABBEConTubeL2 = 2.6;
+ // const Float_t RB24VMABBEBellowL = kRB24VMABBEConTubeL1 + kRB24VMABBEConTubeL2 + kRB24B1BellowUndL;
+
+ // Mother volume
+ TGeoPcon* shRB24VMABBEBellowM = new TGeoPcon(0., 360., 6);
+ // Connection Tube and Flange
+ z = 0.;
+ shRB24VMABBEBellowM->DefineSection( 0, z, kRB24VMABBEConTubeRin, kRB24VMABBEConTubeRou);
+ z += kRB24VMABBEConTubeL1;
+ shRB24VMABBEBellowM->DefineSection( 1, z, kRB24VMABBEConTubeRin, kRB24VMABBEConTubeRou);
+ shRB24VMABBEBellowM->DefineSection( 2, z, kRB24B1BellowRi, kRB24B1BellowRo + kRB24B1ProtTubeThickness);
+ z += kRB24B1BellowUndL;
+ shRB24VMABBEBellowM->DefineSection( 3, z, kRB24B1BellowRi, kRB24B1BellowRo + kRB24B1ProtTubeThickness);
+ shRB24VMABBEBellowM->DefineSection( 4, z, kRB24VMABBEConTubeRin, kRB24VMABBEConTubeRou);
+ z += kRB24VMABBEConTubeL2;
+ shRB24VMABBEBellowM->DefineSection( 5, z, kRB24VMABBEConTubeRin, kRB24VMABBEConTubeRou);
+ TGeoVolume* voRB24VMABBEBellowM = new TGeoVolume("RB24VMABBEBellowM", shRB24VMABBEBellowM, kMedVac);
+ voRB24VMABBEBellowM->SetVisibility(0);
+
+ // Connection tube left
+ TGeoVolume* voRB24VMABBECT1 = new TGeoVolume("RB24VMABBECT1",
+ new TGeoTube(kRB24VMABBEConTubeRin, kRB24VMABBEConTubeRou,kRB24VMABBEConTubeL1/2.),
+ kMedSteel);
+ // Connection tube right
+ TGeoVolume* voRB24VMABBECT2 = new TGeoVolume("RB24VMABBECT2",
+ new TGeoTube(kRB24VMABBEConTubeRin, kRB24VMABBEConTubeRou,kRB24VMABBEConTubeL2/2.),
+ kMedSteel);
+ z = kRB24VMABBEConTubeL1/2.;
+ voRB24VMABBEBellowM->AddNode(voRB24VMABBECT1, 1, new TGeoTranslation(0., 0., z));
+ z += kRB24VMABBEConTubeL1/2.;
+ z += kRB24B1BellowUndL/2.;
+ voRB24VMABBEBellowM->AddNode(voRB24B1Bellow, 2, new TGeoTranslation(0., 0., z));
+ z += kRB24B1BellowUndL/2.;
+ z += kRB24VMABBEConTubeL2/2.;
+ voRB24VMABBEBellowM->AddNode(voRB24VMABBECT2, 1, new TGeoTranslation(0., 0., z));
+ z += kRB24VMABBEConTubeL2/2.;
+
+ voRB24VMABCRB->AddNode(voRB24VMABBEBellowM, 1, new TGeoTranslation(0., 0., kRB24VMABCRBT1L/2.));
+
+ // Pos 1.2 Rotable flange LHCVBU__0013[*]
+ // Front
+ voRB24VMABCRB->AddNode(voRB24B1RFlange, 3, new TGeoCombiTrans(0., 0., - kRB24VMABCRBT1L/2. + 0.86, rot180));
+ // End
+ z = kRB24VMABCRBT1L/2. + kRB24B1BellowUndL +kRB24VMABBEConTubeL1 + kRB24VMABBEConTubeL2;
+ voRB24VMABCRB->AddNode(voRB24B1RFlange, 4, new TGeoTranslation(0., 0., z - 0.86));
+
+
+ // Pos 2 Trans. Tube Flange LHCVSR__0062
+ // Pos 2.1 Transition Tube LHCVSR__0063
+ // Pos 2.2 Transition Flange LHCVSR__0060
+ //
+ // Transition Tube with Flange
+ TGeoPcon* shRB24VMABCTT = new TGeoPcon(0., 360., 7);
+ z = 0.;
+ shRB24VMABCTT->DefineSection(0, z, 6.3/2., 11.16/2.);
+ z += 0.25;
+ shRB24VMABCTT->DefineSection(1, z, 6.3/2., 11.16/2.);
+ shRB24VMABCTT->DefineSection(2, z, 6.3/2., 9.30/2.);
+ z += 0.25;
+ shRB24VMABCTT->DefineSection(3, z, 6.3/2., 9.30/2.);
+ shRB24VMABCTT->DefineSection(4, z, 6.3/2., 6.70/2.);
+ z += (20.35 - 0.63);
+ shRB24VMABCTT->DefineSection(5, z, 6.3/2., 6.7/2.);
+ z += 0.63;
+ shRB24VMABCTT->DefineSection(6, z, 6.3/2., 6.7/2.);
+ TGeoVolume* voRB24VMABCTT = new TGeoVolume("RB24VMABCTT", shRB24VMABCTT, kMedSteel);
+ voRB24VMABCRB->AddNode(voRB24VMABCTT, 1, new TGeoTranslation(0., 0., - kRB24VMABCRBT1L/2.-1.));
+
+ // Pos 3 RF Contact D63 LHCVSR__0057
+ // Pos 3.1 RF Contact Flange LHCVSR__0017
+ //
+ TGeoPcon* shRB24VMABCCTFlange = new TGeoPcon(0., 360., 6);
+ const Float_t kRB24VMABCCTFlangeRin = 6.36/2.; // Inner radius
+ const Float_t kRB24VMABCCTFlangeL = 1.30; // Length
+
+ z = 0.;
+ shRB24VMABCCTFlange->DefineSection(0, z, kRB24VMABCCTFlangeRin, 6.5/2.);
+ z += 0.15;
+ shRB24VMABCCTFlange->DefineSection(1, z, kRB24VMABCCTFlangeRin, 6.5/2.);
+ shRB24VMABCCTFlange->DefineSection(2, z, kRB24VMABCCTFlangeRin, 6.9/2.);
+ z += 0.9;
+ shRB24VMABCCTFlange->DefineSection(3, z, kRB24VMABCCTFlangeRin, 6.9/2.);
+ shRB24VMABCCTFlange->DefineSection(4, z, kRB24VMABCCTFlangeRin, 11.16/2.);
+ z += 0.25;
+ shRB24VMABCCTFlange->DefineSection(5, z, kRB24VMABCCTFlangeRin, 11.16/2.);
+ TGeoVolume* voRB24VMABCCTFlange = new TGeoVolume("RB24VMABCCTFlange", shRB24VMABCCTFlange, kMedCu);
+ //
+ // Pos 3.2 RF-Contact LHCVSR__0056
+ //
+ TGeoPcon* shRB24VMABCCT = new TGeoPcon(0., 360., 4);
+ const Float_t kRB24VMABCCTRin = 6.30/2.; // Inner radius
+ const Float_t kRB24VMABCCTCRin = 7.29/2.; // Max. inner radius conical section
+ const Float_t kRB24VMABCCTL = 11.88; // Length
+ const Float_t kRB24VMABCCTSL = 10.48; // Length of straight section
+ const Float_t kRB24VMABCCTd = 0.03; // Thickness
+ z = 0;
+ shRB24VMABCCT->DefineSection(0, z, kRB24VMABCCTCRin, kRB24VMABCCTCRin + kRB24VMABCCTd);
+ z = kRB24VMABCCTL - kRB24VMABCCTSL;
+ shRB24VMABCCT->DefineSection(1, z, kRB24VMABCCTRin + 0.35, kRB24VMABCCTRin + 0.35 + kRB24VMABCCTd);
+ z = kRB24VMABCCTL - kRB24VMABCCTFlangeL;
+ shRB24VMABCCT->DefineSection(2, z, kRB24VMABCCTRin, kRB24VMABCCTRin + kRB24VMABCCTd);
+ z = kRB24VMABCCTL;
+ shRB24VMABCCT->DefineSection(3, z, kRB24VMABCCTRin, kRB24VMABCCTRin + kRB24VMABCCTd);
+
+ TGeoVolume* voRB24VMABCCT = new TGeoVolume("RB24VMABCCT", shRB24VMABCCT, kMedCu);
+
+ TGeoVolumeAssembly* voRB24VMABRFCT = new TGeoVolumeAssembly("RB24VMABRFCT");
+ voRB24VMABRFCT->AddNode(voRB24VMABCCT, 1, gGeoIdentity);
+ voRB24VMABRFCT->AddNode( voRB24VMABCCTFlange, 1, new TGeoTranslation(0., 0., kRB24VMABCCTL - kRB24VMABCCTFlangeL));
+
+ z = kRB24VMABCRBT1L/2. + kRB24B1BellowUndL + kRB24VMABBEConTubeL1 + kRB24VMABBEConTubeL2 - kRB24VMABCCTL + 1.;
+ voRB24VMABCRB->AddNode(voRB24VMABRFCT, 1, new TGeoTranslation(0., 0., z));
+
+
+ //
+ // Assembling RB24/1
+ //
+ TGeoVolumeAssembly* voRB24 = new TGeoVolumeAssembly("RB24");
+ // Cu Tube with two simplified flanges
+ voRB24->AddNode(voRB24CuTubeM, 1, gGeoIdentity);
+ voRB24->AddNode(voRB24CuTubeA, 1, gGeoIdentity);
+ z = - kRB24CuTubeL/2 + kRB24CuTubeFL/2.;
+ voRB24->AddNode(voRB24CuTubeF, 1, new TGeoTranslation(0., 0., z));
+ z = + kRB24CuTubeL/2 - kRB24CuTubeFL/2.;
+ voRB24->AddNode(voRB24CuTubeF, 2, new TGeoTranslation(0., 0., z));
+ // VMABC close to compensator magnet
+ z = - kRB24CuTubeL/2. - (kRB24VMABCL - kRB24VMABCRBT1L/2) + 1.;
+
+ voRB24->AddNode(voRB24VMABCRB, 2, new TGeoTranslation(0., 0., z));
+ // Bellow
+ z = kRB24CuTubeL/2;
+ voRB24->AddNode(voRB24B1BellowM, 1, new TGeoTranslation(0., 0., z));
+ z += (kRB24B1L + kRB24AIpML/2.);
+ // Annular ion pump
+ voRB24->AddNode(voRB24AIpM, 1, new TGeoTranslation(0., 0., z));
+ z += (kRB24AIpML/2. + kRB24ValveWz/2.);
+ // Valve
+ voRB24->AddNode(voRB24ValveMo, 1, new TGeoTranslation(0., 0., z));
+ z += (kRB24ValveWz/2.+ kRB24VMABCRBT1L/2. + 1.);
+ // VMABC close to forward detectors
+ voRB24->AddNode(voRB24VMABCRB, 3, new TGeoTranslation(0., 0., z));
+ //
+ // RB24/2
+ //
+ // Copper Tube RB24/2
+ const Float_t kRB242CuTubeL = 330.0;
+
+ TGeoVolume* voRB242CuTubeM = new TGeoVolume("voRB242CuTubeM",
+ new TGeoTube(0., kRB24CuTubeRo, kRB242CuTubeL/2.), kMedVac);
+ voRB24CuTubeM->SetVisibility(0);
+ TGeoVolume* voRB242CuTube = new TGeoVolume("voRB242CuTube",
+ new TGeoTube(kRB24CuTubeRi, kRB24CuTubeRo, kRB242CuTubeL/2.), kMedCu);
+ voRB242CuTubeM->AddNode(voRB242CuTube, 1, gGeoIdentity);
+
+
+ TGeoVolumeAssembly* voRB242 = new TGeoVolumeAssembly("RB242");
+ voRB242->AddNode(voRB242CuTube, 1, gGeoIdentity);
+ z = - kRB242CuTubeL/2 + kRB24CuTubeFL/2.;
+ voRB242->AddNode(voRB24CuTubeF, 3, new TGeoTranslation(0., 0., z));
+ z = + kRB242CuTubeL/2 - kRB24CuTubeFL/2.;
+ voRB242->AddNode(voRB24CuTubeF, 4, new TGeoTranslation(0., 0., z));
+ z = - kRB24CuTubeL/2 - kRB24VMABCL - kRB242CuTubeL/2.;
+ voRB24->AddNode(voRB242, 1, new TGeoTranslation(0., 0., z));
+ //
+ // RB24/3
+ //
+ // Copper Tube RB24/3
+ const Float_t kRB243CuTubeL = 303.35;
+
+ TGeoVolume* voRB243CuTubeM = new TGeoVolume("voRB243CuTubeM",
+ new TGeoTube(0., kRB24CuTubeRo, kRB243CuTubeL/2.), kMedVac);
+ voRB24CuTubeM->SetVisibility(0);
+ TGeoVolume* voRB243CuTube = new TGeoVolume("voRB243CuTube",
+ new TGeoTube(kRB24CuTubeRi, kRB24CuTubeRo, kRB243CuTubeL/2.), kMedCu);
+ voRB243CuTubeM->AddNode(voRB243CuTube, 1, gGeoIdentity);
+
+
+ TGeoVolumeAssembly* voRB243 = new TGeoVolumeAssembly("RB243");
+ TGeoVolumeAssembly* voRB243A = new TGeoVolumeAssembly("RB243A");
+
+ voRB243A->AddNode(voRB243CuTube, 1, gGeoIdentity);
+ z = - kRB243CuTubeL/2 + kRB24CuTubeFL/2.;
+ voRB243A->AddNode(voRB24CuTubeF, 5, new TGeoTranslation(0., 0., z));
+ z = + kRB243CuTubeL/2 - kRB24CuTubeFL/2.;
+ voRB243A->AddNode(voRB24CuTubeF, 6, new TGeoTranslation(0., 0., z));
+ z = + kRB243CuTubeL/2;
+ voRB243A->AddNode(voRB24B1BellowM, 2, new TGeoTranslation(0., 0., z));
+
+ z = - kRB243CuTubeL/2. - kRB24B1L;
+ voRB243->AddNode(voRB243A, 1, new TGeoTranslation(0., 0., z));
+ z = - (1.5 * kRB243CuTubeL + 2. * kRB24B1L);
+ voRB243->AddNode(voRB243A, 2, new TGeoTranslation(0., 0., z));
+
+ z = - 2. * (kRB243CuTubeL + kRB24B1L) - (kRB24VMABCL - kRB24VMABCRBT1L/2) + 1.;
+ voRB243->AddNode(voRB24VMABCRB, 3, new TGeoTranslation(0., 0., z));
+
+ z = - kRB24CuTubeL/2 - kRB24VMABCL - kRB242CuTubeL;
+ voRB24->AddNode(voRB243, 1, new TGeoTranslation(0., 0., z));
+
+
+ //
+ //
+ top->AddNode(voRB24, 1, new TGeoCombiTrans(0., 0., kRB24CuTubeL/2 + 88.5 + 400., rot180));
+
+
+ //
+ ////////////////////////////////////////////////////////////////////////////////
+ // //
+ // The Absorber Vacuum system //
+ // //
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ // Rotable Flange starts at: 82.00 cm from IP
+ // Length of rotable flange section: 10.68 cm
+ // Weld 0.08 cm
+ // Length of straight section 207.21 cm
+ // =======================================================================
+ // 299.97 cm [0.03 cm missing ?]
+ // Length of opening cone 252.09 cm
+ // Weld 0.15 cm
+ // Length of compensator 30.54 cm
+ // Weld 0.15 cm
+ // Length of fixed flange 2.13 - 0.97 1.16 cm
+ // =======================================================================
+ // 584.06 cm [584.80 installed] [0.74 cm missing]
+ // RB26/3
+ // Length of split flange 2.13 - 1.2 0.93 cm
+ // Weld 0.15 cm
+ // Length of fixed point section 16.07 cm
+ // Weld 0.15 cm
+ // Length of opening cone 629.20 cm
+ // Weld 0.30 cm
+ // Kength of the compensator 41.70 cm
+ // Weld 0.30 cm
+ // Length of fixed flange 2.99 - 1.72 1.27 cm
+ // =================================================
+ // Length of RB26/3 690.07 cm [689.20 installed] [0.87 cm too much]
+ //
+ // RB26/4-5
+ // Length of split flange 2.13 - 1.2 0.93 cm
+ // Weld 0.15 cm
+ // Length of fixed point section 16.07 cm
+ // Weld 0.15 cm
+ // Length of opening cone 629.20 cm
+ // Weld 0.30 cm
+ // Length of closing cone
+ // Weld
+ // Lenth of straight section
+ // Kength of the compensator 41.70 cm
+ // Weld 0.30 cm
+ // Length of fixed flange 2.99 - 1.72 1.27 cm
+ // =================================================
+ // Length of RB26/3 690.07 cm [689.20 installed] [0.87 cm too much]
+
+ ///////////////////////////////////////////
+ // //
+ // RB26/1-2 //
+ // Drawing LHCV2a_0050 [as installed] //
+ // Drawing LHCV2a_0008 //
+ // Drawing LHCV2a_0001 //
+ ///////////////////////////////////////////
+ // Pos1 Vacuum Tubes LHCVC2A__0010
+ // Pos2 Compensator LHCVC2A__0064
+ // Pos3 Rotable Flange LHCVFX___0016
+ // Pos4 Fixed Flange LHCVFX___0006
+ // Pos5 Bellow Tooling LHCVFX___0003
+ //
+ //
+ //
+ ///////////////////////////////////
+ // RB26/1-2 Vacuum Tubes //
+ // Drawing LHCVC2a_0010 //
+ ///////////////////////////////////
+ const Float_t kRB26s12TubeL = 459.45; // 0.15 cm added for welding
+ //
+ // Add 1 cm on outer diameter for insulation
+ //
+ TGeoPcon* shRB26s12Tube = new TGeoPcon(0., 360., 5);
+ // Section 1: straight section
+ shRB26s12Tube->DefineSection(0, 0.00, 5.84/2., 6.00/2.);
+ shRB26s12Tube->DefineSection(1, 207.21, 5.84/2., 6.00/2.);
+ // Section 2: 0.72 deg opening cone
+ shRB26s12Tube->DefineSection(2, 207.21, 5.84/2., 6.14/2.);
+ shRB26s12Tube->DefineSection(3, 452.30, 12.00/2., 12.30/2.);
+ shRB26s12Tube->DefineSection(4, kRB26s12TubeL, 12.00/2., 12.30/2.);
+ TGeoVolume* voRB26s12Tube = new TGeoVolume("RB26s12Tube", shRB26s12Tube, kMedSteel);
+ // Add the insulation layer
+ TGeoVolume* voRB26s12TubeIns = new TGeoVolume("RB26s12TubeIns", MakeInsulationFromTemplate(shRB26s12Tube), kMedInsu);
+ voRB26s12Tube->AddNode(voRB26s12TubeIns, 1, gGeoIdentity);
+
+
+ TGeoVolume* voRB26s12TubeM = new TGeoVolume("RB26s12TubeM", MakeMotherFromTemplate(shRB26s12Tube), kMedVac);
+ voRB26s12TubeM->AddNode(voRB26s12Tube, 1, gGeoIdentity);
+
+
+
+ ///////////////////////////////////
+ // RB26/2 Axial Compensator //
+ // Drawing LHCVC2a_0064 //
+ ///////////////////////////////////
+ const Float_t kRB26s2CompL = 30.65; // Length of the compensator
+ const Float_t kRB26s2BellowRo = 14.38/2.; // Bellow outer radius [Pos 1]
+ const Float_t kRB26s2BellowRi = 12.12/2.; // Bellow inner radius [Pos 1]
+ const Int_t kRB26s2NumberOfPlies = 14; // Number of plies [Pos 1]
+ const Float_t kRB26s2BellowUndL = 10.00; // Length of undulated region [Pos 1] [+10 mm installed including pretension ?]
+ const Float_t kRB26s2PlieThickness = 0.025; // Plie thickness [Pos 1]
+ const Float_t kRB26s2ConnectionPlieR = 0.21; // Connection plie radius [Pos 1]
+ // Plie radius
+ const Float_t kRB26s2PlieR =
+ (kRB26s2BellowUndL - 4. * kRB26s2ConnectionPlieR + 2. * kRB26s2PlieThickness +
+ (2. * kRB26s2NumberOfPlies - 2.) * kRB26s2PlieThickness) / (4. * kRB26s2NumberOfPlies - 2.);
+ const Float_t kRB26s2CompTubeInnerR = 12.00/2.; // Connection tubes inner radius [Pos 2 + 3]
+ const Float_t kRB26s2CompTubeOuterR = 12.30/2.; // Connection tubes outer radius [Pos 2 + 3]
+ const Float_t kRB26s2WeldingTubeLeftL = 9.00/2.; // Left connection tube half length [Pos 2]
+ const Float_t kRB26s2WeldingTubeRightL = 11.65/2.; // Right connection tube half length [Pos 3] [+ 0.15 cm for welding]
+ const Float_t kRB26s2RingOuterR = 18.10/2.; // Ring inner radius [Pos 4]
+ const Float_t kRB26s2RingL = 0.40/2.; // Ring half length [Pos 4]
+ const Float_t kRB26s2RingZ = 6.50 ; // Ring z-position [Pos 4]
+ const Float_t kRB26s2ProtOuterR = 18.20/2.; // Protection tube outer radius [Pos 5]
+ const Float_t kRB26s2ProtL = 15.00/2.; // Protection tube half length [Pos 5]
+ const Float_t kRB26s2ProtZ = 6.70 ; // Protection tube z-position [Pos 5]
+
+
+ // Mother volume
+ //
+ TGeoPcon* shRB26s2Compensator = new TGeoPcon(0., 360., 6);
+ shRB26s2Compensator->DefineSection( 0, 0.0, 0., kRB26s2CompTubeOuterR);
+ shRB26s2Compensator->DefineSection( 1, kRB26s2RingZ, 0., kRB26s2CompTubeOuterR);
+ shRB26s2Compensator->DefineSection( 2, kRB26s2RingZ, 0., kRB26s2ProtOuterR);
+ shRB26s2Compensator->DefineSection( 3, kRB26s2ProtZ + 2. * kRB26s2ProtL, 0., kRB26s2ProtOuterR);
+ shRB26s2Compensator->DefineSection( 4, kRB26s2ProtZ + 2. * kRB26s2ProtL, 0., kRB26s2CompTubeOuterR);
+ shRB26s2Compensator->DefineSection( 5, kRB26s2CompL , 0., kRB26s2CompTubeOuterR);
+ TGeoVolume* voRB26s2Compensator = new TGeoVolume("RB26s2Compensator", shRB26s2Compensator, kMedVac);
+
+ //
+ // [Pos 1] Bellow
+ //
+ //
+ TGeoVolume* voRB26s2Bellow = new TGeoVolume("RB26s2Bellow", new TGeoTube(kRB26s2BellowRi, kRB26s2BellowRo, kRB26s2BellowUndL/2.), kMedVac);
+ //
+ // Upper part of the undulation
+ //
+ TGeoTorus* shRB26s2PlieTorusU = new TGeoTorus(kRB26s2BellowRo - kRB26s2PlieR, kRB26s2PlieR - kRB26s2PlieThickness, kRB26s2PlieR);
+ shRB26s2PlieTorusU->SetName("RB26s2TorusU");
+ TGeoTube* shRB26s2PlieTubeU = new TGeoTube (kRB26s2BellowRo - kRB26s2PlieR, kRB26s2BellowRo, kRB26s2PlieR);
+ shRB26s2PlieTubeU->SetName("RB26s2TubeU");
+ TGeoCompositeShape* shRB26s2UpperPlie = new TGeoCompositeShape("RB26s2UpperPlie", "RB26s2TorusU*RB26s2TubeU");
+
+ TGeoVolume* voRB26s2WiggleU = new TGeoVolume("RB26s2UpperPlie", shRB26s2UpperPlie, kMedSteel);
+ //
+ // Lower part of the undulation
+ TGeoTorus* shRB26s2PlieTorusL = new TGeoTorus(kRB26s2BellowRi + kRB26s2PlieR, kRB26s2PlieR - kRB26s2PlieThickness, kRB26s2PlieR);
+ shRB26s2PlieTorusL->SetName("RB26s2TorusL");
+ TGeoTube* shRB26s2PlieTubeL = new TGeoTube (kRB26s2BellowRi, kRB26s2BellowRi + kRB26s2PlieR, kRB26s2PlieR);
+ shRB26s2PlieTubeL->SetName("RB26s2TubeL");
+ TGeoCompositeShape* shRB26s2LowerPlie = new TGeoCompositeShape("RB26s2LowerPlie", "RB26s2TorusL*RB26s2TubeL");
+
+ TGeoVolume* voRB26s2WiggleL = new TGeoVolume("RB26s2LowerPlie", shRB26s2LowerPlie, kMedSteel);
+
+ //
+ // Connection between upper and lower part of undulation
+ TGeoVolume* voRB26s2WiggleC1 = new TGeoVolume("RB26s2PlieConn1",
+ new TGeoTube(kRB26s2BellowRi + kRB26s2PlieR,
+ kRB26s2BellowRo - kRB26s2PlieR, kRB26s2PlieThickness / 2.), kMedSteel);
+ //
+ // One wiggle
+ TGeoVolumeAssembly* voRB26s2Wiggle = new TGeoVolumeAssembly("RB26s2Wiggle");
+ z0 = - kRB26s2PlieThickness / 2.;
+ voRB26s2Wiggle->AddNode(voRB26s2WiggleC1, 1 , new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s2PlieR - kRB26s2PlieThickness / 2.;
+ voRB26s2Wiggle->AddNode(voRB26s2WiggleU, 1 , new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s2PlieR - kRB26s2PlieThickness / 2.;
+ voRB26s2Wiggle->AddNode(voRB26s2WiggleC1, 2 , new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s2PlieR - kRB26s2PlieThickness;
+ voRB26s2Wiggle->AddNode(voRB26s2WiggleL , 1 , new TGeoTranslation(0., 0., z0));
+ // Positioning of the volumes
+ z0 = - kRB26s2BellowUndL/2.+ kRB26s2ConnectionPlieR;
+ voRB26s2Bellow->AddNode(voRB26s2WiggleL, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s2ConnectionPlieR;
+ zsh = 4. * kRB26s2PlieR - 2. * kRB26s2PlieThickness;
+ for (Int_t iw = 0; iw < kRB26s2NumberOfPlies; iw++) {
+ Float_t zpos = z0 + iw * zsh;
+ voRB26s2Bellow->AddNode(voRB26s2Wiggle, iw + 1, new TGeoTranslation(0., 0., zpos - kRB26s2PlieThickness));
+ }
+
+ voRB26s2Compensator->AddNode(voRB26s2Bellow, 1, new TGeoTranslation(0., 0., 2. * kRB26s2WeldingTubeLeftL + kRB26s2BellowUndL/2.));
+
+ //
+ // [Pos 2] Left Welding Tube
+ //
+ TGeoTube* shRB26s2CompLeftTube = new TGeoTube(kRB26s2CompTubeInnerR, kRB26s2CompTubeOuterR, kRB26s2WeldingTubeLeftL);
+ TGeoVolume* voRB26s2CompLeftTube = new TGeoVolume("RB26s2CompLeftTube", shRB26s2CompLeftTube, kMedSteel);
+ voRB26s2Compensator->AddNode(voRB26s2CompLeftTube, 1, new TGeoTranslation(0., 0., kRB26s2WeldingTubeLeftL));
+ //
+ // [Pos 3] Right Welding Tube
+ //
+ TGeoTube* shRB26s2CompRightTube = new TGeoTube(kRB26s2CompTubeInnerR, kRB26s2CompTubeOuterR, kRB26s2WeldingTubeRightL);
+ TGeoVolume* voRB26s2CompRightTube = new TGeoVolume("RB26s2CompRightTube", shRB26s2CompRightTube, kMedSteel);
+ voRB26s2Compensator->AddNode(voRB26s2CompRightTube, 1, new TGeoTranslation(0., 0., kRB26s2CompL - kRB26s2WeldingTubeRightL));
+ //
+ // [Pos 4] Ring
+ //
+ TGeoTube* shRB26s2CompRing = new TGeoTube(kRB26s2CompTubeOuterR, kRB26s2RingOuterR, kRB26s2RingL);
+ TGeoVolume* voRB26s2CompRing = new TGeoVolume("RB26s2CompRing", shRB26s2CompRing, kMedSteel);
+ voRB26s2Compensator->AddNode(voRB26s2CompRing, 1, new TGeoTranslation(0., 0., kRB26s2RingZ + kRB26s2RingL));
+
+ //
+ // [Pos 5] Outer Protecting Tube
+ //
+ TGeoTube* shRB26s2CompProtTube = new TGeoTube(kRB26s2RingOuterR, kRB26s2ProtOuterR, kRB26s2ProtL);
+ TGeoVolume* voRB26s2CompProtTube = new TGeoVolume("RB26s2CompProtTube", shRB26s2CompProtTube, kMedSteel);
+ voRB26s2Compensator->AddNode(voRB26s2CompProtTube, 1, new TGeoTranslation(0., 0., kRB26s2ProtZ + kRB26s2ProtL));
+
+ ///////////////////////////////////
+ // Rotable Flange //
+ // Drawing LHCVFX_0016 //
+ ///////////////////////////////////
+ const Float_t kRB26s1RFlangeTubeRi = 5.84/2.-lolo ; // Tube inner radius
+ const Float_t kRB26s1RFlangeTubeRo = 6.00/2.-lolo ; // Tube outer radius
+
+ // Pos 1 Clamp Ring LHCVFX__0015
+ const Float_t kRB26s1RFlangeCrL = 1.40 ; // Lenth of the clamp ring
+ const Float_t kRB26s1RFlangeCrRi1 = 6.72/2.-lolo-1. ; // Ring inner radius section 1
+ const Float_t kRB26s1RFlangeCrRi2 = 6.06/2.-lolo-1. ; // Ring inner radius section 2
+ const Float_t kRB26s1RFlangeCrRo = 8.60/2.-lolo-1. ; // Ring outer radius
+ const Float_t kRB26s1RFlangeCrD = 0.800 ; // Width section 1
+
+ TGeoPcon* shRB26s1RFlangeCr = new TGeoPcon(0., 360., 4);
+ z0 = 0.;
+ shRB26s1RFlangeCr->DefineSection(0, z0, kRB26s1RFlangeCrRi1, kRB26s1RFlangeCrRo);
+ z0 += kRB26s1RFlangeCrD;
+ shRB26s1RFlangeCr->DefineSection(1, z0, kRB26s1RFlangeCrRi1, kRB26s1RFlangeCrRo);
+ shRB26s1RFlangeCr->DefineSection(2, z0, kRB26s1RFlangeCrRi2, kRB26s1RFlangeCrRo);
+ z0 = kRB26s1RFlangeCrL;
+ shRB26s1RFlangeCr->DefineSection(3, z0, kRB26s1RFlangeCrRi2, kRB26s1RFlangeCrRo);
+ TGeoVolume* voRB26s1RFlangeCr =
+ new TGeoVolume("RB26s1RFlangeCr", shRB26s1RFlangeCr, kMedSteel);
+
+ // Pos 2 Insert LHCVFX__0015
+ const Float_t kRB26s1RFlangeIsL = 4.88 ; // Lenth of the insert
+ const Float_t kRB26s1RFlangeIsR = 6.70/2.-lolo ; // Ring radius
+ const Float_t kRB26s1RFlangeIsD = 0.80 ; // Ring Width
+
+ TGeoPcon* shRB26s1RFlangeIs = new TGeoPcon(0., 360., 4);
+ z0 = 0.;
+ shRB26s1RFlangeIs->DefineSection(0, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeIsR);
+ z0 += kRB26s1RFlangeIsD;
+ shRB26s1RFlangeIs->DefineSection(1, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeIsR);
+ shRB26s1RFlangeIs->DefineSection(2, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeTubeRo);
+ z0 = kRB26s1RFlangeIsL;
+ shRB26s1RFlangeIs->DefineSection(3, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeTubeRo);
+ TGeoVolume* voRB26s1RFlangeIs =
+ new TGeoVolume("RB26s1RFlangeIs", shRB26s1RFlangeIs, kMedSteel);
+ // 4.88 + 3.7 = 8.58 (8.7 to avoid overlap)
+ // Pos 3 Fixed Point Section LHCVC2A_0021
+ const Float_t kRB26s1RFlangeFpL = 5.88 ; // Length of the fixed point section (0.08 cm added for welding)
+ const Float_t kRB26s1RFlangeFpZ = 3.82 ; // Position of the ring
+ const Float_t kRB26s1RFlangeFpD = 0.59 ; // Width of the ring
+ const Float_t kRB26s1RFlangeFpR = 7.00/2.-lolo ; // Radius of the ring
+
+ TGeoPcon* shRB26s1RFlangeFp = new TGeoPcon(0., 360., 6);
+ z0 = 0.;
+ shRB26s1RFlangeFp->DefineSection(0, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeTubeRo);
+ z0 += kRB26s1RFlangeFpZ;
+ shRB26s1RFlangeFp->DefineSection(1, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeTubeRo);
+ shRB26s1RFlangeFp->DefineSection(2, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeFpR);
+ z0 += kRB26s1RFlangeFpD;
+ shRB26s1RFlangeFp->DefineSection(3, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeFpR);
+ shRB26s1RFlangeFp->DefineSection(4, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeTubeRo);
+ z0 = kRB26s1RFlangeFpL;
+ shRB26s1RFlangeFp->DefineSection(5, z0, kRB26s1RFlangeTubeRi, kRB26s1RFlangeTubeRo);
+ TGeoVolume* voRB26s1RFlangeFp = new TGeoVolume("RB26s1RFlangeFp", shRB26s1RFlangeFp, kMedSteel);
+
+ // Put everything in a mother volume
+ TGeoPcon* shRB26s1RFlange = new TGeoPcon(0., 360., 8);
+ z0 = 0.;
+ shRB26s1RFlange->DefineSection(0, z0, 0., kRB26s1RFlangeCrRo);
+ z0 += kRB26s1RFlangeCrL;
+ shRB26s1RFlange->DefineSection(1, z0, 0., kRB26s1RFlangeCrRo);
+ shRB26s1RFlange->DefineSection(2, z0, 0., kRB26s1RFlangeTubeRo);
+ z0 = kRB26s1RFlangeIsL + kRB26s1RFlangeFpZ;
+ shRB26s1RFlange->DefineSection(3, z0, 0., kRB26s1RFlangeTubeRo);
+ shRB26s1RFlange->DefineSection(4, z0, 0., kRB26s1RFlangeFpR);
+ z0 += kRB26s1RFlangeFpD;
+ shRB26s1RFlange->DefineSection(5, z0, 0., kRB26s1RFlangeFpR);
+ shRB26s1RFlange->DefineSection(6, z0, 0., kRB26s1RFlangeTubeRo);
+ z0 = kRB26s1RFlangeIsL + kRB26s1RFlangeFpL;
+ shRB26s1RFlange->DefineSection(7, z0, 0., kRB26s1RFlangeTubeRo);
+ TGeoVolume* voRB26s1RFlange = new TGeoVolume("RB26s1RFlange", shRB26s1RFlange, kMedVac);
+
+ voRB26s1RFlange->AddNode(voRB26s1RFlangeIs, 1, gGeoIdentity);
+ voRB26s1RFlange->AddNode(voRB26s1RFlangeCr, 1, gGeoIdentity);
+ voRB26s1RFlange->AddNode(voRB26s1RFlangeFp, 1, new TGeoTranslation(0., 0., kRB26s1RFlangeIsL));
+
+ ///////////////////////////////////
+ // Fixed Flange //
+ // Drawing LHCVFX_0006 //
+ ///////////////////////////////////
+ const Float_t kRB26s2FFlangeL = 2.13; // Length of the flange
+ const Float_t kRB26s2FFlangeD1 = 0.97; // Length of section 1
+ const Float_t kRB26s2FFlangeD2 = 0.29; // Length of section 2
+ const Float_t kRB26s2FFlangeD3 = 0.87; // Length of section 3
+ const Float_t kRB26s2FFlangeRo = 17.15/2.; // Flange outer radius
+ const Float_t kRB26s2FFlangeRi1 = 12.30/2.; // Flange inner radius section 1
+ const Float_t kRB26s2FFlangeRi2 = 12.00/2.; // Flange inner radius section 2
+ const Float_t kRB26s2FFlangeRi3 = 12.30/2.; // Flange inner radius section 3
+ z0 = 0;
+ TGeoPcon* shRB26s2FFlange = new TGeoPcon(0., 360., 6);
+ z0 = 0.;
+ shRB26s2FFlange->DefineSection(0, z0, kRB26s2FFlangeRi1, kRB26s2FFlangeRo);
+ z0 += kRB26s2FFlangeD1;
+ shRB26s2FFlange->DefineSection(1, z0, kRB26s2FFlangeRi1, kRB26s2FFlangeRo);
+ shRB26s2FFlange->DefineSection(2, z0, kRB26s2FFlangeRi2, kRB26s2FFlangeRo);
+ z0 += kRB26s2FFlangeD2;
+ shRB26s2FFlange->DefineSection(3, z0, kRB26s2FFlangeRi2, kRB26s2FFlangeRo);
+ shRB26s2FFlange->DefineSection(4, z0, kRB26s2FFlangeRi3, kRB26s2FFlangeRo);
+ z0 += kRB26s2FFlangeD3;
+ shRB26s2FFlange->DefineSection(5, z0, kRB26s2FFlangeRi3, kRB26s2FFlangeRo);
+ TGeoVolume* voRB26s2FFlange = new TGeoVolume("RB26s2FFlange", shRB26s2FFlange, kMedSteel);
+
+ TGeoVolume* voRB26s2FFlangeM = new TGeoVolume("RB26s2FFlangeM", MakeMotherFromTemplate(shRB26s2FFlange, 2, 5), kMedVac);
+ voRB26s2FFlangeM->AddNode(voRB26s2FFlange, 1, gGeoIdentity);
+
+
+
+ ////////////////////////////////////////
+ // //
+ // RB26/3 //
+ // Drawing LHCV2a_0048 //
+ // Drawing LHCV2a_0002 //
+ ////////////////////////////////////////
+ //
+ // Pos 1 Vacuum Tubes LHCVC2A__0003
+ // Pos 2 Fixed Point LHCVFX___0005
+ // Pos 3 Split Flange LHCVFX___0007
+ // Pos 4 Fixed Flange LHCVFX___0004
+ // Pos 5 Axial Compensator LHCVC2A__0065
+ //
+ //
+ //
+ //
+ ///////////////////////////////////
+ // Vacuum Tube //
+ // Drawing LHCVC2A_0003 //
+ ///////////////////////////////////
+ const Float_t kRB26s3TubeL = 629.35 + 0.3; // 0.3 cm added for welding
+ const Float_t kRB26s3TubeR1 = 12./2.;
+ const Float_t kRB26s3TubeR2 = kRB26s3TubeR1 + 215.8 * TMath::Tan(0.829 / 180. * TMath::Pi());
+
+
+ TGeoPcon* shRB26s3Tube = new TGeoPcon(0., 360., 7);
+ // Section 1: straight section
+ shRB26s3Tube->DefineSection(0, 0.00, kRB26s3TubeR1, kRB26s3TubeR1 + 0.15);
+ shRB26s3Tube->DefineSection(1, 2.00, kRB26s3TubeR1, kRB26s3TubeR1 + 0.15);
+ // Section 2: 0.829 deg opening cone
+ shRB26s3Tube->DefineSection(2, 2.00, kRB26s3TubeR1, kRB26s3TubeR1 + 0.20);
+
+ shRB26s3Tube->DefineSection(3, 217.80, kRB26s3TubeR2, kRB26s3TubeR2 + 0.20);
+ shRB26s3Tube->DefineSection(4, 217.80, kRB26s3TubeR2, kRB26s3TubeR2 + 0.30);
+
+ shRB26s3Tube->DefineSection(5, 622.20, 30.00/2., 30.60/2.);
+ shRB26s3Tube->DefineSection(6, kRB26s3TubeL, 30.00/2., 30.60/2.);
+
+ TGeoVolume* voRB26s3Tube = new TGeoVolume("RB26s3Tube", shRB26s3Tube, kMedSteel);
+ // Add the insulation layer
+ TGeoVolume* voRB26s3TubeIns = new TGeoVolume("RB26s3TubeIns", MakeInsulationFromTemplate(shRB26s3Tube), kMedInsu);
+ voRB26s3Tube->AddNode(voRB26s3TubeIns, 1, gGeoIdentity);
+
+ TGeoVolume* voRB26s3TubeM = new TGeoVolume("RB26s3TubeM", MakeMotherFromTemplate(shRB26s3Tube), kMedVac);
+ voRB26s3TubeM->AddNode(voRB26s3Tube, 1, gGeoIdentity);
+
+
+
+ ///////////////////////////////////
+ // Fixed Point //
+ // Drawing LHCVFX_0005 //
+ ///////////////////////////////////
+ const Float_t kRB26s3FixedPointL = 16.37 ; // Length of the fixed point section (0.3 cm added for welding)
+ const Float_t kRB26s3FixedPointZ = 9.72 ; // Position of the ring (0.15 cm added for welding)
+ const Float_t kRB26s3FixedPointD = 0.595 ; // Width of the ring
+ const Float_t kRB26s3FixedPointR = 13.30/2. ; // Radius of the ring
+ const Float_t kRB26s3FixedPointRi = 12.00/2. ; // Inner radius of the tube
+ const Float_t kRB26s3FixedPointRo1 = 12.30/2. ; // Outer radius of the tube (in)
+ const Float_t kRB26s3FixedPointRo2 = 12.40/2. ; // Outer radius of the tube (out)
+ const Float_t kRB26s3FixedPointDs = 1.5 ; // Width of straight section behind ring
+ const Float_t kRB26s3FixedPointDc = 3.15 ; // Width of conical section behind ring (0.15 cm added for welding)
+
+ TGeoPcon* shRB26s3FixedPoint = new TGeoPcon(0., 360., 8);
+ z0 = 0.;
+ shRB26s3FixedPoint->DefineSection(0, z0, kRB26s3FixedPointRi, kRB26s3FixedPointRo1);
+ z0 += kRB26s3FixedPointZ;
+ shRB26s3FixedPoint->DefineSection(1, z0, kRB26s3FixedPointRi, kRB26s3FixedPointRo1);
+ shRB26s3FixedPoint->DefineSection(2, z0, kRB26s3FixedPointRi, kRB26s3FixedPointR);
+ z0 += kRB26s3FixedPointD;
+ shRB26s3FixedPoint->DefineSection(3, z0, kRB26s3FixedPointRi, kRB26s3FixedPointR);
+ shRB26s3FixedPoint->DefineSection(4, z0, kRB26s3FixedPointRi, kRB26s3FixedPointRo1);
+ z0 += kRB26s3FixedPointDs;
+ shRB26s3FixedPoint->DefineSection(5, z0, kRB26s3FixedPointRi, kRB26s3FixedPointRo1);
+ z0 += kRB26s3FixedPointDc;
+ shRB26s3FixedPoint->DefineSection(6, z0, kRB26s3FixedPointRi, kRB26s3FixedPointRo2);
+ z0 = kRB26s3FixedPointL;
+ shRB26s3FixedPoint->DefineSection(7, z0, kRB26s3FixedPointRi, kRB26s3FixedPointRo2);
+ TGeoVolume* voRB26s3FixedPoint = new TGeoVolume("RB26s3FixedPoint", shRB26s3FixedPoint, kMedSteel);
+
+ TGeoVolume* voRB26s3FixedPointM = new TGeoVolume("RB26s3FixedPointM", MakeMotherFromTemplate(shRB26s3FixedPoint), kMedVac);
+ voRB26s3FixedPointM->AddNode(voRB26s3FixedPoint, 1, gGeoIdentity);
+
+ ///////////////////////////////////
+ // Split Flange //
+ // Drawing LHCVFX_0005 //
+ ///////////////////////////////////
+ const Float_t kRB26s3SFlangeL = 2.13; // Length of the flange
+ const Float_t kRB26s3SFlangeD1 = 0.57; // Length of section 1
+ const Float_t kRB26s3SFlangeD2 = 0.36; // Length of section 2
+ const Float_t kRB26s3SFlangeD3 = 0.50 + 0.70; // Length of section 3
+ const Float_t kRB26s3SFlangeRo = 17.15/2.; // Flange outer radius
+ const Float_t kRB26s3SFlangeRi1 = 12.30/2.; // Flange inner radius section 1
+ const Float_t kRB26s3SFlangeRi2 = 12.00/2.; // Flange inner radius section 2
+ const Float_t kRB26s3SFlangeRi3 = 12.30/2.; // Flange inner radius section 3
+ z0 = 0;
+ TGeoPcon* shRB26s3SFlange = new TGeoPcon(0., 360., 6);
+ z0 = 0.;
+ shRB26s3SFlange->DefineSection(0, z0, kRB26s3SFlangeRi1, kRB26s3SFlangeRo);
+ z0 += kRB26s3SFlangeD1;
+ shRB26s3SFlange->DefineSection(1, z0, kRB26s3SFlangeRi1, kRB26s3SFlangeRo);
+ shRB26s3SFlange->DefineSection(2, z0, kRB26s3SFlangeRi2, kRB26s3SFlangeRo);
+ z0 += kRB26s3SFlangeD2;
+ shRB26s3SFlange->DefineSection(3, z0, kRB26s3SFlangeRi2, kRB26s3SFlangeRo);
+ shRB26s3SFlange->DefineSection(4, z0, kRB26s3SFlangeRi3, kRB26s3SFlangeRo);
+ z0 += kRB26s3SFlangeD3;
+ shRB26s3SFlange->DefineSection(5, z0, kRB26s3SFlangeRi3, kRB26s3SFlangeRo);
+ TGeoVolume* voRB26s3SFlange = new TGeoVolume("RB26s3SFlange", shRB26s3SFlange, kMedSteel);
+
+ TGeoVolume* voRB26s3SFlangeM = new TGeoVolume("RB26s3SFlangeM", MakeMotherFromTemplate(shRB26s3SFlange, 0, 3), kMedVac);
+ voRB26s3SFlangeM->AddNode(voRB26s3SFlange, 1, gGeoIdentity);
+
+ ///////////////////////////////////
+ // RB26/3 Fixed Flange //
+ // Drawing LHCVFX___0004 //
+ ///////////////////////////////////
+ const Float_t kRB26s3FFlangeL = 2.99; // Length of the flange
+ const Float_t kRB26s3FFlangeD1 = 1.72; // Length of section 1
+ const Float_t kRB26s3FFlangeD2 = 0.30; // Length of section 2
+ const Float_t kRB26s3FFlangeD3 = 0.97; // Length of section 3
+ const Float_t kRB26s3FFlangeRo = 36.20/2.; // Flange outer radius
+ const Float_t kRB26s3FFlangeRi1 = 30.60/2.; // Flange inner radius section 1
+ const Float_t kRB26s3FFlangeRi2 = 30.00/2.; // Flange inner radius section 2
+ const Float_t kRB26s3FFlangeRi3 = 30.60/2.; // Flange inner radius section 3
+ z0 = 0;
+ TGeoPcon* shRB26s3FFlange = new TGeoPcon(0., 360., 6);
+ z0 = 0.;
+ shRB26s3FFlange->DefineSection(0, z0, kRB26s3FFlangeRi1, kRB26s3FFlangeRo);
+ z0 += kRB26s3FFlangeD1;
+ shRB26s3FFlange->DefineSection(1, z0, kRB26s3FFlangeRi1, kRB26s3FFlangeRo);
+ shRB26s3FFlange->DefineSection(2, z0, kRB26s3FFlangeRi2, kRB26s3FFlangeRo);
+ z0 += kRB26s3FFlangeD2;
+ shRB26s3FFlange->DefineSection(3, z0, kRB26s3FFlangeRi2, kRB26s3FFlangeRo);
+ shRB26s3FFlange->DefineSection(4, z0, kRB26s3FFlangeRi3, kRB26s3FFlangeRo);
+ z0 += kRB26s3FFlangeD3;
+ shRB26s3FFlange->DefineSection(5, z0, kRB26s3FFlangeRi3, kRB26s3FFlangeRo);
+ TGeoVolume* voRB26s3FFlange = new TGeoVolume("RB26s3FFlange", shRB26s3FFlange, kMedSteel);
+
+ TGeoVolume* voRB26s3FFlangeM = new TGeoVolume("RB26s3FFlangeM", MakeMotherFromTemplate(shRB26s3FFlange, 2, 5), kMedVac);
+ voRB26s3FFlangeM->AddNode(voRB26s3FFlange, 1, gGeoIdentity);
+
+
+
+ ///////////////////////////////////
+ // RB26/3 Axial Compensator //
+ // Drawing LHCVC2a_0065 //
+ ///////////////////////////////////
+ const Float_t kRB26s3CompL = 42.0; // Length of the compensator (0.3 cm added for welding)
+ const Float_t kRB26s3BellowRo = 34.00/2.; // Bellow outer radius [Pos 1]
+ const Float_t kRB26s3BellowRi = 30.10/2.; // Bellow inner radius [Pos 1]
+ const Int_t kRB26s3NumberOfPlies = 13; // Number of plies [Pos 1]
+ const Float_t kRB26s3BellowUndL = 17.70; // Length of undulated region [Pos 1]
+ const Float_t kRB26s3PlieThickness = 0.06; // Plie thickness [Pos 1]
+ const Float_t kRB26s3ConnectionPlieR = 0.21; // Connection plie radius [Pos 1]
+ // Plie radius
+ const Float_t kRB26s3PlieR =
+ (kRB26s3BellowUndL - 4. * kRB26s3ConnectionPlieR + 2. * kRB26s3PlieThickness +
+ (2. * kRB26s3NumberOfPlies - 2.) * kRB26s3PlieThickness) / (4. * kRB26s3NumberOfPlies - 2.);
+
+ //
+ // The welding tubes have 3 sections with different radii and 2 transition regions.
+ // Section 1: connection to the outside
+ // Section 2: commection to the bellow
+ // Section 3: between 1 and 2
+ const Float_t kRB26s3CompTubeInnerR1 = 30.0/2.; // Outer Connection tubes inner radius [Pos 4 + 3]
+ const Float_t kRB26s3CompTubeOuterR1 = 30.6/2.; // Outer Connection tubes outer radius [Pos 4 + 3]
+ const Float_t kRB26s3CompTubeInnerR2 = 29.4/2.; // Connection tubes inner radius [Pos 4 + 3]
+ const Float_t kRB26s3CompTubeOuterR2 = 30.0/2.; // Connection tubes outer radius [Pos 4 + 3]
+ const Float_t kRB26s3CompTubeInnerR3 = 30.6/2.; // Connection tubes inner radius at bellow [Pos 4 + 3]
+ const Float_t kRB26s3CompTubeOuterR3 = 32.2/2.; // Connection tubes outer radius at bellow [Pos 4 + 3]
+
+ const Float_t kRB26s3WeldingTubeLeftL1 = 2.0; // Left connection tube length [Pos 4]
+ const Float_t kRB26s3WeldingTubeLeftL2 = 3.4; // Left connection tube length [Pos 4]
+ const Float_t kRB26s3WeldingTubeLeftL = 7.0; // Left connection tube total length [Pos 4]
+ const Float_t kRB26s3WeldingTubeRightL1 = 2.3; // Right connection tube length [Pos 3] (0.3 cm added for welding)
+ const Float_t kRB26s3WeldingTubeRightL2 = 13.4; // Right connection tube length [Pos 3]
+
+ const Float_t kRB26s3WeldingTubeT1 = 0.6; // Length of first r-transition [Pos 4 + 3]
+ const Float_t kRB26s3WeldingTubeT2 = 1.0; // Length of 2nd r-transition [Pos 4 + 3]
+
+
+
+ const Float_t kRB26s3RingOuterR = 36.1/2.; // Ring inner radius [Pos 4]
+ const Float_t kRB26s3RingL = 0.8/2.; // Ring half length [Pos 4]
+ const Float_t kRB26s3RingZ = 3.7 ; // Ring z-position [Pos 4]
+ const Float_t kRB26s3ProtOuterR = 36.2/2.; // Protection tube outer radius [Pos 2]
+ const Float_t kRB26s3ProtL = 27.0/2.; // Protection tube half length [Pos 2]
+ const Float_t kRB26s3ProtZ = 4.0 ; // Protection tube z-position [Pos 2]
+
+
+ // Mother volume
+ //
+ TGeoPcon* shRB26s3Compensator = new TGeoPcon(0., 360., 6);
+ shRB26s3Compensator->DefineSection( 0, 0.0, 0., kRB26s3CompTubeOuterR1);
+ shRB26s3Compensator->DefineSection( 1, kRB26s3RingZ, 0., kRB26s3CompTubeOuterR1);
+ shRB26s3Compensator->DefineSection( 2, kRB26s3RingZ, 0., kRB26s3ProtOuterR);
+ shRB26s3Compensator->DefineSection( 3, kRB26s3ProtZ + 2. * kRB26s3ProtL, 0., kRB26s3ProtOuterR);
+ shRB26s3Compensator->DefineSection( 4, kRB26s3ProtZ + 2. * kRB26s3ProtL, 0., kRB26s3CompTubeOuterR1);
+ shRB26s3Compensator->DefineSection( 5, kRB26s3CompL , 0., kRB26s3CompTubeOuterR1);
+ TGeoVolume* voRB26s3Compensator =
+ new TGeoVolume("RB26s3Compensator", shRB26s3Compensator, kMedVac);
+
+ //
+ // [Pos 1] Bellow
+ //
+ //
+ TGeoVolume* voRB26s3Bellow = new TGeoVolume("RB26s3Bellow",
+ new TGeoTube(kRB26s3BellowRi, kRB26s3BellowRo, kRB26s3BellowUndL/2.), kMedVac);
+ //
+ // Upper part of the undulation
+ //
+ TGeoTorus* shRB26s3PlieTorusU = new TGeoTorus(kRB26s3BellowRo - kRB26s3PlieR, kRB26s3PlieR - kRB26s3PlieThickness, kRB26s3PlieR);
+ shRB26s3PlieTorusU->SetName("RB26s3TorusU");
+ TGeoTube* shRB26s3PlieTubeU = new TGeoTube (kRB26s3BellowRo - kRB26s3PlieR, kRB26s3BellowRo, kRB26s3PlieR);
+ shRB26s3PlieTubeU->SetName("RB26s3TubeU");
+ TGeoCompositeShape* shRB26s3UpperPlie = new TGeoCompositeShape("RB26s3UpperPlie", "RB26s3TorusU*RB26s3TubeU");
+
+ TGeoVolume* voRB26s3WiggleU = new TGeoVolume("RB26s3UpperPlie", shRB26s3UpperPlie, kMedSteel);
+ //
+ // Lower part of the undulation
+ TGeoTorus* shRB26s3PlieTorusL = new TGeoTorus(kRB26s3BellowRi + kRB26s3PlieR, kRB26s3PlieR - kRB26s3PlieThickness, kRB26s3PlieR);
+ shRB26s3PlieTorusL->SetName("RB26s3TorusL");
+ TGeoTube* shRB26s3PlieTubeL = new TGeoTube (kRB26s3BellowRi, kRB26s3BellowRi + kRB26s3PlieR, kRB26s3PlieR);
+ shRB26s3PlieTubeL->SetName("RB26s3TubeL");
+ TGeoCompositeShape* shRB26s3LowerPlie = new TGeoCompositeShape("RB26s3LowerPlie", "RB26s3TorusL*RB26s3TubeL");
+
+ TGeoVolume* voRB26s3WiggleL = new TGeoVolume("RB26s3LowerPlie", shRB26s3LowerPlie, kMedSteel);
+
+ //
+ // Connection between upper and lower part of undulation
+ TGeoVolume* voRB26s3WiggleC1 = new TGeoVolume("RB26s3PlieConn1",
+ new TGeoTube(kRB26s3BellowRi + kRB26s3PlieR,
+ kRB26s3BellowRo - kRB26s3PlieR, kRB26s3PlieThickness / 2.), kMedSteel);
+ //
+ // One wiggle
+ TGeoVolumeAssembly* voRB26s3Wiggle = new TGeoVolumeAssembly("RB26s3Wiggle");
+ z0 = - kRB26s3PlieThickness / 2.;
+ voRB26s3Wiggle->AddNode(voRB26s3WiggleC1, 1 , new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s3PlieR - kRB26s3PlieThickness / 2.;
+ voRB26s3Wiggle->AddNode(voRB26s3WiggleU, 1 , new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s3PlieR - kRB26s3PlieThickness / 2.;
+ voRB26s3Wiggle->AddNode(voRB26s3WiggleC1, 2 , new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s3PlieR - kRB26s3PlieThickness;
+ voRB26s3Wiggle->AddNode(voRB26s3WiggleL, 1 , new TGeoTranslation(0., 0., z0));
+ // Positioning of the volumes
+ z0 = - kRB26s3BellowUndL/2.+ kRB26s3ConnectionPlieR;
+ voRB26s3Bellow->AddNode(voRB26s3WiggleL, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s3ConnectionPlieR;
+ zsh = 4. * kRB26s3PlieR - 2. * kRB26s3PlieThickness;
+ for (Int_t iw = 0; iw < kRB26s3NumberOfPlies; iw++) {
+ Float_t zpos = z0 + iw * zsh;
+ voRB26s3Bellow->AddNode(voRB26s3Wiggle, iw + 1, new TGeoTranslation(0., 0., zpos - kRB26s3PlieThickness));
+ }
+
+ voRB26s3Compensator->AddNode(voRB26s3Bellow, 1, new TGeoTranslation(0., 0., kRB26s3WeldingTubeLeftL + kRB26s3BellowUndL/2.));
+
+
+ //
+ // [Pos 2] Outer Protecting Tube
+ //
+ TGeoTube* shRB26s3CompProtTube = new TGeoTube(kRB26s3RingOuterR, kRB26s3ProtOuterR, kRB26s3ProtL);
+ TGeoVolume* voRB26s3CompProtTube =
+ new TGeoVolume("RB26s3CompProtTube", shRB26s3CompProtTube, kMedSteel);
+ voRB26s3Compensator->AddNode(voRB26s3CompProtTube, 1, new TGeoTranslation(0., 0., kRB26s3ProtZ + kRB26s3ProtL));
+
+
+ //
+ // [Pos 3] Right Welding Tube
+ //
+ TGeoPcon* shRB26s3CompRightTube = new TGeoPcon(0., 360., 5);
+ z0 = 0.;
+ shRB26s3CompRightTube->DefineSection(0, z0, kRB26s3CompTubeInnerR3, kRB26s3CompTubeOuterR3);
+ z0 += kRB26s3WeldingTubeT2;
+ shRB26s3CompRightTube->DefineSection(1, z0, kRB26s3CompTubeInnerR2, kRB26s3CompTubeOuterR2);
+ z0 += kRB26s3WeldingTubeRightL2;
+ shRB26s3CompRightTube->DefineSection(2, z0, kRB26s3CompTubeInnerR2, kRB26s3CompTubeOuterR2);
+ z0 += kRB26s3WeldingTubeT1;
+ shRB26s3CompRightTube->DefineSection(3, z0, kRB26s3CompTubeInnerR1, kRB26s3CompTubeOuterR1);
+ z0 += kRB26s3WeldingTubeRightL1;
+ shRB26s3CompRightTube->DefineSection(4, z0, kRB26s3CompTubeInnerR1, kRB26s3CompTubeOuterR1);
+
+ TGeoVolume* voRB26s3CompRightTube =
+ new TGeoVolume("RB26s3CompRightTube", shRB26s3CompRightTube, kMedSteel);
+ voRB26s3Compensator->AddNode(voRB26s3CompRightTube, 1, new TGeoTranslation(0., 0., kRB26s3CompL - z0));
+
+ //
+ // [Pos 4] Left Welding Tube
+ //
+ TGeoPcon* shRB26s3CompLeftTube = new TGeoPcon(0., 360., 5);
+ z0 = 0.;
+ shRB26s3CompLeftTube->DefineSection(0, z0, kRB26s3CompTubeInnerR1, kRB26s3CompTubeOuterR1);
+ z0 += kRB26s3WeldingTubeLeftL1;
+ shRB26s3CompLeftTube->DefineSection(1, z0, kRB26s3CompTubeInnerR1, kRB26s3CompTubeOuterR1);
+ z0 += kRB26s3WeldingTubeT1;
+ shRB26s3CompLeftTube->DefineSection(2, z0, kRB26s3CompTubeInnerR2, kRB26s3CompTubeOuterR2);
+ z0 += kRB26s3WeldingTubeLeftL2;
+ shRB26s3CompLeftTube->DefineSection(3, z0, kRB26s3CompTubeInnerR2, kRB26s3CompTubeOuterR2);
+ z0 += kRB26s3WeldingTubeT2;
+ shRB26s3CompLeftTube->DefineSection(4, z0, kRB26s3CompTubeInnerR3, kRB26s3CompTubeOuterR3);
+
+ TGeoVolume* voRB26s3CompLeftTube =
+ new TGeoVolume("RB26s3CompLeftTube", shRB26s3CompLeftTube, kMedSteel);
+ voRB26s3Compensator->AddNode(voRB26s3CompLeftTube, 1, gGeoIdentity);
+ //
+ // [Pos 5] Ring
+ //
+ TGeoTube* shRB26s3CompRing = new TGeoTube(kRB26s3CompTubeOuterR2, kRB26s3RingOuterR, kRB26s3RingL);
+ TGeoVolume* voRB26s3CompRing =
+ new TGeoVolume("RB26s3CompRing", shRB26s3CompRing, kMedSteel);
+ voRB26s3Compensator->AddNode(voRB26s3CompRing, 1, new TGeoTranslation(0., 0., kRB26s3RingZ + kRB26s3RingL));
+
+
+
+ ///////////////////////////////////////////
+ // //
+ // RB26/4-5 //
+ // Drawing LHCV2a_0012 [as installed] //
+ ////////////////////////////////////////////
+ // Pos1 Vacuum Tubes LHCVC2A__0014
+ // Pos2 Compensator LHCVC2A__0066
+ // Pos3 Fixed Point Section LHCVC2A__0016
+ // Pos4 Split Flange LHCVFX___0005
+ // Pos5 RotableFlange LHCVFX___0009
+ ////////////////////////////////////////////
+
+ ///////////////////////////////////
+ // RB26/4-5 Vacuum Tubes //
+ // Drawing LHCVC2a_0014 //
+ ///////////////////////////////////
+ const Float_t kRB26s45TubeL = 593.12 + 0.3; // 0.3 cm added for welding
+
+ TGeoPcon* shRB26s45Tube = new TGeoPcon(0., 360., 11);
+ // Section 1: straight section
+ shRB26s45Tube->DefineSection( 0, 0.00, 30.00/2., 30.60/2.);
+ shRB26s45Tube->DefineSection( 1, 1.20, 30.00/2., 30.60/2.);
+ shRB26s45Tube->DefineSection( 2, 1.20, 30.00/2., 30.80/2.);
+ shRB26s45Tube->DefineSection( 3, 25.10, 30.00/2., 30.80/2.);
+ // Section 2: 0.932 deg opening cone
+ shRB26s45Tube->DefineSection( 4, 486.10, 45.00/2., 45.80/2.);
+ // Section 3: straight section 4 mm
+ shRB26s45Tube->DefineSection( 5, 512.10, 45.00/2., 45.80/2.);
+ // Section 4: straight section 3 mm
+ shRB26s45Tube->DefineSection( 6, 512.10, 45.00/2., 45.60/2.);
+ shRB26s45Tube->DefineSection( 7, 527.70, 45.00/2., 45.60/2.);
+ // Section 4: closing cone
+ shRB26s45Tube->DefineSection( 8, 591.30, 10.00/2., 10.60/2.);
+ shRB26s45Tube->DefineSection( 9, 591.89, 10.00/2., 10.30/2.);
+
+ shRB26s45Tube->DefineSection(10, kRB26s45TubeL, 10.00/2., 10.30/2.);
+ TGeoVolume* voRB26s45Tube =
+ new TGeoVolume("RB26s45Tube", shRB26s45Tube, kMedSteel);
+
+ TGeoVolume* voRB26s45TubeM = new TGeoVolume("RB26s45TubeM", MakeMotherFromTemplate(shRB26s45Tube), kMedVac);
+ voRB26s45TubeM->AddNode(voRB26s45Tube, 1, gGeoIdentity);
+
+
+
+ ///////////////////////////////////
+ // RB26/5 Axial Compensator //
+ // Drawing LHCVC2a_0066 //
+ ///////////////////////////////////
+ const Float_t kRB26s5CompL = 27.60; // Length of the compensator (0.30 cm added for welding)
+ const Float_t kRB26s5BellowRo = 12.48/2.; // Bellow outer radius [Pos 1]
+ const Float_t kRB26s5BellowRi = 10.32/2.; // Bellow inner radius [Pos 1]
+ const Int_t kRB26s5NumberOfPlies = 15; // Number of plies [Pos 1]
+ const Float_t kRB26s5BellowUndL = 10.50; // Length of undulated region [Pos 1]
+ const Float_t kRB26s5PlieThickness = 0.025; // Plie thickness [Pos 1]
+ const Float_t kRB26s5ConnectionPlieR = 0.21; // Connection plie radius [Pos 1]
+ const Float_t kRB26s5ConnectionR = 11.2/2.; // Bellow connection radius [Pos 1]
+ // Plie radius
+ const Float_t kRB26s5PlieR =
+ (kRB26s5BellowUndL - 4. * kRB26s5ConnectionPlieR + 2. * kRB26s5PlieThickness +
+ (2. * kRB26s5NumberOfPlies - 2.) * kRB26s5PlieThickness) / (4. * kRB26s5NumberOfPlies - 2.);
+ const Float_t kRB26s5CompTubeInnerR = 10.00/2.; // Connection tubes inner radius [Pos 2 + 3]
+ const Float_t kRB26s5CompTubeOuterR = 10.30/2.; // Connection tubes outer radius [Pos 2 + 3]
+ const Float_t kRB26s5WeldingTubeLeftL = 3.70/2.; // Left connection tube half length [Pos 2]
+ const Float_t kRB26s5WeldingTubeRightL = 13.40/2.; // Right connection tube half length [Pos 3] (0.3 cm added for welding)
+ const Float_t kRB26s5RingInnerR = 11.2/2.; // Ring inner radius [Pos 4]
+ const Float_t kRB26s5RingOuterR = 16.0/2.; // Ring inner radius [Pos 4]
+ const Float_t kRB26s5RingL = 0.4/2.; // Ring half length [Pos 4]
+ const Float_t kRB26s5RingZ = 14.97; // Ring z-position [Pos 4]
+ const Float_t kRB26s5ProtOuterR = 16.2/2.; // Protection tube outer radius [Pos 5]
+ const Float_t kRB26s5ProtL = 13.0/2.; // Protection tube half length [Pos 5]
+ const Float_t kRB26s5ProtZ = 2.17; // Protection tube z-position [Pos 5]
+ const Float_t kRB26s5DetailZR = 11.3/2.; // Detail Z max radius
+
+
+ // Mother volume
+ //
+ TGeoPcon* shRB26s5Compensator = new TGeoPcon(0., 360., 8);
+ shRB26s5Compensator->DefineSection( 0, 0.0, 0., kRB26s5CompTubeOuterR);
+ shRB26s5Compensator->DefineSection( 1, kRB26s5ProtZ, 0., kRB26s5CompTubeOuterR);
+ shRB26s5Compensator->DefineSection( 2, kRB26s5ProtZ, 0., kRB26s5ProtOuterR);
+ shRB26s5Compensator->DefineSection( 3, kRB26s5ProtZ + 2. * kRB26s5ProtL + 2. * kRB26s5RingL, 0., kRB26s5ProtOuterR);
+ shRB26s5Compensator->DefineSection( 4, kRB26s5ProtZ + 2. * kRB26s5ProtL + 2. * kRB26s5RingL, 0., kRB26s5DetailZR);
+ shRB26s5Compensator->DefineSection( 5, kRB26s5CompL - 8., 0., kRB26s5DetailZR);
+ shRB26s5Compensator->DefineSection( 6, kRB26s5CompL - 8., 0., kRB26s5CompTubeOuterR);
+ shRB26s5Compensator->DefineSection( 7, kRB26s5CompL, 0., kRB26s5CompTubeOuterR);
+ TGeoVolume* voRB26s5Compensator = new TGeoVolume("RB26s5Compensator", shRB26s5Compensator, kMedVac);
+
+ //
+ // [Pos 1] Bellow
+ //
+ //
+ TGeoVolume* voRB26s5Bellow = new TGeoVolume("RB26s5Bellow",
+ new TGeoTube(kRB26s5BellowRi, kRB26s5BellowRo, kRB26s5BellowUndL/2.), kMedVac);
+ //
+ // Upper part of the undulation
+ //
+ TGeoTorus* shRB26s5PlieTorusU = new TGeoTorus(kRB26s5BellowRo - kRB26s5PlieR, kRB26s5PlieR - kRB26s5PlieThickness, kRB26s5PlieR);
+ shRB26s5PlieTorusU->SetName("RB26s5TorusU");
+ TGeoTube* shRB26s5PlieTubeU = new TGeoTube (kRB26s5BellowRo - kRB26s5PlieR, kRB26s5BellowRo, kRB26s5PlieR);
+ shRB26s5PlieTubeU->SetName("RB26s5TubeU");
+ TGeoCompositeShape* shRB26s5UpperPlie = new TGeoCompositeShape("RB26s5UpperPlie", "RB26s5TorusU*RB26s5TubeU");
+
+ TGeoVolume* voRB26s5WiggleU = new TGeoVolume("RB26s5UpperPlie", shRB26s5UpperPlie, kMedSteel);
+ //
+ // Lower part of the undulation
+ TGeoTorus* shRB26s5PlieTorusL = new TGeoTorus(kRB26s5BellowRi + kRB26s5PlieR, kRB26s5PlieR - kRB26s5PlieThickness, kRB26s5PlieR);
+ shRB26s5PlieTorusL->SetName("RB26s5TorusL");
+ TGeoTube* shRB26s5PlieTubeL = new TGeoTube (kRB26s5BellowRi, kRB26s5BellowRi + kRB26s5PlieR, kRB26s5PlieR);
+ shRB26s5PlieTubeL->SetName("RB26s5TubeL");
+ TGeoCompositeShape* shRB26s5LowerPlie = new TGeoCompositeShape("RB26s5LowerPlie", "RB26s5TorusL*RB26s5TubeL");
+
+ TGeoVolume* voRB26s5WiggleL = new TGeoVolume("RB26s5LowerPlie", shRB26s5LowerPlie, kMedSteel);
+
+ //
+ // Connection between upper and lower part of undulation
+ TGeoVolume* voRB26s5WiggleC1 = new TGeoVolume("RB26s5PlieConn1",
+ new TGeoTube(kRB26s5BellowRi + kRB26s5PlieR,
+ kRB26s5BellowRo - kRB26s5PlieR, kRB26s5PlieThickness / 2.), kMedSteel);
+ //
+ // One wiggle
+ TGeoVolumeAssembly* voRB26s5Wiggle = new TGeoVolumeAssembly("RB26s5Wiggle");
+ z0 = - kRB26s5PlieThickness / 2.;
+ voRB26s5Wiggle->AddNode(voRB26s5WiggleC1, 1 , new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s5PlieR - kRB26s5PlieThickness / 2.;
+ voRB26s5Wiggle->AddNode(voRB26s5WiggleU, 1 , new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s5PlieR - kRB26s5PlieThickness / 2.;
+ voRB26s5Wiggle->AddNode(voRB26s5WiggleC1, 2 , new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s5PlieR - kRB26s5PlieThickness;
+ voRB26s5Wiggle->AddNode(voRB26s5WiggleL , 1 , new TGeoTranslation(0., 0., z0));
+ // Positioning of the volumes
+ z0 = - kRB26s5BellowUndL/2.+ kRB26s5ConnectionPlieR;
+ voRB26s5Bellow->AddNode(voRB26s5WiggleL, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s5ConnectionPlieR;
+ zsh = 4. * kRB26s5PlieR - 2. * kRB26s5PlieThickness;
+ for (Int_t iw = 0; iw < kRB26s5NumberOfPlies; iw++) {
+ Float_t zpos = z0 + iw * zsh;
+ voRB26s5Bellow->AddNode(voRB26s5Wiggle, iw + 1, new TGeoTranslation(0., 0., zpos - kRB26s5PlieThickness));
+ }
+
+ voRB26s5Compensator->AddNode(voRB26s5Bellow, 1, new TGeoTranslation(0., 0., 2. * kRB26s5WeldingTubeLeftL + kRB26s5BellowUndL/2.));
+
+ //
+ // [Pos 2] Left Welding Tube
+ //
+ TGeoPcon* shRB26s5CompLeftTube = new TGeoPcon(0., 360., 3);
+ z0 = 0;
+ shRB26s5CompLeftTube->DefineSection(0, z0, kRB26s5CompTubeInnerR, kRB26s5CompTubeOuterR);
+ z0 += 2 * kRB26s5WeldingTubeLeftL - ( kRB26s5ConnectionR - kRB26s5CompTubeOuterR);
+ shRB26s5CompLeftTube->DefineSection(1, z0, kRB26s5CompTubeInnerR, kRB26s5CompTubeOuterR);
+ z0 += ( kRB26s5ConnectionR - kRB26s5CompTubeOuterR);
+ shRB26s5CompLeftTube->DefineSection(2, z0, kRB26s5ConnectionR - 0.15, kRB26s5ConnectionR);
+ TGeoVolume* voRB26s5CompLeftTube = new TGeoVolume("RB26s5CompLeftTube", shRB26s5CompLeftTube, kMedSteel);
+ voRB26s5Compensator->AddNode(voRB26s5CompLeftTube, 1, gGeoIdentity);
+ //
+ // [Pos 3] Right Welding Tube
+ //
+ TGeoPcon* shRB26s5CompRightTube = new TGeoPcon(0., 360., 11);
+ // Detail Z
+ shRB26s5CompRightTube->DefineSection( 0, 0. , kRB26s5CompTubeInnerR + 0.22, 11.2/2.);
+ shRB26s5CompRightTube->DefineSection( 1, 0.05, kRB26s5CompTubeInnerR + 0.18, 11.2/2.);
+ shRB26s5CompRightTube->DefineSection( 2, 0.22, kRB26s5CompTubeInnerR , 11.2/2. - 0.22);
+ shRB26s5CompRightTube->DefineSection( 3, 0.44, kRB26s5CompTubeInnerR , 11.2/2.);
+ shRB26s5CompRightTube->DefineSection( 4, 1.70, kRB26s5CompTubeInnerR , 11.2/2.);
+ shRB26s5CompRightTube->DefineSection( 5, 2.10, kRB26s5CompTubeInnerR , kRB26s5CompTubeOuterR);
+ shRB26s5CompRightTube->DefineSection( 6, 2.80, kRB26s5CompTubeInnerR , kRB26s5CompTubeOuterR);
+ shRB26s5CompRightTube->DefineSection( 7, 2.80, kRB26s5CompTubeInnerR , 11.3/2.);
+ shRB26s5CompRightTube->DefineSection( 8, 3.40, kRB26s5CompTubeInnerR , 11.3/2.);
+ // Normal pipe
+ shRB26s5CompRightTube->DefineSection( 9, 3.50, kRB26s5CompTubeInnerR , kRB26s5CompTubeOuterR);
+ shRB26s5CompRightTube->DefineSection(10, 2. * kRB26s5WeldingTubeRightL, kRB26s5CompTubeInnerR, kRB26s5CompTubeOuterR);
+
+ TGeoVolume* voRB26s5CompRightTube =
+ new TGeoVolume("RB26s5CompRightTube", shRB26s5CompRightTube, kMedSteel);
+ voRB26s5Compensator->AddNode(voRB26s5CompRightTube, 1,
+ new TGeoTranslation(0., 0., kRB26s5CompL - 2. * kRB26s5WeldingTubeRightL));
+ //
+ // [Pos 4] Ring
+ //
+ TGeoTube* shRB26s5CompRing = new TGeoTube(kRB26s5RingInnerR, kRB26s5RingOuterR, kRB26s5RingL);
+ TGeoVolume* voRB26s5CompRing =
+ new TGeoVolume("RB26s5CompRing", shRB26s5CompRing, kMedSteel);
+ voRB26s5Compensator->AddNode(voRB26s5CompRing, 1, new TGeoTranslation(0., 0., kRB26s5RingZ + kRB26s5RingL));
+
+ //
+ // [Pos 5] Outer Protecting Tube
+ //
+ TGeoTube* shRB26s5CompProtTube = new TGeoTube(kRB26s5RingOuterR, kRB26s5ProtOuterR, kRB26s5ProtL);
+ TGeoVolume* voRB26s5CompProtTube =
+ new TGeoVolume("RB26s5CompProtTube", shRB26s5CompProtTube, kMedSteel);
+ voRB26s5Compensator->AddNode(voRB26s5CompProtTube, 1, new TGeoTranslation(0., 0., kRB26s5ProtZ + kRB26s5ProtL));
+
+ ///////////////////////////////////////
+ // RB26/4 Fixed Point Section //
+ // Drawing LHCVC2a_0016 //
+ ///////////////////////////////////////
+ const Float_t kRB26s4TubeRi = 30.30/2. ; // Tube inner radius (0.3 cm added for welding)
+ const Float_t kRB26s4TubeRo = 30.60/2. ; // Tube outer radius
+ const Float_t kRB26s4FixedPointL = 12.63 ; // Length of the fixed point section
+ const Float_t kRB26s4FixedPointZ = 10.53 ; // Position of the ring (0.15 added for welding)
+ const Float_t kRB26s4FixedPointD = 0.595 ; // Width of the ring
+ const Float_t kRB26s4FixedPointR = 31.60/2. ; // Radius of the ring
+
+ TGeoPcon* shRB26s4FixedPoint = new TGeoPcon(0., 360., 6);
+ z0 = 0.;
+ shRB26s4FixedPoint->DefineSection(0, z0, kRB26s4TubeRi, kRB26s4TubeRo);
+ z0 += kRB26s4FixedPointZ;
+ shRB26s4FixedPoint->DefineSection(1, z0, kRB26s4TubeRi, kRB26s4TubeRo);
+ shRB26s4FixedPoint->DefineSection(2, z0, kRB26s4TubeRi, kRB26s4FixedPointR);
+ z0 += kRB26s4FixedPointD;
+ shRB26s4FixedPoint->DefineSection(3, z0, kRB26s4TubeRi, kRB26s4FixedPointR);
+ shRB26s4FixedPoint->DefineSection(4, z0, kRB26s4TubeRi, kRB26s4TubeRo);
+ z0 = kRB26s4FixedPointL;
+ shRB26s4FixedPoint->DefineSection(5, z0, kRB26s4TubeRi, kRB26s4TubeRo);
+ TGeoVolume* voRB26s4FixedPoint = new TGeoVolume("RB26s4FixedPoint", shRB26s4FixedPoint, kMedSteel);
+
+ TGeoVolume* voRB26s4FixedPointM = new TGeoVolume("RB26s4FixedPointM", MakeMotherFromTemplate(shRB26s4FixedPoint), kMedVac);
+ voRB26s4FixedPointM->AddNode(voRB26s4FixedPoint, 1, gGeoIdentity);
+
+
+ ///////////////////////////////////////
+ // RB26/4 Split Flange //
+ // Drawing LHCVFX__0005 //
+ ///////////////////////////////////////
+ const Float_t kRB26s4SFlangeL = 2.99; // Length of the flange
+ const Float_t kRB26s4SFlangeD1 = 0.85; // Length of section 1
+ const Float_t kRB26s4SFlangeD2 = 0.36; // Length of section 2
+ const Float_t kRB26s4SFlangeD3 = 0.73 + 1.05; // Length of section 3
+ const Float_t kRB26s4SFlangeRo = 36.20/2.; // Flange outer radius
+ const Float_t kRB26s4SFlangeRi1 = 30.60/2.; // Flange inner radius section 1
+ const Float_t kRB26s4SFlangeRi2 = 30.00/2.; // Flange inner radius section 2
+ const Float_t kRB26s4SFlangeRi3 = 30.60/2.; // Flange inner radius section 3
+ z0 = 0;
+ TGeoPcon* shRB26s4SFlange = new TGeoPcon(0., 360., 6);
+ z0 = 0.;
+ shRB26s4SFlange->DefineSection(0, z0, kRB26s4SFlangeRi1, kRB26s4SFlangeRo);
+ z0 += kRB26s4SFlangeD1;
+ shRB26s4SFlange->DefineSection(1, z0, kRB26s4SFlangeRi1, kRB26s4SFlangeRo);
+ shRB26s4SFlange->DefineSection(2, z0, kRB26s4SFlangeRi2, kRB26s4SFlangeRo);
+ z0 += kRB26s4SFlangeD2;
+ shRB26s4SFlange->DefineSection(3, z0, kRB26s4SFlangeRi2, kRB26s4SFlangeRo);
+ shRB26s4SFlange->DefineSection(4, z0, kRB26s4SFlangeRi3, kRB26s4SFlangeRo);
+ z0 += kRB26s4SFlangeD3;
+ shRB26s4SFlange->DefineSection(5, z0, kRB26s4SFlangeRi3, kRB26s4SFlangeRo);
+ TGeoVolume* voRB26s4SFlange = new TGeoVolume("RB26s4SFlange", shRB26s4SFlange, kMedSteel);
+
+ TGeoVolume* voRB26s4SFlangeM = new TGeoVolume("RB26s4SFlangeM", MakeMotherFromTemplate(shRB26s4SFlange, 0, 3), kMedVac);
+ voRB26s4SFlangeM->AddNode(voRB26s4SFlange, 1, gGeoIdentity);
+
+ ///////////////////////////////////////
+ // RB26/5 Rotable Flange //
+ // Drawing LHCVFX__0009 //
+ ///////////////////////////////////////
+ const Float_t kRB26s5RFlangeL = 1.86; // Length of the flange
+ const Float_t kRB26s5RFlangeD1 = 0.61; // Length of section 1
+ const Float_t kRB26s5RFlangeD2 = 0.15; // Length of section 2
+ const Float_t kRB26s5RFlangeD3 = 0.60; // Length of section 3
+ const Float_t kRB26s5RFlangeD4 = 0.50; // Length of section 4
+ const Float_t kRB26s5RFlangeRo = 15.20/2.; // Flange outer radius
+ const Float_t kRB26s5RFlangeRi1 = 10.30/2.; // Flange inner radius section 1
+ const Float_t kRB26s5RFlangeRi2 = 10.00/2.; // Flange inner radius section 2
+ const Float_t kRB26s5RFlangeRi3 = 10.30/2.; // Flange inner radius section 3
+ const Float_t kRB26s5RFlangeRi4 = 10.50/2.; // Flange inner radius section 4
+
+ z0 = 0;
+ TGeoPcon* shRB26s5RFlange = new TGeoPcon(0., 360., 8);
+ z0 = 0.;
+ shRB26s5RFlange->DefineSection(0, z0, kRB26s5RFlangeRi4, kRB26s5RFlangeRo);
+ z0 += kRB26s5RFlangeD4;
+ shRB26s5RFlange->DefineSection(1, z0, kRB26s5RFlangeRi4, kRB26s5RFlangeRo);
+ shRB26s5RFlange->DefineSection(2, z0, kRB26s5RFlangeRi3, kRB26s5RFlangeRo);
+ z0 += kRB26s5RFlangeD3;
+ shRB26s5RFlange->DefineSection(3, z0, kRB26s5RFlangeRi3, kRB26s5RFlangeRo);
+ shRB26s5RFlange->DefineSection(4, z0, kRB26s5RFlangeRi2, kRB26s5RFlangeRo);
+ z0 += kRB26s5RFlangeD2;
+ shRB26s5RFlange->DefineSection(5, z0, kRB26s5RFlangeRi2, kRB26s5RFlangeRo);
+ shRB26s5RFlange->DefineSection(6, z0, kRB26s5RFlangeRi1, kRB26s5RFlangeRo);
+ z0 += kRB26s5RFlangeD1;
+ shRB26s5RFlange->DefineSection(7, z0, kRB26s5RFlangeRi1, kRB26s5RFlangeRo);
+ TGeoVolume* voRB26s5RFlange = new TGeoVolume("RB26s5RFlange", shRB26s5RFlange, kMedSteel);
+
+ TGeoVolume* voRB26s5RFlangeM = new TGeoVolume("RB26s5RFlangeM", MakeMotherFromTemplate(shRB26s5RFlange, 4, 7), kMedVac);
+ voRB26s5RFlangeM->AddNode(voRB26s5RFlange, 1, gGeoIdentity);
+
+ //
+ // Assemble RB26/1-2
+ //
+ TGeoVolumeAssembly* asRB26s12 = new TGeoVolumeAssembly("RB26s12");
+ z0 = 0.;
+ asRB26s12->AddNode(voRB26s1RFlange, 1, gGeoIdentity);
+ z0 += kRB26s1RFlangeIsL + kRB26s1RFlangeFpL;
+ asRB26s12->AddNode(voRB26s12TubeM, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s12TubeL;
+ asRB26s12->AddNode(voRB26s2Compensator, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s2CompL;
+ z0 -= kRB26s2FFlangeD1;
+ asRB26s12->AddNode(voRB26s2FFlangeM, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s2FFlangeL;
+ const Float_t kRB26s12L = z0;
+
+ //
+ // Assemble RB26/3
+ //
+ TGeoVolumeAssembly* asRB26s3 = new TGeoVolumeAssembly("RB26s3");
+ z0 = 0.;
+ asRB26s3->AddNode(voRB26s3SFlangeM, 1, gGeoIdentity);
+ z0 += kRB26s3SFlangeL;
+ z0 -= kRB26s3SFlangeD3;
+ asRB26s3->AddNode(voRB26s3FixedPointM, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s3FixedPointL;
+ asRB26s3->AddNode(voRB26s3TubeM, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s3TubeL;
+ asRB26s3->AddNode(voRB26s3Compensator, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s3CompL;
+ z0 -= kRB26s3FFlangeD1;
+ asRB26s3->AddNode(voRB26s3FFlangeM, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s3FFlangeL;
+ const Float_t kRB26s3L = z0;
+
+
+ //
+ // Assemble RB26/4-5
+ //
+ TGeoVolumeAssembly* asRB26s45 = new TGeoVolumeAssembly("RB26s45");
+ z0 = 0.;
+ asRB26s45->AddNode(voRB26s4SFlangeM, 1, gGeoIdentity);
+ z0 += kRB26s4SFlangeL;
+ z0 -= kRB26s4SFlangeD3;
+ asRB26s45->AddNode(voRB26s4FixedPointM, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s4FixedPointL;
+ asRB26s45->AddNode(voRB26s45TubeM, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s45TubeL;
+ asRB26s45->AddNode(voRB26s5Compensator, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s5CompL;
+ z0 -= kRB26s5RFlangeD3;
+ z0 -= kRB26s5RFlangeD4;
+ asRB26s45->AddNode(voRB26s5RFlangeM, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s5RFlangeL;
+ const Float_t kRB26s45L = z0;
+
+ //
+ // Assemble RB26
+ //
+ TGeoVolumeAssembly* asRB26Pipe = new TGeoVolumeAssembly("RB26Pipe");
+ z0 = 0.;
+ asRB26Pipe->AddNode(asRB26s12, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s12L;
+ asRB26Pipe->AddNode(asRB26s3, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s3L;
+ asRB26Pipe->AddNode(asRB26s45, 1, new TGeoTranslation(0., 0., z0));
+ z0 += kRB26s45L;
+ top->AddNode(asRB26Pipe, 1, new TGeoCombiTrans(0., 0., -82., rot180));
+}
+
+
+
+//___________________________________________
+void AliPIPEv4::CreateMaterials()
+{
+ //
+ // Define materials for beam pipe
+ //
+
+ AliDebugClass(1,"Create PIPEv4 materials");
+ Int_t isxfld = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();
+ Float_t sxmgmx = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();
+ // Steel (Inox)
+ Float_t asteel[4] = { 55.847,51.9961,58.6934,28.0855 };
+ Float_t zsteel[4] = { 26.,24.,28.,14. };
+ Float_t wsteel[4] = { .715,.18,.1,.005 };
+ // AlBe - alloy
+ Float_t aAlBe[2] = { 26.98, 9.01};
+ Float_t zAlBe[2] = { 13.00, 4.00};
+ Float_t wAlBe[2] = { 0.4, 0.6};
+ //
+ // Polyamid
+ Float_t aPA[4] = {16., 14., 12., 1.};
+ Float_t zPA[4] = { 8., 7., 6., 1.};
+ Float_t wPA[4] = { 1., 1., 6., 11.};
+ //
+ // Air
+ //
+ Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
+ Float_t zAir[4]={6.,7.,8.,18.};
+ Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
+ Float_t dAir = 1.20479E-3;
+ Float_t dAir1 = 1.20479E-10;
+ //
+ // Insulation powder
+ // Si O Ti Al
+ Float_t ains[4] ={28.0855, 15.9994, 47.867, 26.982};
+ Float_t zins[4] ={14., 8. , 22. , 13. };
+ Float_t wins[4] ={ 0.3019, 0.4887, 0.1914, 0.018};
+ //
+ //
+ // Anticorodal
+ //
+ // Al Si7 Mg 0.6
+ //
+ Float_t aaco[3] ={26.982, 28.0855, 24.035};
+ Float_t zaco[3] ={13., 14. , 12. };
+ Float_t waco[3] ={ 0.924, 0.07, 0.006};
+ // Kapton
+ //
+ Float_t aKapton[4]={1.00794,12.0107, 14.010,15.9994};
+ Float_t zKapton[4]={1.,6.,7.,8.};
+ Float_t wKapton[4]={0.026362,0.69113,0.07327,0.209235};
+ Float_t dKapton = 1.42;
+ // NEG coating
+ // Ti V Zr
+ Float_t aNEG[4] = {47.87, 50.94, 91.24};
+ Float_t zNEG[4] = {22.00, 23.00, 40.00};
+ Float_t wNEG[4] = {1./3., 1./3., 1./3.};
+ Float_t dNEG = 5.6; // ?
+
+ //
+ //
+ // Berillium
+ AliMaterial(5, "BERILLIUM$", 9.01, 4., 1.848, 35.3, 36.7);
+ //
+ // Carbon
+ AliMaterial(6, "CARBON$ ", 12.01, 6., 2.265, 18.8, 49.9);
+ //
+ // Aluminum
+ AliMaterial(9, "ALUMINIUM$", 26.98, 13., 2.7, 8.9, 37.2);
+ //
+ // Copper
+ AliMaterial(10, "COPPER", 63.55, 29, 8.96, 1.43, 85.6/8.96);
+ //
+ // Air
+ AliMixture(15, "AIR$ ", aAir, zAir, dAir, 4, wAir);
+ AliMixture(35, "AIR_HIGH$ ", aAir, zAir, dAir, 4, wAir);
+ //
+ // Vacuum
+ AliMixture(16, "VACUUM$ ", aAir, zAir, dAir1, 4, wAir);
+ //
+ // stainless Steel
+ AliMixture(19, "STAINLESS STEEL$", asteel, zsteel, 7.88, 4, wsteel);
+ //
+ // reduced density steel to approximate pump getter material
+ AliMixture(20, "GETTER$", asteel, zsteel, 1.00, 4, wsteel);
+ // Al-Be alloy
+ //
+ AliMixture(21, "AlBe$", aAlBe, zAlBe, 2.07, 2, wAlBe);
+ // Polyamid
+ //
+ AliMixture(22, "PA$", aPA, zPA, 1.14, -4, wPA);
+ //
+ // Kapton
+ AliMixture(23, "KAPTON", aKapton, zKapton, dKapton, 4, wKapton);
+ // Anticorodal
+ AliMixture(24, "ANTICORODAL", aaco, zaco, 2.66, 3, waco);
+
+ //
+ // Insulation powder
+ AliMixture(14, "INSULATION0$", ains, zins, 0.41, 4, wins);
+ AliMixture(34, "INSULATION1$", ains, zins, 0.41, 4, wins);
+ AliMixture(54, "INSULATION2$", ains, zins, 0.41, 4, wins);
+
+ // NEG
+ AliMixture(25, "NEG COATING", aNEG, zNEG, dNEG, -3, wNEG);
+
+
+ // ****************
+ // Defines tracking media parameters.
+ //
+ Float_t epsil = .001; // Tracking precision,
+ Float_t stemax = -0.01; // Maximum displacement for multiple scat
+ Float_t tmaxfd = -20.; // Maximum angle due to field deflection
+ Float_t deemax = -.3; // Maximum fractional energy loss, DLS
+ Float_t stmin = -.8;
+ // ***************
+ //
+ // Beryllium
+
+ AliMedium(5, "BE", 5, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+
+ // Carbon
+ AliMedium(6, "C", 6, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+ //
+ // Aluminum
+ AliMedium(9, "ALU", 9, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+ // Copper
+ AliMedium(10, "CU", 10, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+ //
+ // Air
+ AliMedium(15, "AIR", 15, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+ AliMedium(35, "AIR_HIGH",35, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+ //
+ // Vacuum
+ AliMedium(16, "VACUUM", 16, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+ //
+ // Steel
+ AliMedium(19, "INOX", 19, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+ //
+ // Getter
+ AliMedium(20, "GETTER", 20, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+ //
+ // AlBe - Aloy
+ AliMedium(21, "AlBe" , 21, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+ //
+ // Polyamid
+ AliMedium(22, "PA" , 22, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+ // Antocorodal
+ AliMedium(24, "ANTICORODAL", 24, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+ // Insulation Powder
+ AliMedium(14, "INS_C0 ", 14, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+ AliMedium(34, "INS_C1 ", 34, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+ AliMedium(54, "INS_C2 ", 54, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+ //
+ // KAPTON
+ AliMedium(23, "KAPTON", 23, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+
+ //
+ // NEG
+ AliMedium(25, "NEG COATING", 25, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
+}
+
+
+TGeoPcon* AliPIPEv4::MakeMotherFromTemplate(TGeoPcon* shape, Int_t imin, Int_t imax, Float_t r0, Int_t nz)
+{
+ //
+ // Create a mother shape from a template setting some min radii to 0
+ //
+ Int_t nz0 = shape->GetNz();
+ // if nz > -1 the number of planes is given by nz
+ if (nz != -1) nz0 = nz;
+ TGeoPcon* mother = new TGeoPcon(0., 360., nz0);
+
+ if (imin == -1 || imax == -1) {
+ imin = 0;
+ imax = shape->GetNz();
+ } else if (imax >= nz0) {
+ imax = nz0 - 1;
+ printf("Warning: imax reset to nz-1 %5d %5d %5d %5d\n", imin, imax, nz, nz0);
+ }
+
+
+
+ for (Int_t i = 0; i < shape->GetNz(); i++) {
+ Double_t rmin = shape->GetRmin(i);
+ if ((i >= imin) && (i <= imax) ) rmin = r0;
+ Double_t rmax = shape->GetRmax(i);
+ Double_t z = shape->GetZ(i);
+ mother->DefineSection(i, z, rmin, rmax);
+ }
+ return mother;
+
+}
+
+TGeoPcon* AliPIPEv4::MakeInsulationFromTemplate(TGeoPcon* shape)
+{
+ //
+ // Create an beam pipe insulation layer shape from a template
+ //
+ Int_t nz = shape->GetNz();
+ TGeoPcon* insu = new TGeoPcon(0., 360., nz);
+
+ for (Int_t i = 0; i < nz; i++) {
+ Double_t z = shape->GetZ(i);
+ Double_t rmin = shape->GetRmin(i);
+ Double_t rmax = shape->GetRmax(i);
+ rmax += 0.5;
+ shape->DefineSection(i, z, rmin, rmax);
+ rmin = rmax - 0.5;
+ insu->DefineSection(i, z, rmin, rmax);
+ }
+ return insu;
+
+}
+
+
+TGeoVolume* AliPIPEv4::MakeBellow(const char* ext, Int_t nc, Float_t rMin, Float_t rMax, Float_t dU, Float_t rPlie, Float_t dPlie)
+{
+ // nc Number of convolution
+ // rMin Inner radius of the bellow
+ // rMax Outer radius of the bellow
+ // dU Undulation length
+ // rPlie Plie radius
+ // dPlie Plie thickness
+ const TGeoMedium* kMedVac = gGeoManager->GetMedium("PIPE_VACUUM");
+ const TGeoMedium* kMedSteel = gGeoManager->GetMedium("PIPE_INOX");
+
+ char name[64], nameA[64], nameB[64], bools[64];
+ sprintf(name, "%sBellowUS", ext);
+ TGeoVolume* voBellow = new TGeoVolume(name, new TGeoTube(rMin, rMax, dU/2.), kMedVac);
+ //
+ // Upper part of the undulation
+ //
+ TGeoTorus* shPlieTorusU = new TGeoTorus(rMax - rPlie, rPlie - dPlie, rPlie);
+ sprintf(nameA, "%sTorusU", ext);
+ shPlieTorusU->SetName(nameA);
+ TGeoTube* shPlieTubeU = new TGeoTube (rMax - rPlie, rMax, rPlie);
+ sprintf(nameB, "%sTubeU", ext);
+ shPlieTubeU->SetName(nameB);
+ sprintf(name, "%sUpperPlie", ext);
+ sprintf(bools, "%s*%s", nameA, nameB);
+ TGeoCompositeShape* shUpperPlie = new TGeoCompositeShape(name, bools);
+
+ TGeoVolume* voWiggleU = new TGeoVolume(name, shUpperPlie, kMedSteel);
+ //
+ // Lower part of the undulation
+ TGeoTorus* shPlieTorusL = new TGeoTorus(rMin + rPlie, rPlie - dPlie, rPlie);
+ sprintf(nameA, "%sTorusL", ext);
+ shPlieTorusL->SetName(nameA);
+ TGeoTube* shPlieTubeL = new TGeoTube (rMin, rMin + rPlie, rPlie);
+ sprintf(nameB, "%sTubeL", ext);
+ shPlieTubeL->SetName(nameB);
+ sprintf(name, "%sLowerPlie", ext);
+ sprintf(bools, "%s*%s", nameA, nameB);
+ TGeoCompositeShape* shLowerPlie = new TGeoCompositeShape(name, bools);
+
+ TGeoVolume* voWiggleL = new TGeoVolume(name, shLowerPlie, kMedSteel);
+
+ //
+ // Connection between upper and lower part of undulation
+ sprintf(name, "%sPlieConn1", ext);
+ TGeoVolume* voWiggleC1 = new TGeoVolume(name, new TGeoTube(rMin + rPlie, rMax - rPlie, dPlie/2.), kMedSteel);
+ //
+ // One wiggle
+ Float_t dz = rPlie - dPlie / 2.;
+ Float_t z0 = - dPlie / 2.;
+ sprintf(name, "%sWiggle", ext);
+ TGeoVolumeAssembly* asWiggle = new TGeoVolumeAssembly(name);
+ asWiggle->AddNode(voWiggleC1, 1 , new TGeoTranslation(0., 0., z0));
+ z0 += dz;
+ asWiggle->AddNode(voWiggleU, 1 , new TGeoTranslation(0., 0., z0));
+ z0 += dz;
+ asWiggle->AddNode(voWiggleC1, 2 , new TGeoTranslation(0., 0., z0));
+ z0 += dz;
+ asWiggle->AddNode(voWiggleL , 1 , new TGeoTranslation(0., 0., z0));
+ // Positioning of the volumes
+ z0 = - dU / 2.+ rPlie;
+ voBellow->AddNode(voWiggleL, 2, new TGeoTranslation(0., 0., z0));
+ z0 += rPlie;
+ Float_t zsh = 4. * rPlie - 2. * dPlie;
+ for (Int_t iw = 0; iw < nc; iw++) {
+ Float_t zpos = z0 + iw * zsh;
+ voBellow->AddNode(asWiggle, iw + 1, new TGeoTranslation(0., 0., zpos - dPlie));
+ }
+ return voBellow;
+}
+
+
+
+
--- /dev/null
+#ifndef ALIPIPEVGEO4_H
+#define ALIPIPEVGEO4_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$*/
+
+/////////////////////////////////////////////////////////
+// ALICE beam pipe geometry //
+// This version uses TGeo. //
+// Author: //
+// Andreas Morsch //
+// e-mail: andreas.morsch@cern.ch //
+/////////////////////////////////////////////////////////
+
+#include "AliPIPE.h"
+class TGeoPcon;
+class TGeoVolume;
+
+
+class AliPIPEv4 : public AliPIPE {
+
+ public:
+ enum constants {kC=6, kAlu=9, kInox=19, kGetter=20, kBe=5, kVac=16,
+ kAir=15, kAlBe=21, kPA = 22};
+
+ AliPIPEv4();
+ AliPIPEv4(const char *name, const char *title);
+ AliPIPEv4(const char *name, const char *title, const Float_t theta_cone, const Float_t rmin1,
+ const Float_t epaisseur, const Float_t sigmaz, const Float_t z_chambre);
+ virtual ~AliPIPEv4() {};
+ virtual void CreateGeometry();
+ virtual void CreateMaterials();
+ virtual Int_t IsVersion() const {return 0;}
+ private:
+ virtual TGeoPcon* MakeMotherFromTemplate(TGeoPcon* shape, Int_t imin = -1, Int_t imax = -1, Float_t r0 = 0., Int_t nz =-1);
+ virtual TGeoPcon* MakeInsulationFromTemplate(TGeoPcon* shape);
+ virtual TGeoVolume* MakeBellow(const char* ext, Int_t nc, Float_t rMin, Float_t rMax, Float_t dU, Float_t rPlie, Float_t dPlie);
+
+ Float_t ftheta_cone; // angle of conical beam pipe, if angle < 3 --> cylindrical beam pipe
+ Float_t frmin1; // internal radius of Be beam pipe
+ Float_t fepaisseur; // width of Be beam pipe
+ Float_t fsigmaz; // dispersion of z location (1 sigma) of beam impact position
+ Float_t fz_chambre; // first pixel chamber location, closest to the IP
+ Float_t fzdebut1; // beginning of beam pipe z location (A side)
+ Float_t fzfin4; // end of beamp pipe z location (C side)
+
+
+ protected:
+ ClassDef(AliPIPEv4,1) //Class for PIPE version using TGeo
+};
+
+#endif
AliPIPE.cxx
AliPIPEv0.cxx
AliPIPEv3.cxx
+ AliPIPEv4.cxx
AliBODY.cxx
AliSHILv2.cxx
AliSHILv3.cxx
#pragma link C++ class AliPIPE+;
#pragma link C++ class AliPIPEv0+;
#pragma link C++ class AliPIPEv3+;
+#pragma link C++ class AliPIPEv4+;
#pragma link C++ class AliSHIL+;
#pragma link C++ class AliSHILv0+;
#pragma link C++ class AliSHILv2+;
#list of detectors
#set(ONLINEDETECTORS T00)
-set(ONLINEDETECTORS SPD SDD SSD ACO GRP TST HLT EMC TRI T00 PMD CPV PHS FMD TPC TRD ZDC V00 MTR MCH HMP TOF)
+set(ONLINEDETECTORS SPD SDD SSD ACO GRP TST HLT EMC TRI T00 PMD CPV PHS FMD TPC TRD ZDC V00 MTR MCH HMP TOF MFT)
function(expand output input)
string(REGEX MATCH "\\\${[^}]*}" m "${input}")
while(m)
#function to get module for detector
function (detector_module _module detector)
#Map of online detectors to DA in pairs of ONLINEDETECTORNAME DAMODULE
- set (DETECTORMODULEMAP SPD ITS SDD ITS SSD ITS HMP HMPID PHS PHOS CPV PHOS MCH MUON MTR MUON T00 T0 V00 VZERO ACO ACORDE EMC EMCAL)
+ set (DETECTORMODULEMAP SPD ITS SDD ITS SSD ITS HMP HMPID PHS PHOS CPV PHOS MCH MUON MTR MUON T00 T0 V00 VZERO ACO ACORDE EMC EMCAL MFT)
list(FIND DETECTORMODULEMAP ${detector} _index)
if(_index STREQUAL "-1")
set(${_module} "${detector}" PARENT_SCOPE)
if ( gSystem->Load("libHLTinterface") < 0 ) return ret; ret--;
if ( gSystem->Load("libHLTsim") < 0 ) return ret; ret--;
if ( gSystem->Load("libHLTrec") < 0 ) return ret; ret--;
+
+ #ifdef MFT_UPGRADE
+ if ( gSystem->Load("libMFTbase") < 0 ) return ret; ret--;
+ if ( gSystem->Load("libMFTrec") < 0 ) return ret; ret--;
+ if ( gSystem->Load("libMFTsim") < 0 ) return ret; ret--;
+ #endif
+
return 0;
if ( gSystem->Load("libTOFbase") < 0 ) return ret; ret--;
if ( gSystem->Load("libTOFrec") < 0 ) return ret; ret--;
if ( gSystem->Load("libTOFsim") < 0 ) return ret; ret--;
-
+ #ifdef MFT_UPGRADE
+ if ( gSystem->Load("libMFTbase") < 0 ) return ret; ret--;
+ if ( gSystem->Load("libMFTrec") < 0 ) return ret; ret--;
+ if ( gSystem->Load("libMFTsim") < 0 ) return ret; ret--;
+ #endif
if ( gSystem->Load("libHLTbase") < 0 ) return ret; ret--;
return 0;
if ( gSystem->Load("libHLTinterface") < 0 ) return ret; ret--;
if ( gSystem->Load("libHLTsim") < 0 ) return ret; ret--;
if ( gSystem->Load("libHLTrec") < 0 ) return ret; ret--;
-
+
+ #ifdef MFT_UPGRADE
+ if ( gSystem->Load("libMFTbase") < 0 ) return ret; ret--;
+ if ( gSystem->Load("libMFTrec") < 0 ) return ret; ret--;
+ if ( gSystem->Load("libMFTsim") < 0 ) return ret; ret--;
+ #endif
+
+
return 0;
}