From aafdfba82a17f22ffb7fec589f7a772799f3342c Mon Sep 17 00:00:00 2001 From: chkouzin Date: Mon, 13 Oct 2014 10:24:09 +0200 Subject: [PATCH] Initial commit of the ITS simulation code --- AliBase/CMakeLists.txt | 34 + AliBase/O2BaseLinkDef.h | 13 + AliBase/O2Detector.cxx | 121 ++ AliBase/O2Detector.h | 62 + AliBase/O2Module.cxx | 91 + AliBase/O2Module.h | 53 + AliBase/O2TrackReference.cxx | 168 ++ AliBase/O2TrackReference.h | 103 ++ CMakeLists.txt | 1 + its/AliGeomManager.cxx | 141 ++ its/AliGeomManager.h | 54 + its/AliITSUGeomTGeo.cxx | 1020 +++++++++++ its/AliITSUGeomTGeo.h | 382 +++++ its/AliITSUSegmentationPix.cxx | 575 +++++++ its/AliITSUSegmentationPix.h | 113 ++ its/AliITSUv1Layer.cxx | 2930 ++++++++++++++++++++++++++++++++ its/AliITSUv1Layer.h | 184 ++ its/AliITSsegmentation.cxx | 59 + its/AliITSsegmentation.h | 112 ++ its/AliITSv11Geometry.cxx | 1549 +++++++++++++++++ its/AliITSv11Geometry.h | 197 +++ its/AliIts.cxx | 225 --- its/AliIts.h | 106 -- its/AliItsContFact.cxx | 59 - its/AliItsContFact.h | 26 - its/AliItsGeo.cxx | 43 - its/AliItsGeo.h | 38 - its/AliItsGeoPar.cxx | 50 - its/AliItsGeoPar.h | 43 - its/AliItsLinkDef.h | 20 - its/AliItsPoint.cxx | 51 - its/AliItsPoint.h | 56 - its/CMakeLists.txt | 41 +- its/O2its.cxx | 968 +++++++++++ its/O2its.h | 237 +++ its/O2itsContFact.cxx | 51 + its/O2itsContFact.h | 19 + its/O2itsDigi.cxx | 28 + its/O2itsDigi.h | 73 + its/O2itsDigiTask.cxx | 99 ++ its/O2itsDigiTask.h | 45 + its/O2itsGeoHandler.cxx | 197 +++ its/O2itsGeoHandler.h | 82 + its/O2itsLinkDef.h | 21 + its/O2itsMisalignPar.cxx | 70 + its/O2itsMisalignPar.h | 48 + its/O2itsPoint.cxx | 49 + its/O2itsPoint.h | 70 + macro/run_sim.C | 316 ++-- 49 files changed, 10233 insertions(+), 860 deletions(-) create mode 100644 AliBase/CMakeLists.txt create mode 100644 AliBase/O2BaseLinkDef.h create mode 100644 AliBase/O2Detector.cxx create mode 100644 AliBase/O2Detector.h create mode 100644 AliBase/O2Module.cxx create mode 100644 AliBase/O2Module.h create mode 100644 AliBase/O2TrackReference.cxx create mode 100644 AliBase/O2TrackReference.h create mode 100644 its/AliGeomManager.cxx create mode 100644 its/AliGeomManager.h create mode 100644 its/AliITSUGeomTGeo.cxx create mode 100644 its/AliITSUGeomTGeo.h create mode 100644 its/AliITSUSegmentationPix.cxx create mode 100644 its/AliITSUSegmentationPix.h create mode 100644 its/AliITSUv1Layer.cxx create mode 100644 its/AliITSUv1Layer.h create mode 100644 its/AliITSsegmentation.cxx create mode 100644 its/AliITSsegmentation.h create mode 100644 its/AliITSv11Geometry.cxx create mode 100644 its/AliITSv11Geometry.h delete mode 100644 its/AliIts.cxx delete mode 100644 its/AliIts.h delete mode 100644 its/AliItsContFact.cxx delete mode 100644 its/AliItsContFact.h delete mode 100644 its/AliItsGeo.cxx delete mode 100644 its/AliItsGeo.h delete mode 100644 its/AliItsGeoPar.cxx delete mode 100644 its/AliItsGeoPar.h delete mode 100644 its/AliItsLinkDef.h delete mode 100644 its/AliItsPoint.cxx delete mode 100644 its/AliItsPoint.h create mode 100644 its/O2its.cxx create mode 100644 its/O2its.h create mode 100644 its/O2itsContFact.cxx create mode 100644 its/O2itsContFact.h create mode 100644 its/O2itsDigi.cxx create mode 100644 its/O2itsDigi.h create mode 100644 its/O2itsDigiTask.cxx create mode 100644 its/O2itsDigiTask.h create mode 100644 its/O2itsGeoHandler.cxx create mode 100644 its/O2itsGeoHandler.h create mode 100644 its/O2itsLinkDef.h create mode 100644 its/O2itsMisalignPar.cxx create mode 100644 its/O2itsMisalignPar.h create mode 100644 its/O2itsPoint.cxx create mode 100644 its/O2itsPoint.h mode change 100755 => 100644 macro/run_sim.C diff --git a/AliBase/CMakeLists.txt b/AliBase/CMakeLists.txt new file mode 100644 index 0000000000000..d2e131d90e9d3 --- /dev/null +++ b/AliBase/CMakeLists.txt @@ -0,0 +1,34 @@ +# Create a library called "O2MCStack" which includes the source files given in +# the array . +# The extension is already found. Any number of sources could be listed here. + +set(INCLUDE_DIRECTORIES +${ROOT_INCLUDE_DIR} +${BASE_INCLUDE_DIRECTORIES} +${CMAKE_SOURCE_DIR}/AliBase +) + +include_directories( ${INCLUDE_DIRECTORIES}) + +set(LINK_DIRECTORIES +${ROOT_LIBRARY_DIR} +${FAIRROOT_LIBRARY_DIR} +${CMAKE_SOURCE_DIR}/AliBase + +) + +link_directories( ${LINK_DIRECTORIES}) + +set(SRCS +O2Module.cxx +O2Detector.cxx +O2TrackReference.cxx +) + +Set(HEADERS) +Set(LINKDEF O2BaseLinkDef.h) +Set(LIBRARY_NAME O2Base) +Set(DEPENDENCIES Base EG Physics Cint Core) + +GENERATE_LIBRARY() + diff --git a/AliBase/O2BaseLinkDef.h b/AliBase/O2BaseLinkDef.h new file mode 100644 index 0000000000000..24f953be23574 --- /dev/null +++ b/AliBase/O2BaseLinkDef.h @@ -0,0 +1,13 @@ + +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class O2Module+; +#pragma link C++ class O2Detector+; +#pragma link C++ class O2TrackReference+; + +#endif + diff --git a/AliBase/O2Detector.cxx b/AliBase/O2Detector.cxx new file mode 100644 index 0000000000000..2586fdb68fac1 --- /dev/null +++ b/AliBase/O2Detector.cxx @@ -0,0 +1,121 @@ +#include "O2Detector.h" + +#include +#include + + +using std::endl; +using std::cout; +using std::fstream; +using std::ios; +using std::ostream; + +ClassImp(O2Detector) + +Float_t O2Detector::fgDensityFactor = 1.0; + +//_______________________________________________________________________ +O2Detector::O2Detector(): +FairDetector() +{ + // + // Default constructor for the O2Detector class + // +} + +//_______________________________________________________________________ +O2Detector::O2Detector(const char* name,Bool_t Active, Int_t DetId): + FairDetector(name,Active,DetId) +{ +} + +//_______________________________________________________________________ +O2Detector::~O2Detector() +{ + +} + +//_______________________________________________________________________ +void O2Detector::AliMaterial(Int_t imat, const char* name, Float_t a, + Float_t z, Float_t dens, Float_t radl, + Float_t absl, Float_t *buf, Int_t nwbuf) const +{ + TString uniquename = GetName(); + uniquename.Append("_"); + uniquename.Append(name); + + //Check this!!! + gMC->Material(imat, uniquename.Data(), a, z, dens * fgDensityFactor, radl, absl, buf, nwbuf); +} + + +//_______________________________________________________________________ +void O2Detector::AliMixture(Int_t imat, const char *name, Float_t *a, + Float_t *z, Float_t dens, Int_t nlmat, + Float_t *wmat) const +{ + TString uniquename = GetName(); + uniquename.Append("_"); + uniquename.Append(name); + + //Check this!!! + gMC->Mixture(imat, uniquename.Data(), a, z, dens * fgDensityFactor, nlmat, wmat); +} + +//_______________________________________________________________________ +void O2Detector::AliMedium(Int_t numed, const char *name, Int_t nmat, + Int_t isvol, Int_t ifield, Float_t fieldm, + Float_t tmaxfd, Float_t stemax, Float_t deemax, + Float_t epsil, Float_t stmin, Float_t *ubuf, + Int_t nbuf) const +{ + TString uniquename = GetName(); + uniquename.Append("_"); + uniquename.Append(name); + + //Check this!!! + gMC->Medium(numed, uniquename.Data(), nmat, isvol, ifield, + fieldm, tmaxfd, stemax, deemax, epsil, stmin, ubuf, nbuf); +} + +//_______________________________________________________________________ +void O2Detector::AliMatrix(Int_t &nmat, Float_t theta1, Float_t phi1, + Float_t theta2, Float_t phi2, Float_t theta3, + Float_t phi3) const +{ + // + // Define a rotation matrix. Angles are in degrees. + // + // nmat on output contains the number assigned to the rotation matrix + // theta1 polar angle for axis I + // phi1 azimuthal angle for axis I + // theta2 polar angle for axis II + // phi2 azimuthal angle for axis II + // theta3 polar angle for axis III + // phi3 azimuthal angle for axis III + // + gMC->Matrix(nmat, theta1, phi1, theta2, phi2, theta3, phi3); +} + +void O2Detector::DefineWrapVolume(Int_t id, Double_t rmin,Double_t rmax, Double_t zspan) +{ +} + +void O2Detector::SetNWrapVolumes(Int_t n) +{ +} + +void O2Detector::DefineLayer(const Int_t nlay, const double phi0, const Double_t r, + const Double_t zlen, const Int_t nladd, + const Int_t nmod, const Double_t lthick, + const Double_t dthick, const UInt_t dettypeID, + const Int_t buildLevel) +{ +} + +void O2Detector::DefineLayerTurbo(Int_t nlay, Double_t phi0, Double_t r, Double_t zlen, Int_t nladd, + Int_t nmod, Double_t width, Double_t tilt, + Double_t lthick,Double_t dthick, + UInt_t dettypeID, Int_t buildLevel) +{ +} diff --git a/AliBase/O2Detector.h b/AliBase/O2Detector.h new file mode 100644 index 0000000000000..632a800825fa2 --- /dev/null +++ b/AliBase/O2Detector.h @@ -0,0 +1,62 @@ +#ifndef O2DETECTOR_H +#define O2DETECTOR_H + +// +// This is the basic class for any +// ALICE detector module, whether it is +// sensitive or not. Detector classes depend +// on this. +// + +#include "FairDetector.h" + +class O2Detector : public FairDetector { +public: + + // Creators - distructors + O2Detector(const char* name, Bool_t Active, Int_t DetId=0); + O2Detector(); + virtual ~O2Detector(); + + // Module composition + virtual void AliMaterial(Int_t imat, const char* name, Float_t a, + Float_t z, Float_t dens, Float_t radl, + Float_t absl, Float_t *buf=0, Int_t nwbuf=0) const; + virtual void AliMixture(Int_t imat, const char *name, Float_t *a, + Float_t *z, Float_t dens, Int_t nlmat, + Float_t *wmat) const; + virtual void AliMedium(Int_t numed, const char *name, Int_t nmat, + Int_t isvol, Int_t ifield, Float_t fieldm, + Float_t tmaxfd, Float_t stemax, Float_t deemax, + Float_t epsil, Float_t stmin, Float_t *ubuf=0, + Int_t nbuf=0) const; + virtual void AliMatrix(Int_t &nmat, Float_t theta1, Float_t phi1, + Float_t theta2, Float_t phi2, Float_t theta3, + Float_t phi3) const; + + static void SetDensityFactor(Float_t density) { fgDensityFactor = density; } + static Float_t GetDensityFactor() { return fgDensityFactor; } + + /** Set per wrapper volume parameters */ + virtual void DefineWrapVolume(Int_t id, Double_t rmin,Double_t rmax, Double_t zspan); + + /** Book arrays for wrapper volumes */ + virtual void SetNWrapVolumes(Int_t n); + + virtual void DefineLayer(Int_t nlay,Double_t phi0,Double_t r,Double_t zlen,Int_t nladd, + Int_t nmod, Double_t lthick=0.,Double_t dthick=0.,UInt_t detType=0, Int_t buildFlag=0); + + virtual void DefineLayerTurbo(Int_t nlay,Double_t phi0,Double_t r,Double_t zlen,Int_t nladd, + Int_t nmod,Double_t width,Double_t tilt, + Double_t lthick = 0.,Double_t dthick = 0.,UInt_t detType=0, Int_t buildFlag=0); + +protected: + + static Float_t fgDensityFactor; //! factor that is multiplied to all material densities (ONLY for systematic studies) +private: + O2Detector(const O2Detector&); + O2Detector& operator=(const O2Detector&); + +ClassDef(O2Detector, 1) //Base class for ALICE Modules +}; +#endif diff --git a/AliBase/O2Module.cxx b/AliBase/O2Module.cxx new file mode 100644 index 0000000000000..5d6095bcce89b --- /dev/null +++ b/AliBase/O2Module.cxx @@ -0,0 +1,91 @@ +#include "O2Module.h" +#include +#include + +using std::endl; +using std::cout; +using std::fstream; +using std::ios; +using std::ostream; + +ClassImp(O2Module) + +Float_t O2Module::fgDensityFactor = 1.0; + +//_______________________________________________________________________ +O2Module::O2Module(): +FairModule() +{ + // + // Default constructor for the O2Module class + // +} + +//_______________________________________________________________________ +O2Module::O2Module(const char* name,const char *title, Bool_t Active): + FairModule(name,title, Active) +{ +} + +//_______________________________________________________________________ +O2Module::~O2Module() +{ + +} + +void O2Module::AliMaterial(Int_t imat, const char* name, Float_t a, + Float_t z, Float_t dens, Float_t radl, + Float_t absl, Float_t *buf, Int_t nwbuf) const +{ + TString uniquename = GetName(); + uniquename.Append("_"); + uniquename.Append(name); + + //Check this!!! + gMC->Material(imat, uniquename.Data(), a, z, dens * fgDensityFactor, radl, absl, buf, nwbuf); +} + +void O2Module::AliMixture(Int_t imat, const char *name, Float_t *a, + Float_t *z, Float_t dens, Int_t nlmat, + Float_t *wmat) const +{ + TString uniquename = GetName(); + uniquename.Append("_"); + uniquename.Append(name); + + //Check this!!! + gMC->Mixture(imat, uniquename.Data(), a, z, dens * fgDensityFactor, nlmat, wmat); +} + +void O2Module::AliMedium(Int_t numed, const char *name, Int_t nmat, + Int_t isvol, Int_t ifield, Float_t fieldm, + Float_t tmaxfd, Float_t stemax, Float_t deemax, + Float_t epsil, Float_t stmin, Float_t *ubuf, + Int_t nbuf) const +{ + TString uniquename = GetName(); + uniquename.Append("_"); + uniquename.Append(name); + + //Check this!!! + gMC->Medium(numed, uniquename.Data(), nmat, isvol, ifield, + fieldm, tmaxfd, stemax, deemax, epsil, stmin, ubuf, nbuf); +} + +void O2Module::AliMatrix(Int_t &nmat, Float_t theta1, Float_t phi1, + Float_t theta2, Float_t phi2, Float_t theta3, + Float_t phi3) const +{ + // + // Define a rotation matrix. Angles are in degrees. + // + // nmat on output contains the number assigned to the rotation matrix + // theta1 polar angle for axis I + // phi1 azimuthal angle for axis I + // theta2 polar angle for axis II + // phi2 azimuthal angle for axis II + // theta3 polar angle for axis III + // phi3 azimuthal angle for axis III + // + gMC->Matrix(nmat, theta1, phi1, theta2, phi2, theta3, phi3); +} diff --git a/AliBase/O2Module.h b/AliBase/O2Module.h new file mode 100644 index 0000000000000..750882d2e7267 --- /dev/null +++ b/AliBase/O2Module.h @@ -0,0 +1,53 @@ +#ifndef O2MODULE_H +#define O2MODULE_H + +// +// This is the basic class for any +// ALICE detector module, whether it is +// sensitive or not. Detector classes depend +// on this. +// + +#include "FairModule.h" + + +class O2Module : public FairModule { + +public: + + // Creators - distructors + O2Module(const char* name, const char *title, Bool_t Active=kFALSE); + O2Module(); + virtual ~O2Module(); + + // Module composition + virtual void AliMaterial(Int_t imat, const char* name, Float_t a, + Float_t z, Float_t dens, Float_t radl, + Float_t absl, Float_t *buf=0, Int_t nwbuf=0) const; + virtual void AliMixture(Int_t imat, const char *name, Float_t *a, + Float_t *z, Float_t dens, Int_t nlmat, + Float_t *wmat) const; + virtual void AliMedium(Int_t numed, const char *name, Int_t nmat, + Int_t isvol, Int_t ifield, Float_t fieldm, + Float_t tmaxfd, Float_t stemax, Float_t deemax, + Float_t epsil, Float_t stmin, Float_t *ubuf=0, + Int_t nbuf=0) const; + virtual void AliMatrix(Int_t &nmat, Float_t theta1, Float_t phi1, + Float_t theta2, Float_t phi2, Float_t theta3, + Float_t phi3) const; + + static void SetDensityFactor(Float_t density) { fgDensityFactor = density; } + static Float_t GetDensityFactor() { return fgDensityFactor; } + +protected: + + static Float_t fgDensityFactor; //! factor that is multiplied to all material densities (ONLY for systematic studies) + + private: + + O2Module(const O2Module&); + O2Module& operator=(const O2Module&); + + ClassDef(O2Module, 1) //Base class for ALICE Modules +}; +#endif diff --git a/AliBase/O2TrackReference.cxx b/AliBase/O2TrackReference.cxx new file mode 100644 index 0000000000000..d45e4cb375347 --- /dev/null +++ b/AliBase/O2TrackReference.cxx @@ -0,0 +1,168 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* $Id$ */ + +#include "TVirtualMC.h" +#include "TParticle.h" + +#include "O2TrackReference.h" +#include + +// +// Track Reference object is created every time particle is +// crossing detector bounds. The object is created by Step Manager +// +// The class stores the following informations: +// track label, +// track position: X,Y,X +// track momentum px, py, pz +// track length and time of fligth: both in cm +// status bits from Monte Carlo +// + +using std::endl; +using std::cout; +ClassImp(O2TrackReference) + +O2TrackReference::O2TrackReference(): + TObject(), + fTrack(0), + fX(0), + fY(0), + fZ(0), + fPx(0), + fPy(0), + fPz(0), + fLength(0), + fTime(0), + fUserId(0), + fDetectorId(-999) +{ + // + // Default constructor + // Creates empty object + + for(Int_t i=0; i<16; i++) ResetBit(BIT(i)); +} + +O2TrackReference::O2TrackReference(const O2TrackReference &tr) : + TObject(tr), + fTrack(tr.fTrack), + fX(tr.fX), + fY(tr.fY), + fZ(tr.fZ), + fPx(tr.fPx), + fPy(tr.fPy), + fPz(tr.fPz), + fLength(tr.fLength), + fTime(tr.fTime), + fUserId(tr.fUserId), + fDetectorId(tr.fDetectorId) +{ + // Copy Constructor +} + +O2TrackReference::O2TrackReference(Int_t label, Int_t id) : + TObject(), + fTrack(label), + fX(0), + fY(0), + fZ(0), + fPx(0), + fPy(0), + fPz(0), + fLength(gMC->TrackLength()), + fTime(gMC->TrackTime()), + fUserId(0), + fDetectorId(id) +{ + // + // Create Reference object out of label and + // data in TVirtualMC object + // + // Creates an object and fill all parameters + // from data in VirtualMC + // + // Sylwester Radomski, (S.Radomski@gsi.de) + // GSI, Jan 31, 2003 + // + + Double_t vec[4]; + + gMC->TrackPosition(vec[0],vec[1],vec[2]); + + fX = vec[0]; + fY = vec[1]; + fZ = vec[2]; + + gMC->TrackMomentum(vec[0],vec[1],vec[2],vec[3]); + + fPx = vec[0]; + fPy = vec[1]; + fPz = vec[2]; + + // Set Up status code + // Copy Bits from virtual MC + + for(Int_t i=14; i<22; i++) ResetBit(BIT(i)); + + SetBit(BIT(14), gMC->IsNewTrack()); + SetBit(BIT(15), gMC->IsTrackAlive()); + SetBit(BIT(16), gMC->IsTrackDisappeared()); + SetBit(BIT(17), gMC->IsTrackEntering()); + SetBit(BIT(18), gMC->IsTrackExiting()); + SetBit(BIT(19), gMC->IsTrackInside()); + SetBit(BIT(20), gMC->IsTrackOut()); + SetBit(BIT(21), gMC->IsTrackStop()); + // + // This particle has to be kept +} + +/* +AliExternalTrackParam * O2TrackReference::MakeTrack(const O2TrackReference *ref, Double_t mass) +{ + // + // Make dummy track from the track reference + // negative mass means opposite charge + // + Double_t xx[5]; + Double_t cc[15]; + for (Int_t i=0;i<15;i++) cc[i]=0; + Double_t x = ref->X(), y = ref->Y(), z = ref->Z(); + Double_t alpha = TMath::ATan2(y,x); + Double_t xr = TMath::Sqrt(x*x+y*y); + xx[0] = ref->LocalY(); + xx[1] = z; + xx[3] = ref->Pz()/ref->Pt(); + xx[4] = 1./ref->Pt(); + if (mass<0) xx[4]*=-1.; // negative mass - negative direction + Double_t alphap = TMath::ATan2(ref->Py(),ref->Px())-alpha; + if (alphap> TMath::Pi()) alphap-=TMath::Pi(); + if (alphap<-TMath::Pi()) alphap+=TMath::Pi(); + xx[2] = TMath::Sin(alphap); + + AliExternalTrackParam * track = new AliExternalTrackParam(xr,alpha,xx,cc); + return track; +} +*/ + +void O2TrackReference::Print(Option_t* /*opt*/) const +{ + cout << Form("Label %d P=%7.2f (PX,PY,PZ)=(%7.2f,%7.2f,%7.2f) (X,Y,Z)=(%7.2f,%7.2f,%7.2f)" + " Length=%7.2f Time=%7.2f UserId=%d", + Label(),P(),Px(),Py(),Pz(),X(),Y(),Z(),GetLength(),GetTime(),UserId()) << endl; +} + diff --git a/AliBase/O2TrackReference.h b/AliBase/O2TrackReference.h new file mode 100644 index 0000000000000..46fd5853f3aa0 --- /dev/null +++ b/AliBase/O2TrackReference.h @@ -0,0 +1,103 @@ +#ifndef O2TRACKREFERENCE_H +#define O2TRACKREFERENCE_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +// +// Track Reference object is created every time particle is +// crossing detector bounds. +// The object is created by Step Manager +// + +#include "TObject.h" +#include "TMath.h" + +class O2TrackReference : public TObject { + + public: + + enum constants {kDisappeared = -1, + kITS = 0, + kTPC = 1, + kFRAME = 2, + kTRD = 3, + kTOF = 4, + kMUON = 5, + kHMPID = 6, + kT0 = 7, + kEMCAL = 8, + kPMD = 10, + kFMD = 12, + kVZERO = 14, + kMFT = 16, + kHALL = 17 + }; + + O2TrackReference(); + O2TrackReference(Int_t label, Int_t id = -999); + O2TrackReference(const O2TrackReference &tr); + virtual ~O2TrackReference() {} + + // static AliExternalTrackParam * MakeTrack(const O2TrackReference *ref, Double_t mass); + virtual Int_t GetTrack() const {return fTrack;} + virtual void SetTrack(Int_t track) {fTrack=track;} + virtual void SetLength(Float_t length){fLength=length;} + virtual void SetTime(Float_t time) {fTime = time;} + virtual Float_t GetLength() const {return fLength;} + virtual Float_t GetTime() const {return fTime;} + virtual Int_t Label() const {return fTrack;} + virtual void SetLabel(Int_t track) {fTrack=track;} + virtual Float_t R() const {return TMath::Sqrt(fX*fX+fY*fY);} + virtual Float_t Pt() const {return TMath::Sqrt(fPx*fPx+fPy*fPy);} + virtual Float_t Phi() const {return TMath::Pi()+TMath::ATan2(-fPy,-fPx);} + virtual Float_t Theta() const {return (fPz==0)?TMath::Pi()/2:TMath::ACos(fPz/P());} + virtual Float_t X() const {return fX;} + virtual Float_t Y() const {return fY;} + virtual Float_t Z() const {return fZ;} + virtual Float_t Px() const {return fPx;} + virtual Float_t Py() const {return fPy;} + virtual Float_t Pz() const {return fPz;} + virtual Float_t P() const {return TMath::Sqrt(fPx*fPx+fPy*fPy+fPz*fPz);} + virtual Int_t UserId() const {return fUserId;} + virtual Int_t DetectorId() const {return fDetectorId;} + virtual void SetDetectorId(Int_t id){fDetectorId = id;} + virtual void SetPosition(Float_t x, Float_t y, Float_t z){fX=x; fY=y; fZ=z;} + virtual void SetMomentum(Float_t px, Float_t py, Float_t pz){fPx=px; fPy=py; fPz=pz;} + virtual void SetUserId(Int_t userId){fUserId=userId;} + + // Methods to get position of the track reference in + // in the TPC/TRD/TOF Tracking coordinate system + + virtual Float_t PhiPos() const {return TMath::Pi()+TMath::ATan2(-fY, -fX);} + virtual Float_t Alpha() const + {return TMath::Pi()*(20*((((Int_t)(PhiPos()*180/TMath::Pi()))/20))+10)/180.;} + virtual Float_t LocalX() const {return fX*TMath::Cos(-Alpha()) - fY*TMath::Sin(-Alpha());} + virtual Float_t LocalY() const {return fX*TMath::Sin(-Alpha()) + fY*TMath::Cos(-Alpha());} + + Bool_t IsSortable() const {return kTRUE;} + Int_t Compare(const TObject *obj) const { + Int_t ll = ((O2TrackReference*)obj)->GetTrack(); + if (ll < fTrack) return 1; + if (ll > fTrack) return -1; + return 0; + } + + virtual void Print(Option_t* opt="") const; + + protected: + Int_t fTrack; // Track number + Float_t fX; // X reference position of the track + Float_t fY; // Y reference position of the track + Float_t fZ; // Z reference position of the track + Float_t fPx; // momentum + Float_t fPy; // momentum + Float_t fPz; // momentum + Float_t fLength; // track lenght from its origin in cm + Float_t fTime; // time of flight in cm + Int_t fUserId; // optional Id defined by user + Int_t fDetectorId; // Detector Id + ClassDef(O2TrackReference,6) //Base class for all Alice track references +}; +#endif diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b37d2ba9d26f..666675839718f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,6 +160,7 @@ ENDIF(HAS_CXX11_SHAREDPOINTER) # cause another cmake executable to run. The same process will walk through # the project's entire directory structure. +add_subdirectory (AliBase) add_subdirectory (AliData) add_subdirectory (AliGenerators) add_subdirectory (its) diff --git a/its/AliGeomManager.cxx b/its/AliGeomManager.cxx new file mode 100644 index 0000000000000..0f53df916818a --- /dev/null +++ b/its/AliGeomManager.cxx @@ -0,0 +1,141 @@ +/************************************************************************** + * 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. * + **************************************************************************/ +//------------------------------------------------------------------------- +// Implementation of AliGeomManager, the geometry manager class +// which interfaces to TGeo and the look-up table mapping unique +// volume indices to symbolic volume names. For that it collects +// several static methods. +//------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "AliGeomManager.h" + +#include "FairLogger.h" + +ClassImp(AliGeomManager) + +TGeoManager* AliGeomManager::fgGeometry = 0x0; + +AliGeomManager::AliGeomManager(): + TObject() +{ + // default constructor +} + +AliGeomManager::~AliGeomManager() +{ + // dummy destructor +} + +Bool_t AliGeomManager::GetOrigGlobalMatrix(const char* symname, TGeoHMatrix &m) +{ + // Get the global transformation matrix (ideal geometry) for a given alignable volume + // The alignable volume is identified by 'symname' which has to be either a valid symbolic + // name, the query being performed after alignment, or a valid volume path if the query is + // performed before alignment. + // + m.Clear(); + + if (!fgGeometry || !fgGeometry->IsClosed()) { + LOG(ERROR) << "No active geometry or geometry not yet closed!" << FairLogger::endl; + return kFALSE; + } + if (!fgGeometry->GetListOfPhysicalNodes()) { + LOG(WARNING) << "gGeoManager doesn't contain any aligned nodes!" << FairLogger::endl; + if (!fgGeometry->cd(symname)) { + LOG(ERROR) << "Volume path " << symname << " not valid!" << FairLogger::endl; + return kFALSE; + } + else { + m = *fgGeometry->GetCurrentMatrix(); + return kTRUE; + } + } + + TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname); + const char* path = NULL; + if(pne){ + m = *pne->GetGlobalOrig(); + return kTRUE; + }else{ + LOG(WARNING) << "The symbolic volume name " << symname + << "does not correspond to a physical entry. Using it as a volume path!" + << FairLogger::endl; + path=symname; + } + + return GetOrigGlobalMatrixFromPath(path,m); +} + +//_____________________________________________________________________________ +Bool_t AliGeomManager::GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix &m) +{ + // The method returns the global matrix for the volume identified by + // 'path' in the ideal detector geometry. + // The output global matrix is stored in 'm'. + // Returns kFALSE in case TGeo has not been initialized or the volume + // path is not valid. + // + m.Clear(); + + if (!fgGeometry || !fgGeometry->IsClosed()) { + LOG(ERROR) << "Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!" + << FairLogger::endl; + return kFALSE; + } + + if (!fgGeometry->CheckPath(path)) { + LOG(ERROR) << "Volume path " << path << " not valid!" << FairLogger::endl; + return kFALSE; + } + + TIter next(fgGeometry->GetListOfPhysicalNodes()); + fgGeometry->cd(path); + + while(fgGeometry->GetLevel()){ + + TGeoPhysicalNode *physNode = NULL; + next.Reset(); + TGeoNode *node = fgGeometry->GetCurrentNode(); + while ((physNode=(TGeoPhysicalNode*)next())) + if (physNode->GetNode() == node) break; + + TGeoMatrix *lm = NULL; + if (physNode) { + lm = physNode->GetOriginalMatrix(); + if (!lm) lm = node->GetMatrix(); + } else + lm = node->GetMatrix(); + + m.MultiplyLeft(lm); + + fgGeometry->CdUp(); + } + + return kTRUE; +} diff --git a/its/AliGeomManager.h b/its/AliGeomManager.h new file mode 100644 index 0000000000000..73c49132bd699 --- /dev/null +++ b/its/AliGeomManager.h @@ -0,0 +1,54 @@ +#ifndef ALI_GEOM_MANAGER_H +#define ALI_GEOM_MANAGER_H + +// +// Class for interfacing to the geometry; it also builds and manages the +// look-up tables for fast access to geometry and alignment information +// for sensitive alignable volumes: +// 1) the look-up table mapping unique volume ids to TGeoPNEntries +// this allows to access directly by means of the unique index +// the associated symbolic name and original global matrix +// in addition to the functionality of the physical node +// associated to a given alignable volume +// 2) the look-up table of the alignment objects associated to the +// indexed alignable volumes +// + +#include + +class TGeoManager; +class TGeoPNEntry; +class TGeoHMatrix; +class TObjArray; + +class AliGeomManager: public TObject { + +public: + enum ELayerID{kInvalidLayer=0, + kFirstLayer=1, + kSPD1=1, kSPD2=2, + kSDD1=3, kSDD2=4, + kSSD1=5, kSSD2=6, + kTPC1=7, kTPC2=8, + kTRD1=9, kTRD2=10, kTRD3=11, kTRD4=12, kTRD5=13, kTRD6=14, + kTOF=15, + kPHOS1=16, kPHOS2=17, + kHMPID=18, + kMUON=19, + kEMCAL=20, + kLastLayer=21}; + + static Bool_t GetOrigGlobalMatrix(const char *symname, TGeoHMatrix &m); + + ~AliGeomManager(); + + private: + AliGeomManager(); + static Bool_t GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix &m); + + static TGeoManager* fgGeometry; + + ClassDef(AliGeomManager, 0); // Manager of geometry information for alignment +}; + +#endif diff --git a/its/AliITSUGeomTGeo.cxx b/its/AliITSUGeomTGeo.cxx new file mode 100644 index 0000000000000..1eeb487a8e096 --- /dev/null +++ b/its/AliITSUGeomTGeo.cxx @@ -0,0 +1,1020 @@ +/************************************************************************** + * 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. * + **************************************************************************/ + +/////////////////////////////////////////////////////////////////////////// +// AliITSUGeomTGeo is a simple interface class to TGeoManager // +// It is used in the simulation and reconstruction in order to // +// query the TGeo ITS geometry // +// // +// author - cvetan.cheshkov@cern.ch // +// 15/02/2007 // +// adapted to ITSupg 18/07/2012 - ruben.shahoyan@cern.ch // +// // +// ATTENTION: In opposite to ols AliITSgeomTGeo, all indices start // +// from 0, not from 1!!! // +// // +/////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "AliGeomManager.h" +#include "AliITSUGeomTGeo.h" +#include "AliITSsegmentation.h" +#include "AliITSUSegmentationPix.h" + +#include "FairLogger.h" +using namespace TMath; + +ClassImp(AliITSUGeomTGeo) + +UInt_t AliITSUGeomTGeo::fgUIDShift = 16; // bit shift to go from mod.id to modUUID for TGeo +TString AliITSUGeomTGeo::fgITSVolName = "ITSV"; +TString AliITSUGeomTGeo::fgITSLrName = "ITSULayer"; +TString AliITSUGeomTGeo::fgITSStaveName = "ITSUStave"; +TString AliITSUGeomTGeo::fgITSHalfStaveName = "ITSUHalfStave"; +TString AliITSUGeomTGeo::fgITSModuleName = "ITSUModule"; +TString AliITSUGeomTGeo::fgITSChipName = "ITSUChip"; +TString AliITSUGeomTGeo::fgITSSensName = "ITSUSensor"; +TString AliITSUGeomTGeo::fgITSWrapVolName = "ITSUWrapVol"; +TString AliITSUGeomTGeo::fgITSChipTypeName[AliITSUGeomTGeo::kNChipTypes] = {"Pix"}; +// +TString AliITSUGeomTGeo::fgITSsegmFileName = "itsSegmentations.root"; + +AliITSUGeomTGeo::AliITSUGeomTGeo(Bool_t build, Bool_t loadSegm) + :fVersion(kITSVNA) + ,fNLayers(0) + ,fNChips(0) + ,fNStaves(0) + ,fNHalfStaves(0) + ,fNModules(0) + ,fNChipsPerModule(0) + ,fNChipRowsPerModule(0) + ,fNChipsPerHalfStave(0) + ,fNChipsPerStave(0) + ,fNChipsPerLayer(0) + ,fLrChipType(0) + ,fLastChipIndex(0) + ,fMatSens(0) + ,fMatT2L(0) + ,fSegm(0) +{ + // default c-tor + for (int i=kMaxLayers;i--;) fLr2Wrapper[i] = -1; + if (build) BuildITS(loadSegm); +} + +AliITSUGeomTGeo::AliITSUGeomTGeo(const AliITSUGeomTGeo &src) + :TObject(src) + ,fVersion(src.fVersion) + ,fNLayers(src.fNLayers) + ,fNChips(src.fNChips) + ,fNStaves(0) + ,fNHalfStaves(0) + ,fNModules(0) + ,fNChipsPerModule(0) + ,fNChipRowsPerModule(0) + ,fNChipsPerHalfStave(0) + ,fNChipsPerStave(0) + ,fNChipsPerLayer(0) + ,fLrChipType(0) + ,fLastChipIndex(0) + ,fMatSens(0) + ,fMatT2L(0) + ,fSegm(0) +{ + // copy c-tor + if (fNLayers) { + fNStaves = new Int_t[fNLayers]; + fNChipsPerModule = new Int_t[fNLayers]; + fNChipRowsPerModule = new Int_t[fNLayers]; + fLrChipType = new Int_t[fNLayers]; + fLastChipIndex = new Int_t[fNLayers]; + fNChipsPerHalfStave = new Int_t[fNLayers]; + fNChipsPerStave = new Int_t[fNLayers]; + fNChipsPerLayer = new Int_t[fNLayers]; + + for (int i=fNLayers;i--;) { + fNStaves[i] = src.fNStaves[i]; + fNHalfStaves[i] = src.fNHalfStaves[i]; + fNModules[i] = src.fNModules[i]; + fNChipsPerModule[i] = src.fNChipsPerModule[i]; + fNChipRowsPerModule[i] = src.fNChipRowsPerModule[i]; + fNChipsPerHalfStave[i] = src.fNChipsPerHalfStave[i]; + fNChipsPerStave[i] = src.fNChipsPerStave[i]; + fNChipsPerLayer[i] = src.fNChipsPerLayer[i]; + fLrChipType[i] = src.fLrChipType[i]; + fLastChipIndex[i] = src.fLastChipIndex[i]; + } + if (src.fMatSens) { + fMatSens = new TObjArray(fNChips); + fMatSens->SetOwner(kTRUE); + for (int i=0;iAt(i); + fMatSens->AddAt(new TGeoHMatrix(*mat),i); + } + } + if (src.fMatT2L) { + fMatT2L = new TObjArray(fNChips); + fMatT2L->SetOwner(kTRUE); + for (int i=0;iAt(i); + fMatT2L->AddAt(new TGeoHMatrix(*mat),i); + } + } + if (src.fSegm) { + int sz = src.fSegm->GetEntriesFast(); + fSegm = new TObjArray(sz); + fSegm->SetOwner(kTRUE); + for (int i=0;iUncheckedAt(i); + if (!sg) continue; + fSegm->AddAt(sg->Clone(),i); + } + } + } + for (int i=kMaxLayers;i--;) fLr2Wrapper[i] = src.fLr2Wrapper[i]; +} + +AliITSUGeomTGeo::~AliITSUGeomTGeo() +{ + //d-tor + delete[] fNStaves; + delete[] fNHalfStaves; + delete[] fNModules; + delete[] fLrChipType; + delete[] fNChipsPerModule; + delete[] fNChipRowsPerModule; + delete[] fNChipsPerHalfStave; + delete[] fNChipsPerStave; + delete[] fNChipsPerLayer; + delete[] fLastChipIndex; + delete fMatT2L; + delete fMatSens; + delete fSegm; +} + +AliITSUGeomTGeo& AliITSUGeomTGeo::operator=(const AliITSUGeomTGeo &src) +{ + // cp op. + if (this!=&src) { + delete[] fNStaves; + delete[] fNHalfStaves; + delete[] fNModules; + delete[] fLrChipType; + delete[] fNChipsPerModule; + delete[] fNChipRowsPerModule; + delete[] fNChipsPerHalfStave; + delete[] fNChipsPerStave; + delete[] fNChipsPerLayer; + delete[] fLastChipIndex; + fNStaves = fNHalfStaves = fNModules = fLrChipType = fNChipsPerModule = fLastChipIndex = 0; + fVersion = src.fVersion; + fNLayers = src.fNLayers; + fNChips = src.fNChips; + if (src.fMatSens) { + delete fMatSens; + fMatSens = new TObjArray(fNChips); + fMatSens->SetOwner(kTRUE); + for (int i=0;iAt(i); + fMatSens->AddAt(new TGeoHMatrix(*mat),i); + } + } + if (src.fMatT2L) { + delete fMatT2L; + fMatT2L = new TObjArray(fNChips); + fMatT2L->SetOwner(kTRUE); + for (int i=0;iAt(i); + fMatT2L->AddAt(new TGeoHMatrix(*mat),i); + } + } + if (src.fSegm) { + int sz = src.fSegm->GetEntriesFast(); + fSegm = new TObjArray(sz); + fSegm->SetOwner(kTRUE); + for (int i=0;iUncheckedAt(i); + if (!sg) continue; + fSegm->AddAt(sg->Clone(),i); + } + } + + if (fNLayers) { + fNStaves = new Int_t[fNLayers]; + fNHalfStaves = new Int_t[fNLayers]; + fNModules = new Int_t[fNLayers]; + fNChipsPerModule = new Int_t[fNLayers]; + fNChipRowsPerModule = new Int_t[fNLayers]; + fNChipsPerHalfStave = new Int_t[fNLayers]; + fNChipsPerStave = new Int_t[fNLayers]; + fNChipsPerLayer = new Int_t[fNLayers]; + fLrChipType = new Int_t[fNLayers]; + fLastChipIndex = new Int_t[fNLayers]; + for (int i=fNLayers;i--;) { + fNStaves[i] = src.fNStaves[i]; + fNHalfStaves[i] = src.fNHalfStaves[i]; + fNModules[i] = src.fNModules[i]; + fNChipsPerModule[i] = src.fNChipsPerModule[i]; + fNChipRowsPerModule[i] = src.fNChipRowsPerModule[i]; + fNChipsPerHalfStave[i] = src.fNChipsPerHalfStave[i]; + fNChipsPerStave[i] = src.fNChipsPerStave[i]; + fNChipsPerLayer[i] = src.fNChipsPerLayer[i]; + fLrChipType[i] = src.fLrChipType[i]; + fLastChipIndex[i] = src.fLastChipIndex[i]; + } + } + } + return *this; +} + +Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta,Int_t chipInStave) const +{ + // This routine computes the chip index number from the layer, + // stave, and chip number in stave. + // Inputs: + // Int_t lay The layer number. Starting from 0. + // Int_t sta The stave number. Starting from 0 + // Int_t chipInStave The chip number in the stave. Starting from 0 + // + return GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInStave; +} + +Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta, Int_t substa, Int_t chipInSStave) const +{ + // This routine computes the chip index number from the layer, + // stave, substave and chip number in substave. + // Inputs: + // Int_t lay The layer number. Starting from 0. + // Int_t sta The stave number. Starting from 0 + // Int_t substa The substave number. Starting from 0 + // Int_t chipInSStave The chip number in the sub stave. Starting from 0 + // + int n = GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInSStave; + if (fNHalfStaves[lay] && substa>0) n += fNChipsPerHalfStave[lay]*substa; + return n; +} + +Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta, Int_t substa, Int_t md, Int_t chipInMod) const +{ + // This routine computes the chip index number from the layer, + // stave, substave module and chip number in module. + // Inputs: + // Int_t lay The layer number. Starting from 0. + // Int_t sta The stave number. Starting from 0 + // Int_t substa The substave number. Starting from 0 + // Int_t module The module number ... + // Int_t chipInSStave The chip number in the module. Starting from 0 + // + int n = GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInMod; + if (fNHalfStaves[lay] && substa>0) n += fNChipsPerHalfStave[lay]*substa; + if (fNModules[lay] && md>0) n += fNChipsPerModule[lay]*md; + return n; +} + +Bool_t AliITSUGeomTGeo::GetLayer(Int_t index,Int_t &lay,Int_t &indexInLr) const +{ + // This routine computes the layer number a + // given the chip index. The + // Inputs: + // Int_t index The chip index number, starting from zero. + // Outputs: + // Int_t indexInLr The chip index inside a layer, starting from zero. + // Int_t lay The layer number. Starting from 0. + // + lay = GetLayer(index); + indexInLr = index - GetFirstChipIndex(lay); + return kTRUE; + +} + +Int_t AliITSUGeomTGeo::GetLayer(Int_t index) const +{ + // Get chip layer, from 0 + // + int lay = 0; + while(index>fLastChipIndex[lay]) lay++; + return lay; +} + +Int_t AliITSUGeomTGeo::GetStave(Int_t index) const +{ + // Get chip stave, from 0 + // + int lay = 0; + while(index>fLastChipIndex[lay]) lay++; + index -= GetFirstChipIndex(lay); + return index/fNChipsPerStave[lay]; +} + +Int_t AliITSUGeomTGeo::GetHalfStave(Int_t index) const +{ + // Get chip substave id in stave, from 0 + // + int lay = 0; + while(index>fLastChipIndex[lay]) lay++; + if (fNHalfStaves[lay]<0) return -1; + index -= GetFirstChipIndex(lay); + index %= fNChipsPerStave[lay]; + return index/fNChipsPerHalfStave[lay]; +} + +Int_t AliITSUGeomTGeo::GetModule(Int_t index) const +{ + // Get chip module id in substave, from 0 + // + int lay = 0; + while(index>fLastChipIndex[lay]) lay++; + if (fNModules[lay]<0) return 0; + index -= GetFirstChipIndex(lay); + index %= fNChipsPerStave[lay]; + if (fNHalfStaves[lay]) index %= fNChipsPerHalfStave[lay]; + return index/fNChipsPerModule[lay]; +} + +Int_t AliITSUGeomTGeo::GetChipIdInLayer(Int_t index) const +{ + // Get chip number within layer, from 0 + // + int lay = 0; + while(index>fLastChipIndex[lay]) lay++; + index -= GetFirstChipIndex(lay); + return index; +} + +Int_t AliITSUGeomTGeo::GetChipIdInStave(Int_t index) const +{ + // Get chip number within stave, from 0 + // + int lay = 0; + while(index>fLastChipIndex[lay]) lay++; + index -= GetFirstChipIndex(lay); + return index%fNChipsPerStave[lay]; +} + +Int_t AliITSUGeomTGeo::GetChipIdInHalfStave(Int_t index) const +{ + // Get chip number within stave, from 0 + // + int lay = 0; + while(index>fLastChipIndex[lay]) lay++; + index -= GetFirstChipIndex(lay); + return index%fNChipsPerHalfStave[lay]; +} + +Int_t AliITSUGeomTGeo::GetChipIdInModule(Int_t index) const +{ + // Get chip number within module, from 0 + // + int lay = 0; + while(index>fLastChipIndex[lay]) lay++; + index -= GetFirstChipIndex(lay); + return index%fNChipsPerModule[lay]; +} + +Bool_t AliITSUGeomTGeo::GetChipId(Int_t index,Int_t &lay,Int_t &sta,Int_t &hsta, Int_t &mod, Int_t &chip) const +{ + // + // This routine computes the layer, stave, substave, module and chip number + // given the chip index number. + // Inputs: + // Int_t index The chip index number, starting from zero. + // Outputs: + // Int_t lay The layer number. Starting from 0 + // Int_t sta The stave number. Starting from 0 + // Int_t ssta The halfstave number. Starting from 0 + // Int_t mod The module number. Starting from 0 + // Int_t chip The detector number. Starting from 0 + // + lay = GetLayer(index); + index -= GetFirstChipIndex(lay); + sta = index/fNChipsPerStave[lay]; + index %= fNChipsPerStave[lay]; + hsta = fNHalfStaves[lay]>0 ? index/fNChipsPerHalfStave[lay] : -1; + index %= fNChipsPerHalfStave[lay]; + mod = fNModules[lay]>0 ? index/fNChipsPerModule[lay] : -1; + chip = index%fNChipsPerModule[lay]; + + return kTRUE; +} + +const char* AliITSUGeomTGeo::GetSymName(Int_t index) const +{ + // Get the TGeoPNEntry symbolic name + // for a given chip identified by 'index' + // + Int_t lay, index2; + if (!GetLayer(index,lay,index2)) return NULL; + // return AliGeomManager::SymName((AliGeomManager::ELayerID)((lay-1)+AliGeomManager::kSPD1),index2); + // RS: this is not optimal, but we cannod access directly AliGeomManager, since the latter has hardwired layers + // TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( AliGeomManager::LayerToVolUID(lay+1,index2) ); + TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( ChipVolUID(index) ); + if (!pne) { + LOG(ERROR) << "Failed to find alignable entry with index " << index << ": (Lr" << lay + << " Chip:" << index2 << ") !" << FairLogger::endl; + return NULL; + } + return pne->GetName(); +} + +const char* AliITSUGeomTGeo::ComposeSymNameITS() +{ + // sym name of the layer + return "ITS"; +} + +const char* AliITSUGeomTGeo::ComposeSymNameLayer(Int_t lr) +{ + // sym name of the layer + return Form("%s/%s%d",ComposeSymNameITS(),GetITSLayerPattern(),lr); +} + +const char* AliITSUGeomTGeo::ComposeSymNameStave(Int_t lr, Int_t stave) +{ + // sym name of the stave at given layer + return Form("%s/%s%d",ComposeSymNameLayer(lr),GetITSStavePattern(),stave); +} + +const char* AliITSUGeomTGeo::ComposeSymNameHalfStave(Int_t lr, Int_t stave, Int_t substave) +{ + // sym name of the stave at given layer + return substave>=0 ? + Form("%s/%s%d",ComposeSymNameStave(lr,stave),GetITSHalfStavePattern(),substave) : + ComposeSymNameStave(lr,stave); +} + +const char* AliITSUGeomTGeo::ComposeSymNameModule(Int_t lr, Int_t stave, Int_t substave, Int_t mod) +{ + // sym name of the substave at given layer/stave + return mod>=0 ? + Form("%s/%s%d",ComposeSymNameHalfStave(lr,stave,substave),GetITSModulePattern(),mod) : + ComposeSymNameHalfStave(lr,stave,substave); +} + +const char* AliITSUGeomTGeo::ComposeSymNameChip(Int_t lr, Int_t sta, Int_t substave, Int_t mod, Int_t chip) +{ + // sym name of the chip in the given layer/stave/substave/module + return Form("%s/%s%d",ComposeSymNameModule(lr,sta,substave,mod),GetITSChipPattern(),chip); +} + +TGeoHMatrix* AliITSUGeomTGeo::GetMatrix(Int_t index) const +{ + // Get the transformation matrix for a given chip 'index' + // by quering the TGeoManager + static TGeoHMatrix matTmp; + TGeoPNEntry *pne = GetPNEntry(index); + if (!pne) return NULL; + + TGeoPhysicalNode *pnode = pne->GetPhysicalNode(); + if (pnode) return pnode->GetMatrix(); + + const char* path = pne->GetTitle(); + gGeoManager->PushPath(); // Preserve the modeler state. + if (!gGeoManager->cd(path)) { + gGeoManager->PopPath(); + LOG(ERROR) << "Volume path " << path << " not valid!" << FairLogger::endl; + return NULL; + } + matTmp = *gGeoManager->GetCurrentMatrix(); + gGeoManager->PopPath(); + return &matTmp; +} + +Bool_t AliITSUGeomTGeo::GetTranslation(Int_t index, Double_t t[3]) const +{ + // Get the translation vector for a given chip 'index' + // by quering the TGeoManager + TGeoHMatrix *m = GetMatrix(index); + if (!m) return kFALSE; + + Double_t *trans = m->GetTranslation(); + for (Int_t i = 0; i < 3; i++) t[i] = trans[i]; + + return kTRUE; +} + +Bool_t AliITSUGeomTGeo::GetRotation(Int_t index, Double_t r[9]) const +{ + // Get the rotation matrix for a given chip 'index' + // by quering the TGeoManager + TGeoHMatrix *m = GetMatrix(index); + if (!m) return kFALSE; + + Double_t *rot = m->GetRotationMatrix(); + for (Int_t i = 0; i < 9; i++) r[i] = rot[i]; + + return kTRUE; +} + +Bool_t AliITSUGeomTGeo::GetOrigMatrix(Int_t index, TGeoHMatrix &m) const +{ + // Get the original (ideal geometry) TGeo matrix for + // a given chip identified by 'index'. + // The method is slow, so it should be used + // with great care. + m.Clear(); + + const char *symname = GetSymName(index); + if (!symname) return kFALSE; + + return AliGeomManager::GetOrigGlobalMatrix(symname,m); +} + +Bool_t AliITSUGeomTGeo::GetOrigTranslation(Int_t index, Double_t t[3]) const +{ + // Get the original translation vector (ideal geometry) + // for a given chip 'index' by quering the TGeoManager + TGeoHMatrix m; + if (!GetOrigMatrix(index,m)) return kFALSE; + + Double_t *trans = m.GetTranslation(); + for (Int_t i = 0; i < 3; i++) t[i] = trans[i]; + + return kTRUE; +} + +Bool_t AliITSUGeomTGeo::GetOrigRotation(Int_t index, Double_t r[9]) const +{ + // Get the original rotation matrix (ideal geometry) + // for a given chip 'index' by quering the TGeoManager + TGeoHMatrix m; + if (!GetOrigMatrix(index,m)) return kFALSE; + + Double_t *rot = m.GetRotationMatrix(); + for (Int_t i = 0; i < 9; i++) r[i] = rot[i]; + + return kTRUE; +} + +TGeoHMatrix* AliITSUGeomTGeo::ExtractMatrixT2L(Int_t index) const +{ + // Get the matrix which transforms from the tracking to local r.s. + // The method queries directly the TGeoPNEntry + TGeoPNEntry *pne = GetPNEntry(index); + if (!pne) return NULL; + + TGeoHMatrix *m = (TGeoHMatrix*) pne->GetMatrix(); + if (!m) LOG(ERROR) << "TGeoPNEntry (" << pne->GetName() << ") contains no matrix !" + << FairLogger::endl; + + return m; +} + +Bool_t AliITSUGeomTGeo::GetTrackingMatrix(Int_t index, TGeoHMatrix &m) +{ + // Get the matrix which transforms from the tracking r.s. to + // the global one. + // Returns kFALSE in case of error. + m.Clear(); + + TGeoHMatrix *m1 = GetMatrix(index); + if (!m1) return kFALSE; + + const TGeoHMatrix *m2 = GetMatrixT2L(index); + if (!m2) return kFALSE; + + m = *m1; + m.Multiply(m2); + + return kTRUE; +} + +TGeoHMatrix* AliITSUGeomTGeo::ExtractMatrixSens(Int_t index) const +{ + // Get the transformation matrix of the SENSOR (not necessary the same as the chip) + // for a given chip 'index' by quering the TGeoManager + Int_t lay,stav,sstav,mod,chipInMod; + GetChipId(index,lay,stav,sstav,mod,chipInMod); + int wrID = fLr2Wrapper[lay]; + TString path = Form("/cave_1/%s_2/",AliITSUGeomTGeo::GetITSVolPattern()); + if (wrID>=0) path += Form("%s%d_1/",GetITSWrapVolPattern(),wrID); + path += Form("%s%d_1/%s%d_%d/",AliITSUGeomTGeo::GetITSLayerPattern(),lay,AliITSUGeomTGeo::GetITSStavePattern(),lay,stav); + if (fNHalfStaves[lay]>0) path += Form("%s%d_%d/",AliITSUGeomTGeo::GetITSHalfStavePattern(),lay,sstav); + if (fNModules[lay]>0) path += Form("%s%d_%d/",AliITSUGeomTGeo::GetITSModulePattern(),lay,mod); + path += Form("%s%d_%d/%s%d_1",AliITSUGeomTGeo::GetITSChipPattern(),lay,chipInMod,AliITSUGeomTGeo::GetITSSensorPattern(),lay); + static TGeoHMatrix matTmp; + gGeoManager->PushPath(); + if (!gGeoManager->cd(path.Data())) { + gGeoManager->PopPath(); + LOG(ERROR) << "Error in cd-ing to " << path.Data() << FairLogger::endl; + return 0; + } // end if !gGeoManager + matTmp = *gGeoManager->GetCurrentMatrix(); // matrix may change after cd + //RSS + // printf("%d/%d/%d %s\n",lay,stav,detInSta,path.Data()); + // mat->Print(); + // Retstore the modeler state. + gGeoManager->PopPath(); + return &matTmp; +} + +TGeoPNEntry* AliITSUGeomTGeo::GetPNEntry(Int_t index) const +{ + // Get a pointer to the TGeoPNEntry of a chip + // identified by 'index' + // Returns NULL in case of invalid index, + // missing TGeoManager or invalid symbolic name + // + if (index >= fNChips) { + LOG(ERROR) << "Invalid ITS chip index: " << index << " (0 -> "<< fNChips << ") !" + << FairLogger::endl; + return NULL; + } + + if (!gGeoManager || !gGeoManager->IsClosed()) { + LOG(ERROR) << "Can't get the matrix! gGeoManager doesn't exist or it is still opened!" + << FairLogger::endl; + return NULL; + } + TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( ChipVolUID(index) ); + // TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(GetSymName(index)); + if (!pne) LOG(ERROR) << "The index " << index << " does not correspond to a physical entry!" + << FairLogger::endl; + + return pne; +} + +void AliITSUGeomTGeo::BuildITS(Bool_t loadSegm) +{ + // exract upg ITS parameters from TGeo + if (fVersion!=kITSVNA) { + LOG(WARNING) << "Already built" << FairLogger::endl; return; // already initialized + } + if (!gGeoManager) LOG(FATAL) << "Geometry is not loaded" << FairLogger::endl; + fNLayers = ExtractNumberOfLayers(); + if (!fNLayers) return; + // + fNStaves = new Int_t[fNLayers]; + fNHalfStaves = new Int_t[fNLayers]; + fNModules = new Int_t[fNLayers]; + fNChipsPerModule = new Int_t[fNLayers]; + fNChipRowsPerModule = new Int_t[fNLayers]; + fNChipsPerHalfStave = new Int_t[fNLayers]; + fNChipsPerStave = new Int_t[fNLayers]; + fNChipsPerLayer = new Int_t[fNLayers]; + fLrChipType = new Int_t[fNLayers]; + fLastChipIndex = new Int_t[fNLayers]; + fNChips = 0; + + for (int i=0;iGetVolume(GetITSVolPattern()); + if (!itsV) LOG(FATAL) << "ITS volume " << GetITSVolPattern() << " is not in the geometry" + << FairLogger::endl; + SetUIDShift(itsV->GetUniqueID()); + + // Loop on all ITSV nodes, count Layer volumes by checking names + // Build on the fly layer - wrapper correspondence + TObjArray* nodes = itsV->GetNodes(); + Int_t nNodes = nodes->GetEntriesFast(); + for (Int_t j=0; jAt(j); + const char* name = nd->GetName(); + if (strstr(name,GetITSLayerPattern())) { + numberOfLayers++; + if ( (lrID=ExtractVolumeCopy(name,AliITSUGeomTGeo::GetITSLayerPattern()))<0 ) { + LOG(FATAL) << "Failed to extract layer ID from the " << name << FairLogger::endl; + exit(1); + } + // + fLr2Wrapper[lrID] = -1; // not wrapped + } + else if (strstr(name,GetITSWrapVolPattern())) { // this is a wrapper volume, may cointain layers + int wrID = -1; + if ( (wrID=ExtractVolumeCopy(name,AliITSUGeomTGeo::GetITSWrapVolPattern()))<0 ) { + LOG(FATAL) << "Failed to extract wrapper ID from the " << name << FairLogger::endl; + exit(1); + } + // + TObjArray* nodesW = nd->GetNodes(); + int nNodesW = nodesW->GetEntriesFast(); + for (Int_t jw=0; jwAt(jw); + if (strstr(ndW->GetName(),GetITSLayerPattern())) { + if ( (lrID=ExtractVolumeCopy(ndW->GetName(),AliITSUGeomTGeo::GetITSLayerPattern()))<0 ) { + LOG(FATAL) << "Failed to extract layer ID from the " << name << FairLogger::endl; + exit(1); + } + numberOfLayers++; + fLr2Wrapper[lrID] = wrID; + } + } + } + } + return numberOfLayers; +} + +Int_t AliITSUGeomTGeo::ExtractNumberOfStaves(Int_t lay) const +{ + // Determines the number of layers in the Upgrade Geometry + // + // Inputs: + // lay: layer number, starting from 0 + // + // MS + Int_t numberOfStaves = 0; + char laynam[30]; + snprintf(laynam, 30, "%s%d",GetITSLayerPattern(),lay); + TGeoVolume* volLr = gGeoManager->GetVolume(laynam); + if (!volLr) { LOG(FATAL) << "can't find " << laynam << " volume" << FairLogger::endl; return -1; } + + // Loop on all layer nodes, count Stave volumes by checking names + Int_t nNodes = volLr->GetNodes()->GetEntries(); + for (Int_t j=0; jGetNodes()->At(j)->GetName() << " " + // << GetITSStavePattern() << " -> " << numberOfStaves << FairLogger::endl; + if (strstr(volLr->GetNodes()->At(j)->GetName(),GetITSStavePattern())) numberOfStaves++; + } + // + return numberOfStaves; + // +} + +Int_t AliITSUGeomTGeo::ExtractNumberOfHalfStaves(Int_t lay) const +{ + // Determines the number of substaves in the stave of the layer + // + // Inputs: + // lay: layer number, starting from 0 + // + // MS + if (fgITSHalfStaveName.IsNull()) return 0; // for the setup w/o substave defined the stave and the substave is the same thing + Int_t nSS = 0; + char stavnam[30]; + snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay); + TGeoVolume* volLd = gGeoManager->GetVolume(stavnam); + if (!volLd) LOG(FATAL) << "can't find volume " << stavnam << FairLogger::endl; + // + // Loop on all stave nodes, count Chip volumes by checking names + Int_t nNodes = volLd->GetNodes()->GetEntries(); + for (Int_t j=0; jGetNodes()->At(j)->GetName(),GetITSHalfStavePattern())) nSS++; + // + return nSS; + // +} + +Int_t AliITSUGeomTGeo::ExtractNumberOfModules(Int_t lay) const +{ + // Determines the number of modules in substave in the stave of the layer + // + // Inputs: + // lay: layer number, starting from 0 + // + // for the setup w/o modules defined the module and the stave or the substave is the same thing + if (fgITSModuleName.IsNull()) return 0; + char stavnam[30]; + TGeoVolume* volLd = 0; + if (!fgITSHalfStaveName.IsNull()) { + snprintf(stavnam, 30, "%s%d", GetITSHalfStavePattern(),lay); + volLd = gGeoManager->GetVolume(stavnam); + } + if (!volLd) { // no substaves, check staves + snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay); + volLd = gGeoManager->GetVolume(stavnam); + } + if (!volLd) return 0; + Int_t nMod = 0; + // + // Loop on all substave nodes, count module volumes by checking names + Int_t nNodes = volLd->GetNodes()->GetEntries(); + for (Int_t j=0; jGetNodes()->At(j)->GetName(),GetITSModulePattern())) nMod++; + // + return nMod; + // +} + +Int_t AliITSUGeomTGeo::ExtractNChipsPerModule(Int_t lay, int &nrow) const +{ + // Determines the number of chips per module on the (sub)stave in the Upgrade Geometry + // Also extract the layout: span of module centers in Z and X + // Inputs: + // lay: layer number from 0 + // MS + Int_t numberOfChips = 0; + char stavnam[30]; + TGeoVolume* volLd = 0; + if (!fgITSModuleName.IsNull()) { + snprintf(stavnam, 30, "%s%d", GetITSModulePattern(),lay); + volLd = gGeoManager->GetVolume(stavnam); + } + if (!volLd) { // no modules on this layer, check substaves + if (!fgITSHalfStaveName.IsNull()) { + snprintf(stavnam, 30, "%s%d", GetITSHalfStavePattern(),lay); + volLd = gGeoManager->GetVolume(stavnam); + } + } + if (!volLd) { // no substaves on this layer, check staves + snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay); + volLd = gGeoManager->GetVolume(stavnam); + } + if (!volLd) LOG(FATAL) << "can't find volume containing chips on layer " << lay << FairLogger::endl; + // + // Loop on all stave nodes, count Chip volumes by checking names + Int_t nNodes = volLd->GetNodes()->GetEntries(); + // + double xmin=1e9,xmax=-1e9, zmin=1e9,zmax=-1e9; + double lab[3],loc[3]={0,0,0}; + double dx=-1,dz=-1; + for (Int_t j=0; j %d",lay,j,nNodes,volLd->GetNodes()->At(j)->GetName(),GetITSChipPattern(),numberOfChips)); + TGeoNodeMatrix* node = (TGeoNodeMatrix*)volLd->GetNodes()->At(j); + if (!strstr(node->GetName(),GetITSChipPattern())) continue; + node->LocalToMaster(loc,lab); + if (lab[0]>xmax) xmax=lab[0]; + if (lab[0]zmax) zmax=lab[2]; + if (lab[2]GetVolume()->GetShape(); + TGeoBBox* bbox = dynamic_cast(chShape); + if (!bbox) { + LOG(FATAL) << "Chip " << node->GetName() << " volume is of unprocessed shape " + << chShape->IsA()->GetName() << FairLogger::endl; + } + else { + dx = 2*bbox->GetDX(); + dz = 2*bbox->GetDZ(); + } + } + } + // + double spanX = xmax-xmin; + double spanZ = zmax-zmin; + nrow = TMath::Nint(spanX/dx + 1); + int ncol = TMath::Nint(spanZ/dz + 1); + if (nrow*ncol != numberOfChips) + LOG(ERROR) << "Inconsistency between Nchips=" << numberOfChips << " and Nrow*Ncol=" << nrow + << "*" << ncol << "->" << nrow * ncol << FairLogger::endl + << "Extracted chip dimensions (x,z): " << dx << " " << dz << " Module Span: " + << spanX << " " << spanZ << FairLogger::endl; + return numberOfChips; + // +} + +Int_t AliITSUGeomTGeo::ExtractLayerChipType(Int_t lay) const +{ + // Determines the layer detector type the Upgrade Geometry + // + // Inputs: + // lay: layer number from 0 + // Outputs: + // none + // Return: + // detector type id for the layer + // MS + char stavnam[30]; + snprintf(stavnam, 30, "%s%d", GetITSLayerPattern(),lay); + TGeoVolume* volLd = gGeoManager->GetVolume(stavnam); + if (!volLd) {LOG(FATAL) << "can't find volume " << stavnam << FairLogger::endl; return -1;} + // + return volLd->GetUniqueID(); +} + +UInt_t AliITSUGeomTGeo::ComposeChipTypeID(UInt_t segmId) +{ + if (segmId>=kMaxSegmPerChipType) LOG(FATAL) << "Id=" << segmId << " is >= max.allowed " + << kMaxSegmPerChipType << FairLogger::endl; + return segmId + kChipTypePix*kMaxSegmPerChipType; +} + +void AliITSUGeomTGeo::Print(Option_t *) const +{ + // print + printf("Geometry version %d, NLayers:%d NChips:%d\n",fVersion,fNLayers,fNChips); + if (fVersion==kITSVNA) return; + for (int i=0;iSetOwner(kTRUE); + for (int i=0;iAddAt(new TGeoHMatrix(*ExtractMatrixSens(i)),i); + CreateT2LMatrices(); +} + +void AliITSUGeomTGeo::CreateT2LMatrices() +{ + // create tracking to local (Sensor!) matrices + fMatT2L = new TObjArray(fNChips); + fMatT2L->SetOwner(kTRUE); + TGeoHMatrix matLtoT; + double locA[3]={-100,0,0},locB[3]={100,0,0},gloA[3],gloB[3]; + for (int isn=0;isnLocalToMaster(locA,gloA); + matSens->LocalToMaster(locB,gloB); + double dx = gloB[0]-gloA[0]; + double dy = gloB[1]-gloA[1]; + double t = (gloB[0]*dx+gloB[1]*dy)/(dx*dx+dy*dy),x=gloB[0]-dx*t,y=gloB[1]-dy*t; + TGeoHMatrix* t2l = new TGeoHMatrix(); + t2l->RotateZ(ATan2(y,x)*RadToDeg()); // rotate in direction of normal to the sensor plane + t2l->SetDx(x); + t2l->SetDy(y); + t2l->MultiplyLeft(&matSens->Inverse()); + fMatT2L->AddAt(t2l,isn); + /* + const double *gtrans = matSens->GetTranslation(); + memcpy(&rotMatrix[0], matSens->GetRotationMatrix(), 9*sizeof(Double_t)); + Double_t al = -ATan2(rotMatrix[1],rotMatrix[0]); + Double_t rSens = Sqrt(gtrans[0]*gtrans[0] + gtrans[1]*gtrans[1]); + Double_t tanAl = ATan2(gtrans[1],gtrans[0]) - Pi()/2; //angle of tangent + Double_t alTr = tanAl - al; + // + // The X axis of tracking frame must always look outward + loc[1] = rSens/2; + matSens->LocalToMaster(loc,glo); + double rPos = Sqrt(glo[0]*glo[0] + glo[1]*glo[1]); + Bool_t rotOutward = rPos>rSens ? kFALSE : kTRUE; + // + // Transformation matrix + matLtoT.Clear(); + matLtoT.SetDx(-rSens*Sin(alTr)); // translation + matLtoT.SetDy(0.); + matLtoT.SetDz(gtrans[2]); + // Rotation matrix + rotMatrix[0]= 0; rotMatrix[1]= 1; rotMatrix[2]= 0; // + rotation + rotMatrix[3]=-1; rotMatrix[4]= 0; rotMatrix[5]= 0; + rotMatrix[6]= 0; rotMatrix[7]= 0; rotMatrix[8]= 1; + // + TGeoRotation rot; + rot.SetMatrix(rotMatrix); + matLtoT.MultiplyLeft(&rot); + if (rotOutward) matLtoT.RotateZ(180.); + // Inverse transformation Matrix + fMatT2L->AddAt(new TGeoHMatrix(matLtoT.Inverse()),isn); + */ + } + // +} + +//______________________________________________________________________ +Int_t AliITSUGeomTGeo::ExtractVolumeCopy(const char* name, const char* prefix) const +{ + // extract Number following the prefix in the name string + TString nms = name; + if (!nms.BeginsWith(prefix)) return -1; + nms.Remove(0,strlen(prefix)); + if (!isdigit(nms.Data()[0])) return -1; + return nms.Atoi(); + // +} diff --git a/its/AliITSUGeomTGeo.h b/its/AliITSUGeomTGeo.h new file mode 100644 index 0000000000000..f2ea7da2b8231 --- /dev/null +++ b/its/AliITSUGeomTGeo.h @@ -0,0 +1,382 @@ +#ifndef ALIITSUGEOMTGEO_H +#define ALIITSUGEOMTGEO_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +///////////////////////////////////////////////////////////////////////// +// AliITSUGeomTGeo is a simple interface class to TGeoManager // +// It is used in the simulation and reconstruction in order to // +// query the TGeo ITS geometry // +// // +// author - cvetan.cheshkov@cern.ch // +// 15/02/2007 // +// adapted to ITSupg 18/07/2012 - ruben.shahoyan@cern.ch // +// RS: in order to preserve the static character of the class but // +// make it dynamically access geometry, we need to check in every // +// method if the structures are initialized. To be converted to // +// singleton at later stage. // +// // +// Note on the upgrade chip types: // +// The coarse type defines chips served by different classes, // +// like Pix. Each such a chip type can have kMaxSegmPerChipType // +// segmentations (pitch etc.) whose parameteres are stored in the // +// AliITSsegmentation derived class (like AliITSUSegmentationPix) // +// This allows to have in the setup chips served by the same // +// classes but with different segmentations. // +// The full chip type is composed as: // +// CoarseType*kMaxSegmPerChipType + segmentationType // +// The only requirement on the segmentationType that should be // +// < kMaxSegmPerChipType. // +// The methods like GetLayerChipTypeID return the full chip type // +// // +// // +///////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +//FIXME: This is temporary and you have to remove it to avoid cyclic deps +#include + +class TGeoPNEntry; +class TDatime; +class AliITSsegmentation; + +/** From AliITSUAux */ +const UInt_t kMaxLayers = 15; // max number of active layers + +class AliITSUGeomTGeo : public TObject { + + public: + enum {kITSVNA, kITSVUpg}; // ITS version + enum {kChipTypePix=0, kNChipTypes, kMaxSegmPerChipType=10}; // defined detector chip types (each one can have different segmentations) + // + AliITSUGeomTGeo(Bool_t build = kFALSE, Bool_t loadSegmentations = kTRUE); + virtual ~AliITSUGeomTGeo(); + AliITSUGeomTGeo(const AliITSUGeomTGeo &src); + AliITSUGeomTGeo& operator=(const AliITSUGeomTGeo &geom); + // + Int_t GetNChips() const {return fNChips;} + Int_t GetNChipRowsPerModule(Int_t lay) const {return fNChipRowsPerModule[lay];} + Int_t GetNChipColsPerModule(Int_t lay) const {return fNChipRowsPerModule[lay] ? fNChipsPerModule[lay]/fNChipRowsPerModule[lay] : -1;} + Int_t GetNChipsPerModule(Int_t lay) const {return fNChipsPerModule[lay];} + Int_t GetNChipsPerHalfStave(Int_t lay) const {return fNChipsPerHalfStave[lay];} + Int_t GetNChipsPerStave(Int_t lay) const {return fNChipsPerStave[lay];} + Int_t GetNChipsPerLayer(Int_t lay) const {return fNChipsPerLayer[lay];} + Int_t GetNModules(Int_t lay) const {return fNModules[lay];} + Int_t GetNHalfStaves(Int_t lay) const {return fNHalfStaves[lay];} + Int_t GetNStaves(Int_t lay) const {return fNStaves[lay];} + Int_t GetNLayers() const {return fNLayers;} + + Int_t GetChipIndex(Int_t lay,int detInLay) const {return GetFirstChipIndex(lay)+detInLay;} + Int_t GetChipIndex(Int_t lay,Int_t sta,Int_t detInSta) const; + Int_t GetChipIndex(Int_t lay,Int_t sta, Int_t subSta, Int_t detInSubSta) const; + Int_t GetChipIndex(Int_t lay,Int_t sta, Int_t subSta, Int_t md, Int_t detInMod) const; + Bool_t GetChipId(Int_t index,Int_t &lay,Int_t &sta,Int_t &ssta,Int_t &mod,Int_t &chip) const; + Int_t GetLayer(Int_t index) const; + Int_t GetStave(Int_t index) const; + Int_t GetHalfStave(Int_t index) const; + Int_t GetModule(Int_t index) const; + Int_t GetChipIdInLayer(Int_t index) const; + Int_t GetChipIdInStave(Int_t index) const; + Int_t GetChipIdInHalfStave(Int_t index) const; + Int_t GetChipIdInModule(Int_t index) const; + // + Int_t GetLastChipIndex(Int_t lay) const {return fLastChipIndex[lay];} + Int_t GetFirstChipIndex(Int_t lay) const {return (lay==0) ? 0:fLastChipIndex[lay-1]+1;} + // + const char *GetSymName(Int_t index) const; + const char *GetSymName(Int_t lay,Int_t sta,Int_t det) const; + // + // Attention: these are the matrices for the alignable volumes of the chips, i.e. not necessarily the sensors + TGeoHMatrix* GetMatrix(Int_t index) const; + TGeoHMatrix* GetMatrix(Int_t lay,Int_t sta,Int_t det) const; + Bool_t GetTranslation(Int_t index, Double_t t[3]) const; + Bool_t GetTranslation(Int_t lay,Int_t sta,Int_t det, Double_t t[3]) const; + Bool_t GetRotation(Int_t index, Double_t r[9]) const; + Bool_t GetRotation(Int_t lay,Int_t sta,Int_t det, Double_t r[9]) const; + Bool_t GetOrigMatrix(Int_t index, TGeoHMatrix &m) const; + Bool_t GetOrigMatrix(Int_t lay,Int_t sta,Int_t det, TGeoHMatrix &m) const; + Bool_t GetOrigTranslation(Int_t index, Double_t t[3]) const; + Bool_t GetOrigTranslation(Int_t lay,Int_t sta,Int_t det, Double_t t[3]) const; + Bool_t GetOrigRotation(Int_t index, Double_t r[9]) const; + Bool_t GetOrigRotation(Int_t lay,Int_t sta,Int_t det, Double_t r[9]) const; + // + const TGeoHMatrix* GetMatrixT2L(Int_t index); + const TGeoHMatrix* GetMatrixT2L(Int_t lay,Int_t sta,Int_t det) {return GetMatrixT2L( GetChipIndex(lay,sta,det) );} + const TGeoHMatrix* GetMatrixSens(Int_t index); + const TGeoHMatrix* GetMatrixSens(Int_t lay,Int_t sta,Int_t det) {return GetMatrixSens( GetChipIndex(lay,sta,det) );} + // + Bool_t GetTrackingMatrix(Int_t index, TGeoHMatrix &m); + Bool_t GetTrackingMatrix(Int_t lay,Int_t sta,Int_t det, TGeoHMatrix &m); + // + // Attention: these are transformations wrt sensitive volume! + void LocalToGlobal(Int_t index, const Double_t *loc, Double_t *glob); + void LocalToGlobal(Int_t lay, Int_t sta, Int_t det,const Double_t *loc, Double_t *glob); + // + void GlobalToLocal(Int_t index, const Double_t *glob, Double_t *loc); + void GlobalToLocal(Int_t lay, Int_t sta, Int_t det,const Double_t *glob, Double_t *loc); + // + void LocalToGlobalVect(Int_t index, const Double_t *loc, Double_t *glob); + void GlobalToLocalVect(Int_t index, const Double_t *glob, Double_t *loc); + Int_t GetLayerChipTypeID(Int_t lr) const; + Int_t GetChipChipTypeID(Int_t id) const; + // + const AliITSsegmentation* GetSegmentationByID(Int_t id) const; + const AliITSsegmentation* GetSegmentation(Int_t lr) const; + TObjArray* GetSegmentations() const {return (TObjArray*)fSegm;} + virtual void Print(Option_t *opt="") const; + // + static UInt_t GetUIDShift() {return fgUIDShift;} + static void SetUIDShift(UInt_t s=16) {fgUIDShift = s<16 ? s:16;} + // + static const char* GetITSVolPattern() {return fgITSVolName.Data();} + static const char* GetITSLayerPattern() {return fgITSLrName.Data();} + static const char* GetITSWrapVolPattern() {return fgITSWrapVolName.Data();} + static const char* GetITSStavePattern() {return fgITSStaveName.Data();} + static const char* GetITSHalfStavePattern() {return fgITSHalfStaveName.Data();} + static const char* GetITSModulePattern() {return fgITSModuleName.Data();} + static const char* GetITSChipPattern() {return fgITSChipName.Data();} + static const char* GetITSSensorPattern() {return fgITSSensName.Data();} + static const char* GetITSsegmentationFileName() {return fgITSsegmFileName.Data();} + static const char* GetChipTypeName(Int_t i); + + static void SetITSVolPattern(const char* nm) {fgITSVolName = nm;} + static void SetITSLayerPattern(const char* nm) {fgITSLrName = nm;} + static void SetITSWrapVolPattern(const char* nm) {fgITSWrapVolName = nm;} + static void SetITSStavePattern(const char* nm) {fgITSStaveName = nm;} + static void SetITSHalfStavePattern(const char* nm) {fgITSHalfStaveName = nm;} + static void SetITSModulePattern(const char* nm) {fgITSModuleName = nm;} + static void SetITSChipPattern(const char* nm) {fgITSChipName = nm;} + static void SetITSSensorPattern(const char* nm) {fgITSSensName = nm;} + static void SetChipTypeName(Int_t i,const char* nm); + static void SetITSsegmentationFileName(const char* nm) {fgITSsegmFileName = nm;} + static UInt_t ComposeChipTypeID(UInt_t segmId); + // + static const char *ComposeSymNameITS(); + static const char *ComposeSymNameLayer(Int_t lr); + static const char *ComposeSymNameStave(Int_t lr, Int_t sta); + static const char *ComposeSymNameHalfStave(Int_t lr, Int_t sta, Int_t ssta); + static const char *ComposeSymNameModule(Int_t lr, Int_t sta, Int_t ssta, Int_t mod); + static const char *ComposeSymNameChip(Int_t lr, Int_t sta, Int_t ssta, Int_t mod, Int_t chip); + // + // hack to avoid using AliGeomManager + Int_t LayerToVolUID(Int_t lay,int detInLay) const {return ChipVolUID(GetChipIndex(lay,detInLay));} + static Int_t ChipVolUID(Int_t mod) {return (mod&0xffff)< wrapper correspondence + // + TObjArray* fMatSens; // Sensor's matrices pointers in the geometry + TObjArray* fMatT2L; // Tracking to Local matrices pointers in the geometry + TObjArray* fSegm; // segmentations + // + static UInt_t fgUIDShift; // bit shift to go from mod.id to modUUID for TGeo + static TString fgITSVolName; // ITS mother volume name + static TString fgITSLrName; // ITS Layer name + static TString fgITSStaveName; // ITS Stave name + static TString fgITSHalfStaveName; // ITS HalfStave name + static TString fgITSModuleName; // ITS Module name + static TString fgITSChipName; // ITS Chip name + static TString fgITSSensName; // ITS Sensor name + static TString fgITSWrapVolName; // ITS Wrapper volume name + static TString fgITSChipTypeName[kNChipTypes]; // ITS upg detType Names + // + static TString fgITSsegmFileName; // file name for segmentations + // + ClassDef(AliITSUGeomTGeo, 2) // ITS geometry based on TGeo +}; + +//_____________________________________________________________________________________________ +inline const char *AliITSUGeomTGeo::GetSymName(Int_t lay,Int_t sta,Int_t det) const +{ + // sym name + return GetSymName(GetChipIndex(lay,sta,det)); +} + +//_____________________________________________________________________________________________ +inline TGeoHMatrix* AliITSUGeomTGeo::GetMatrix(Int_t lay,Int_t sta,Int_t det) const +{ + // chip current matrix + return GetMatrix(GetChipIndex(lay,sta,det)); +} + +//_____________________________________________________________________________________________ +inline Bool_t AliITSUGeomTGeo::GetTranslation(Int_t lay,Int_t sta,Int_t det, Double_t t[3]) const +{ + // translation + return GetTranslation(GetChipIndex(lay,sta,det),t); +} + +//_____________________________________________________________________________________________ +inline Bool_t AliITSUGeomTGeo::GetRotation(Int_t lay,Int_t sta,Int_t det, Double_t r[9]) const +{ + // rot + return GetRotation(GetChipIndex(lay,sta,det),r); +} + +//_____________________________________________________________________________________________ +inline Bool_t AliITSUGeomTGeo::GetOrigMatrix(Int_t lay,Int_t sta,Int_t det, TGeoHMatrix &m) const +{ + // orig matrix + return GetOrigMatrix(GetChipIndex(lay,sta,det),m); +} + +//_____________________________________________________________________________________________ +inline Bool_t AliITSUGeomTGeo::GetOrigTranslation(Int_t lay,Int_t sta,Int_t det, Double_t t[3]) const +{ + // orig trans + return GetOrigTranslation(GetChipIndex(lay,sta,det),t); +} + +//_____________________________________________________________________________________________ +inline Bool_t AliITSUGeomTGeo::GetOrigRotation(Int_t lay,Int_t sta,Int_t det, Double_t r[9]) const +{ + // orig rot + return GetOrigRotation(GetChipIndex(lay,sta,det),r); +} + +//_____________________________________________________________________________________________ +inline Bool_t AliITSUGeomTGeo::GetTrackingMatrix(Int_t lay,Int_t sta,Int_t det, TGeoHMatrix &m) +{ + // tracking mat + return GetTrackingMatrix(GetChipIndex(lay,sta,det),m); +} + +//_____________________________________________________________________________________________ +inline Int_t AliITSUGeomTGeo::GetLayerChipTypeID(Int_t lr) const +{ + // detector type ID of layer + return fLrChipType[lr]; +} + +//_____________________________________________________________________________________________ +inline Int_t AliITSUGeomTGeo::GetChipChipTypeID(Int_t id) const +{ + // detector type ID of chip + return GetLayerChipTypeID(GetLayer(id)); +} + +//_____________________________________________________________________________________________ +inline const TGeoHMatrix* AliITSUGeomTGeo::GetMatrixSens(Int_t index) +{ + // access global to sensor matrix + if (!fMatSens) FetchMatrices(); + return (TGeoHMatrix*)fMatSens->At(index); +} + +//_____________________________________________________________________________________________ +inline const TGeoHMatrix* AliITSUGeomTGeo::GetMatrixT2L(Int_t index) +{ + // access tracking to local matrix + if (!fMatT2L) FetchMatrices(); + return (TGeoHMatrix*)fMatT2L->At(index); +} + +//______________________________________________________________________ +inline void AliITSUGeomTGeo::LocalToGlobal(Int_t index,const Double_t *loc, Double_t *glob) +{ + // sensor local to global + GetMatrixSens(index)->LocalToMaster(loc,glob); +} + +//______________________________________________________________________ +inline void AliITSUGeomTGeo::GlobalToLocal(Int_t index, const Double_t *glob, Double_t *loc) +{ + // global to sensor local + GetMatrixSens(index)->MasterToLocal(glob,loc); +} + +//______________________________________________________________________ +inline void AliITSUGeomTGeo::LocalToGlobalVect(Int_t index, const Double_t *loc, Double_t *glob) +{ + // sensor local to global + GetMatrixSens(index)->LocalToMasterVect(loc,glob); +} + +//______________________________________________________________________ +inline void AliITSUGeomTGeo::GlobalToLocalVect(Int_t index, const Double_t *glob, Double_t *loc) +{ + // global to sensor local + GetMatrixSens(index)->MasterToLocalVect(glob,loc); +} + +//_____________________________________________________________________________________________ +inline void AliITSUGeomTGeo::LocalToGlobal(Int_t lay, Int_t sta, Int_t det,const Double_t *loc, Double_t *glob) +{ + // Local2Master (sensor) + LocalToGlobal(GetChipIndex(lay,sta,det), loc, glob); +} + +//_____________________________________________________________________________________________ +inline void AliITSUGeomTGeo::GlobalToLocal(Int_t lay, Int_t sta, Int_t det,const Double_t *glob, Double_t *loc) +{ + // master2local (sensor) + GlobalToLocal(GetChipIndex(lay,sta,det), glob, loc); +} + +//_____________________________________________________________________________________________ +inline const char* AliITSUGeomTGeo::GetChipTypeName(Int_t i) +{ + if (i>=kNChipTypes) i/=kMaxSegmPerChipType; // full type is provided + return fgITSChipTypeName[i].Data(); +} + +//_____________________________________________________________________________________________ +inline void AliITSUGeomTGeo::SetChipTypeName(Int_t i, const char* nm) +{ + if (i>=kNChipTypes) i/=kMaxSegmPerChipType; // full type is provided + fgITSChipTypeName[i] = nm; +} + +//_____________________________________________________________________________________________ +inline const AliITSsegmentation* AliITSUGeomTGeo::GetSegmentationByID(Int_t id) const +{ + // get segmentation by ID + return fSegm ? (AliITSsegmentation*)fSegm->At(id) : 0; +} + +//_____________________________________________________________________________________________ +inline const AliITSsegmentation* AliITSUGeomTGeo::GetSegmentation(Int_t lr) const +{ + // get segmentation of layer + return fSegm ? (AliITSsegmentation*)fSegm->At( GetLayerChipTypeID(lr) ) : 0; +} + +#endif diff --git a/its/AliITSUSegmentationPix.cxx b/its/AliITSUSegmentationPix.cxx new file mode 100644 index 0000000000000..86e288a13755d --- /dev/null +++ b/its/AliITSUSegmentationPix.cxx @@ -0,0 +1,575 @@ +/************************************************************************** + * 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: AliITSUSegmentationPix.cxx 47180 2011-02-08 09:42:29Z masera $ */ +#include +#include +#include +#include +#include +#include +#include +#include "AliITSUGeomTGeo.h" +#include "AliITSUSegmentationPix.h" + +using namespace TMath; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Segmentation class for pixels // +// Questions to solve: are guardrings needed and do they belong to the sensor or to the chip in TGeo // +// At the moment assume that the local coord syst. is located at bottom left corner // +// of the ACTIVE matrix. If the guardring to be accounted in the local coords, in // +// the Z and X conversions one needs to first subtract the fGuardLft and fGuardBot // +// from the local Z,X coordinates // +// // +//////////////////////////////////////////////////////////////////////////////////////////////////////////// + +ClassImp(AliITSUSegmentationPix) + +const char* AliITSUSegmentationPix::fgkSegmListName = "ITSUSegmentations"; + +AliITSUSegmentationPix::AliITSUSegmentationPix(UInt_t id, int nchips,int ncol,int nrow, + float pitchX,float pitchZ, + float thickness, + float pitchLftC,float pitchRgtC, + float edgL,float edgR,float edgT,float edgB) +: AliITSsegmentation() + ,fGuardLft(edgL) + ,fGuardRgt(edgR) + ,fGuardTop(edgT) + ,fGuardBot(edgB) + ,fShiftXLoc(0.5*(edgT-edgB)) + ,fShiftZLoc(0.5*(edgR-edgL)) + ,fDxActive(0) + ,fDzActive(0) + ,fPitchX(pitchX) + ,fPitchZ(pitchZ) + ,fPitchZLftCol(pitchLftC<0 ? pitchZ:pitchLftC) + ,fPitchZRgtCol(pitchRgtC<0 ? pitchZ:pitchRgtC) + ,fChipDZ(0) + ,fNChips(nchips) + ,fNColPerChip(nchips>0 ? ncol/nchips:0) + ,fNRow(nrow) + ,fNCol(ncol) + ,fDiodShiftMatNCol(0) + ,fDiodShiftMatNRow(0) + ,fDiodShiftMatDim(0) + ,fDiodShidtMatX(0) + ,fDiodShidtMatZ(0) +{ + // Default constructor, sizes in cm + if (nchips) SetUniqueID( AliITSUGeomTGeo::ComposeChipTypeID(id) ); + fChipDZ = (fNColPerChip-2)*fPitchZ + fPitchZLftCol + fPitchZRgtCol;; + fDxActive = fNRow*fPitchX; + fDzActive = fNChips*fChipDZ; + SetDetSize( fDxActive + fGuardTop+fGuardBot, + fDzActive + fGuardLft+fGuardRgt, + thickness); +} + +AliITSUSegmentationPix::~AliITSUSegmentationPix() +{ + // d-tor + delete[] fDiodShidtMatX; + delete[] fDiodShidtMatZ; +} + +void AliITSUSegmentationPix::GetPadIxz(Float_t x,Float_t z,Int_t &ix,Int_t &iz) const +{ + // Returns pixel coordinates (ix,iz) for given coordinates (x,z counted from corner of col/row 0:0) + // expects x, z in cm. + ix = int(x/fPitchX); + iz = int(Z2Col(z)); + // + if (iz<0) { LOG(WARNING) << "Z=" << z << " gives col=" << iz << " outside [0:" + << fNCol << ")" << FairLogger::endl; iz=0; } + else if (iz >= fNCol) { LOG(WARNING) << "Z=" << z << " gives col=" << iz << " outside [0:" + << fNCol << ")" << FairLogger::endl; iz= fNCol-1;} + if (ix<0) { LOG(WARNING) << "X=" << x << " gives row=" << ix << " outside [0:" + << fNRow << ")" << FairLogger::endl; ix=0; } + else if (ix >= fNRow) { LOG(WARNING) << "X=" << x << " gives row=" << ix << " outside [0:" + << fNRow << ")" << FairLogger::endl; ix= fNRow-1;} + // +} + +void AliITSUSegmentationPix::GetPadTxz(Float_t &x,Float_t &z) const +{ + // local transformation of real local coordinates (x,z) + // expects x, z in cm (wrt corner of col/row 0:0 + x /= fPitchX; + z = Z2Col(z); + // +} + +void AliITSUSegmentationPix::GetPadCxz(Int_t ix,Int_t iz,Float_t &x,Float_t&z) const +{ + // Transform from pixel to real local coordinates + // returns x, z in cm. wrt corner of col/row 0:0 + x = Float_t((ix+0.5)*fPitchX); + z = Col2Z(iz); + // +} + +Float_t AliITSUSegmentationPix::Z2Col(Float_t z) const +{ + // get column number (from 0) from local Z (wrt bottom left corner of the active matrix) + int chip = int(z/fChipDZ); + float col = chip*fNColPerChip; + z -= chip*fChipDZ; + if (z>fPitchZLftCol) col += 1+(z-fPitchZLftCol)/fPitchZ; + return col; +} + +Float_t AliITSUSegmentationPix::Col2Z(Int_t col) const +{ + // convert column number (from 0) to Z coordinate wrt bottom left corner of the active matrix + int nchip = col/fNColPerChip; + col %= fNColPerChip; + float z = nchip*fChipDZ; + if (col>0) { + if (colDxActive()) return kFALSE; // outside x range. + if(z<0 || z>DzActive()) return kFALSE; // outside z range. + ix = int(x/fPitchX); + iz = Z2Col(z); + return kTRUE; // Found ix and iz, return. +} + +void AliITSUSegmentationPix::DetToLocal(Int_t ix,Int_t iz,Float_t &x,Float_t &z) const +{ +// Transformation from Detector cell coordiantes to Geant detector centered +// local coordinates (cm). +// Input: +// Int_t ix detector x cell coordinate. Has the range 0<=ix=fNRow) {LOG(WARNING) << "Obtained row " << ix << " is not in range [0:" << fNRow + << ")" << FairLogger::endl; return;} // outside of detector + if(iz<0 || iz>=fNCol) {LOG(WARNING) << "Obtained col " << ix << " is not in range [0:" << fNCol + << ")" << FairLogger::endl; return;} // outside of detector + x += (ix+0.5)*fPitchX - fShiftXLoc; // RS: we go to the center of the pad, i.e. + pitch/2, not to the boundary as in SPD + z += Col2Z(iz) - fShiftZLoc; + return; // Found x and z, return. +} + +void AliITSUSegmentationPix::CellBoundries(Int_t ix,Int_t iz,Double_t &xl,Double_t &xu,Double_t &zl,Double_t &zu) const +{ + // Transformation from Detector cell coordiantes to Geant detector centerd + // local coordinates (cm). + // Input: + // Int_t ix detector x cell coordinate. Has the range 0<=ix=fNRow || iz<0 || iz>=fNCol) { + xl = xu = -0.5*Dx(); // default value. + zl = zu = -0.5*Dz(); // default value. + return; // outside of detctor + } + float zpitchH = Dpz(iz)*0.5; + float xpitchH = fPitchX*0.5; + xl -= xpitchH; + xu += xpitchH; + zl -= zpitchH; + zu += zpitchH; + return; // Found x and z, return. +} + +Int_t AliITSUSegmentationPix::GetChipFromChannel(Int_t, Int_t iz) const +{ + // returns chip number (in range 0-4) starting from channel number + if(iz>=fNCol || iz<0 ){ + LOG(WARNING) << "Bad cell number" << FairLogger::endl; + return -1; + } + return iz/fNColPerChip; +} + +Int_t AliITSUSegmentationPix::GetChipFromLocal(Float_t, Float_t zloc) const +{ + // returns chip number (in range 0-4) starting from local Geant coordinates + Int_t ix0,iz; + if (!LocalToDet(0,zloc,ix0,iz)) { + LOG(WARNING) << "Bad local coordinate" << FairLogger::endl; + return -1; + } + return GetChipFromChannel(ix0,iz); +} + +Int_t AliITSUSegmentationPix::GetChipsInLocalWindow(Int_t* array, Float_t zmin, Float_t zmax, Float_t, Float_t) const +{ + // returns the number of chips containing a road defined by given local Geant coordinate limits + if (zmin>zmax) { + LOG(WARNING) << "Bad coordinate limits: zmin>zmax!" << FairLogger::endl; + return -1; + } + + Int_t nChipInW = 0; + + Float_t zminDet = -0.5*DzActive()-fShiftZLoc; + Float_t zmaxDet = 0.5*DzActive()-fShiftZLoc; + if(zminzmaxDet) zmax=zmaxDet; + + Int_t n1 = GetChipFromLocal(0,zmin); + array[nChipInW] = n1; + nChipInW++; + + Int_t n2 = GetChipFromLocal(0,zmax); + + if(n2!=n1){ + Int_t imin=Min(n1,n2); + Int_t imax=Max(n1,n2); + for(Int_t ichip=imin; ichip<=imax; ichip++){ + if(ichip==n1) continue; + array[nChipInW]=ichip; + nChipInW++; + } + } + return nChipInW; +} + +void AliITSUSegmentationPix::Init() +{ + // init settings +} + +Bool_t AliITSUSegmentationPix::Store(const char* outf) +{ + // store in the special list under given ID + TString fns = outf; + gSystem->ExpandPathName(fns); + if (fns.IsNull()) {LOG(FATAL) << "No file name provided" << FairLogger::endl; return kFALSE;} + TFile* fout = TFile::Open(fns.Data(),"update"); + if (!fout) {LOG(FATAL) << "Failed to open output file " << outf << FairLogger::endl; return kFALSE;} + TObjArray* arr = (TObjArray*)fout->Get(fgkSegmListName); + int id = GetUniqueID(); + if (!arr) arr = new TObjArray(); + else if (arr->At(id)) {LOG(FATAL) << "Segmenation " << id << " already exists in file " + << outf << FairLogger::endl; return kFALSE;} + + arr->AddAtAndExpand(this,id); + arr->SetOwner(kTRUE); + fout->WriteObject(arr,fgkSegmListName,"kSingleKey"); + fout->Close(); + delete fout; + arr->RemoveAt(id); + delete arr; + LOG(INFO) << "Stored segmentation " << id << " in " << outf << FairLogger::endl; + return kTRUE; +} + + +AliITSUSegmentationPix* AliITSUSegmentationPix::LoadWithID(UInt_t id, const char* inpf) +{ + // store in the special list under given ID + TString fns = inpf; + gSystem->ExpandPathName(fns); + if (fns.IsNull()) {LOG(FATAL) << "LoadWithID: No file name provided" << FairLogger::endl; return 0;} + TFile* finp = TFile::Open(fns.Data()); + if (!finp) {LOG(FATAL) << "LoadWithID: Failed to open file " << inpf << FairLogger::endl; return 0;} + TObjArray* arr = (TObjArray*)finp->Get(fgkSegmListName); + if (!arr) { + LOG(FATAL) << "LoadWithID: Failed to find segmenation array " << fgkSegmListName + << " in " << inpf << FairLogger::endl; + return 0; + } + AliITSUSegmentationPix* segm = dynamic_cast(arr->At(id)); + if (!segm || segm->GetUniqueID()!=id) {LOG(FATAL) << "LoadWithID: Failed to find segmenation " + << id << " in " << inpf << FairLogger::endl; return 0;} + + arr->RemoveAt(id); + arr->SetOwner(kTRUE); // to not leave in memory other segmenations + finp->Close(); + delete finp; + delete arr; + + return segm; +} + +void AliITSUSegmentationPix::LoadSegmentations(TObjArray* dest, const char* inpf) +{ + // store in the special list under given ID + if (!dest) return; + TString fns = inpf; + gSystem->ExpandPathName(fns); + if (fns.IsNull()) LOG(FATAL) << "LoadWithID: No file name provided" << FairLogger::endl; + TFile* finp = TFile::Open(fns.Data()); + if (!finp) LOG(FATAL) << "LoadWithID: Failed to open file " << inpf << FairLogger::endl; + TObjArray* arr = (TObjArray*)finp->Get(fgkSegmListName); + if (!arr) LOG(FATAL) << "LoadWithID: Failed to find segmentation array " << fgkSegmListName + << " in " << inpf << FairLogger::endl; + int nent = arr->GetEntriesFast(); + TObject *segm = 0; + for (int i=nent;i--;) if ((segm=arr->At(i))) dest->AddAtAndExpand(segm,segm->GetUniqueID()); + LOG(INFO) << "LoadSegmentations: Loaded " << arr->GetEntries() << " segmentations from " + << inpf << FairLogger::endl; + arr->SetOwner(kFALSE); + arr->Clear(); + finp->Close(); + delete finp; + delete arr; +} + +void AliITSUSegmentationPix::SetDiodShiftMatrix(Int_t nrow,Int_t ncol, const Float_t *shiftX, const Float_t *shiftZ) +{ + // set matrix of periodic shifts of diod center. provided arrays must be in the format shift[nrow][ncol] + if (fDiodShiftMatDim) { + delete fDiodShidtMatX; + delete fDiodShidtMatZ; + fDiodShidtMatX = fDiodShidtMatZ = 0; + } + fDiodShiftMatNCol = ncol; + fDiodShiftMatNRow = nrow; + fDiodShiftMatDim = fDiodShiftMatNCol*fDiodShiftMatNRow; + if (fDiodShiftMatDim) { + fDiodShidtMatX = new Float_t[fDiodShiftMatDim]; + fDiodShidtMatZ = new Float_t[fDiodShiftMatDim]; + for (int ir=0;ir DX: %.1f DZ: %.1f Shift: x:%.1f z:%.1f\n", + kmc*fGuardBot,kmc*fGuardRgt,kmc*fGuardTop,kmc*fGuardLft,kmc*Dx(),kmc*Dz(),kmc*fShiftXLoc,kmc*fShiftZLoc); + printf("%d chips along Z: chip Ncol=%d Nrow=%d\n",fNChips, fNColPerChip,fNRow); + if (Abs(fPitchZLftCol-fPitchZ)>1e-5) printf("Special left column pitch: %.1f\n",fPitchZLftCol*kmc); + if (Abs(fPitchZRgtCol-fPitchZ)>1e-5) printf("Special right column pitch: %.1f\n",fPitchZRgtCol*kmc); + + if (fDiodShiftMatDim) { + double dx,dz=0; + printf("Diod shift (fraction of pitch) periodicity pattern (X,Z[row][col])\n"); + for (int irow=0;irow +// Chinorat Kobdaj (kobdaj@g.sut.ac.th) +//************************************************************************* + + +/* $Id: AliITSUv1Layer.cxx */ +// General Root includes +#include +// Root Geometry includes +#include +#include +#include +#include +#include // contaings TGeoTubeSeg +#include +#include +#include +#include +#include "AliITSUv1Layer.h" +#include "AliITSUGeomTGeo.h" +#include +#include +#include +#include "FairLogger.h" + +using namespace TMath; + +// General Parameters +const Int_t AliITSUv1Layer::fgkNumberOfInnerLayers = 3; + +const Double_t AliITSUv1Layer::fgkDefaultSensorThick = 300*fgkmicron; +const Double_t AliITSUv1Layer::fgkDefaultStaveThick = 1*fgkcm; + +// Inner Barrel Parameters +const Int_t AliITSUv1Layer::fgkIBChipsPerRow = 9; +const Int_t AliITSUv1Layer::fgkIBNChipRows = 1; + +// Outer Barrel Parameters +const Int_t AliITSUv1Layer::fgkOBChipsPerRow = 7; +const Int_t AliITSUv1Layer::fgkOBNChipRows = 2; + +const Double_t AliITSUv1Layer::fgkOBHalfStaveWidth = 3.01 *fgkcm; +const Double_t AliITSUv1Layer::fgkOBModuleWidth = fgkOBHalfStaveWidth; +const Double_t AliITSUv1Layer::fgkOBModuleGap = 0.01 *fgkcm; +const Double_t AliITSUv1Layer::fgkOBChipXGap = 0.01 *fgkcm; +const Double_t AliITSUv1Layer::fgkOBChipZGap = 0.01 *fgkcm; +const Double_t AliITSUv1Layer::fgkOBFlexCableAlThick = 0.005*fgkcm; +const Double_t AliITSUv1Layer::fgkOBFlexCableKapThick = 0.01 *fgkcm; +const Double_t AliITSUv1Layer::fgkOBBusCableAlThick = 0.02 *fgkcm; +const Double_t AliITSUv1Layer::fgkOBBusCableKapThick = 0.02 *fgkcm; +const Double_t AliITSUv1Layer::fgkOBColdPlateThick = 0.012*fgkcm; +const Double_t AliITSUv1Layer::fgkOBCarbonPlateThick = 0.012*fgkcm; +const Double_t AliITSUv1Layer::fgkOBGlueThick = 0.03 *fgkcm; +const Double_t AliITSUv1Layer::fgkOBModuleZLength = 21.06 *fgkcm; +const Double_t AliITSUv1Layer::fgkOBHalfStaveYTrans = 1.76 *fgkmm; +const Double_t AliITSUv1Layer::fgkOBHalfStaveXOverlap = 4.3 *fgkmm; +const Double_t AliITSUv1Layer::fgkOBGraphiteFoilThick = 30.0 *fgkmicron; +const Double_t AliITSUv1Layer::fgkOBCoolTubeInnerD = 2.052*fgkmm; +const Double_t AliITSUv1Layer::fgkOBCoolTubeThick = 32.0 *fgkmicron; +const Double_t AliITSUv1Layer::fgkOBCoolTubeXDist = 11.1 *fgkmm; + +const Double_t AliITSUv1Layer::fgkOBSpaceFrameWidth = 42.0 *fgkmm; +const Double_t AliITSUv1Layer::fgkOBSpaceFrameTotHigh = 43.1 *fgkmm; +const Double_t AliITSUv1Layer::fgkOBSFrameBeamRadius = 0.6 *fgkmm; +const Double_t AliITSUv1Layer::fgkOBSpaceFrameLa = 3.0 *fgkmm; +const Double_t AliITSUv1Layer::fgkOBSpaceFrameHa = 0.721979*fgkmm; +const Double_t AliITSUv1Layer::fgkOBSpaceFrameLb = 3.7 *fgkmm; +const Double_t AliITSUv1Layer::fgkOBSpaceFrameHb = 0.890428*fgkmm; +const Double_t AliITSUv1Layer::fgkOBSpaceFrameL = 0.25 *fgkmm; +const Double_t AliITSUv1Layer::fgkOBSFBotBeamAngle = 56.5; +const Double_t AliITSUv1Layer::fgkOBSFrameBeamSidePhi = 65.0; + +ClassImp(AliITSUv1Layer) + +#define SQ(A) (A)*(A) + +AliITSUv1Layer::AliITSUv1Layer(): + AliITSv11Geometry(), + fLayerNumber(0), + fPhi0(0), + fLayRadius(0), + fZLength(0), + fSensorThick(0), + fStaveThick(0), + fStaveWidth(0), + fStaveTilt(0), + fNStaves(0), + fNModules(0), + fNChips(0), + fChipTypeID(0), + fIsTurbo(0), + fBuildLevel(0), + fStaveModel(O2its::kIBModelDummy) +{ + // + // Standard constructor + for (int i=kNHLevels;i--;) fHierarchy[i] = 0; + // +} + +AliITSUv1Layer::AliITSUv1Layer(Int_t debug): + AliITSv11Geometry(debug), + fLayerNumber(0), + fPhi0(0), + fLayRadius(0), + fZLength(0), + fSensorThick(0), + fStaveThick(0), + fStaveWidth(0), + fStaveTilt(0), + fNStaves(0), + fNModules(0), + fNChips(0), + fChipTypeID(0), + fIsTurbo(0), + fBuildLevel(0), + fStaveModel(O2its::kIBModelDummy) +{ + // + // Constructor setting debugging level + for (int i=kNHLevels;i--;) fHierarchy[i] = 0; + // +} + +AliITSUv1Layer::AliITSUv1Layer(Int_t lay, Int_t debug): + AliITSv11Geometry(debug), + fLayerNumber(lay), + fPhi0(0), + fLayRadius(0), + fZLength(0), + fSensorThick(0), + fStaveThick(0), + fStaveWidth(0), + fStaveTilt(0), + fNStaves(0), + fNModules(0), + fNChips(0), + fChipTypeID(0), + fIsTurbo(0), + fBuildLevel(0), + fStaveModel(O2its::kIBModelDummy) +{ + // + // Constructor setting layer number and debugging level + for (int i=kNHLevels;i--;) fHierarchy[i] = 0; + // +} + +AliITSUv1Layer::AliITSUv1Layer(Int_t lay, Bool_t turbo, Int_t debug): + AliITSv11Geometry(debug), + fLayerNumber(lay), + fPhi0(0), + fLayRadius(0), + fZLength(0), + fSensorThick(0), + fStaveThick(0), + fStaveWidth(0), + fStaveTilt(0), + fNStaves(0), + fNModules(0), + fNChips(0), + fChipTypeID(0), + fIsTurbo(turbo), + fBuildLevel(0), + fStaveModel(O2its::kIBModelDummy) +{ + // + // Constructor setting layer number and debugging level + // for a "turbo" layer (i.e. where staves overlap in phi) + for (int i=kNHLevels;i--;) fHierarchy[i] = 0; + // +} + +AliITSUv1Layer::AliITSUv1Layer(const AliITSUv1Layer &s): + AliITSv11Geometry(s.GetDebug()), + fLayerNumber(s.fLayerNumber), + fPhi0(s.fPhi0), + fLayRadius(s.fLayRadius), + fZLength(s.fZLength), + fSensorThick(s.fSensorThick), + fStaveThick(s.fStaveThick), + fStaveWidth(s.fStaveWidth), + fStaveTilt(s.fStaveTilt), + fNStaves(s.fNStaves), + fNModules(s.fNModules), + fNChips(s.fNChips), + fChipTypeID(s.fChipTypeID), + fIsTurbo(s.fIsTurbo), + fBuildLevel(s.fBuildLevel), + fStaveModel(s.fStaveModel) +{ + // + // Copy constructor + for (int i=kNHLevels;i--;) fHierarchy[i] = s.fHierarchy[i]; + // +} + +AliITSUv1Layer& AliITSUv1Layer::operator=(const AliITSUv1Layer &s) +{ + // + // Assignment operator + // + if(&s == this) return *this; + + fLayerNumber = s.fLayerNumber; + fPhi0 = s.fPhi0; + fLayRadius = s.fLayRadius; + fZLength = s.fZLength; + fSensorThick = s.fSensorThick; + fStaveThick = s.fStaveThick; + fStaveWidth = s.fStaveWidth; + fStaveTilt = s.fStaveTilt; + fNStaves = s.fNStaves; + fNModules = s.fNModules; + fNChips = s.fNChips; + fIsTurbo = s.fIsTurbo; + fChipTypeID = s.fChipTypeID; + fBuildLevel = s.fBuildLevel; + fStaveModel = s.fStaveModel; + for (int i=kNHLevels;i--;) fHierarchy[i] = s.fHierarchy[i]; + // + + return *this; +} + +AliITSUv1Layer::~AliITSUv1Layer() { + // + // Destructor + // +} + +void AliITSUv1Layer::CreateLayer(TGeoVolume *moth){ +// +// Creates the actual Layer and places inside its mother volume +// +// Input: +// moth : the TGeoVolume owing the volume structure +// +// Output: +// +// Return: +// +// Created: 17 Jun 2011 Mario Sitta +// Updated: 08 Jul 2011 Mario Sitta +// Updated: 20 May 2013 Mario Sitta Layer is Assembly instead of Tube +// + // Local variables + char volname[30]; + Double_t xpos, ypos, zpos; + Double_t alpha; + + + // Check if the user set the proper parameters + if (fLayRadius <= 0) LOG(FATAL) << "Wrong layer radius " << fLayRadius << FairLogger::endl; + if (fZLength <= 0) LOG(FATAL) << "Wrong layer length " << fZLength << FairLogger::endl; + if (fNStaves <= 0) LOG(FATAL) << "Wrong number of staves " << fNStaves << FairLogger::endl; + if (fNChips <= 0) LOG(FATAL) << "Wrong number of chips " << fNChips << FairLogger::endl; + + if (fLayerNumber >= fgkNumberOfInnerLayers && fNModules <= 0) + LOG(FATAL) << "Wrong number of modules " << fNModules << FairLogger::endl; + + if (fStaveThick <= 0) { + LOG(INFO) << "Stave thickness wrong or not set " << fStaveThick << " using default " + << fgkDefaultStaveThick << FairLogger::endl; + fStaveThick = fgkDefaultStaveThick; + } + + if (fSensorThick <= 0) { + LOG(INFO) << "Sensor thickness wrong or not set " << fSensorThick << " using default " + << fgkDefaultSensorThick << FairLogger::endl; + fSensorThick = fgkDefaultSensorThick; + } + + if (fSensorThick > fStaveThick) { + LOG(WARNING) << "Sensor thickness " << fSensorThick << " is greater than stave thickness " + << fStaveThick << " fixing" << FairLogger::endl; + fSensorThick = fStaveThick; + } + + // If a Turbo layer is requested, do it and exit + if (fIsTurbo) { + CreateLayerTurbo(moth); + return; + } + + // First create the stave container + alpha = (360./(2*fNStaves))*DegToRad(); + + // fStaveWidth = fLayRadius*Tan(alpha); + + snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSLayerPattern(),fLayerNumber); + TGeoVolume *layVol = new TGeoVolumeAssembly(volname); + layVol->SetUniqueID(fChipTypeID); + + // layVol->SetVisibility(kFALSE); + layVol->SetVisibility(kTRUE); + layVol->SetLineColor(1); + + TGeoVolume *stavVol = CreateStave(); + + + // Now build up the layer + alpha = 360./fNStaves; + Double_t r = fLayRadius + ((TGeoBBox*)stavVol->GetShape())->GetDY(); + for (Int_t j=0; jAddNode(stavVol, j, new TGeoCombiTrans( xpos, ypos, zpos, + new TGeoRotation("",phi,0,0))); + } + + + // Finally put everything in the mother volume + moth->AddNode(layVol, 1, 0); + + + // Upgrade geometry is served + return; +} + +void AliITSUv1Layer::CreateLayerTurbo(TGeoVolume *moth){ +// +// Creates the actual Layer and places inside its mother volume +// A so-called "turbo" layer is a layer where staves overlap in phi +// User can set width and tilt angle, no check is performed here +// to avoid volume overlaps +// +// Input: +// moth : the TGeoVolume owing the volume structure +// +// Output: +// +// Return: +// +// Created: 08 Jul 2011 Mario Sitta +// Updated: 08 Mar 2012 Mario Sitta Correct way to compute container R +// Updated: 20 May 2013 Mario Sitta Layer is Assemgbly instead of Tube +// + + + // Local variables + char volname[30]; + Double_t xpos, ypos, zpos; + Double_t alpha; + + + // Check if the user set the proper (remaining) parameters + if (fStaveWidth <= 0) + LOG(FATAL) << "Wrong stave width " << fStaveWidth << FairLogger::endl; + if (Abs(fStaveTilt) > 45) + LOG(WARNING) << "Stave tilt angle (" << fStaveTilt << ") greater than 45deg" + << FairLogger::endl; + + + snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSLayerPattern(), fLayerNumber); + TGeoVolume *layVol = new TGeoVolumeAssembly(volname); + layVol->SetUniqueID(fChipTypeID); + layVol->SetVisibility(kTRUE); + layVol->SetLineColor(1); + TGeoVolume *stavVol = CreateStave(); + + + // Now build up the layer + alpha = 360./fNStaves; + Double_t r = fLayRadius /* +chip thick ?! */; + for (Int_t j=0; jAddNode(stavVol, j, new TGeoCombiTrans( xpos, ypos, zpos, + new TGeoRotation("", phi-fStaveTilt,0,0))); + } + + + // Finally put everything in the mother volume + moth->AddNode(layVol, 1, 0); + + return; +} + +TGeoVolume* AliITSUv1Layer::CreateStave(const TGeoManager * /*mgr*/){ +// +// Creates the actual Stave +// +// Input: +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// +// Created: 22 Jun 2011 Mario Sitta +// Updated: 18 Dec 2013 Mario Sitta Handle IB and OB +// + + char volname[30]; + + Double_t xlen, ylen, zlen; + Double_t xpos, ypos; + Double_t alpha; + + + // First create all needed shapes + alpha = (360./(2*fNStaves))*DegToRad(); + + // The stave + xlen = fLayRadius*Tan(alpha); + if (fIsTurbo) xlen = 0.5*fStaveWidth; + ylen = 0.5*fStaveThick; + zlen = 0.5*fZLength; + + Double_t yplus = 0.46; + TGeoXtru *stave = new TGeoXtru(2); //z sections + Double_t xv[5] = {xlen,xlen,0,-xlen,-xlen}; + Double_t yv[5] = {ylen+0.09,-0.15,-yplus-fSensorThick,-0.15,ylen+0.09}; + stave->DefinePolygon(5,xv,yv); + stave->DefineSection(0,-zlen,0,0,1.); + stave->DefineSection(1,+zlen,0,0,1.); + + // We have all shapes: now create the real volumes + + snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSStavePattern(), fLayerNumber); +// TGeoVolume *staveVol = new TGeoVolume(volname, stave, medAir); + TGeoVolume *staveVol = new TGeoVolumeAssembly(volname); + + // staveVol->SetVisibility(kFALSE); + staveVol->SetVisibility(kTRUE); + staveVol->SetLineColor(2); + TGeoVolume *mechStaveVol = 0; + + // Now build up the stave + if (fLayerNumber < fgkNumberOfInnerLayers) { + TGeoVolume *modVol = CreateStaveInnerB(xlen,ylen,zlen); + staveVol->AddNode(modVol, 0); + fHierarchy[kHalfStave] = 1; + + // Mechanical stave structure + mechStaveVol = CreateStaveStructInnerB(xlen,zlen); + if (mechStaveVol) { + ypos = ((TGeoBBox*)(modVol->GetShape()))->GetDY() + + ((TGeoBBox*)(mechStaveVol->GetShape()))->GetDY(); + staveVol->AddNode(mechStaveVol, 1, new TGeoCombiTrans(0, -ypos, 0, new TGeoRotation("",0, 0, 180))); + } + } + + else{ + TGeoVolume *hstaveVol = CreateStaveOuterB(); + if (fStaveModel == O2its::kOBModel0) { // Create simplified stave struct as in v0 + staveVol->AddNode(hstaveVol, 0); + fHierarchy[kHalfStave] = 1; + } else { // (if fStaveModel) Create new stave struct as in TDR + xpos = ((TGeoBBox*)(hstaveVol->GetShape()))->GetDX() + - fgkOBHalfStaveXOverlap/2; + // ypos is CF height as computed in CreateSpaceFrameOuterB1 + ypos = (fgkOBSpaceFrameTotHigh - fgkOBHalfStaveYTrans)/2; + staveVol->AddNode(hstaveVol, 0, new TGeoTranslation(-xpos, ypos, 0)); + staveVol->AddNode(hstaveVol, 1, new TGeoTranslation( xpos, ypos+fgkOBHalfStaveYTrans, 0)); + fHierarchy[kHalfStave] = 2; // RS + mechStaveVol = CreateSpaceFrameOuterB(); + if (mechStaveVol) + staveVol->AddNode(mechStaveVol, 1, + new TGeoCombiTrans(0, 0, 0, + new TGeoRotation("", 180, 0, 0))); + } // if (fStaveModel) + } + + + // Done, return the stave + return staveVol; +} + +TGeoVolume* AliITSUv1Layer::CreateStaveInnerB(const Double_t xsta, + const Double_t ysta, + const Double_t zsta, + const TGeoManager *mgr){ +// +// Create the chip stave for the Inner Barrel +// (Here we fake the halfstave volume to have the same +// formal geometry hierarchy as for the Outer Barrel) +// +// Input: +// xsta, ysta, zsta : X, Y, Z stave half lengths +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// +// Created: 06 Mar 2014 Mario Sitta +// + + // Local variables + Double_t xmod, ymod, zmod; + char volname[30]; + + // First we create the module (i.e. the HIC with 9 chips) + TGeoVolume *moduleVol = CreateModuleInnerB(xsta, ysta, zsta); + + // Then we create the fake halfstave and the actual stave + xmod = ((TGeoBBox*)(moduleVol->GetShape()))->GetDX(); + ymod = ((TGeoBBox*)(moduleVol->GetShape()))->GetDY(); + zmod = ((TGeoBBox*)(moduleVol->GetShape()))->GetDZ(); + + TGeoBBox *hstave = new TGeoBBox(xmod, ymod, zmod); + + TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$"); + + snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSHalfStavePattern(), fLayerNumber); + TGeoVolume *hstaveVol = new TGeoVolume(volname, hstave, medAir); + + + // Finally build it up + hstaveVol->AddNode(moduleVol, 0); + fHierarchy[kModule] = 1; + + // Done, return the stave structure + return hstaveVol; +} + +TGeoVolume* AliITSUv1Layer::CreateModuleInnerB(Double_t xmod, + Double_t ymod, + Double_t zmod, + const TGeoManager *mgr){ +// +// Creates the IB Module: (only the chips for the time being) +// +// Input: +// xmod, ymod, zmod : X, Y, Z module half lengths +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// the module as a TGeoVolume +// +// Created: 06 Mar 2014 M. Sitta +// + + Double_t zchip; + Double_t zpos; + char volname[30]; + + // First create the single chip + zchip = zmod/fgkIBChipsPerRow; + TGeoVolume *chipVol = CreateChipInnerB(xmod, ymod, zchip); + + // Then create the module and populate it with the chips + TGeoBBox *module = new TGeoBBox(xmod, ymod, zmod); + + TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$"); + + snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSModulePattern(), fLayerNumber); + TGeoVolume *modVol = new TGeoVolume(volname, module, medAir); + + // mm (not used) zlen = ((TGeoBBox*)chipVol->GetShape())->GetDZ(); + for (Int_t j=0; jAddNode(chipVol, j, new TGeoTranslation(0, 0, zpos)); + fHierarchy[kChip]++; + } + + // Done, return the module + return modVol; +} + +TGeoVolume* AliITSUv1Layer::CreateStaveStructInnerB(const Double_t xsta, + const Double_t zsta, + const TGeoManager *mgr){ +// +// Create the mechanical stave structure +// +// Input: +// xsta : X length +// zsta : Z length +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// +// Created: 22 Mar 2013 Chinorat Kobdaj +// Updated: 26 Apr 2013 Mario Sitta +// + + TGeoVolume *mechStavVol = 0; + + switch (fStaveModel) { + case O2its::kIBModelDummy: + mechStavVol = CreateStaveModelInnerBDummy(xsta,zsta,mgr); + break; + case O2its::kIBModel0: + mechStavVol = CreateStaveModelInnerB0(xsta,zsta,mgr); + break; + case O2its::kIBModel1: + mechStavVol = CreateStaveModelInnerB1(xsta,zsta,mgr); + break; + case O2its::kIBModel21: + mechStavVol = CreateStaveModelInnerB21(xsta,zsta,mgr); + break; + case O2its::kIBModel22: + mechStavVol = CreateStaveModelInnerB22(xsta,zsta,mgr); + break; + case O2its::kIBModel3: + mechStavVol = CreateStaveModelInnerB3(xsta,zsta,mgr); + break; + default: + LOG(FATAL) << "Unknown stave model " << fStaveModel << FairLogger::endl; + break; + } + + return mechStavVol; +} + +TGeoVolume* AliITSUv1Layer::CreateStaveModelInnerBDummy(const Double_t , + const Double_t , + const TGeoManager *) const { +// +// Create dummy stave +// +// Input: +// xsta : X length +// zsta : Z length +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// +// Created: 22 Mar 2013 Chinorat Kobdaj +// Updated: 26 Apr 2013 Mario Sitta +// + + // Done, return the stave structur + return 0; +} + +TGeoVolume* AliITSUv1Layer::CreateStaveModelInnerB0(const Double_t xsta, + const Double_t zsta, + const TGeoManager *mgr){ +// +// Create the mechanical stave structure for Model 0 of TDR +// +// Input: +// xsta : X length +// zsta : Z length +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// +// Created: 22 Mar 2013 Chinorat Kobdaj +// Updated: 26 Apr 2013 Mario Sitta +// + + // Materials defined in AliITSUv1 + TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$"); + TGeoMedium *medWater = mgr->GetMedium("ITS_WATER$"); + + TGeoMedium *medM60J3K = mgr->GetMedium("ITS_M60J3K$"); + TGeoMedium *medKapton = mgr->GetMedium("ITS_KAPTON(POLYCH2)$"); + TGeoMedium *medGlue = mgr->GetMedium("ITS_GLUE$"); + TGeoMedium *medFlexCable = mgr->GetMedium("ITS_FLEXCABLE$"); + + // Local parameters + Double_t kConeOutRadius = 0.15/2; + Double_t kConeInRadius = 0.1430/2; + Double_t kStaveLength = zsta*2; + Double_t kStaveWidth = xsta*2-kConeOutRadius*2; + Double_t kWidth = kStaveWidth/4;//1/2 of kWidth + Double_t kStaveHeight = 0.3; + Double_t kHeight = kStaveHeight/2; + Double_t kAlpha = 90-67;//90-33.69; + Double_t kTheta = kAlpha*TMath::DegToRad(); + Double_t kS1 = kWidth/TMath::Sin(kTheta); + Double_t kL1 = kWidth/TMath::Tan(kTheta); + Double_t kS2 = TMath::Sqrt(kHeight*kHeight + kS1*kS1);//TMath::Sin(the2); + Double_t kThe2 = TMath::ATan(kHeight/kS1); + Double_t kBeta = kThe2*TMath::RadToDeg(); + // Int_t loop = kStaveLength/(kL1); + // Double_t s3 = kWidth/(2*TMath::Sin(kTheta)); + // Double_t s4 = 3*kWidth/(2*TMath::Sin(kTheta)); + + LOG(DEBUG1) << "BuildLevel " << fBuildLevel << FairLogger::endl; + + char volname[30]; + snprintf(volname, 30, "%s%d_StaveStruct", AliITSUGeomTGeo::GetITSStavePattern(), fLayerNumber); + + Double_t z=0, y=-0.011+0.0150, x=0; + + TGeoVolume *mechStavVol = 0; + + if (fBuildLevel < 5) { + + // world (trapezoid) + TGeoXtru *mechStruct = new TGeoXtru(2); //z sections + Double_t xv[5] = {kStaveWidth/2+0.1,kStaveWidth/2+0.1,0,-kStaveWidth/2-0.1,-kStaveWidth/2-0.1}; + Double_t yv[5] = {-kConeOutRadius*2-0.07,0,kStaveHeight,0,-kConeOutRadius*2-0.07}; + mechStruct->DefinePolygon(5,xv,yv); + mechStruct->DefineSection(0,-kStaveLength-0.1,0,0,1.); + mechStruct->DefineSection(1,kStaveLength+0.1,0,0,1.); + + mechStavVol = new TGeoVolume(volname, mechStruct, medAir); + mechStavVol->SetLineColor(12); + mechStavVol->SetFillColor(12); + mechStavVol->SetVisibility(kTRUE); + + // detailed structure ++++++++++++++ + //Pipe Kapton grey-35 + TGeoTube *coolTube = new TGeoTube(kConeInRadius,kConeOutRadius,kStaveLength/2); + TGeoVolume *volCoolTube= new TGeoVolume("pipe", coolTube, medKapton); + volCoolTube->SetFillColor(35); + volCoolTube->SetLineColor(35); + mechStavVol->AddNode(volCoolTube,0,new TGeoTranslation(x+(kStaveWidth/2),y-(kHeight-kConeOutRadius),0)); + mechStavVol->AddNode(volCoolTube,1,new TGeoTranslation(x-(kStaveWidth/2),y-(kHeight-kConeOutRadius),0)); + } + + if (fBuildLevel < 4) { + TGeoTube *coolTubeW = new TGeoTube(0.,kConeInRadius,kStaveLength/2); + TGeoVolume *volCoolTubeW= new TGeoVolume("pipeWater", coolTubeW, medWater); + volCoolTubeW->SetFillColor(4); + volCoolTubeW->SetLineColor(4); + mechStavVol->AddNode(volCoolTubeW,0,new TGeoTranslation(x+(kStaveWidth/2),y-(kHeight-kConeOutRadius),0)); + mechStavVol->AddNode(volCoolTubeW,1,new TGeoTranslation(x-(kStaveWidth/2),y-(kHeight-kConeOutRadius),0)); + } + + //frequency of filament + //n = 4 means very dense(4 filaments per interval) + //n = 2 means dense(2 filaments per interval) + Int_t n =4; + Int_t loop = (Int_t)(kStaveLength/(4*kL1/n) + 2/n)-1; + if (fBuildLevel < 3) { + //Top CFRP Filament black-12 Carbon structure TGeoBBox (length,thickness,width) + TGeoBBox *t2=new TGeoBBox(kS2,0.007/2,0.15/2);//(kS2,0.002,0.02); + TGeoVolume *volT2=new TGeoVolume("TopFilament", t2, medM60J3K); + volT2->SetLineColor(12); + volT2->SetFillColor(12); + + for(int i=1;iAddNode(volT2,4*i+0, + new TGeoCombiTrans(x+kWidth,y+(2*kConeOutRadius),z-kStaveLength/2+(i*(4/n)*kL1)+kS1/2,//z-14.25+(i*2*kL1), + new TGeoRotation("volT2",90,90-kAlpha,90-kBeta))); + mechStavVol->AddNode(volT2,4*i+1, + new TGeoCombiTrans(x-kWidth,y+(2*kConeOutRadius),z-kStaveLength/2+(i*(4/n)*kL1)+kS1/2,//z-14.25+(i*2*kL1), + new TGeoRotation("volT2",90,-90+kAlpha,-90+kBeta))); + mechStavVol->AddNode(volT2,4*i+2, + new TGeoCombiTrans(x+kWidth,y+(2*kConeOutRadius),z-kStaveLength/2+(i*(4/n)*kL1)+kS1/2,//z-14.25+(i*2*kL1), + new TGeoRotation("volT2",90,-90+kAlpha,90-kBeta))); + mechStavVol->AddNode(volT2,4*i+3, + new TGeoCombiTrans(x-kWidth,y+(2*kConeOutRadius),z-kStaveLength/2+(i*(4/n)*kL1)+kS1/2,//z-14.25+(i*2*kL1), + new TGeoRotation("volT2",90,90-kAlpha,-90+kBeta))); + } + + + //Bottom CFRP Filament black-12 Carbon structure TGeoBBox (thickness,width,length) + TGeoBBox *t1=new TGeoBBox(0.007/2,0.15/2,kS1);//(0.002,0.02,kS1); + TGeoVolume *volT1=new TGeoVolume("CFRPBottom", t1, medM60J3K); + volT1->SetLineColor(12); + volT1->SetFillColor(12); + + for(int i=1;iAddNode(volT1,4*i+0, + new TGeoCombiTrans(x+kWidth,y-kHeight,z-kStaveLength/2+((4/n)*kL1*i)+kS1/2, //z-14.25+(i*2*kL1), + new TGeoRotation("volT1",-90,kAlpha,0))); + mechStavVol->AddNode(volT1,4*i+1, + new TGeoCombiTrans(x-kWidth,y-kHeight,z-kStaveLength/2+((4/n)*kL1*i)+kS1/2, //z-14.25+(i*2*kL1), + new TGeoRotation("volT1",90,kAlpha,0))); + mechStavVol->AddNode(volT1,4*i+2, + new TGeoCombiTrans(x+kWidth,y-kHeight,z-kStaveLength/2+(i*(4/n)*kL1)+kS1/2, //z-14.25+(i*2*kL1), + new TGeoRotation("volT1",-90,-kAlpha,0))); + mechStavVol->AddNode(volT1,4*i+3, + new TGeoCombiTrans(x-kWidth,y-kHeight,z-kStaveLength/2+(i*(4/n)*kL1)+kS1/2, //z-14.25+(i*2*kL1), + new TGeoRotation("volT1",-90,+kAlpha,0))); + } + } + + if (fBuildLevel < 2) { + // Glue CFRP-Silicon layers TGeoBBox(thickness,width,kS1); + TGeoBBox *tG=new TGeoBBox(0.0075/2,0.18/2,kS1); + TGeoVolume *volTG=new TGeoVolume("Glue1", tG, medGlue); + volTG->SetLineColor(5); + volTG->SetFillColor(5); + + for(int i=1;iAddNode(volTG,4*i+0, + new TGeoCombiTrans(x+kWidth,y-0.16,z-kStaveLength/2+((4/n)*kL1*i)+kS1/2, //z-14.25+(2*kL1*i), + new TGeoRotation("volTG",-90,kAlpha,0))); + mechStavVol->AddNode(volTG,4*i+1, + new TGeoCombiTrans(x-kWidth,y-0.16,z-kStaveLength/2+((4/n)*kL1*i)+kS1/2, //z-14.25+(2*kL1*i), + new TGeoRotation("volTG",90,kAlpha,0))); + mechStavVol->AddNode(volTG,4*i+2, + new TGeoCombiTrans(x+kWidth,y-0.16,z-kStaveLength/2+((4/n)*i*kL1)+kS1/2, //z-14.25+(i*2*kL1), + new TGeoRotation("volTG",-90,-kAlpha,0))); + mechStavVol->AddNode(volTG,4*i+3, + new TGeoCombiTrans(x-kWidth,y-0.16,z-kStaveLength/2+(i*(4/n)*kL1)+kS1/2, //z-14.25+(i*2*kL1), + new TGeoRotation("volTG",-90,+kAlpha,0))); + } + + TGeoBBox *glue = new TGeoBBox(xsta, 0.005/2, zsta); + TGeoVolume *volGlue=new TGeoVolume("Glue2", glue, medGlue); + volGlue->SetLineColor(5); + volGlue->SetFillColor(5); + //mechStavVol->AddNode(volGlue, 0, new TGeoCombiTrans(x, y-0.16, z, new TGeoRotation("",0, 0, 0))); + mechStavVol->AddNode(volGlue, 1, new TGeoCombiTrans(x, y-0.165-fSensorThick-0.005, z, new TGeoRotation("",0, 0, 0))); + } + + if (fBuildLevel < 1) { + //Flex cable brown-28 TGeoBBox(width,thickness,length); + TGeoBBox *kapCable = new TGeoBBox(xsta, 0.01/2, zsta); + TGeoVolume *volCable=new TGeoVolume("FlexCable", kapCable, medFlexCable); + volCable->SetLineColor(28); + volCable->SetFillColor(28); + mechStavVol->AddNode(volCable, 0, new TGeoCombiTrans(x, y-0.165-fSensorThick-0.005-0.01, z, new TGeoRotation("",0, 0, 0))); + } + + // Done, return the stave structur + return mechStavVol; +} + +TGeoVolume* AliITSUv1Layer::CreateStaveModelInnerB1(const Double_t xsta, + const Double_t zsta, + const TGeoManager *mgr){ +// +// Create the mechanical stave structure for Model 1 of TDR +// +// Input: +// xsta : X length +// zsta : Z length +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// +// Created: 22 Mar 2013 Chinorat Kobdaj +// Updated: 26 Apr 2013 Mario Sitta +// + + // Materials defined in AliITSUv1 + TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$"); + TGeoMedium *medWater = mgr->GetMedium("ITS_WATER$"); + + TGeoMedium *medM60J3K = mgr->GetMedium("ITS_M60J3K$"); + TGeoMedium *medKapton = mgr->GetMedium("ITS_KAPTON(POLYCH2)$"); + TGeoMedium *medGlue = mgr->GetMedium("ITS_GLUE$"); + TGeoMedium *medFlexCable = mgr->GetMedium("ITS_FLEXCABLE$"); + + // Local parameters + Double_t kConeOutRadius = 0.15/2; + // Double_t kConeInRadius = 0.1430/2; + Double_t kStaveLength = zsta*2; + // Double_t kStaveWidth = xsta*2-kConeOutRadius*2; + Double_t kStaveWidth = xsta*2; + Double_t kWidth = kStaveWidth/4;//1/2 of kWidth + Double_t kStaveHeight = 0.3; + Double_t kHeight = kStaveHeight/2; + Double_t kAlpha = 90-33.;//90-30; + Double_t kTheta = kAlpha*TMath::DegToRad(); + Double_t kS1 = kWidth/TMath::Sin(kTheta); + Double_t kL1 = kWidth/TMath::Tan(kTheta); + Double_t kS2 = TMath::Sqrt(kHeight*kHeight + kS1*kS1);//TMath::Sin(the2); + Double_t kThe2 = TMath::ATan(kHeight/kS1); + Double_t kBeta = kThe2*TMath::RadToDeg(); + Int_t loop = (Int_t)((kStaveLength/(2*kL1))/2); + + + TGeoVolume *mechStavVol = 0; + + char volname[30]; + snprintf(volname, 30, "%s%d_StaveStruct", AliITSUGeomTGeo::GetITSStavePattern(), fLayerNumber); + + // detailed structure ++++++++++++++ + Double_t z=0, y=-0.011+0.0150, x=0; + + // Polimide micro channels numbers + Double_t yMC = y-kHeight+0.01; + Int_t nb = (Int_t)(kStaveWidth/0.1)+1; + Double_t xstaMC = (nb*0.1-0.08)/2; + + if (fBuildLevel < 5) { + // world (trapezoid) + TGeoXtru *mechStruct = new TGeoXtru(2); //z sections + Double_t xv[5] = {kStaveWidth/2+0.1,kStaveWidth/2+0.1,0,-kStaveWidth/2-0.1,-kStaveWidth/2-0.1}; + Double_t yv[5] = {-kConeOutRadius*2-0.07,0,kStaveHeight,0,-kConeOutRadius*2-0.07}; + mechStruct->DefinePolygon(5,xv,yv); + mechStruct->DefineSection(0,-kStaveLength-0.1,0,0,1.); + mechStruct->DefineSection(1,kStaveLength+0.1,0,0,1.); + + mechStavVol = new TGeoVolume(volname, mechStruct, medAir); + mechStavVol->SetLineColor(12); + mechStavVol->SetFillColor(12); + mechStavVol->SetVisibility(kTRUE); + + // Polimide micro channels numbers + TGeoBBox *tM0=new TGeoBBox(xstaMC, 0.005/2, zsta); + TGeoVolume *volTM0=new TGeoVolume("MicroChanCover", tM0, medKapton); + volTM0->SetLineColor(35); + volTM0->SetFillColor(35); + mechStavVol->AddNode(volTM0, 0, new TGeoCombiTrans(x,-0.0125+yMC, z, new TGeoRotation("",0, 0, 0))); + mechStavVol->AddNode(volTM0, 1, new TGeoCombiTrans(x,+0.0125+yMC, z, new TGeoRotation("",0, 0, 0))); + + TGeoBBox *tM0b=new TGeoBBox(0.02/2, 0.02/2, zsta); + TGeoVolume *volTM0b=new TGeoVolume("MicroChanWalls", tM0b, medKapton); + volTM0b->SetLineColor(35); + volTM0b->SetFillColor(35); + for (Int_t ib=0;ibAddNode(volTM0b, ib, new TGeoCombiTrans(x+ib*0.1-xstaMC+0.01,yMC, z, new TGeoRotation("",0, 0, 0))); + } + } + + if (fBuildLevel < 4) { + // Water in Polimide micro channels + TGeoBBox *water=new TGeoBBox(0.08/2, 0.02/2, zsta+0.1); + TGeoVolume *volWater=new TGeoVolume("Water", water, medWater); + volWater->SetLineColor(4); + volWater->SetFillColor(4); + for (Int_t ib=0;ib<(nb-1);ib++) { + mechStavVol->AddNode(volWater, ib, new TGeoCombiTrans(x+ib*0.1-xstaMC+0.06,yMC, z, new TGeoRotation("",0, 0, 0))); + } + } + + if (fBuildLevel < 3) { + //Bottom filament CFRP black-12 Carbon structure TGeoBBox (thickness,width,length) + Double_t filWidth = 0.04; + Double_t filHeight= 0.02; + TGeoBBox *t1=new TGeoBBox(filHeight/2,filWidth/2,kS1); + TGeoVolume *volT1=new TGeoVolume("CFRPBottom", t1, medM60J3K); + volT1->SetLineColor(12); + volT1->SetFillColor(12); + for(int i=0;iAddNode(volT1,4*i+0, + new TGeoCombiTrans(x+kWidth,y-kHeight+0.04+filHeight/2,z-kStaveLength/2+(4*kL1)+kS1/2, + new TGeoRotation("volT1",-90,kAlpha,0))); + mechStavVol->AddNode(volT1,4*i+1, + new TGeoCombiTrans(x-kWidth,y-kHeight+0.04+filHeight/2,z-kStaveLength/2+(4*kL1*i)+kS1/2, + new TGeoRotation("volT1",90,kAlpha,0))); + mechStavVol->AddNode(volT1,4*i+2, + new TGeoCombiTrans(x+kWidth,y-kHeight+0.04+filHeight/2,z-kStaveLength/2+2*kL1+(i*4*kL1)+kS1/2, + new TGeoRotation("volT1",-90,-kAlpha,0))); + mechStavVol->AddNode(volT1,4*i+3, + new TGeoCombiTrans(x-kWidth,y-kHeight+0.04+filHeight/2,z-kStaveLength/2+2*kL1+(i*4*kL1)+kS1/2, + new TGeoRotation("volT1",-90,+kAlpha,0))); + } + + // Top filament CFRP black-12 Carbon structure TGeoBBox (length,thickness,width) + TGeoBBox *t2=new TGeoBBox(kS2,filHeight/2,filWidth/2); + TGeoVolume *volT2=new TGeoVolume("CFRPTop", t2, medM60J3K); + volT2->SetLineColor(12); + volT2->SetFillColor(12); + for(int i=0;iAddNode(volT2,4*i+0, + new TGeoCombiTrans(x+kWidth,y+0.04+filHeight/2,z-kStaveLength/2+(i*4*kL1)+kS1/2, + new TGeoRotation("volT2",90,90-kAlpha,90-kBeta))); + mechStavVol->AddNode(volT2,4*i+1, + new TGeoCombiTrans(x-kWidth,y+0.04+filHeight/2,z-kStaveLength/2+(i*4*kL1)+kS1/2, + new TGeoRotation("volT2",90,-90+kAlpha,-90+kBeta))); + mechStavVol->AddNode(volT2,4*i+2, + new TGeoCombiTrans(x+kWidth,y+0.04+filHeight/2,z-kStaveLength/2+2*kL1+(i*4*kL1)+kS1/2, + new TGeoRotation("volT2",90,-90+kAlpha,90-kBeta))); + mechStavVol->AddNode(volT2,4*i+3, + new TGeoCombiTrans(x-kWidth,y+0.04+filHeight/2,z-kStaveLength/2+2*kL1+(i*4*kL1)+kS1/2, + new TGeoRotation("volT2",90,90-kAlpha,-90+kBeta))); + } + } + + if (fBuildLevel < 2) { + // Glue between filament and polimide micro channel + TGeoBBox *t3=new TGeoBBox(0.01/2,0.04,kS1); + TGeoVolume *volT3=new TGeoVolume("FilamentGlue", t3, medGlue); + volT3->SetLineColor(5); + volT3->SetFillColor(5); + for(int i=0;iAddNode(volT3,4*i+0, + new TGeoCombiTrans(x+kWidth,y-kHeight+0.0325,z-kStaveLength/2+(4*kL1*i)+kS1/2, + new TGeoRotation("volT1",-90,kAlpha,0))); + mechStavVol->AddNode(volT3,4*i+1, + new TGeoCombiTrans(x-kWidth,y-kHeight+0.0325,z-kStaveLength/2+(4*kL1*i)+kS1/2, + new TGeoRotation("volT1",90,kAlpha,0))); + mechStavVol->AddNode(volT3,4*i+2, + new TGeoCombiTrans(x+kWidth,y-kHeight+0.0325,z-kStaveLength/2+2*kL1+(i*4*kL1)+kS1/2, + new TGeoRotation("volT1",-90,-kAlpha,0))); + mechStavVol->AddNode(volT3,4*i+3, + new TGeoCombiTrans(x-kWidth,y-kHeight+0.0325,z-kStaveLength/2+2*kL1+(i*4*kL1)+kS1/2, + new TGeoRotation("volT1",-90,+kAlpha,0))); + } + + // Glue microchannel and sensor + TGeoBBox *glueM = new TGeoBBox(xsta, 0.01/2, zsta); + TGeoVolume *volGlueM=new TGeoVolume("MicroChanGlue", glueM, medGlue); + volGlueM->SetLineColor(5); + volGlueM->SetFillColor(5); + mechStavVol->AddNode(volGlueM, 0, new TGeoCombiTrans(x, y-0.16, z, new TGeoRotation("",0, 0, 0))); + + // Glue sensor and kapton + TGeoBBox *glue = new TGeoBBox(xsta, 0.005/2, zsta); + TGeoVolume *volGlue=new TGeoVolume("SensorGlue", glue, medGlue); + volGlue->SetLineColor(5); + volGlue->SetFillColor(5); + mechStavVol->AddNode(volGlue, 1, new TGeoCombiTrans(x, y-0.165-fSensorThick-0.005, z, new TGeoRotation("",0, 0, 0))); + } + + if (fBuildLevel < 1) { + TGeoBBox *kapCable = new TGeoBBox(xsta, 0.01/2, zsta); + TGeoVolume *volCable=new TGeoVolume("FlexCable", kapCable, medFlexCable); + volCable->SetLineColor(28); + volCable->SetFillColor(28); + mechStavVol->AddNode(volCable, 0, new TGeoCombiTrans(x, y-0.165-fSensorThick-0.005-0.01, z, new TGeoRotation("",0, 0, 0))); + } + + // Done, return the stave structur + return mechStavVol; + +} + +TGeoVolume* AliITSUv1Layer::CreateStaveModelInnerB21(const Double_t xsta, + const Double_t zsta, + const TGeoManager *mgr){ +// +// Create the mechanical stave structure for Model 2.1 of TDR +// +// Input: +// xsta : X length +// zsta : Z length +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// +// Created: 22 Mar 2013 Chinorat Kobdaj +// Updated: 26 Apr 2013 Mario Sitta +// + + // Materials defined in AliITSUv1 + TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$"); + TGeoMedium *medWater = mgr->GetMedium("ITS_WATER$"); + + TGeoMedium *medM60J3K = mgr->GetMedium("ITS_M60J3K$"); + TGeoMedium *medKapton = mgr->GetMedium("ITS_KAPTON(POLYCH2)$"); + TGeoMedium *medGlue = mgr->GetMedium("ITS_GLUE$"); + TGeoMedium *medFlexCable = mgr->GetMedium("ITS_FLEXCABLE$"); + TGeoMedium *medK13D2U2k = mgr->GetMedium("ITS_K13D2U2k$"); + TGeoMedium *medFGS003 = mgr->GetMedium("ITS_FGS003$"); + TGeoMedium *medCarbonFleece = mgr->GetMedium("ITS_CarbonFleece$"); + + // Local parameters + Double_t kConeOutRadius =0.151384/2; + Double_t kConeInRadius = 0.145034/2; + Double_t kStaveLength = zsta; + Double_t kStaveWidth = xsta*2; + Double_t kWidth = (kStaveWidth+0.005)/4; + Double_t kStaveHeigth = 0.33;//0.33; + Double_t kHeight = (kStaveHeigth+0.025)/2; + Double_t kAlpha = 57; //56.31; + Double_t kTheta = kAlpha*TMath::DegToRad(); + Double_t kS1 = (kStaveWidth/4)/TMath::Sin(kTheta); + Double_t kL1 = (kStaveWidth/4)/TMath::Tan(kTheta); + Double_t kS2 = sqrt(kHeight*kHeight + kS1*kS1);//TMath::Sin(the2); + Double_t kThe2 = TMath::ATan(kHeight/kS1); + Double_t kBeta = kThe2*TMath::RadToDeg(); + // Double_t lay1 = 0.003157; + Double_t kLay1 = 0.003;//Amec carbon + // Double_t lay2 = 0.0043215;//C Fleece carbon + Double_t kLay2 = 0.002;//C Fleece carbon + Double_t kLay3 = 0.007;//K13D2U carbon + Int_t loop = (Int_t)(kStaveLength/(2*kL1)); + + char volname[30]; + snprintf(volname, 30, "%s%d_StaveStruct", AliITSUGeomTGeo::GetITSStavePattern(), fLayerNumber); + + Double_t z=0, y=-(kConeOutRadius+0.03)+0.0385, x=0; + + TGeoVolume *mechStavVol = 0; + + if (fBuildLevel < 5) { + // world (trapezoid) + TGeoXtru *mechStruct = new TGeoXtru(2); //z sections + Double_t xv[5] = {kStaveWidth/2+0.1,kStaveWidth/2+0.1,0,-kStaveWidth/2-0.1,-kStaveWidth/2-0.1}; + Double_t yv[5] = {-kConeOutRadius*2-0.07,0,kStaveHeigth,0,-kConeOutRadius*2-0.07}; + mechStruct->DefinePolygon(5,xv,yv); + mechStruct->DefineSection(0,-kStaveLength-0.1,0,0,1.); + mechStruct->DefineSection(1,kStaveLength+0.1,0,0,1.); + + mechStavVol = new TGeoVolume(volname, mechStruct, medAir); + mechStavVol->SetLineColor(12); + mechStavVol->SetFillColor(12); + mechStavVol->SetVisibility(kTRUE); + + //Pipe Kapton grey-35 + TGeoCone *cone1 = new TGeoCone(kStaveLength,kConeInRadius,kConeOutRadius,kConeInRadius,kConeOutRadius); + TGeoVolume *volCone1= new TGeoVolume("PolyimidePipe", cone1, medKapton); + volCone1->SetFillColor(35); + volCone1->SetLineColor(35); + mechStavVol->AddNode(volCone1,1,new TGeoTranslation(x+0.25,y,z)); + mechStavVol->AddNode(volCone1,2,new TGeoTranslation(x-0.25,y,z)); + } + + if (fBuildLevel < 4) { + + TGeoTube *coolTubeW = new TGeoTube(0.,kConeInRadius,kStaveLength); + TGeoVolume *volCoolTubeW= new TGeoVolume("Water", coolTubeW, medWater); + volCoolTubeW->SetFillColor(4); + volCoolTubeW->SetLineColor(4); + mechStavVol->AddNode(volCoolTubeW,0,new TGeoTranslation(x-0.25,y,z)); + mechStavVol->AddNode(volCoolTubeW,1,new TGeoTranslation(x+0.25,y,z)); + } + + if (fBuildLevel < 3) { + //top fillament + // Top filament M60J black-12 Carbon structure TGeoBBox (length,thickness,width) + TGeoBBox *t2=new TGeoBBox(kS2,0.02/2,0.04/2); //TGeoBBox *t2=new TGeoBBox(kS2,0.01,0.02); + TGeoVolume *volT2=new TGeoVolume("TopFilament", t2, medM60J3K); + volT2->SetLineColor(12); + volT2->SetFillColor(12); + + for(int i=0;iAddNode(volT2,i*4+1,new TGeoCombiTrans(x+kWidth,y+kHeight+(0.12/2)-0.014+0.007,z-kStaveLength+(i*4*kL1)+kS1/2, new TGeoRotation("volT2",90,90-kAlpha,90-kBeta))); + mechStavVol->AddNode(volT2,i*4+2,new TGeoCombiTrans(x-kWidth,y+kHeight+(0.12/2)-0.014+0.007,z-kStaveLength+(i*4*kL1)+kS1/2, new TGeoRotation("volT2",90,-90+kAlpha,-90+kBeta))); + mechStavVol->AddNode(volT2,i*4+3,new TGeoCombiTrans(x+kWidth,y+kHeight+(0.12/2)-0.014+0.007,z-kStaveLength+2*kL1+(i*4*kL1)+kS1/2, new TGeoRotation("volT2",90,-90+kAlpha,90-kBeta))); + mechStavVol->AddNode(volT2,i*4+4,new TGeoCombiTrans(x-kWidth,y+kHeight+(0.12/2)-0.014+0.007,z-kStaveLength+2*kL1+(i*4*kL1)+kS1/2, new TGeoRotation("volT2",90,90-kAlpha,-90+kBeta))); +// mechStavVol->AddNode(volT2,i*4+1,new TGeoCombiTrans(x+kWidth+0.0036,y+kHeight-(0.12/2)+0.072,z+kStaveLength+(i*4*kL1)+kS1/2, new TGeoRotation("volT2",90,90-kAlpha,90-kBeta))); + + } + + //wall side structure out + TGeoBBox *box4 = new TGeoBBox(0.03/2,0.12/2,kStaveLength-0.50); + TGeoVolume *plate4 = new TGeoVolume("WallOut",box4,medM60J3K); + plate4->SetFillColor(35); + plate4->SetLineColor(35); + mechStavVol->AddNode(plate4,1,new TGeoCombiTrans(x+(2*kStaveWidth/4)-(0.03/2),y-0.0022-kConeOutRadius+0.12/2+0.007,z,new TGeoRotation("plate4",0,0,0))); + mechStavVol->AddNode(plate4,2,new TGeoCombiTrans(x-(2*kStaveWidth/4)+(0.03/2),y-0.0022-kConeOutRadius+0.12/2+0.007,z,new TGeoRotation("plate4",0,0,0))); + //wall side in + TGeoBBox *box5 = new TGeoBBox(0.015/2,0.12/2,kStaveLength-0.50); + TGeoVolume *plate5 = new TGeoVolume("WallIn",box5,medM60J3K); + plate5->SetFillColor(12); + plate5->SetLineColor(12); + mechStavVol->AddNode(plate5,1,new TGeoCombiTrans(x+(2*kStaveWidth/4)-0.03-0.015/2,y-0.0022-kConeOutRadius+0.12/2+0.007,z,new TGeoRotation("plate5",0,0,0))); + mechStavVol->AddNode(plate5,2,new TGeoCombiTrans(x-(2*kStaveWidth/4)+0.03+0.015/2,y-0.0022-kConeOutRadius+0.12/2+0.007,z,new TGeoRotation("plate5",0,0,0))); + + //Amec Thermasol red-2 cover tube FGS300 + TGeoConeSeg *cons1 = new TGeoConeSeg(kStaveLength-0.50,kConeOutRadius,kConeOutRadius+kLay1,kConeOutRadius,kConeOutRadius+kLay1,0,180); + TGeoVolume *cone11 = new TGeoVolume("ThermasolPipeCover",cons1,medFGS003); + cone11->SetFillColor(2); + cone11->SetLineColor(2); + mechStavVol->AddNode(cone11,1,new TGeoCombiTrans(x+0.25,y,z,new TGeoRotation("Cone11",0,0,0))); + mechStavVol->AddNode(cone11,2,new TGeoCombiTrans(x-0.25,y,z,new TGeoRotation("Cone11",0,0,0))); + + TGeoBBox *box2 = new TGeoBBox((0.50-(2*kConeOutRadius))/2,kLay1/2,kStaveLength-0.50); + TGeoVolume *plate2 = new TGeoVolume("ThermasolMiddle",box2,medFGS003); + plate2->SetFillColor(2); + plate2->SetLineColor(2); + mechStavVol->AddNode(plate2,1,new TGeoCombiTrans(x,y-kConeOutRadius+(kLay1/2),z,new TGeoRotation("plate2",0,0,0))); + + TGeoBBox *box21 = new TGeoBBox((0.75-0.25-kConeOutRadius-kLay1)/2,kLay1/2,kStaveLength-0.50); + TGeoVolume *plate21 = new TGeoVolume("ThermasolLeftRight",box21,medFGS003); + plate21->SetFillColor(2); + plate21->SetLineColor(2); + mechStavVol->AddNode(plate21,1,new TGeoCombiTrans(x+0.25+kConeOutRadius+(0.75-0.25-kConeOutRadius)/2-(kLay1/2),y-kConeOutRadius+(kLay1/2),z,new TGeoRotation("plate21",0,0,0))); + mechStavVol->AddNode(plate21,2,new TGeoCombiTrans(x-0.25-kConeOutRadius-(0.75-0.25-kConeOutRadius)/2+(kLay1/2),y-kConeOutRadius+(kLay1/2),z,new TGeoRotation("plate21",0,0,0))); + + TGeoBBox *box22 = new TGeoBBox((kLay1/2),kConeOutRadius/2,kStaveLength-0.50); + TGeoVolume *plate22 = new TGeoVolume("ThermasolVertical",box22,medFGS003); + plate22->SetFillColor(2); + plate22->SetLineColor(2); + mechStavVol->AddNode(plate22,1,new TGeoCombiTrans(x+0.25+kConeOutRadius+(kLay1/2),y-kConeOutRadius/2,z,new TGeoRotation("plate22",0,0,0))); + mechStavVol->AddNode(plate22,2,new TGeoCombiTrans(x+0.25-kConeOutRadius-(kLay1/2),y-kConeOutRadius/2,z,new TGeoRotation("plate22",0,0,0))); + mechStavVol->AddNode(plate22,3,new TGeoCombiTrans(x-0.25+kConeOutRadius+(kLay1/2),y-kConeOutRadius/2,z,new TGeoRotation("plate22",0,0,0))); + mechStavVol->AddNode(plate22,4,new TGeoCombiTrans(x-0.25-kConeOutRadius-(kLay1/2),y-kConeOutRadius/2,z,new TGeoRotation("plate22",0,0,0))); + + //C Fleece + TGeoConeSeg *cons2 = new TGeoConeSeg(kStaveLength-0.50,kConeOutRadius+kLay1,kConeOutRadius+kLay1+kLay2,kConeOutRadius+kLay1,kConeOutRadius+kLay1+kLay2,0,180); + TGeoVolume *cone12 = new TGeoVolume("CFleecePipeCover",cons2,medCarbonFleece); + cone12->SetFillColor(28); + cone12->SetLineColor(28); + mechStavVol->AddNode(cone12,1,new TGeoCombiTrans(x+0.25,y,z,new TGeoRotation("Cone12",0,0,0))); + mechStavVol->AddNode(cone12,2,new TGeoCombiTrans(x-0.25,y,z,new TGeoRotation("Cone12",0,0,0))); + + TGeoBBox *box3 = new TGeoBBox((0.50-(2*(kConeOutRadius+kLay1)))/2,kLay2/2,kStaveLength-0.50); + TGeoVolume *plate3 = new TGeoVolume("CFleeceMiddle",box3,medCarbonFleece); + plate3->SetFillColor(28); + plate3->SetLineColor(28); + mechStavVol->AddNode(plate3,1,new TGeoCombiTrans(x,y-kConeOutRadius+kLay1+(kLay2/2),z,new TGeoRotation("plate3",0,0,0))); + + TGeoBBox *box31 = new TGeoBBox((0.75-0.25-kConeOutRadius-kLay1)/2,kLay2/2,kStaveLength-0.50); + TGeoVolume *plate31 = new TGeoVolume("CFleeceLeftRight",box31,medCarbonFleece); + plate31->SetFillColor(28); + plate31->SetLineColor(28); + mechStavVol->AddNode(plate31,1,new TGeoCombiTrans(x+0.25+kConeOutRadius+kLay1+(0.75-0.25-kConeOutRadius-kLay1)/2,y-kConeOutRadius+kLay1+(kLay2/2),z,new TGeoRotation("plate31",0,0,0))); + mechStavVol->AddNode(plate31,2,new TGeoCombiTrans(x-0.25-kConeOutRadius-kLay1-(0.75-0.25-kConeOutRadius-kLay1)/2,y-kConeOutRadius+kLay1+(kLay2/2),z,new TGeoRotation("plate31",0,0,0))); + + TGeoBBox *box32 = new TGeoBBox((kLay2/2),(kConeOutRadius-kLay1)/2,kStaveLength-0.50); + TGeoVolume *plate32 = new TGeoVolume("CFleeceVertical",box32,medCarbonFleece); + plate32->SetFillColor(28); + plate32->SetLineColor(28); + mechStavVol->AddNode(plate32,1,new TGeoCombiTrans(x+0.25+kConeOutRadius+kLay1+(kLay2/2),y+(kLay1-kConeOutRadius)/2,z,new TGeoRotation("plate32",0,0,0))); + mechStavVol->AddNode(plate32,2,new TGeoCombiTrans(x+0.25-kConeOutRadius-kLay1-(kLay2/2),y+(kLay1-kConeOutRadius)/2,z,new TGeoRotation("plate32",0,0,0))); + mechStavVol->AddNode(plate32,3,new TGeoCombiTrans(x-0.25+kConeOutRadius+kLay1+(kLay2/2),y+(kLay1-kConeOutRadius)/2,z,new TGeoRotation("plate32",0,0,0))); + mechStavVol->AddNode(plate32,4,new TGeoCombiTrans(x-0.25-kConeOutRadius-kLay1-(kLay2/2),y+(kLay1-kConeOutRadius)/2,z,new TGeoRotation("plate32",0,0,0))); + + + //K13D2U carbon plate + TGeoBBox *box1 = new TGeoBBox(2*kWidth,kLay3/2,kStaveLength-0.50); + TGeoVolume *plate1 = new TGeoVolume("CarbonPlate",box1,medK13D2U2k); + plate1->SetFillColor(5); + plate1->SetLineColor(5); + mechStavVol->AddNode(plate1,1,new TGeoCombiTrans(x,y-(kConeOutRadius+(kLay3/2)),z,new TGeoRotation("plate1",0,0,0))); + + //C Fleece bottom plate + TGeoBBox *box6 = new TGeoBBox(2*kWidth,kLay2/2,kStaveLength-0.50); + TGeoVolume *plate6 = new TGeoVolume("CFleeceBottom",box6,medCarbonFleece); + plate6->SetFillColor(2); + plate6->SetLineColor(2); + mechStavVol->AddNode(plate6,1,new TGeoCombiTrans(x,y-(kConeOutRadius+kLay3+(kLay2/2)),z,new TGeoRotation("plate1",0,0,0))); + } + + if (fBuildLevel < 2) { + //Glue layers and kapton + TGeoBBox *glue = new TGeoBBox(kStaveWidth/2, 0.005/2, zsta); + TGeoVolume *volGlue=new TGeoVolume("Glue", glue, medGlue); + volGlue->SetLineColor(5); + volGlue->SetFillColor(5); + mechStavVol->AddNode(volGlue, 0, new TGeoCombiTrans(x,y-(kConeOutRadius+kLay3+(kLay2/2)+(0.01/2)), z, new TGeoRotation("",0, 0, 0))); + mechStavVol->AddNode(volGlue, 1, new TGeoCombiTrans(x,y-(kConeOutRadius+kLay3+(kLay2/2)+0.01+fSensorThick+(0.01/2)), z, new TGeoRotation("",0, 0, 0))); + } + + if (fBuildLevel < 1) { + TGeoBBox *kapCable = new TGeoBBox(kStaveWidth/2, 0.01/2, zsta); + TGeoVolume *volCable=new TGeoVolume("FlexCable", kapCable, medFlexCable); + volCable->SetLineColor(28); + volCable->SetFillColor(28); + mechStavVol->AddNode(volCable, 0, new TGeoCombiTrans(x, y-(kConeOutRadius+kLay3+(kLay2/2)+0.01+fSensorThick+0.01+(0.01/2)), z, new TGeoRotation("",0, 0, 0))); + } + + // Done, return the stave structure + return mechStavVol; + +} +// new model22 +TGeoVolume* AliITSUv1Layer::CreateStaveModelInnerB22(const Double_t xsta, + const Double_t zsta, + const TGeoManager *mgr){ +// +// Create the mechanical stave structure for Model 2.2 of TDR +// +// Input: +// xsta : X length +// zsta : Z length +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// +// Created: 22 Mar 2013 Chinorat Kobdaj +// Updated: 26 Apr 2013 Mario Sitta +// Updated: 30 Apr 2013 Wanchaloem Poonsawat +// + + // Materials defined in AliITSUv1 + TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$"); + TGeoMedium *medWater = mgr->GetMedium("ITS_WATER$"); + + TGeoMedium *medM60J3K = mgr->GetMedium("ITS_M60J3K$"); + TGeoMedium *medKapton = mgr->GetMedium("ITS_KAPTON(POLYCH2)$"); + TGeoMedium *medGlue = mgr->GetMedium("ITS_GLUE$"); + TGeoMedium *medFlexCable = mgr->GetMedium("ITS_FLEXCABLE$"); + TGeoMedium *medK13D2U2k = mgr->GetMedium("ITS_K13D2U2k$"); + TGeoMedium *medFGS003 = mgr->GetMedium("ITS_FGS003$"); + TGeoMedium *medCarbonFleece = mgr->GetMedium("ITS_CarbonFleece$"); + + // Local parameters + Double_t kConeOutRadius =(0.1024+0.0025)/2;//0.107/2; + Double_t kConeInRadius = 0.1024/2;//0.10105/2 + Double_t kStaveLength = zsta; + Double_t kStaveWidth = xsta*2; + Double_t kWidth = (kStaveWidth)/4; + Double_t kStaveHeight = 0.283;//0.33; + Double_t kHeight = (kStaveHeight)/2; + Double_t kAlpha = 57;//56.31; + Double_t kTheta = kAlpha*TMath::DegToRad(); + Double_t kS1 = ((kStaveWidth)/4)/TMath::Sin(kTheta); + Double_t kL1 = (kStaveWidth/4)/TMath::Tan(kTheta); + Double_t kS2 = sqrt(kHeight*kHeight + kS1*kS1);//TMath::Sin(kThe2); + Double_t kThe2 = TMath::ATan(kHeight/(0.375-0.036)); + Double_t kBeta = kThe2*TMath::RadToDeg(); + Double_t klay1 = 0.003;//Amec carbon + Double_t klay2 = 0.002;//C Fleece carbon + Double_t klay3 = 0.007;//CFplate K13D2U carbon + Double_t klay4 = 0.007;//GluekStaveLength/2 + Double_t klay5 = 0.01;//Flex cable + Double_t kTopVertexMaxWidth = 0.072; + Double_t kTopVertexHeight = 0.04; + Double_t kSideVertexMWidth = 0.052; + Double_t kSideVertexHeight = 0.11; + + Int_t loop = (Int_t)(kStaveLength/(2*kL1)); + + char volname[30]; + snprintf(volname, 30, "%s%d_StaveStruct", AliITSUGeomTGeo::GetITSStavePattern(), fLayerNumber); + + Double_t z=0, y=-(2*kConeOutRadius)+klay1+klay2+fSensorThick/2-0.0004, x=0; + + TGeoVolume *mechStavVol = 0; + + if (fBuildLevel < 5) { + // world (trapezoid) + TGeoXtru *mechStruct = new TGeoXtru(2); //z sections + Double_t xv[6] = {kStaveWidth/2,kStaveWidth/2,0.012,-0.012,-kStaveWidth/2,-kStaveWidth/2}; + /* Double_t yv[6] = {-2*(kConeOutRadius+klay1+1.5*klay2+klay3+klay4+fSensorThick+klay5), + 0-0.02,kStaveHeight+0.01,kStaveHeight+0.01,0-0.02, + -2*(kConeOutRadius+klay1+1.5*klay2+klay3+klay4+fSensorThick+klay5)}; // (kConeOutRadius*2)-0.0635 */ + Double_t yv[6] = {-(kConeOutRadius*2)-0.06395,0-0.02,kStaveHeight+0.01,kStaveHeight+0.01,0-0.02,-(kConeOutRadius*2)-0.06395}; // (kConeOutRadius*2)-0.064 + mechStruct->DefinePolygon(6,xv,yv); + mechStruct->DefineSection(0,-kStaveLength,0,0,1.); + mechStruct->DefineSection(1,kStaveLength,0,0,1.); + + mechStavVol = new TGeoVolume(volname, mechStruct, medAir); + mechStavVol->SetLineColor(12); + mechStavVol->SetFillColor(12); + mechStavVol->SetVisibility(kTRUE); + + //Polyimide Pipe Kapton grey-35 + TGeoCone *cone1 = new TGeoCone(kStaveLength,kConeInRadius,kConeOutRadius-0.0001,kConeInRadius,kConeOutRadius-0.0001); + TGeoVolume *volCone1= new TGeoVolume("PolyimidePipe", cone1, medKapton); + volCone1->SetFillColor(35); + volCone1->SetLineColor(35); + mechStavVol->AddNode(volCone1,1,new TGeoTranslation(x+0.25,y,z)); + mechStavVol->AddNode(volCone1,2,new TGeoTranslation(x-0.25,y,z)); + } + + if (fBuildLevel < 4) { + TGeoTube *coolTubeW = new TGeoTube(0.,kConeInRadius-0.0001,kStaveLength); + TGeoVolume *volCoolTubeW= new TGeoVolume("Water", coolTubeW, medWater); + volCoolTubeW->SetFillColor(4); + volCoolTubeW->SetLineColor(4); + mechStavVol->AddNode(volCoolTubeW,0,new TGeoTranslation(x-0.25,y,z)); + mechStavVol->AddNode(volCoolTubeW,1,new TGeoTranslation(x+0.25,y,z)); + } + + if (fBuildLevel < 3) { + //top fillament + // Top filament M60J black-12 Carbon structure TGeoBBox (length,thickness,width) + TGeoBBox *t2=new TGeoBBox(kS2-0.028,0.02/2,0.02/2); //0.04/2//TGeoBBox *t2=new TGeoBBox(kS2,0.01,0.02);//kS2-0.03 old Config.C + TGeoVolume *volT2=new TGeoVolume("TopFilament", t2, medM60J3K); + volT2->SetLineColor(12); + volT2->SetFillColor(12); + for(int i=0;iAddNode(volT2,i*4+1,new TGeoCombiTrans(x+kWidth+0.0036,y+kHeight+0.01,z-kStaveLength+0.1+(i*4*kL1)+kS1/2, new TGeoRotation("volT2",90,90-kAlpha,90-kBeta))); + // 2) Front Right Top Filament + mechStavVol->AddNode(volT2,i*4+2,new TGeoCombiTrans(x-kWidth-0.0036,y+kHeight+0.01,z-kStaveLength+0.1+(i*4*kL1)+kS1/2, new TGeoRotation("volT2",90,-90+kAlpha,-90+kBeta))); + // 3) Back Left Top Filament + mechStavVol->AddNode(volT2,i*4+3,new TGeoCombiTrans(x+kWidth+0.0036,y+kHeight+0.01,z-kStaveLength+0.1+2*kL1+(i*4*kL1)+kS1/2, new TGeoRotation("volT2",90,-90+kAlpha,90-kBeta))); + // 4) Back Right Top Filament + mechStavVol->AddNode(volT2,i*4+4,new TGeoCombiTrans(x-kWidth-0.0036,y+kHeight+0.01,z-kStaveLength+0.1+2*kL1+(i*4*kL1)+kS1/2, new TGeoRotation("volT2",90,90-kAlpha,-90+kBeta))); + } + + //Vertex structure + + //top ver trd1 + TGeoTrd1 *trd1 = new TGeoTrd1(0,kTopVertexMaxWidth/2,kStaveLength,kTopVertexHeight/2); + TGeoVolume *ibdv = new TGeoVolume("TopVertex",trd1,medM60J3K); + ibdv->SetFillColor(12); + ibdv->SetLineColor(12); + mechStavVol->AddNode(ibdv,1,new TGeoCombiTrans(x,y+kStaveHeight+0.03,z,new TGeoRotation("ibdv",0.,-90,0)));//y+kStaveHeight+0.056 + + //left trd2 + TGeoTrd1 *trd2 = new TGeoTrd1(0,kSideVertexMWidth/2,kStaveLength, kSideVertexHeight/2); + TGeoVolume *ibdv2 = new TGeoVolume("LeftVertex",trd2,medM60J3K); + ibdv2->SetFillColor(12); + ibdv2->SetLineColor(12); + mechStavVol->AddNode(ibdv2,1,new TGeoCombiTrans(x+kStaveWidth/2-0.06,y-0.0355,z,new TGeoRotation("ibdv2",-103.3,90,0))); //x-kStaveWidth/2-0.09 old Config.C y-0.0355, + + //right trd3 + TGeoTrd1 *trd3 = new TGeoTrd1(0,kSideVertexMWidth/2,kStaveLength, kSideVertexHeight/2); + TGeoVolume *ibdv3 = new TGeoVolume("RightVertex",trd3,medM60J3K); + ibdv3->SetFillColor(12); + ibdv3->SetLineColor(12); + mechStavVol->AddNode(ibdv3,1,new TGeoCombiTrans(x-kStaveWidth/2+0.06,y-0.0355,z,new TGeoRotation("ibdv3",103.3,90,0))); //x-kStaveWidth/2+0.09 old Config.C + + //Carbon Fleece + TGeoConeSeg *cons2 = new TGeoConeSeg(zsta,kConeOutRadius+klay1,kConeOutRadius+klay1+klay2,kConeOutRadius+klay1,kConeOutRadius+klay1+klay2,0,180); + TGeoVolume *cone12 = new TGeoVolume("CarbonFleecePipeCover",cons2,medCarbonFleece); + cone12->SetFillColor(28); + cone12->SetLineColor(28); + mechStavVol->AddNode(cone12,1,new TGeoCombiTrans(x+0.25,y,z,new TGeoRotation("cone12",0,0,0))); + mechStavVol->AddNode(cone12,2,new TGeoCombiTrans(x-0.25,y,z,new TGeoRotation("cone12",0,0,0))); + + TGeoBBox *box3 = new TGeoBBox((0.50-(2*(kConeOutRadius+klay1)))/2,klay2/2,zsta);//kStaveLength-0.50); + TGeoVolume *plate3 = new TGeoVolume("CarbonFleeceMiddle",box3,medCarbonFleece); + plate3->SetFillColor(28); + plate3->SetLineColor(28); + mechStavVol->AddNode(plate3,1,new TGeoCombiTrans(x,y-kConeOutRadius+klay1+(klay2/2),z,new TGeoRotation("plate3",0,0,0))); + + TGeoBBox *box31 = new TGeoBBox((0.75-0.25-kConeOutRadius-klay1)/2+0.0025,klay2/2,zsta); + TGeoVolume *plate31 = new TGeoVolume("CarbonFleeceLeftRight",box31,medCarbonFleece); + plate31->SetFillColor(28); + plate31->SetLineColor(28); + mechStavVol->AddNode(plate31,1,new TGeoCombiTrans(x+0.25+kConeOutRadius+klay1+(0.75-0.25-kConeOutRadius-klay1)/2,y-kConeOutRadius+klay1+(klay2/2),z,new TGeoRotation("plate31",0,0,0))); + mechStavVol->AddNode(plate31,2,new TGeoCombiTrans(x-0.25-kConeOutRadius-klay1-(0.75-0.25-kConeOutRadius-klay1)/2,y-kConeOutRadius+klay1+(klay2/2),z,new TGeoRotation("plate31",0,0,0))); + + TGeoBBox *box32 = new TGeoBBox((klay2/2),(kConeOutRadius-klay1)/2,zsta); + TGeoVolume *plate32 = new TGeoVolume("CarbonFleeceVertical",box32,medCarbonFleece); + plate32->SetFillColor(28); + plate32->SetLineColor(28); + mechStavVol->AddNode(plate32,1,new TGeoCombiTrans(x+0.25+kConeOutRadius+klay1+(klay2/2),y+(klay1-kConeOutRadius)/2,z,new TGeoRotation("plate32",0,0,0))); + mechStavVol->AddNode(plate32,2,new TGeoCombiTrans(x+0.25-kConeOutRadius-klay1-(klay2/2),y+(klay1-kConeOutRadius)/2,z,new TGeoRotation("plate32",0,0,0))); + mechStavVol->AddNode(plate32,3,new TGeoCombiTrans(x-0.25+kConeOutRadius+klay1+(klay2/2),y+(klay1-kConeOutRadius)/2,z,new TGeoRotation("plate32",0,0,0))); + mechStavVol->AddNode(plate32,4,new TGeoCombiTrans(x-0.25-kConeOutRadius-klay1-(klay2/2),y+(klay1-kConeOutRadius)/2,z,new TGeoRotation("plate32",0,0,0))); + + //Amec Thermasol red-2 cover tube FGS300 or Carbon Paper + TGeoConeSeg *cons1 = new TGeoConeSeg(zsta,kConeOutRadius,kConeOutRadius+klay1-0.0001,kConeOutRadius,kConeOutRadius+klay1-0.0001,0,180);//kConeOutRadius+klay1-0.0001 + TGeoVolume *cone11 = new TGeoVolume("ThermasolPipeCover",cons1,medFGS003); + cone11->SetFillColor(2); + cone11->SetLineColor(2); + mechStavVol->AddNode(cone11,1,new TGeoCombiTrans(x+0.25,y,z,new TGeoRotation("cone11",0,0,0))); + mechStavVol->AddNode(cone11,2,new TGeoCombiTrans(x-0.25,y,z,new TGeoRotation("cone11",0,0,0))); + + TGeoBBox *box2 = new TGeoBBox((0.50-(2*kConeOutRadius))/2,(klay1/2),zsta);//kStaveLength-0.50); + TGeoVolume *plate2 = new TGeoVolume("ThermasolMiddle",box2,medFGS003); + plate2->SetFillColor(2); + plate2->SetLineColor(2); + mechStavVol->AddNode(plate2,1,new TGeoCombiTrans(x,y-kConeOutRadius+(klay1/2),z,new TGeoRotation("plate2",0,0,0))); + + TGeoBBox *box21 = new TGeoBBox((0.75-0.25-kConeOutRadius-klay1)/2+0.0025,(klay1/2),zsta); + TGeoVolume *plate21 = new TGeoVolume("ThermasolLeftRight",box21,medFGS003); + plate21->SetFillColor(2); + plate21->SetLineColor(2); + mechStavVol->AddNode(plate21,1,new TGeoCombiTrans(x+0.25+kConeOutRadius+(0.75-0.25-kConeOutRadius)/2-(klay1/2)+0.0025,y-kConeOutRadius+(klay1/2),z,new TGeoRotation("plate21",0,0,0))); + mechStavVol->AddNode(plate21,2,new TGeoCombiTrans(x-0.25-kConeOutRadius-(0.75-0.25-kConeOutRadius)/2+(klay1/2)-0.0025,y-kConeOutRadius+(klay1/2),z,new TGeoRotation("plate21",0,0,0))); + + TGeoBBox *box22 = new TGeoBBox((klay1/2),kConeOutRadius/2,zsta); + TGeoVolume *plate22 = new TGeoVolume("ThermasolVertical",box22,medFGS003); + plate22->SetFillColor(2); + plate22->SetLineColor(2); + mechStavVol->AddNode(plate22,1,new TGeoCombiTrans(x+0.25+kConeOutRadius+(klay1/2),y-kConeOutRadius/2,z,new TGeoRotation("plate22",0,0,0))); + mechStavVol->AddNode(plate22,2,new TGeoCombiTrans(x+0.25-kConeOutRadius-(klay1/2),y-kConeOutRadius/2,z,new TGeoRotation("plate22",0,0,0))); + mechStavVol->AddNode(plate22,3,new TGeoCombiTrans(x-0.25+kConeOutRadius+(klay1/2),y-kConeOutRadius/2,z,new TGeoRotation("plate22",0,0,0))); + mechStavVol->AddNode(plate22,4,new TGeoCombiTrans(x-0.25-kConeOutRadius-(klay1/2),y-kConeOutRadius/2,z,new TGeoRotation("plate22",0,0,0))); + + //K13D2U CF plate + TGeoBBox *box1 = new TGeoBBox(2*kWidth,(klay3)/2,zsta); + TGeoVolume *plate1 = new TGeoVolume("CFPlate",box1,medK13D2U2k); + plate1->SetFillColor(5); + plate1->SetLineColor(5); + mechStavVol->AddNode(plate1,1,new TGeoCombiTrans(x,y-(kConeOutRadius+(klay3/2)),z,new TGeoRotation("plate1",0,0,0))); + + //C Fleece bottom plate + TGeoBBox *box6 = new TGeoBBox(2*kWidth,(klay2)/2,zsta); + TGeoVolume *plate6 = new TGeoVolume("CarbonFleeceBottom",box6,medCarbonFleece); + plate6->SetFillColor(2); + plate6->SetLineColor(2); + mechStavVol->AddNode(plate6,1,new TGeoCombiTrans(x,y-(kConeOutRadius+klay3+(klay2/2)),z,new TGeoRotation("plate6",0,0,0))); + + } + if (fBuildLevel < 2) { + //Glue klayers and kapton + TGeoBBox *glue = new TGeoBBox(kStaveWidth/2, (klay4)/2, zsta); + TGeoVolume *volGlue=new TGeoVolume("Glue", glue, medGlue); + volGlue->SetLineColor(5); + volGlue->SetFillColor(5); + // mechStavVol->AddNode(volGlue, 0, new TGeoCombiTrans(x,y-(kConeOutRadius+klay3+klay2+(klay4/2)), z, new TGeoRotation("",0, 0, 0))); + mechStavVol->AddNode(volGlue, 0, new TGeoCombiTrans(x,y-(kConeOutRadius+klay3+klay2+(klay4)/2)+0.00005, z, new TGeoRotation("",0, 0, 0))); + } + + if (fBuildLevel < 1) { + //Flex Cable or Bus + TGeoBBox *kapCable = new TGeoBBox(kStaveWidth/2, klay5/2, zsta);//klay5/2 + TGeoVolume *volCable=new TGeoVolume("FlexCable", kapCable, medFlexCable); + volCable->SetLineColor(28); + volCable->SetFillColor(28); + // mechStavVol->AddNode(volCable, 0, new TGeoCombiTrans(x, y-(kConeOutRadius+klay3+klay2+klay4+fSensorThick+(klay5)/2)+0.0002, z, new TGeoRotation("",0, 0, 0))); + mechStavVol->AddNode(volCable, 0, new TGeoCombiTrans(x, y-(kConeOutRadius+klay3+klay2+klay4+fSensorThick+(klay5)/2)+0.01185, z, new TGeoRotation("",0, 0, 0))); + } + // Done, return the stave structe + return mechStavVol; +} + +// model3 +TGeoVolume* AliITSUv1Layer::CreateStaveModelInnerB3(const Double_t xsta, + const Double_t zsta, + const TGeoManager *mgr){ +// +// Create the mechanical stave structure for Model 3 of TDR +// +// Input: +// xsta : X length +// zsta : Z length +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// +// Created: 28 May 2013 Chinorat Kobdaj +// Updated: Mario Sitta +// Updated: Wanchaloem Poonsawat +// + + // Materials defined in AliITSUv1 + TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$"); + TGeoMedium *medWater = mgr->GetMedium("ITS_WATER$"); + + TGeoMedium *medM60J3K = mgr->GetMedium("ITS_M60J3K$"); + TGeoMedium *medKapton = mgr->GetMedium("ITS_KAPTON(POLYCH2)$"); + TGeoMedium *medGlue = mgr->GetMedium("ITS_GLUE$"); + TGeoMedium *medFlexCable = mgr->GetMedium("ITS_FLEXCABLE$"); + //TGeoMedium *medK13D2U2k = mgr->GetMedium("ITS_K13D2U2k$"); + //TGeoMedium *medFGS003 = mgr->GetMedium("ITS_FGS003$"); + //TGeoMedium *medCarbonFleece = mgr->GetMedium("ITS_CarbonFleece$"); + + // Local parameters + Double_t kConeOutRadius = 0.15/2; + Double_t kStaveLength = zsta*2; + Double_t kStaveWidth = xsta*2; + Double_t w = kStaveWidth/4;//1/2 of W + Double_t staveHeight = 0.3; + Double_t h = staveHeight/2; + Double_t alpha = 90-33.;//90-30; + Double_t the1 = alpha*TMath::DegToRad(); + Double_t s1 = w/TMath::Sin(the1); + Double_t l = w/TMath::Tan(the1); + Double_t s2 = TMath::Sqrt(h*h + s1*s1);//TMath::Sin(the2); + Double_t the2 = TMath::ATan(h/s1); + Double_t beta = the2*TMath::RadToDeg(); + Double_t klay4 = 0.007; //Glue + Double_t klay5 = 0.01; //Flexcable + Int_t loop = (Int_t)((kStaveLength/(2*l))/2); + Double_t hh = 0.01; + Double_t ang1 = 0*TMath::DegToRad(); + Double_t ang2 = 0*TMath::DegToRad(); + Double_t ang3 = 0*TMath::DegToRad(); + Int_t chips = 4; + Double_t headWidth=0.25; + Double_t smcLength=kStaveLength/chips-2*headWidth;//6.25; + Double_t smcWidth=kStaveWidth; + Double_t smcSide1Thick=0.03; + Double_t vaporThick=0.032; + Double_t liquidThick=0.028; + Double_t smcSide2Thick=0.01; + Double_t smcSide3Thick=0.0055; + Double_t smcSide4Thick=0.0095; + Double_t smcSide5Thick=0.0075; + Double_t smcSpace=0.01; + + char volname[30]; + snprintf(volname, 30, "%s%d_StaveStruct", AliITSUGeomTGeo::GetITSStavePattern(), fLayerNumber); + + // detailed structure ++++++++++++++ + Double_t z=0, y=0-0.007, x=0; + + // Polimide micro channels numbers + Double_t yMC = y-h+0.01; + Int_t nb = (Int_t)(kStaveWidth/0.1)+1; + Double_t xstaMC = (nb*0.1-0.08)/2; + + TGeoVolume *mechStavVol = 0; + if (fBuildLevel < 5) { + // world (trapezoid) + TGeoXtru *mechStruct = new TGeoXtru(2); //z sections + Double_t xv[5] = {kStaveWidth/2+0.1,kStaveWidth/2+0.1,0,-kStaveWidth/2-0.1,-kStaveWidth/2-0.1}; + Double_t yv[5] = {-kConeOutRadius*2-0.07,0,staveHeight,0,-kConeOutRadius*2-0.07}; + mechStruct->DefinePolygon(5,xv,yv); + mechStruct->DefineSection(0,-kStaveLength-0.1,0,0,1.); + mechStruct->DefineSection(1,kStaveLength+0.1,0,0,1.); + mechStavVol = new TGeoVolume(volname, mechStruct, medAir); + mechStavVol->SetLineColor(12); + mechStavVol->SetFillColor(12); + mechStavVol->SetVisibility(kTRUE); + + // Silicon micro channels numbers + + TGeoBBox *tM0a=new TGeoBBox(smcWidth/2, 0.003/2, headWidth/2); + TGeoVolume *volTM0a=new TGeoVolume("microChanTop1", tM0a, medKapton); + volTM0a->SetLineColor(35); + volTM0a->SetFillColor(35); + + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0a, 0, new TGeoCombiTrans(x,yMC+0.03, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth+smcLength/2+(headWidth/2), new TGeoRotation("",ang1, ang2, ang3))); + mechStavVol->AddNode(volTM0a, 1, new TGeoCombiTrans(x,yMC+0.03, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth-smcLength/2-(headWidth/2), new TGeoRotation("",ang1, ang2, ang3))); + } + TGeoBBox *tM0c=new TGeoBBox(0.3/2, 0.003/2,smcLength/2); + TGeoVolume *volTM0c=new TGeoVolume("microChanTop2", tM0c, medKapton); + volTM0c->SetLineColor(35); + volTM0c->SetFillColor(35); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0c, 0, new TGeoCombiTrans(x+(smcWidth/2)-(0.3/2),yMC+0.03, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3))); + mechStavVol->AddNode(volTM0c, 1, new TGeoCombiTrans(x-(smcWidth/2)+(0.3/2),yMC+0.03, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + TGeoBBox *tM0c1=new TGeoBBox(0.2225/2, 0.003/2,smcLength/2); + TGeoVolume *volTM0c1=new TGeoVolume("microChanBot1", tM0c1, medKapton); + volTM0c1->SetLineColor(6); + volTM0c1->SetFillColor(6); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0c1, 0, new TGeoCombiTrans(x+smcWidth/2-(smcSide1Thick)-(vaporThick)-(smcSide2Thick)-(smcSide3Thick)-(0.2225/2),yMC+0.03-hh-(0.003), z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + mechStavVol->AddNode(volTM0c1, 1, new TGeoCombiTrans(x-smcWidth/2+(smcSide1Thick)+(liquidThick)+(smcSide2Thick)+(smcSide4Thick)+(0.2225/2),yMC+0.03-hh-(0.003), z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + TGeoBBox *tM0c2=new TGeoBBox(0.072/2, 0.003/2,smcLength/2); + TGeoVolume *volTM0c2=new TGeoVolume("microChanBot2", tM0c2, medKapton); + volTM0c2->SetLineColor(35); + volTM0c2->SetFillColor(35); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0c2, 0, new TGeoCombiTrans(x+smcWidth/2-(0.072/2),yMC+0.03-(0.035+0.0015)-(0.003)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + TGeoBBox *tM0c2r=new TGeoBBox(0.068/2, 0.003/2,smcLength/2); + TGeoVolume *volTM0c2r=new TGeoVolume("microChanBot3", tM0c2r, medKapton); + volTM0c2r->SetLineColor(35); + volTM0c2r->SetFillColor(35); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0c2r, 0, new TGeoCombiTrans(x-smcWidth/2+(0.068/2),yMC+0.03-(0.035+0.0015)-(0.003)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + TGeoBBox *tM0d=new TGeoBBox(smcSide1Thick/2, 0.035/2,smcLength/2); + TGeoVolume *volTM0d=new TGeoVolume("microChanSide1", tM0d, medKapton); + volTM0d->SetLineColor(12); + volTM0d->SetFillColor(12); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0d, 0, new TGeoCombiTrans(x+smcWidth/2-(smcSide1Thick/2),yMC+0.03-0.0015-(0.035)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + mechStavVol->AddNode(volTM0d, 1, new TGeoCombiTrans(x-smcWidth/2+(smcSide1Thick/2),yMC+0.03-0.0015-(0.035)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + + TGeoBBox *tM0d1=new TGeoBBox(smcSide2Thick/2, 0.035/2,smcLength/2); + TGeoVolume *volTM0d1=new TGeoVolume("microChanSide2", tM0d1, medKapton); + volTM0d1->SetLineColor(12); + volTM0d1->SetFillColor(12); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0d1, 0, new TGeoCombiTrans(x+smcWidth/2-(smcSide1Thick)-(vaporThick)-(smcSide2Thick/2),yMC+0.03-(0.003+0.035)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + mechStavVol->AddNode(volTM0d1, 1, new TGeoCombiTrans(x-smcWidth/2+(smcSide1Thick)+(liquidThick)+(smcSide2Thick/2),yMC+0.03-(0.003+0.035)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + TGeoBBox *tM0d2=new TGeoBBox(smcSide3Thick/2, (hh+0.003)/2, smcLength/2); + TGeoVolume *volTM0d2=new TGeoVolume("microChanSide3", tM0d2, medKapton); + volTM0d2->SetLineColor(12); + volTM0d2->SetFillColor(12); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0d2, 0, new TGeoCombiTrans(x+smcWidth/2-(smcSide1Thick)-(vaporThick)-(smcSide2Thick)-(smcSide3Thick/2),yMC+0.03-(0.003+hh+0.003)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + TGeoBBox *tM0d2r=new TGeoBBox(smcSide4Thick/2, (hh+0.003)/2, smcLength/2); + TGeoVolume *volTM0d2r=new TGeoVolume("microChanSide4", tM0d2r, medKapton); + volTM0d2r->SetLineColor(12); + volTM0d2r->SetFillColor(12); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0d2r, 0, new TGeoCombiTrans(x-smcWidth/2+(smcSide1Thick)+(liquidThick)+(smcSide2Thick)+(smcSide4Thick/2),yMC+0.03-(0.003+hh+0.003)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + TGeoBBox *tM0e=new TGeoBBox(smcSide5Thick/2, hh/2,smcLength/2); + TGeoVolume *volTM0e=new TGeoVolume("microChanSide5", tM0e, medKapton); + volTM0e->SetLineColor(12); + volTM0e->SetFillColor(12); + for(Int_t mo=1; mo<=chips; mo++) { + for (Int_t ie=0;ie<11;ie++) { + mechStavVol->AddNode(volTM0e, 0, new TGeoCombiTrans(x-(ie*(smcSpace+smcSide5Thick))+smcWidth/2-(smcSide1Thick)-(vaporThick)-(smcSide2Thick)-(smcSide3Thick)-smcSpace-(smcSide5Thick/2),yMC+0.03-(0.003+hh)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + mechStavVol->AddNode(volTM0e, 1, new TGeoCombiTrans(x+(ie*(smcSpace+smcSide5Thick))-smcWidth/2+(smcSide1Thick)+(liquidThick)+(smcSide2Thick)+(smcSide4Thick)+smcSpace+(smcSide5Thick/2),yMC+0.03-(0.003+hh)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + } + + TGeoBBox *tM0f=new TGeoBBox(0.02/2, hh/2, smcLength/2); + TGeoVolume *volTM0f=new TGeoVolume("microChanTop3", tM0f, medKapton); + //Double_t smcChannels=12; + Double_t smcCloseWallvapor=smcWidth/2-smcSide1Thick-vaporThick-smcSide2Thick-smcSide3Thick-12*smcSpace-11*smcSide5Thick; + Double_t smcCloseWallliquid=smcWidth/2-smcSide1Thick-liquidThick-smcSide2Thick-smcSide4Thick-12*smcSpace-11*smcSide5Thick; + volTM0f->SetLineColor(12); + volTM0f->SetFillColor(12); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0f, 0, new TGeoCombiTrans(x+smcCloseWallvapor-(0.02)/2,yMC+0.03-(0.003+hh)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + mechStavVol->AddNode(volTM0f, 1, new TGeoCombiTrans(x-smcCloseWallliquid+(0.02)/2,yMC+0.03-(0.003+hh)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + //Head(back) microchannel + + TGeoBBox *tM0hb=new TGeoBBox(smcWidth/2, 0.025/2, headWidth/2); + TGeoVolume *volTM0hb=new TGeoVolume("microChanHeadBackBottom1", tM0hb, medKapton); + volTM0hb->SetLineColor(4); + volTM0hb->SetFillColor(4); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0hb, 0, new TGeoCombiTrans(x,yMC+0.03-0.0145-(0.025/2), z+(mo-3)*kStaveLength/4+smcLength/2+headWidth+smcLength/2+(headWidth/2), new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + mechStavVol->AddNode(volTM0hb, 1, new TGeoCombiTrans(x,yMC+0.03-0.0145-(0.025)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth-smcLength/2-(headWidth/2), new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + TGeoBBox *tM0h1=new TGeoBBox(smcWidth/2, 0.013/2, 0.05/2); + TGeoVolume *volTM0h1=new TGeoVolume("microChanHeadBackBottom2", tM0h1, medKapton); + volTM0h1->SetLineColor(5); + volTM0h1->SetFillColor(5); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0h1, 0, new TGeoCombiTrans(x,yMC+0.03-0.0015-(0.013/2), z+(mo-3)*kStaveLength/4+smcLength/2+headWidth-smcLength/2-headWidth+(0.05/2), new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + TGeoBBox *tM0h2=new TGeoBBox(smcWidth/2, 0.003/2, 0.18/2); + TGeoVolume *volTM0h2=new TGeoVolume("microChanHeadBackBottom7", tM0h2, medKapton); + volTM0h2->SetLineColor(6); + volTM0h2->SetFillColor(6); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0h2, 0, new TGeoCombiTrans(x,yMC+0.03-0.0015-0.01-(0.003/2), z+(mo-3)*kStaveLength/4+smcLength/2+headWidth-smcLength/2-0.02-(0.18/2), new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + TGeoBBox *tM0h3=new TGeoBBox(smcWidth/2, 0.013/2, 0.02/2); + TGeoVolume *volTM0h3=new TGeoVolume("microChanHeadBackBottom3", tM0h3, medKapton); + volTM0h3->SetLineColor(5); + volTM0h3->SetFillColor(5); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0h3, 0, new TGeoCombiTrans(x,yMC+0.03-0.0015-(0.013/2), z+(mo-3)*kStaveLength/4+smcLength/2+headWidth-smcLength/2-(0.02/2), new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + TGeoBBox *tM0b1=new TGeoBBox(smcWidth/2, 0.013/2, 0.03/2); + TGeoVolume *volTM0b1=new TGeoVolume("microChanHeadBackBottom4", tM0b1, medKapton); + volTM0b1->SetLineColor(5); + volTM0b1->SetFillColor(5); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0b1, 0, new TGeoCombiTrans(x,yMC+0.03-0.0015-(0.013/2), z+(mo-3)*kStaveLength/4+smcLength/2+headWidth+smcLength/2+headWidth-(0.03/2), new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + TGeoBBox *tM0b2=new TGeoBBox(smcWidth/2, 0.003/2, 0.2/2); + TGeoVolume *volTM0b2=new TGeoVolume("microChanHeadBackBottom5", tM0b2, medKapton); + volTM0b2->SetLineColor(6); + volTM0b2->SetFillColor(6); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0b2, 0, new TGeoCombiTrans(x,yMC+0.03-0.0015-0.01-(0.003/2), z+(mo-3)*kStaveLength/4+smcLength/2+headWidth+smcLength/2+0.02+(0.2/2), new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + TGeoBBox *tM0b3=new TGeoBBox(smcWidth/2, 0.013/2, 0.02/2); + TGeoVolume *volTM0b3=new TGeoVolume("microChanHeadBackBottom6", tM0b3, medKapton); + volTM0b3->SetLineColor(5); + volTM0b3->SetFillColor(5); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0b3, 0, new TGeoCombiTrans(x,yMC+0.03-0.0015-(0.013/2), z+(mo-3)*kStaveLength/4+smcLength/2+headWidth+smcLength/2+(0.02/2), new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + + TGeoBBox *tM0b=new TGeoBBox(0.02/2, 0.02/2, zsta); + TGeoVolume *volTM0b=new TGeoVolume("microChanWalls", tM0b, medKapton); + volTM0b->SetLineColor(35); + volTM0b->SetFillColor(35); + for (Int_t ib=0;ibAddNode(volTM0b, ib, new TGeoCombiTrans(x+ib*0.1-xstaMC+0.01,yMC, z, new TGeoRotation("",0, 0, 0))); + } + + } + + if (fBuildLevel < 4) { + + //**********cooling inlet outlet + + TGeoBBox *tM0dv=new TGeoBBox(vaporThick/2, 0.035/2,smcLength/2); + TGeoVolume *volTM0dv=new TGeoVolume("microChanVapor", tM0dv, medWater); + volTM0dv->SetLineColor(2); + volTM0dv->SetFillColor(2); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0dv, 0, new TGeoCombiTrans(x+smcWidth/2-(smcSide1Thick)-(vaporThick/2),yMC+0.03-0.0015-(0.035)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + TGeoBBox *tM0dl=new TGeoBBox(liquidThick/2, 0.035/2,smcLength/2); + TGeoVolume *volTM0dl=new TGeoVolume("microChanLiquid", tM0dl, medWater); + volTM0dl->SetLineColor(3); + volTM0dl->SetFillColor(3); + for(Int_t mo=1; mo<=chips; mo++) { + mechStavVol->AddNode(volTM0dl, 0, new TGeoCombiTrans(x-smcWidth/2+(smcSide1Thick)+(liquidThick/2),yMC+0.03-0.0015-(0.035)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + // small cooling fluid now using water wait for freeon value + TGeoBBox *tM0dlq=new TGeoBBox(smcSpace/2, hh/2,smcLength/2); + TGeoVolume *volTM0dlq=new TGeoVolume("smallLiquid", tM0dlq, medWater); + volTM0dlq->SetLineColor(3); + volTM0dlq->SetFillColor(3); + TGeoBBox *tM0dvp=new TGeoBBox(smcSpace/2, hh/2,smcLength/2); + TGeoVolume *volTM0dvp=new TGeoVolume("microChanVapor", tM0dvp, medWater); + volTM0dvp->SetLineColor(2); + volTM0dvp->SetFillColor(2); + for(Int_t mo=1; mo<=chips; mo++) { + for (Int_t is=0;is<12;is++) { + mechStavVol->AddNode(volTM0dlq, 0, new TGeoCombiTrans(x+(is*(smcSpace+smcSide5Thick))-smcWidth/2+(smcSide1Thick)+(vaporThick)+(smcSide2Thick)+(smcSide3Thick)+smcSpace/2,yMC+0.03-(0.003+hh)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + mechStavVol->AddNode(volTM0dvp, 1, new TGeoCombiTrans(x-(is*(smcSpace+smcSide5Thick))+smcWidth/2-(smcSide1Thick)-(vaporThick)-(smcSide2Thick)-(smcSide3Thick)-smcSpace/2,yMC+0.03-(0.003+hh)/2, z+(mo-3)*kStaveLength/4+smcLength/2+headWidth, new TGeoRotation("",ang1, ang2, ang3)));//("",0, 0, 0))); + } + } + + //************* + + } + + if (fBuildLevel < 3) { + + //Bottom filament CFRP black-12 Carbon structure TGeoBBox (thickness,width,length) + + Double_t filWidth = 0.04; + Double_t filHeight= 0.02; + TGeoBBox *t1=new TGeoBBox(filHeight/2,filWidth/2,s1); + TGeoVolume *volT1=new TGeoVolume("bottomFilament", t1, medM60J3K); + volT1->SetLineColor(12); + volT1->SetFillColor(12); + for(int i=0;iAddNode(volT1,4*i+0, + new TGeoCombiTrans(x+w,y-h+0.04+filHeight/2,z-kStaveLength/2+(4*l*i)+s1/2, + new TGeoRotation("volT1",-90,alpha,0))); + mechStavVol->AddNode(volT1,4*i+1, + new TGeoCombiTrans(x-w,y-h+0.04+filHeight/2,z-kStaveLength/2+(4*l*i)+s1/2, + new TGeoRotation("volT1",90,alpha,0))); + mechStavVol->AddNode(volT1,4*i+2, + new TGeoCombiTrans(x+w,y-h+0.04+filHeight/2,z-kStaveLength/2+2*l+(i*4*l)+s1/2, + new TGeoRotation("volT1",-90,-alpha,0))); + mechStavVol->AddNode(volT1,4*i+3, + new TGeoCombiTrans(x-w,y-h+0.04+filHeight/2,z-kStaveLength/2+2*l+(i*4*l)+s1/2, + new TGeoRotation("volT1",-90,+alpha,0))); + } + + // Top filament CERP black-12 Carbon structure TGeoBBox (length,thickness,width) + + TGeoBBox *t2=new TGeoBBox(s2,filHeight/2,filWidth/2); + TGeoVolume *volT2=new TGeoVolume("topFilament", t2, medM60J3K); + volT2->SetLineColor(12); + volT2->SetFillColor(12); + for(int i=0;iAddNode(volT2,4*i+0, + new TGeoCombiTrans(x+w,y+0.04+filHeight/2,z-kStaveLength/2+(i*4*l)+s1/2, + new TGeoRotation("volT2",90,90-alpha,90-beta))); + mechStavVol->AddNode(volT2,4*i+1, + new TGeoCombiTrans(x-w,y+0.04+filHeight/2,z-kStaveLength/2+(i*4*l)+s1/2, + new TGeoRotation("volT2",90,-90+alpha,-90+beta))); + mechStavVol->AddNode(volT2,4*i+2, + new TGeoCombiTrans(x+w,y+0.04+filHeight/2,z-kStaveLength/2+2*l+(i*4*l)+s1/2, + new TGeoRotation("volT2",90,-90+alpha,90-beta))); + mechStavVol->AddNode(volT2,4*i+3, + new TGeoCombiTrans(x-w,y+0.04+filHeight/2,z-kStaveLength/2+2*l+(i*4*l)+s1/2, + new TGeoRotation("volT2",90,90-alpha,-90+beta))); + } + } + + if (fBuildLevel < 2) { + + // Glue Filament and Silicon MicroChannel + TGeoBBox *tM0=new TGeoBBox(xstaMC/5, klay4/2, zsta); + TGeoVolume *volTM0=new TGeoVolume("glueFM", tM0,medGlue ); + volTM0->SetLineColor(5); + volTM0->SetFillColor(5); + mechStavVol->AddNode(volTM0, 0, new TGeoCombiTrans(x-xsta/2-0.25,0.03+yMC, z, new TGeoRotation("",0, 0, 0))); + mechStavVol->AddNode(volTM0, 1, new TGeoCombiTrans(x+xsta/2+0.25,0.03+yMC, z, new TGeoRotation("",0, 0, 0))); + + + // Glue microchannel and sensor + TGeoBBox *glueM = new TGeoBBox(xstaMC/5, klay4/2, zsta); + TGeoVolume *volGlueM=new TGeoVolume("glueMS", glueM, medGlue); + volGlueM->SetLineColor(5); + volGlueM->SetFillColor(5); + mechStavVol->AddNode(volGlueM, 0, new TGeoCombiTrans(x-xsta/2-0.25,yMC-0.01, z, new TGeoRotation("",0, 0, 0))); + mechStavVol->AddNode(volGlueM, 1, new TGeoCombiTrans(x+xsta/2+0.25,yMC-0.01, z, new TGeoRotation("",0, 0, 0))); + + // Glue sensor and kapton + TGeoBBox *glue = new TGeoBBox(xsta, klay4/2, zsta); + TGeoVolume *volGlue=new TGeoVolume("glueSensorBus", glue, medGlue); + volGlue->SetLineColor(5); + volGlue->SetFillColor(5); + mechStavVol->AddNode(volGlue, 1, new TGeoCombiTrans(x, y-0.154-fSensorThick-klay4/2, z, new TGeoRotation("",0, 0, 0))); + } + + if (fBuildLevel < 1) { + TGeoBBox *kapCable = new TGeoBBox(xsta, klay5/2, zsta); + TGeoVolume *volCable=new TGeoVolume("Flexcable", kapCable, medFlexCable); + volCable->SetLineColor(28); + volCable->SetFillColor(28); + mechStavVol->AddNode(volCable, 0, new TGeoCombiTrans(x, y-0.154-fSensorThick-klay4-klay5/2, z, new TGeoRotation("",0, 0, 0))); + } + + // Done, return the stave structur + return mechStavVol; + } + +TGeoVolume* AliITSUv1Layer::CreateStaveOuterB(const TGeoManager *mgr){ +// +// Create the chip stave for the Outer Barrel +// +// Input: +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// +// Created: 20 Dec 2013 Mario Sitta +// Updated: 12 Mar 2014 Mario Sitta +// + + TGeoVolume *mechStavVol = 0; + + switch (fStaveModel) { + case O2its::kOBModelDummy: + mechStavVol = CreateStaveModelOuterBDummy(mgr); + break; + case O2its::kOBModel0: + mechStavVol = CreateStaveModelOuterB0(mgr); + break; + case O2its::kOBModel1: + mechStavVol = CreateStaveModelOuterB1(mgr); + break; + default: + LOG(FATAL) << "Unknown stave model "<< fStaveModel << FairLogger::endl; + break; + } + + return mechStavVol; +} + +TGeoVolume* AliITSUv1Layer::CreateStaveModelOuterBDummy(const TGeoManager *) const { +// +// Create dummy stave +// +// Input: +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// +// Created: 20 Dec 2013 Mario Sitta +// + + + // Done, return the stave structure + return 0; +} + +TGeoVolume* AliITSUv1Layer::CreateStaveModelOuterB0(const TGeoManager *mgr){ +// +// Creation of the mechanical stave structure for the Outer Barrel as in v0 +// (we fake the module and halfstave volumes to have always +// the same formal geometry hierarchy) +// +// Input: +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// +// Created: 20 Dec 2013 Mario Sitta +// Updated: 12 Mar 2014 Mario Sitta +// + + // Local variables + Double_t xmod, ymod, zmod; + Double_t xlen, ylen, zlen; + Double_t ypos, zpos; + char volname[30]; + + // First create all needed shapes + + // The chip + xlen = fgkOBHalfStaveWidth; + ylen = 0.5*fStaveThick; // TO BE CHECKED + zlen = fgkOBModuleZLength/2; + + TGeoVolume *chipVol = CreateChipInnerB(xlen, ylen, zlen); + + xmod = ((TGeoBBox*)chipVol->GetShape())->GetDX(); + ymod = ((TGeoBBox*)chipVol->GetShape())->GetDY(); + zmod = ((TGeoBBox*)chipVol->GetShape())->GetDZ(); + + TGeoBBox *module = new TGeoBBox(xmod, ymod, zmod); + + zlen = fgkOBModuleZLength*fNModules; + TGeoBBox *hstave = new TGeoBBox(xlen, ylen, zlen/2); + + + // We have all shapes: now create the real volumes + + TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$"); + + snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSModulePattern(), fLayerNumber); + TGeoVolume *modVol = new TGeoVolume(volname, module, medAir); + modVol->SetVisibility(kTRUE); + + snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSHalfStavePattern(), fLayerNumber); + TGeoVolume *hstaveVol = new TGeoVolume(volname, hstave, medAir); + + + // Finally build it up + modVol->AddNode(chipVol, 0); + fHierarchy[kChip]=1; + + for (Int_t j=0; jGetDZ() + j*2*zmod + zmod; + hstaveVol->AddNode(modVol, j, new TGeoTranslation(0, ypos, zpos)); + fHierarchy[kModule]++; + } + + + // Done, return the stave structure + return hstaveVol; +} + +TGeoVolume* AliITSUv1Layer::CreateStaveModelOuterB1(const TGeoManager *mgr){ +// +// Create the mechanical half stave structure +// for the Outer Barrel as in TDR +// +// Input: +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// +// Created: 20 Nov 2013 Anastasia Barbano +// Updated: 16 Jan 2014 Mario Sitta +// Updated: 24 Feb 2014 Mario Sitta +// + + // Local parameters + Double_t yFlex1 = fgkOBFlexCableAlThick; + Double_t yFlex2 = fgkOBFlexCableKapThick; + Double_t flexOverlap = 5; // to be checked + Double_t xHalfSt = fgkOBHalfStaveWidth/2; + Double_t rCoolMin = fgkOBCoolTubeInnerD/2; + Double_t rCoolMax = rCoolMin + fgkOBCoolTubeThick; + Double_t kLay1 = 0.004; // to be checked + Double_t kLay2 = fgkOBGraphiteFoilThick; + + Double_t xlen, ylen; + Double_t ymod, zmod; + Double_t xtru[12], ytru[12]; + Double_t xpos, ypos, ypos1, zpos/*, zpos5cm*/; + Double_t zlen; + char volname[30]; + + zlen = (fNModules*fgkOBModuleZLength + (fNModules-1)*fgkOBModuleGap)/2; + + // First create all needed shapes + + TGeoVolume *moduleVol = CreateModuleOuterB(); + moduleVol->SetVisibility(kTRUE); + ymod = ((TGeoBBox*)(moduleVol->GetShape()))->GetDY(); + zmod = ((TGeoBBox*)(moduleVol->GetShape()))->GetDZ(); + + TGeoBBox *busAl = new TGeoBBox("BusAl", xHalfSt, fgkOBBusCableAlThick/2, + zlen); + TGeoBBox *busKap = new TGeoBBox("BusKap", xHalfSt, fgkOBBusCableKapThick/2, + zlen); + + TGeoBBox *coldPlate = new TGeoBBox("ColdPlate", fgkOBHalfStaveWidth/2, + fgkOBColdPlateThick/2, zlen); + + TGeoTube *coolTube = new TGeoTube("CoolingTube", rCoolMin, rCoolMax, zlen); + TGeoTube *coolWater = new TGeoTube("CoolingWater", 0., rCoolMin, zlen); + + xlen = xHalfSt - fgkOBCoolTubeXDist/2 - coolTube->GetRmax(); + TGeoBBox *graphlat = new TGeoBBox("GraphLateral", xlen/2, kLay2/2, zlen); + + xlen = fgkOBCoolTubeXDist/2 - coolTube->GetRmax(); + TGeoBBox *graphmid = new TGeoBBox("GraphMiddle", xlen, kLay2/2, zlen); + + ylen = coolTube->GetRmax() - kLay2; + TGeoBBox *graphvert = new TGeoBBox("GraphVertical", kLay2/2, ylen/2, zlen); + + TGeoTubeSeg *graphtub = new TGeoTubeSeg("GraphTube", rCoolMax, + rCoolMax+kLay2, zlen, + 180., 360.); + + xlen = xHalfSt - fgkOBCoolTubeXDist/2 - coolTube->GetRmax() - kLay2; + TGeoBBox *fleeclat = new TGeoBBox("FleecLateral", xlen/2, kLay1/2, zlen); + + xlen = fgkOBCoolTubeXDist/2 - coolTube->GetRmax() - kLay2; + TGeoBBox *fleecmid = new TGeoBBox("FleecMiddle", xlen, kLay1/2, zlen); + + ylen = coolTube->GetRmax() - kLay2 - kLay1; + TGeoBBox *fleecvert = new TGeoBBox("FleecVertical", kLay1/2, ylen/2, zlen); + + TGeoTubeSeg *fleectub = new TGeoTubeSeg("FleecTube", rCoolMax+kLay2, + rCoolMax+kLay1+kLay2, + zlen, 180., 360.); + + TGeoBBox *flex1_5cm = new TGeoBBox("Flex1MV_5cm",xHalfSt,yFlex1/2,flexOverlap/2); + TGeoBBox *flex2_5cm = new TGeoBBox("Flex2MV_5cm",xHalfSt,yFlex2/2,flexOverlap/2); + + // The half stave container (an XTru to avoid overlaps between neightbours) + xtru[0] = xHalfSt; + ytru[0] = 0; + xtru[1] = xtru[0]; + ytru[1] = -2*(ymod + busAl->GetDY() + busKap->GetDY() + coldPlate->GetDY() + + graphlat->GetDY() + fleeclat->GetDY()); + xtru[2] = fgkOBCoolTubeXDist/2 + fleectub->GetRmax(); + ytru[2] = ytru[1]; + xtru[3] = xtru[2]; + ytru[3] = ytru[2] - (coolTube->GetRmax() + fleectub->GetRmax()); + xtru[4] = fgkOBCoolTubeXDist/2 - fleectub->GetRmax(); + ytru[4] = ytru[3]; + xtru[5] = xtru[4]; + ytru[5] = ytru[2]; + for (Int_t i = 0; i<6; i++) { + xtru[6+i] = -xtru[5-i]; + ytru[6+i] = ytru[5-i]; + } + TGeoXtru *halfStave = new TGeoXtru(2); + halfStave->DefinePolygon(12, xtru, ytru); + halfStave->DefineSection(0,-fZLength/2); + halfStave->DefineSection(1, fZLength/2); + + // We have all shapes: now create the real volumes + + TGeoMedium *medAluminum = mgr->GetMedium("ITS_ALUMINUM$"); + TGeoMedium *medCarbon = mgr->GetMedium("ITS_CARBON$"); + TGeoMedium *medKapton = mgr->GetMedium("ITS_KAPTON(POLYCH2)$"); + TGeoMedium *medWater = mgr->GetMedium("ITS_WATER$"); + TGeoMedium *medCarbonFleece = mgr->GetMedium("ITS_CarbonFleece$"); + TGeoMedium *medFGS003 = mgr->GetMedium("ITS_FGS003$"); //amec thermasol + TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$"); + + TGeoVolume *busAlVol = new TGeoVolume("BusAlVol", busAl , medAluminum); + busAlVol->SetLineColor(kCyan); + busAlVol->SetFillColor(busAlVol->GetLineColor()); + busAlVol->SetFillStyle(4000); // 0% transparent + + TGeoVolume *busKapVol = new TGeoVolume("BusKapVol", busKap, medKapton); + busKapVol->SetLineColor(kBlue); + busKapVol->SetFillColor(busKapVol->GetLineColor()); + busKapVol->SetFillStyle(4000); // 0% transparent + + TGeoVolume *coldPlateVol = new TGeoVolume("ColdPlateVol", + coldPlate, medCarbon); + coldPlateVol->SetLineColor(kYellow-3); + coldPlateVol->SetFillColor(coldPlateVol->GetLineColor()); + coldPlateVol->SetFillStyle(4000); // 0% transparent + + TGeoVolume *coolTubeVol = new TGeoVolume("CoolingTubeVol", + coolTube, medKapton); + coolTubeVol->SetLineColor(kGray); + coolTubeVol->SetFillColor(coolTubeVol->GetLineColor()); + coolTubeVol->SetFillStyle(4000); // 0% transparent + + TGeoVolume *coolWaterVol = new TGeoVolume("CoolingWaterVol", + coolWater,medWater); + coolWaterVol->SetLineColor(kBlue); + coolWaterVol->SetFillColor(coolWaterVol->GetLineColor()); + coolWaterVol->SetFillStyle(4000); // 0% transparent + + TGeoVolume *graphlatVol = new TGeoVolume("GraphiteFoilLateral", + graphlat, medFGS003); + graphlatVol->SetLineColor(kGreen); + graphlatVol->SetFillColor(graphlatVol->GetLineColor()); + graphlatVol->SetFillStyle(4000); // 0% transparent + + TGeoVolume *graphmidVol = new TGeoVolume("GraphiteFoilMiddle", + graphmid, medFGS003); + graphmidVol->SetLineColor(kGreen); + graphmidVol->SetFillColor(graphmidVol->GetLineColor()); + graphmidVol->SetFillStyle(4000); // 0% transparent + + TGeoVolume *graphvertVol = new TGeoVolume("GraphiteFoilVertical", + graphvert, medFGS003); + graphvertVol->SetLineColor(kGreen); + graphvertVol->SetFillColor(graphvertVol->GetLineColor()); + graphvertVol->SetFillStyle(4000); // 0% transparent + + TGeoVolume *graphtubVol = new TGeoVolume("GraphiteFoilPipeCover", + graphtub, medFGS003); + graphtubVol->SetLineColor(kGreen); + graphtubVol->SetFillColor(graphtubVol->GetLineColor()); + graphtubVol->SetFillStyle(4000); // 0% transparent + + TGeoVolume *fleeclatVol = new TGeoVolume("CarbonFleeceLateral", + fleeclat, medCarbonFleece); + fleeclatVol->SetLineColor(kViolet); + fleeclatVol->SetFillColor(fleeclatVol->GetLineColor()); + fleeclatVol->SetFillStyle(4000); // 0% transparent + + TGeoVolume *fleecmidVol = new TGeoVolume("CarbonFleeceMiddle", + fleecmid, medCarbonFleece); + fleecmidVol->SetLineColor(kViolet); + fleecmidVol->SetFillColor(fleecmidVol->GetLineColor()); + fleecmidVol->SetFillStyle(4000); // 0% transparent + + TGeoVolume *fleecvertVol = new TGeoVolume("CarbonFleeceVertical", + fleecvert, medCarbonFleece); + fleecvertVol->SetLineColor(kViolet); + fleecvertVol->SetFillColor(fleecvertVol->GetLineColor()); + fleecvertVol->SetFillStyle(4000); // 0% transparent + + TGeoVolume *fleectubVol = new TGeoVolume("CarbonFleecePipeCover", + fleectub, medCarbonFleece); + fleectubVol->SetLineColor(kViolet); + fleectubVol->SetFillColor(fleectubVol->GetLineColor()); + fleectubVol->SetFillStyle(4000); // 0% transparent + + snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSHalfStavePattern(), fLayerNumber); + TGeoVolume *halfStaveVol = new TGeoVolume(volname, halfStave, medAir); +// halfStaveVol->SetLineColor(12); +// halfStaveVol->SetFillColor(12); +// halfStaveVol->SetVisibility(kTRUE); + + TGeoVolume *flex1_5cmVol = new TGeoVolume("Flex1Vol5cm",flex1_5cm,medAluminum); + TGeoVolume *flex2_5cmVol = new TGeoVolume("Flex2Vol5cm",flex2_5cm,medKapton); + + flex1_5cmVol->SetLineColor(kRed); + flex2_5cmVol->SetLineColor(kGreen); + + // Now build up the half stave + ypos = - busKap->GetDY(); + halfStaveVol->AddNode(busKapVol, 1, new TGeoTranslation(0, ypos, 0)); + + ypos -= (busKap->GetDY() + busAl->GetDY()); + halfStaveVol->AddNode(busAlVol, 1, new TGeoTranslation(0, ypos, 0)); + + ypos -= (busAl->GetDY() + ymod); + for (Int_t j=0; jAddNode(moduleVol, j, new TGeoTranslation(0, ypos, zpos)); + fHierarchy[kModule]++; + } + + ypos -= (ymod + coldPlate->GetDY()); + halfStaveVol->AddNode(coldPlateVol, 1, new TGeoTranslation(0, ypos, 0)); + + coolTubeVol->AddNode(coolWaterVol, 1, 0); + + xpos = fgkOBCoolTubeXDist/2; + ypos1 = ypos - (coldPlate->GetDY() + coolTube->GetRmax()); + halfStaveVol->AddNode(coolTubeVol, 1, new TGeoTranslation(-xpos, ypos1, 0)); + halfStaveVol->AddNode(coolTubeVol, 2, new TGeoTranslation( xpos, ypos1, 0)); + + halfStaveVol->AddNode(graphtubVol, 1, new TGeoTranslation(-xpos, ypos1, 0)); + halfStaveVol->AddNode(graphtubVol, 2, new TGeoTranslation( xpos, ypos1, 0)); + + halfStaveVol->AddNode(fleectubVol, 1, new TGeoTranslation(-xpos, ypos1, 0)); + halfStaveVol->AddNode(fleectubVol, 2, new TGeoTranslation( xpos, ypos1, 0)); + + xpos = xHalfSt - graphlat->GetDX(); + ypos1 = ypos - (coldPlate->GetDY() + graphlat->GetDY()); + halfStaveVol->AddNode(graphlatVol, 1, new TGeoTranslation(-xpos, ypos1, 0)); + halfStaveVol->AddNode(graphlatVol, 2, new TGeoTranslation( xpos, ypos1, 0)); + + halfStaveVol->AddNode(graphmidVol, 1, new TGeoTranslation(0, ypos1, 0)); + + xpos = xHalfSt - 2*graphlat->GetDX() + graphvert->GetDX(); + ypos1 = ypos - (coldPlate->GetDY() +2*graphlat->GetDY() +graphvert->GetDY()); + halfStaveVol->AddNode(graphvertVol, 1, new TGeoTranslation(-xpos, ypos1, 0)); + halfStaveVol->AddNode(graphvertVol, 2, new TGeoTranslation( xpos, ypos1, 0)); + xpos = graphmid->GetDX() - graphvert->GetDX(); + halfStaveVol->AddNode(graphvertVol, 3, new TGeoTranslation(-xpos, ypos1, 0)); + halfStaveVol->AddNode(graphvertVol, 4, new TGeoTranslation( xpos, ypos1, 0)); + + xpos = xHalfSt - fleeclat->GetDX(); + ypos1 = ypos - (coldPlate->GetDY() +2*graphlat->GetDY() +fleeclat->GetDY()); + halfStaveVol->AddNode(fleeclatVol, 1, new TGeoTranslation(-xpos, ypos1, 0)); + halfStaveVol->AddNode(fleeclatVol, 2, new TGeoTranslation( xpos, ypos1, 0)); + + halfStaveVol->AddNode(fleecmidVol, 1, new TGeoTranslation(0, ypos1, 0)); + + xpos = xHalfSt - 2*fleeclat->GetDX() + fleecvert->GetDX(); + ypos1 = ypos - (coldPlate->GetDY() +2*graphlat->GetDY() + + 2*fleeclat->GetDY() + fleecvert->GetDY()); + halfStaveVol->AddNode(fleecvertVol, 1, new TGeoTranslation(-xpos, ypos1, 0)); + halfStaveVol->AddNode(fleecvertVol, 2, new TGeoTranslation( xpos, ypos1, 0)); + xpos = fleecmid->GetDX() - fleecvert->GetDX(); + halfStaveVol->AddNode(fleecvertVol, 3, new TGeoTranslation(-xpos, ypos1, 0)); + halfStaveVol->AddNode(fleecvertVol, 4, new TGeoTranslation( xpos, ypos1, 0)); + + //THE FOLLOWING IS ONLY A REMINDER FOR WHAT IS STILL MISSING + +// for (Int_t j=0; jAddNode(moduleVol, j, new TGeoTranslation(xPos, -ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + ymod, zpos)); +// halfStaveVol->AddNode(moduleVol, fNChips+j, new TGeoTranslation(-xPos, -ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + ymod +deltaY, zpos)); + +// if((j+1)!=fNChips){ +// halfStaveVol->AddNode(flex1_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1 + yFlex2 + yFlex1/2,zpos5cm)); +// halfStaveVol->AddNode(flex1_5cmVol,fNChips+j,new TGeoTranslation(-xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1 + yFlex2 + yFlex1/2 +deltaY,zpos5cm)); +// halfStaveVol->AddNode(flex2_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + 2*yFlex1 + 3*yFlex2/2,zpos5cm)); +// halfStaveVol->AddNode(flex2_5cmVol,fNChips+j,new TGeoTranslation(-xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + 2*yFlex1 + 3*yFlex2/2 +deltaY,zpos5cm)); +// } +// else { +// halfStaveVol->AddNode(flex1_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1/2,zpos5cm-modGap)); +// halfStaveVol->AddNode(flex1_5cmVol,fNChips+j,new TGeoTranslation(-xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1/2 +deltaY,zpos5cm-modGap)); +// halfStaveVol->AddNode(flex2_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate +2*ymod + yFlex1 + yFlex2/2,zpos5cm-modGap)); +// halfStaveVol->AddNode(flex2_5cmVol,fNChips+j,new TGeoTranslation(-xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1 + yFlex2/2 +deltaY,zpos5cm-modGap)); + +// } +// } + + + // Done, return the half stave structure + return halfStaveVol; +} + +TGeoVolume* AliITSUv1Layer::CreateSpaceFrameOuterB(const TGeoManager *mgr){ +// +// Create the space frame for the Outer Barrel +// +// Input: +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// +// + + TGeoVolume *mechStavVol = 0; + + switch (fStaveModel) { + case O2its::kOBModelDummy: + case O2its::kOBModel0: + mechStavVol = CreateSpaceFrameOuterBDummy(mgr); + break; + case O2its::kOBModel1: + mechStavVol = CreateSpaceFrameOuterB1(mgr); + break; + default: + LOG(FATAL) << "Unknown stave model " << fStaveModel << FairLogger::endl; + break; + } + + return mechStavVol; +} + +TGeoVolume* AliITSUv1Layer::CreateSpaceFrameOuterBDummy(const TGeoManager *) const { +// +// Create dummy stave +// +// Input: +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// + + + // Done, return the stave structur + return 0; +} + +TGeoVolume* AliITSUv1Layer::CreateSpaceFrameOuterB1(const TGeoManager *mgr){ +// +// Create the space frame for the Outer Barrel (Model 1) +// +// Input: +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// a TGeoVolume with the Space Frame of a stave +// +// Created: 20 Dec 2013 Anastasia Barbano +// Updated: 15 Jan 2014 Mario Sitta +// Updated: 18 Feb 2014 Mario Sitta +// Updated: 12 Mar 2014 Mario Sitta +// + + // Materials defined in AliITSUv0 + TGeoMedium *medCarbon = mgr->GetMedium("ITS_CARBON$"); + TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$"); + + // Local parameters + Double_t sframeWidth = fgkOBSpaceFrameWidth; + Double_t sframeHeight = fgkOBSpaceFrameTotHigh - fgkOBHalfStaveYTrans; + Double_t staveBeamRadius = fgkOBSFrameBeamRadius; + Double_t staveLa = fgkOBSpaceFrameLa; + Double_t staveHa = fgkOBSpaceFrameHa; + Double_t staveLb = fgkOBSpaceFrameLb; + Double_t staveHb = fgkOBSpaceFrameHb; + Double_t stavel = fgkOBSpaceFrameL; + Double_t bottomBeamAngle = fgkOBSFBotBeamAngle; + Double_t triangleHeight = sframeHeight - staveBeamRadius; + Double_t halfTheta = TMath::ATan( 0.5*sframeWidth/triangleHeight ); +// Double_t alpha = TMath::Pi()*3./4. - halfTheta/2.; + Double_t beta = (TMath::Pi() - 2.*halfTheta)/4.; +// Double_t distCenterSideDown = 0.5*sframeWidth/TMath::Cos(beta); + + Double_t zlen; + Double_t xpos, ypos, zpos; + Double_t seglen; + char volname[30]; + + + zlen = fNModules*fgkOBModuleZLength + (fNModules-1)*fgkOBModuleGap; + + snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSHalfStavePattern(), fLayerNumber); + if (gGeoManager->GetVolume(volname)) { // Should always be so + sframeHeight -= ((TGeoBBox*)gGeoManager->GetVolume(volname)->GetShape())->GetDY()*2; + zlen = ((TGeoBBox*)gGeoManager->GetVolume(volname)->GetShape())->GetDZ()*2; + } + seglen = zlen/fNModules; + + + // First create all needed shapes and volumes + + TGeoBBox *spaceFrame = new TGeoBBox(sframeWidth/2,sframeHeight/2,zlen/2); + TGeoBBox *segment = new TGeoBBox(sframeWidth/2,sframeHeight/2,seglen/2); + + TGeoVolume *spaceFrameVol = new TGeoVolume("CarbonFrameVolume", + spaceFrame, medAir); + spaceFrameVol->SetVisibility(kFALSE); + + TGeoVolume *segmentVol = new TGeoVolume("segmentVol", segment, medAir); + + //SpaceFrame + + //--- the top V of the Carbon Fiber Stave (segment) + TGeoArb8 *cfStavTop1 = CreateStaveSide("CFstavTopCornerVol1shape", seglen/2., halfTheta, -1, staveLa, staveHa, stavel); + TGeoVolume *cfStavTopVol1 = new TGeoVolume("CFstavTopCornerVol1", + cfStavTop1, medCarbon); + cfStavTopVol1->SetLineColor(35); + + TGeoArb8 *cfStavTop2 = CreateStaveSide("CFstavTopCornerVol2shape", seglen/2., halfTheta, 1, staveLa, staveHa, stavel); + TGeoVolume *cfStavTopVol2 = new TGeoVolume("CFstavTopCornerVol2", + cfStavTop2, medCarbon ); + cfStavTopVol2->SetLineColor(35); + + TGeoTranslation *trTop1 = new TGeoTranslation(0, sframeHeight/2, 0); + + //--- the 2 side V + TGeoArb8 *cfStavSide1 = CreateStaveSide("CFstavSideCornerVol1shape", seglen/2., beta, -1, staveLb, staveHb, stavel); + TGeoVolume *cfStavSideVol1 = new TGeoVolume("CFstavSideCornerVol1", + cfStavSide1, medCarbon); + cfStavSideVol1->SetLineColor(35); + + TGeoArb8 *cfStavSide2 = CreateStaveSide("CFstavSideCornerVol2shape", seglen/2., beta, 1, staveLb, staveHb, stavel); + TGeoVolume *cfStavSideVol2 = new TGeoVolume("CFstavSideCornerVol2", + cfStavSide2, medCarbon ); + cfStavSideVol2->SetLineColor(35); + + xpos = -sframeWidth/2; + ypos = -sframeHeight/2 + staveBeamRadius + staveHb*TMath::Sin(beta); + TGeoCombiTrans *ctSideR = new TGeoCombiTrans( xpos, ypos, 0, + new TGeoRotation("", 180-2*beta*TMath::RadToDeg(), 0, 0)); + TGeoCombiTrans *ctSideL = new TGeoCombiTrans(-xpos, ypos, 0, + new TGeoRotation("",-180+2*beta*TMath::RadToDeg(), 0, 0)); + + segmentVol->AddNode(cfStavTopVol1,1,trTop1); + segmentVol->AddNode(cfStavTopVol2,1,trTop1); + segmentVol->AddNode(cfStavSideVol1,1,ctSideR); + segmentVol->AddNode(cfStavSideVol1,2,ctSideL); + segmentVol->AddNode(cfStavSideVol2,1,ctSideR); + segmentVol->AddNode(cfStavSideVol2,2,ctSideL); + + //--- The beams + // Beams on the sides + Double_t beamPhiPrime = TMath::ASin(1./TMath::Sqrt( (1+TMath::Sin(2*beta)*TMath::Sin(2*beta)/(TanD(fgkOBSFrameBeamSidePhi)*TanD(fgkOBSFrameBeamSidePhi))) )); + Double_t beamLength = TMath::Sqrt( sframeHeight*sframeHeight/( TMath::Sin(beamPhiPrime)*TMath::Sin(beamPhiPrime))+ sframeWidth*sframeWidth/4.)-staveLa/2-staveLb/2; + TGeoTubeSeg *sideBeam = new TGeoTubeSeg(0, staveBeamRadius, + beamLength/2, 0, 180); + TGeoVolume *sideBeamVol = new TGeoVolume("CFstavSideBeamVol", + sideBeam, medCarbon); + sideBeamVol->SetLineColor(35); + + TGeoRotation *beamRot1 = new TGeoRotation("", /*90-2*beta*/halfTheta*TMath::RadToDeg(), + -beamPhiPrime*TMath::RadToDeg(), -90); + TGeoRotation *beamRot2 = new TGeoRotation("", 90-2.*beta*TMath::RadToDeg(), + beamPhiPrime*TMath::RadToDeg(), -90); + TGeoRotation *beamRot3 = new TGeoRotation("", 90+2.*beta*TMath::RadToDeg(), + beamPhiPrime*TMath::RadToDeg(), -90); + TGeoRotation *beamRot4 = new TGeoRotation("", 90+2.*beta*TMath::RadToDeg(), + -beamPhiPrime*TMath::RadToDeg(), -90); + + TGeoCombiTrans *beamTransf[8]; + xpos = 0.49*triangleHeight*TMath::Tan(halfTheta);//was 0.5, fix small overlap + ypos = staveBeamRadius/2; + zpos = seglen/8; + beamTransf[0] = new TGeoCombiTrans( xpos, ypos,-3*zpos, beamRot1); + + beamTransf[1] = new TGeoCombiTrans( xpos, ypos,-3*zpos, beamRot1); + AddTranslationToCombiTrans(beamTransf[1], 0, 0, seglen/2); + + beamTransf[2] = new TGeoCombiTrans( xpos, ypos, -zpos, beamRot2); + + beamTransf[3] = new TGeoCombiTrans( xpos, ypos, -zpos, beamRot2); + AddTranslationToCombiTrans(beamTransf[3], 0, 0, seglen/2); + + beamTransf[4] = new TGeoCombiTrans(-xpos, ypos,-3*zpos, beamRot3); + + beamTransf[5] = new TGeoCombiTrans(-xpos, ypos,-3*zpos, beamRot3); + AddTranslationToCombiTrans(beamTransf[5], 0, 0, seglen/2); + + beamTransf[6] = new TGeoCombiTrans(-xpos, ypos, -zpos, beamRot4); + beamTransf[7] = new TGeoCombiTrans(-xpos, ypos, 3*zpos, beamRot4); + + //--- Beams of the bottom + TGeoTubeSeg *bottomBeam1 = new TGeoTubeSeg(0, staveBeamRadius, + sframeWidth/2.-staveLb/3, 0, 180); + TGeoVolume *bottomBeam1Vol = new TGeoVolume("CFstavBottomBeam1Vol", + bottomBeam1, medCarbon); + bottomBeam1Vol->SetLineColor(35); + + TGeoTubeSeg *bottomBeam2 = new TGeoTubeSeg(0, staveBeamRadius, + sframeWidth/2.-staveLb/3, 0, 90); + TGeoVolume *bottomBeam2Vol = new TGeoVolume("CFstavBottomBeam2Vol", + bottomBeam2, medCarbon); + bottomBeam2Vol->SetLineColor(35); + + TGeoTubeSeg *bottomBeam3 = new TGeoTubeSeg(0, staveBeamRadius, + 0.5*sframeWidth/SinD(bottomBeamAngle) - staveLb/3, + 0, 180); + TGeoVolume *bottomBeam3Vol = new TGeoVolume("CFstavBottomBeam3Vol", + bottomBeam3, medCarbon); + bottomBeam3Vol->SetLineColor(35); + + TGeoRotation *bottomBeamRot1 = new TGeoRotation("", 90, 90, 90); + TGeoRotation *bottomBeamRot2 = new TGeoRotation("",-90, 90, -90); + + TGeoCombiTrans *bottomBeamTransf1 = new TGeoCombiTrans("",0, + -(sframeHeight/2-staveBeamRadius), 0, + bottomBeamRot1); + TGeoCombiTrans *bottomBeamTransf2 = new TGeoCombiTrans(0, + -(sframeHeight/2-staveBeamRadius), + -seglen/2, + bottomBeamRot1); + TGeoCombiTrans *bottomBeamTransf3 = new TGeoCombiTrans(0, + -(sframeHeight/2-staveBeamRadius), + seglen/2, + bottomBeamRot2); + // be careful for beams #3: when "reading" from -z to +z and + // from the bottom of the stave, it should draw a Lambda, and not a V + TGeoRotation *bottomBeamRot4 = new TGeoRotation("",-90, bottomBeamAngle,-90); + TGeoRotation *bottomBeamRot5 = new TGeoRotation("",-90,-bottomBeamAngle,-90); + + TGeoCombiTrans *bottomBeamTransf4 = new TGeoCombiTrans(0, + -(sframeHeight/2-staveBeamRadius), + -seglen/4, + bottomBeamRot4); + TGeoCombiTrans *bottomBeamTransf5 = new TGeoCombiTrans(0, + -(sframeHeight/2-staveBeamRadius), + seglen/4, + bottomBeamRot5); + + segmentVol->AddNode(sideBeamVol,1, beamTransf[0]); + segmentVol->AddNode(sideBeamVol,2, beamTransf[1]); + segmentVol->AddNode(sideBeamVol,3, beamTransf[2]); + segmentVol->AddNode(sideBeamVol,4, beamTransf[3]); + segmentVol->AddNode(sideBeamVol,5, beamTransf[4]); + segmentVol->AddNode(sideBeamVol,6, beamTransf[5]); + segmentVol->AddNode(sideBeamVol,7, beamTransf[6]); + segmentVol->AddNode(sideBeamVol,8, beamTransf[7]); + segmentVol->AddNode(bottomBeam1Vol,1,bottomBeamTransf1); + segmentVol->AddNode(bottomBeam2Vol,1,bottomBeamTransf2); + segmentVol->AddNode(bottomBeam2Vol,2,bottomBeamTransf3); + segmentVol->AddNode(bottomBeam3Vol,1,bottomBeamTransf4); + segmentVol->AddNode(bottomBeam3Vol,2,bottomBeamTransf5); + + // Then build up the space frame + for(Int_t i=0; iGetDZ() + (1 + 2*i)*segment->GetDZ(); + spaceFrameVol->AddNode(segmentVol, i, new TGeoTranslation(0, 0, zpos)); + } + + // Done, return the space frame structure + return spaceFrameVol; +} + +TGeoVolume* AliITSUv1Layer::CreateChipInnerB(const Double_t xchip, + const Double_t ychip, + const Double_t zchip, + const TGeoManager *mgr){ +// +// Creates the actual Chip +// +// Input: +// xchip,ychip,zchip : the chip dimensions +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// +// Created: 22 Jun 2011 Mario Sitta +// + + char volname[30]; + Double_t xlen, ylen, zlen; + Double_t xpos, ypos, zpos; + + + // First create all needed shapes + + // The chip + TGeoBBox *chip = new TGeoBBox(xchip, ychip, zchip); + + // The sensor + xlen = chip->GetDX(); + ylen = 0.5*fSensorThick; + zlen = chip->GetDZ(); + TGeoBBox *sensor = new TGeoBBox(xlen, ylen, zlen); + + + // We have all shapes: now create the real volumes + TGeoMedium *medSi = mgr->GetMedium("ITS_SI$"); + + snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSChipPattern(), fLayerNumber); + TGeoVolume *chipVol = new TGeoVolume(volname, chip, medSi); + chipVol->SetVisibility(kTRUE); + chipVol->SetLineColor(1); + + snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSSensorPattern(), fLayerNumber); + TGeoVolume *sensVol = new TGeoVolume(volname, sensor, medSi); + sensVol->SetVisibility(kTRUE); + sensVol->SetLineColor(8); + sensVol->SetLineWidth(1); + sensVol->SetFillColor(sensVol->GetLineColor()); + sensVol->SetFillStyle(4000); // 0% transparent + + // Now build up the chip + xpos = 0.; + ypos = -chip->GetDY() + sensor->GetDY(); + zpos = 0.; + + chipVol->AddNode(sensVol, 1, new TGeoTranslation(xpos, ypos, zpos)); + + // Done, return the chip + return chipVol; +} + +TGeoVolume* AliITSUv1Layer::CreateModuleOuterB(const TGeoManager *mgr){ +// +// Creates the OB Module: HIC + FPC + Carbon plate +// +// Input: +// mgr : the GeoManager (used only to get the proper material) +// +// Output: +// +// Return: +// the module as a TGeoVolume +// +// Created: 18 Dec 2013 M. Sitta, A. Barbano +// Updated: 26 Feb 2014 M. Sitta +// + + char volname[30]; + + Double_t xGap = fgkOBChipXGap; + Double_t zGap = fgkOBChipZGap; + + Double_t xchip, ychip, zchip; + Double_t xlen, ylen, zlen; + Double_t xpos, ypos, zpos; + + // First create all needed shapes + + // The chip (the same as for IB) + xlen = (fgkOBHalfStaveWidth/2-xGap/2)/fgkOBNChipRows; + ylen = 0.5*fStaveThick; // TO BE CHECKED + zlen = (fgkOBModuleZLength - (fgkOBChipsPerRow-1)*zGap)/(2*fgkOBChipsPerRow); + + TGeoVolume *chipVol = CreateChipInnerB(xlen, ylen, zlen); + + xchip = ((TGeoBBox*)chipVol->GetShape())->GetDX(); + ychip = ((TGeoBBox*)chipVol->GetShape())->GetDY(); + zchip = ((TGeoBBox*)chipVol->GetShape())->GetDZ(); + + // The module carbon plate + xlen = fgkOBHalfStaveWidth/2; + ylen = fgkOBCarbonPlateThick/2; + zlen = fgkOBModuleZLength/2; + TGeoBBox *modPlate = new TGeoBBox("CarbonPlate", xlen, ylen, zlen); + + // The glue + ylen = fgkOBGlueThick/2; + TGeoBBox *glue = new TGeoBBox("Glue", xlen, ylen, zlen); + + // The flex cables + ylen = fgkOBFlexCableAlThick/2; + TGeoBBox *flexAl = new TGeoBBox("FlexAl", xlen, ylen, zlen); + + ylen = fgkOBFlexCableKapThick/2; + TGeoBBox *flexKap = new TGeoBBox("FlexKap", xlen, ylen, zlen); + + // The module + xlen = fgkOBHalfStaveWidth/2; + ylen = ychip + modPlate->GetDY() + glue->GetDY() + + flexAl->GetDY() + flexKap->GetDY(); + zlen = fgkOBModuleZLength/2; + TGeoBBox *module = new TGeoBBox("OBModule", xlen, ylen, zlen); + + + // We have all shapes: now create the real volumes + + TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$"); + TGeoMedium *medCarbon = mgr->GetMedium("ITS_CARBON$"); + TGeoMedium *medGlue = mgr->GetMedium("ITS_GLUE$"); + TGeoMedium *medAluminum = mgr->GetMedium("ITS_ALUMINUM$"); + TGeoMedium *medKapton = mgr->GetMedium("ITS_KAPTON(POLYCH2)$"); + + TGeoVolume *modPlateVol = new TGeoVolume("CarbonPlateVol", + modPlate, medCarbon); + modPlateVol->SetLineColor(kMagenta-8); + modPlateVol->SetFillColor(modPlateVol->GetLineColor()); + modPlateVol->SetFillStyle(4000); // 0% transparent + + TGeoVolume *glueVol = new TGeoVolume("GlueVol", glue, medGlue); + glueVol->SetLineColor(kBlack); + glueVol->SetFillColor(glueVol->GetLineColor()); + glueVol->SetFillStyle(4000); // 0% transparent + + TGeoVolume *flexAlVol = new TGeoVolume("FlexAlVol", flexAl, medAluminum); + flexAlVol->SetLineColor(kRed); + flexAlVol->SetFillColor(flexAlVol->GetLineColor()); + flexAlVol->SetFillStyle(4000); // 0% transparent + + TGeoVolume *flexKapVol = new TGeoVolume("FlexKapVol", flexKap, medKapton); + flexKapVol->SetLineColor(kGreen); + flexKapVol->SetFillColor(flexKapVol->GetLineColor()); + flexKapVol->SetFillStyle(4000); // 0% transparent + + snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSModulePattern(), fLayerNumber); + TGeoVolume *modVol = new TGeoVolume(volname, module, medAir); + modVol->SetVisibility(kTRUE); + + // Now build up the module + ypos = -module->GetDY() + modPlate->GetDY(); + modVol->AddNode(modPlateVol, 1, new TGeoTranslation(0, ypos, 0)); + + ypos += (modPlate->GetDY() + glue->GetDY()); + modVol->AddNode(glueVol, 1, new TGeoTranslation(0, ypos, 0)); + + xpos = -module->GetDX() + xchip; + ypos += (glue->GetDY() + ychip); + for(Int_t k=0; kGetDZ() + zchip + k*(2*zchip + zGap); + modVol->AddNode(chipVol, 2*k , new TGeoTranslation( xpos, ypos, zpos)); + modVol->AddNode(chipVol, 2*k+1, + new TGeoCombiTrans(-xpos, ypos, zpos, new TGeoRotation("",0,180,180))); + fHierarchy[kChip]+=2; + } + + ypos += (ychip + flexAl->GetDY()); + modVol->AddNode(flexAlVol, 1, new TGeoTranslation(0, ypos, 0)); + + ypos += (flexAl->GetDY() + flexKap->GetDY()); + modVol->AddNode(flexKapVol, 1, new TGeoTranslation(0, ypos, 0)); + + // Done, return the module + return modVol; +} + +Double_t AliITSUv1Layer::RadiusOfTurboContainer(){ +// +// Computes the inner radius of the air container for the Turbo configuration +// as the radius of either the circle tangent to the stave or the circle +// passing for the stave's lower vertex +// +// Input: +// none (all needed parameters are class members) +// +// Output: +// +// Return: +// the radius of the container if >0, else flag to use the lower vertex +// +// Created: 08 Mar 2012 Mario Sitta +// + + Double_t rr, delta, z, lstav, rstav; + + if (fStaveThick > 89.) // Very big angle: avoid overflows since surely + return -1; // the radius from lower vertex is the right value + + rstav = fLayRadius + 0.5*fStaveThick; + delta = (0.5*fStaveThick)/CosD(fStaveTilt); + z = (0.5*fStaveThick)*TanD(fStaveTilt); + + rr = rstav - delta; + lstav = (0.5*fStaveWidth) - z; + + if ( (rr*SinD(fStaveTilt) < lstav) ) + return (rr*CosD(fStaveTilt)); + else + return -1; +} + +void AliITSUv1Layer::SetNUnits(Int_t u) +{ +// +// Sets the number of units in a stave: +// for the Inner Barrel: the number of chips per stave +// for the Outer Barrel: the number of modules per half stave +// +// +// Input: +// u : the number of units +// +// Output: +// +// Return: +// +// Created: 18 Feb 2013 Mario Sitta (was already SetNChips) +// + + if (fLayerNumber < fgkNumberOfInnerLayers) + fNChips = u; + else { + fNModules = u; + fNChips = fgkOBChipsPerRow; + } + +} + +void AliITSUv1Layer::SetStaveTilt(const Double_t t) +{ +// +// Sets the Stave tilt angle (for turbo layers only) +// +// Input: +// t : the stave tilt angle +// +// Output: +// +// Return: +// +// Created: 08 Jul 2011 Mario Sitta +// + + if (fIsTurbo) + fStaveTilt = t; + else + LOG(ERROR) << "Not a Turbo layer" << FairLogger::endl; + +} + +void AliITSUv1Layer::SetStaveWidth(const Double_t w){ +// +// Sets the Stave width (for turbo layers only) +// +// Input: +// w : the stave width +// +// Output: +// +// Return: +// +// Created: 08 Jul 2011 Mario Sitta +// + + if (fIsTurbo) + fStaveWidth = w; + else + LOG(ERROR) << "Not a Turbo layer" << FairLogger::endl; + +} + +TGeoArb8 *AliITSUv1Layer::CreateStaveSide(const char *name, + Double_t dz, Double_t angle, Double_t xSign, + Double_t L, Double_t H, Double_t l) { +// +// Creates the V-shaped sides of the OB space frame +// (from a similar method with same name and function +// in AliITSv11GeometrySDD class by L.Gaudichet) +// + + // Create one half of the V shape corner of CF stave + + TGeoArb8 *cfStavSide = new TGeoArb8(dz); + cfStavSide->SetName(name); + + // Points must be in clockwise order + cfStavSide->SetVertex(0, 0, 0); + cfStavSide->SetVertex(2, xSign*(L*TMath::Sin(angle)-l*TMath::Cos(angle)), + -L*TMath::Cos(angle)-l*TMath::Sin(angle)); + cfStavSide->SetVertex(4, 0, 0); + cfStavSide->SetVertex(6, xSign*(L*TMath::Sin(angle)-l*TMath::Cos(angle)), + -L*TMath::Cos(angle)-l*TMath::Sin(angle)); + if (xSign < 0) { + cfStavSide->SetVertex(1, 0, -H); + cfStavSide->SetVertex(3, xSign*L*TMath::Sin(angle), -L*TMath::Cos(angle)); + cfStavSide->SetVertex(5, 0, -H); + cfStavSide->SetVertex(7, xSign*L*TMath::Sin(angle), -L*TMath::Cos(angle)); + } else { + cfStavSide->SetVertex(1, xSign*L*TMath::Sin(angle), -L*TMath::Cos(angle)); + cfStavSide->SetVertex(3, 0, -H); + cfStavSide->SetVertex(5, xSign*L*TMath::Sin(angle), -L*TMath::Cos(angle)); + cfStavSide->SetVertex(7, 0, -H); + } + return cfStavSide; +} + +TGeoCombiTrans *AliITSUv1Layer::CreateCombiTrans(const char *name, + Double_t dy, Double_t dz, + Double_t dphi, Bool_t planeSym) { +// +// Help method to create a TGeoCombiTrans matrix +// (from a similar method with same name and function +// in AliITSv11GeometrySDD class by L.Gaudichet) +// + + // + // return the TGeoCombiTrans which make a translation in y and z + // and a rotation in phi in the global coord system + // If planeSym = true, the rotation places the object symetrically + // (with respect to the transverse plane) to its position in the + // case planeSym = false + // + + TGeoTranslation t1(dy*CosD(90.+dphi),dy*SinD(90.+dphi), dz); + TGeoRotation r1("",0.,0.,dphi); + TGeoRotation r2("",90, 180, -90-dphi); + + TGeoCombiTrans *combiTrans1 = new TGeoCombiTrans(name); + combiTrans1->SetTranslation(t1); + if (planeSym) combiTrans1->SetRotation(r1); + else combiTrans1->SetRotation(r2); + return combiTrans1; +} + +void AliITSUv1Layer::AddTranslationToCombiTrans(TGeoCombiTrans* ct, + Double_t dx, + Double_t dy, + Double_t dz) const{ +// +// Help method to add a translation to a TGeoCombiTrans matrix +// (from a similar method with same name and function +// in AliITSv11GeometrySDD class by L.Gaudichet) +// + + // Add a dx,dy,dz translation to the initial TGeoCombiTrans + const Double_t *vect = ct->GetTranslation(); + Double_t newVect[3] = {vect[0]+dx, vect[1]+dy, vect[2]+dz}; + ct->SetTranslation(newVect); +} diff --git a/its/AliITSUv1Layer.h b/its/AliITSUv1Layer.h new file mode 100644 index 0000000000000..2b01612673dcd --- /dev/null +++ b/its/AliITSUv1Layer.h @@ -0,0 +1,184 @@ +#ifndef ALIITSUV1LAYER_H +#define ALIITSUV1LAYER_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + + +//************************************************************************* +// This class Defines the Geometry for the ITS Upgrade using TGeo +// This is a work class used to study different configurations +// during the development of the new ITS structure. +// +// Mario Sitta +//************************************************************************* + +/* + $Id: AliITSUv1Layer.h + */ + +#include "AliITSv11Geometry.h" +#include "O2its.h" +#include +#include +#include + +class TGeoVolume; + +class AliITSUv1Layer : public AliITSv11Geometry { + public: + enum {kStave,kHalfStave,kModule,kChip,kNHLevels}; + + public: + AliITSUv1Layer(); + AliITSUv1Layer(Int_t debug); + AliITSUv1Layer(Int_t lay, Int_t debug); + AliITSUv1Layer(Int_t lay, Bool_t turbo, Int_t debug); + AliITSUv1Layer(const AliITSUv1Layer &source); + AliITSUv1Layer& operator=(const AliITSUv1Layer &source); + virtual ~AliITSUv1Layer(); + + Bool_t IsTurbo() const {return fIsTurbo;}; + + Double_t GetStaveThick() const {return fStaveThick;}; + Double_t GetStaveTilt() const {return fStaveTilt;}; + Double_t GetStaveWidth() const {return fStaveWidth;}; + Double_t GetSensorThick() const {return fSensorThick;}; + Double_t GetNStaves() const {return fNStaves;}; + Double_t GetNChips() const {return fNChips;}; + Double_t GetRadius() const {return fLayRadius;}; + Double_t GetPhi0() const {return fPhi0;}; + Double_t GetZLength() const {return fZLength;}; + Int_t GetChipType() const {return fChipTypeID;} + // + Int_t GetNStavesPerParent() const {return fHierarchy[kStave];} + Int_t GetNHalfStavesPerParent() const {return fHierarchy[kHalfStave];} + Int_t GetNModulesPerParent() const {return fHierarchy[kModule];} + Int_t GetNChipsPerParent() const {return fHierarchy[kChip];} + // + O2its::AliITSUModel_t GetStaveModel() const {return fStaveModel;} + // + void SetStaveThick(Double_t t) {fStaveThick = t;}; + void SetStaveTilt(Double_t t); + void SetStaveWidth(Double_t w); + void SetSensorThick(Double_t t) {fSensorThick = t;}; + void SetNStaves(Int_t n) {fHierarchy[kStave] = fNStaves = n;}; + void SetNUnits(Int_t u); + void SetRadius(Double_t r) {fLayRadius = r;}; + void SetPhi0(Double_t phi) {fPhi0 = phi;} + void SetZLength(Double_t z) {fZLength = z;}; + void SetChipType(Int_t tp) {fChipTypeID = tp;} + void SetBuildLevel(Int_t buildLevel){fBuildLevel=buildLevel;} + void SetStaveModel(O2its::AliITSUModel_t model) {fStaveModel=model;} + virtual void CreateLayer(TGeoVolume *moth); + + private: + void CreateLayerTurbo(TGeoVolume *moth); + + Double_t RadiusOfTurboContainer(); + + TGeoVolume* CreateStave(const TGeoManager *mgr=gGeoManager); + //TGeoVolume* CreateChip(Double_t x, Double_t z, const TGeoManager *mgr=gGeoManager); + TGeoVolume* CreateModuleInnerB(Double_t x,Double_t y, Double_t z, const TGeoManager *mgr=gGeoManager); + TGeoVolume* CreateChipInnerB(Double_t x,Double_t y, Double_t z, const TGeoManager *mgr=gGeoManager); + TGeoVolume* CreateModuleOuterB(const TGeoManager *mgr=gGeoManager); + + + TGeoVolume* CreateStaveInnerB(Double_t x, Double_t y, Double_t z, const TGeoManager *mgr=gGeoManager); + TGeoVolume* CreateStaveStructInnerB(Double_t x,Double_t z, const TGeoManager *mgr=gGeoManager); + TGeoVolume* CreateStaveModelInnerBDummy(Double_t x,Double_t z, const TGeoManager *mgr=gGeoManager) const; + TGeoVolume* CreateStaveModelInnerB0(Double_t x,Double_t z, const TGeoManager *mgr=gGeoManager); + TGeoVolume* CreateStaveModelInnerB1(Double_t x,Double_t z, const TGeoManager *mgr=gGeoManager); + TGeoVolume* CreateStaveModelInnerB21(Double_t x,Double_t z, const TGeoManager *mgr=gGeoManager); + TGeoVolume* CreateStaveModelInnerB22(Double_t x,Double_t z, const TGeoManager *mgr=gGeoManager); + TGeoVolume* CreateStaveModelInnerB3(Double_t x,Double_t z, const TGeoManager *mgr=gGeoManager); + + TGeoVolume* CreateStaveOuterB(const TGeoManager *mgr=gGeoManager); + TGeoVolume* CreateStaveModelOuterBDummy(const TGeoManager *mgr=gGeoManager) const; + TGeoVolume* CreateStaveModelOuterB0(const TGeoManager *mgr=gGeoManager); + TGeoVolume* CreateStaveModelOuterB1(const TGeoManager *mgr=gGeoManager); + TGeoVolume* CreateSpaceFrameOuterB(const TGeoManager *mgr=gGeoManager); + TGeoVolume* CreateSpaceFrameOuterBDummy(const TGeoManager *mgr=gGeoManager) const; + TGeoVolume* CreateSpaceFrameOuterB1(const TGeoManager *mgr=gGeoManager); + + TGeoArb8* CreateStaveSide(const char *name, + Double_t dz, Double_t angle, Double_t xSign, + Double_t L, Double_t H, Double_t l); + TGeoCombiTrans* CreateCombiTrans( const char *name, + Double_t dy, Double_t dz, Double_t dphi, + Bool_t planeSym=kFALSE); + void AddTranslationToCombiTrans( TGeoCombiTrans* ct, + Double_t dx=0, Double_t dy=0, + Double_t dz=0) const; + + + Int_t fLayerNumber; // Current layer number + Double_t fPhi0; // lab phi of 1st stave, in degrees!!! + Double_t fLayRadius; // Inner radius of this layer + Double_t fZLength; // Z length of this layer + Double_t fSensorThick; // Sensor thickness + Double_t fStaveThick; // Stave thickness + Double_t fStaveWidth; // Stave width (for turbo layers only) + Double_t fStaveTilt; // Stave tilt angle (for turbo layers only) in degrees + Int_t fNStaves; // Number of staves in this layer + Int_t fNModules; // Number of modules per container if defined (HalfStave, Stave, whatever is container) + Int_t fNChips; // N. chips per container (module, HalfStave, Stave, whatever is container) + Int_t fHierarchy[kNHLevels]; // array to query number of staves, hstaves, modules, chips per its parent volume + // + UInt_t fChipTypeID; // detector type id + Bool_t fIsTurbo; // True if this layer is a "turbo" layer + Int_t fBuildLevel; // Used for material studies + + O2its::AliITSUModel_t fStaveModel; // The stave model + + // Parameters for the Upgrade geometry + + // General Parameters + static const Int_t fgkNumberOfInnerLayers;// Number of IB Layers + + static const Double_t fgkDefaultSensorThick; // Default sensor thickness + static const Double_t fgkDefaultStaveThick; // Default stave thickness + + // Inner Barrel Parameters + static const Int_t fgkIBChipsPerRow; // IB chips per row in module + static const Int_t fgkIBNChipRows; // IB chip rows in module + + // Outer Barrel Parameters + static const Int_t fgkOBChipsPerRow; // OB chips per row in module + static const Int_t fgkOBNChipRows; // OB chip rows in module + + static const Double_t fgkOBHalfStaveWidth; // OB Half Stave Width + static const Double_t fgkOBModuleWidth; // OB Module Width + static const Double_t fgkOBModuleGap; // Gap between OB modules + static const Double_t fgkOBChipXGap; // Gap between OB chips on X + static const Double_t fgkOBChipZGap; // Gap between OB chips on Z + static const Double_t fgkOBFlexCableAlThick; // Thickness of FPC Aluminum + static const Double_t fgkOBFlexCableKapThick;// Thickness of FPC Kapton + static const Double_t fgkOBBusCableAlThick; // Thickness of Bus Aluminum + static const Double_t fgkOBBusCableKapThick; // Thickness of Bus Kapton + static const Double_t fgkOBCarbonPlateThick; // OB Carbon Plate Thickness + static const Double_t fgkOBColdPlateThick; // OB Cold Plate Thickness + static const Double_t fgkOBGlueThick; // OB Glue total Thickness + static const Double_t fgkOBModuleZLength; // OB Chip Length along Z + static const Double_t fgkOBHalfStaveYTrans; // OB half staves Y transl. + static const Double_t fgkOBHalfStaveXOverlap;// OB half staves X overlap + static const Double_t fgkOBGraphiteFoilThick;// OB graphite foil thickness + static const Double_t fgkOBCoolTubeInnerD; // OB cooling inner diameter + static const Double_t fgkOBCoolTubeThick; // OB cooling tube thickness + static const Double_t fgkOBCoolTubeXDist; // OB cooling tube separation + + static const Double_t fgkOBSpaceFrameWidth; // OB Space Frame Width + static const Double_t fgkOBSpaceFrameTotHigh;// OB Total Y Height + static const Double_t fgkOBSFrameBeamRadius; // OB Space Frame Beam Radius + static const Double_t fgkOBSpaceFrameLa; // Parameters defining... + static const Double_t fgkOBSpaceFrameHa; // ...the V side shape... + static const Double_t fgkOBSpaceFrameLb; // ...of the carbon... + static const Double_t fgkOBSpaceFrameHb; // ...OB Space Frame + static const Double_t fgkOBSpaceFrameL; // OB SF + static const Double_t fgkOBSFBotBeamAngle; // OB SF bottom beam angle + static const Double_t fgkOBSFrameBeamSidePhi;// OB SF side beam angle + + + ClassDef(AliITSUv1Layer,0) // ITS Upgrade v1 geometry +}; + +#endif diff --git a/its/AliITSsegmentation.cxx b/its/AliITSsegmentation.cxx new file mode 100644 index 0000000000000..c36638abec7ad --- /dev/null +++ b/its/AliITSsegmentation.cxx @@ -0,0 +1,59 @@ +//////////////////////////////////////////////// +// Segmentation class for set:ITS // +// All methods implemented in the derived // +// classes are set = 0 in the header file // +// so this class cannot be instantiated // +// methods implemented in a part of the // +// derived classes are implemented here as // +// TObject::MayNotUse // +//////////////////////////////////////////////// + +#include +#include "AliITSsegmentation.h" + +ClassImp(AliITSsegmentation) + +AliITSsegmentation::AliITSsegmentation(): +fDx(0), +fDz(0), +fDy(0), +fCorr(0){ + // Default constructor +} + +AliITSsegmentation::~AliITSsegmentation(){ + // destructor + if(fCorr)delete fCorr; +} + +void AliITSsegmentation::Copy(TObject &obj) const { + // copy this to obj + ((AliITSsegmentation& ) obj).fDz = fDz; + ((AliITSsegmentation& ) obj).fDx = fDx; + ((AliITSsegmentation& ) obj).fDy = fDy; + if(fCorr){ + ((AliITSsegmentation& ) obj).fCorr = new TF1(*fCorr); // make a proper copy + } + else { + ((AliITSsegmentation& ) obj).fCorr = 0; + } +} + +AliITSsegmentation& AliITSsegmentation::operator=( + const AliITSsegmentation &source){ +// Operator = + if(this != &source){ + source.Copy(*this); + } + return *this; +} + +AliITSsegmentation::AliITSsegmentation(const AliITSsegmentation &source): + TObject(source), +fDx(0), +fDz(0), +fDy(0), +fCorr(0){ + // copy constructor + source.Copy(*this); +} diff --git a/its/AliITSsegmentation.h b/its/AliITSsegmentation.h new file mode 100644 index 0000000000000..8c00eea156714 --- /dev/null +++ b/its/AliITSsegmentation.h @@ -0,0 +1,112 @@ +#ifndef ALIITSSEGMENTATION_H +#define ALIITSSEGMENTATION_H + +#include + +/* $Id$ */ + +//---------------------------------------------- +// - +// ITS segmentation virtual base class - +// - +//---------------------------------------------- +class TF1; +class AliITSsegmentation : +public TObject { + public: + AliITSsegmentation(); + AliITSsegmentation(const AliITSsegmentation& source); + virtual ~AliITSsegmentation(); + AliITSsegmentation& operator=(const AliITSsegmentation &source); + // Set Detector Segmentation Parameters + // + // Detector size + virtual void SetDetSize(Float_t p1,Float_t p2,Float_t p3) + {fDx=p1; fDz=p2; fDy=p3;} + // Cell size + virtual void SetPadSize(Float_t,Float_t) {MayNotUse("SetPadSize");} + // Maximum number of cells along the two coordinates + virtual void SetNPads(Int_t,Int_t) = 0; + // Returns the maximum number of cells (digits) posible + virtual Int_t GetNPads() const = 0; + // Set layer + virtual void SetLayer(Int_t) {MayNotUse("SetLayer");} + // Number of Chips + virtual Int_t GetNumberOfChips() const {MayNotUse("GetNumberOfChips"); return 0;} + virtual Int_t GetMaximumChipIndex() const {MayNotUse("GetNumberOfChips"); return 0;} + // Chip number from local coordinates + virtual Int_t GetChipFromLocal(Float_t, Float_t) const {MayNotUse("GetChipFromLocal"); return 0;} + virtual Int_t GetChipsInLocalWindow(Int_t* /*array*/, Float_t /*zmin*/, Float_t /*zmax*/, Float_t /*xmin*/, Float_t /*xmax*/) const {MayNotUse("GetChipsInLocalWindow"); return 0;} + // Chip number from channel number + virtual Int_t GetChipFromChannel(Int_t, Int_t) const {MayNotUse("GetChipFromChannel"); return 0;} + + // Transform from real to cell coordinates + virtual void GetPadIxz(Float_t,Float_t,Int_t &,Int_t &) const = 0; + // Transform from cell to real coordinates + virtual void GetPadCxz(Int_t,Int_t,Float_t &,Float_t &) const = 0; + // Local transformation of real local coordinates - + virtual void GetPadTxz(Float_t &,Float_t &) const = 0; + // Transformation from Geant cm detector center local coordinates + // to detector segmentation/cell coordiantes starting from (0,0). + virtual Bool_t LocalToDet(Float_t,Float_t,Int_t &,Int_t &) const = 0; + // Transformation from detector segmentation/cell coordiantes starting + // from (0,0) to Geant cm detector center local coordinates. + virtual void DetToLocal(Int_t,Int_t,Float_t &,Float_t &) const = 0; + // Initialisation + virtual void Init() = 0; + // + // Get member data + // + // Detector length + virtual Float_t Dx() const {return fDx;} + // Detector width + virtual Float_t Dz() const {return fDz;} + // Detector thickness + virtual Float_t Dy() const {return fDy;} + // Cell size in x + virtual Float_t Dpx(Int_t) const = 0; + // Cell size in z + virtual Float_t Dpz(Int_t) const = 0; + // Maximum number of Cells in x + virtual Int_t Npx() const = 0; + // Maximum number of Cells in z + virtual Int_t Npz() const = 0; + // Layer + virtual Int_t GetLayer() const {MayNotUse("GetLayer"); return 0;} + // Set hit position + // virtual void SetHit(Float_t, Float_t) {} + // angles + virtual void Angles(Float_t& /* p */, Float_t& /* n */) const + {MayNotUse("Angles");} + + // + // Get next neighbours + virtual void Neighbours(Int_t,Int_t,Int_t*,Int_t[10],Int_t[10]) const + {MayNotUse("Neighbours");} + + // Function for systematic corrections + // Set the correction function + virtual void SetCorrFunc(TF1* fc) {fCorr = fc;} + // Get the correction Function + virtual TF1* CorrFunc() {return fCorr;} + // Print Default parameters + virtual void PrintDefaultParameters() const = 0; + + protected: + + virtual void Copy(TObject &obj) const; + + Float_t fDx; //SPD: Full width of the detector (x axis)- microns + //SDD: Drift distance of the 1/2detector (x axis)-microns + //SSD: Full length of the detector (x axis)- microns + Float_t fDz; //SPD: Full length of the detector (z axis)- microns + //SDD: Full Length of the detector (z axis) - microns + //SSD: Full width of the detector (z axis)- microns + Float_t fDy; //SPD: Full thickness of the detector (y axis) -um + //SDD: Full thickness of the detector (y axis) - microns + //SSD: Full thickness of the detector (y axis) -um + TF1* fCorr; // correction function + + ClassDef(AliITSsegmentation,2) //Segmentation virtual base class +}; +#endif diff --git a/its/AliITSv11Geometry.cxx b/its/AliITSv11Geometry.cxx new file mode 100644 index 0000000000000..5f9db06bec8c4 --- /dev/null +++ b/its/AliITSv11Geometry.cxx @@ -0,0 +1,1549 @@ +/************************************************************************** + * 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$ +*/ + + +//////////////////////////////////////////////////////////////////////// +// This class is a base class for the ITS geometry version 11. It +// contains common/standard functions used in many places in defining +// the ITS geometry, version 11. Large posions of the ITS geometry, +// version 11, should be derived from this class so as to make maximum +// use of these common functions. This class also defines the proper +// conversion valuse such, to cm and degrees, such that the most usefull +// units, those used in the Engineering drawings, can be used. +//////////////////////////////////////////////////////////////////////// + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include // contaings TGeoTubeSeg +#include +#include +#include +#include +#include + +#include "AliITSv11Geometry.h" + +using std::endl; +using std::cout; +using std::cin; +ClassImp(AliITSv11Geometry) + +const Double_t AliITSv11Geometry::fgkmicron = 1.0E-4; +const Double_t AliITSv11Geometry::fgkmm = 0.10; +const Double_t AliITSv11Geometry::fgkcm = 1.00; +const Double_t AliITSv11Geometry::fgkDegree = 1.0; +const Double_t AliITSv11Geometry::fgkRadian = 180./3.14159265358979323846; +const Double_t AliITSv11Geometry::fgkgcm3 = 1.0; // assume default is g/cm^3 +const Double_t AliITSv11Geometry::fgkKgm3 = 1.0E+3;// assume Kg/m^3 +const Double_t AliITSv11Geometry::fgkKgdm3 = 1.0; // assume Kg/dm^3 +const Double_t AliITSv11Geometry::fgkCelsius = 1.0; // Assume default is C +const Double_t AliITSv11Geometry::fgkPascal = 1.0E-3; // Assume kPascal +const Double_t AliITSv11Geometry::fgkKPascal = 1.0; // Asume kPascal +const Double_t AliITSv11Geometry::fgkeV = 1.0E-9; // GeV default +const Double_t AliITSv11Geometry::fgkKeV = 1.0e-6; // GeV default +const Double_t AliITSv11Geometry::fgkMeV = 1.0e-3; // GeV default +const Double_t AliITSv11Geometry::fgkGeV = 1.0; // GeV default + +void AliITSv11Geometry::IntersectLines(Double_t m, Double_t x0, Double_t y0, + Double_t n, Double_t x1, Double_t y1, + Double_t &xi, Double_t &yi)const{ + // Given the two lines, one passing by (x0,y0) with slope m and + // the other passing by (x1,y1) with slope n, returns the coordinates + // of the intersecting point (xi,yi) + // Inputs: + // Double_t m The slope of the first line + // Double_t x0,y0 The x and y coord. of the first point + // Double_t n The slope of the second line + // Double_t x1,y1 The x and y coord. of the second point + // Outputs: + // The coordinates xi and yi of the intersection point + // Return: + // none. + // Created: 14 Dec 2009 Mario Sitta + + if (TMath::Abs(m-n) < 0.000001) { + LOG(ERROR) << "Lines are parallel: m = " << m << " n = " << n << FairLogger::endl; + return; + } + + xi = (y1 - n*x1 - y0 + m*x0)/(m - n); + yi = y0 + m*(xi - x0); + + return; +} + +Bool_t AliITSv11Geometry::IntersectCircle(Double_t m, Double_t x0, Double_t y0, + Double_t rr, Double_t xc, Double_t yc, + Double_t &xi1, Double_t &yi1, + Double_t &xi2, Double_t &yi2){ + // Given a lines passing by (x0,y0) with slope m and a circle with + // radius rr and center (xc,yc), returns the coordinates of the + // intersecting points (xi1,yi1) and (xi2,yi2) (xi1 > xi2) + // Inputs: + // Double_t m The slope of the line + // Double_t x0,y0 The x and y coord. of the point + // Double_t rr The radius of the circle + // Double_t xc,yc The x and y coord. of the center of circle + // Outputs: + // The coordinates xi and yi of the intersection points + // Return: + // kFALSE if the line does not intercept the circle, otherwise kTRUE + // Created: 18 Dec 2009 Mario Sitta + + Double_t p = m*x0 - y0; + Double_t q = m*m + 1; + + p = p-m*xc+yc; + + Double_t delta = m*m*p*p - q*(p*p - rr*rr); + + if (delta < 0) + return kFALSE; + else { + Double_t root = TMath::Sqrt(delta); + xi1 = (m*p + root)/q + xc; + xi2 = (m*p - root)/q + xc; + yi1 = m*(xi1 - x0) + y0; + yi2 = m*(xi2 - x0) + y0; + return kTRUE; + } +} + +Double_t AliITSv11Geometry::Yfrom2Points(Double_t x0,Double_t y0, + Double_t x1,Double_t y1, + Double_t x)const{ + // Given the two points (x0,y0) and (x1,y1) and the location x, returns + // the value y corresponding to that point x on the line defined by the + // two points. + // Inputs: + // Double_t x0 The first x value defining the line + // Double_t y0 The first y value defining the line + // Double_t x1 The second x value defining the line + // Double_t y1 The second y value defining the line + // Double_t x The x value for which the y value is wanted. + // Outputs: + // none. + // Return: + // The value y corresponding to the point x on the line defined by + // the two points (x0,y0) and (x1,y1). + + if(x0==x1 && y0==y1) { + printf("Error: AliITSv11Geometry::Yfrom2Ponts The two points are " + "the same (%e,%e) and (%e,%e)",x0,y0,x1,y1); + return 0.0; + } // end if + if(x0==x1){ + printf("Warning: AliITSv11Geometry::Yfrom2Points x0=%e == x1=%e. " + "line vertical ""returning mean y",x0,x1); + return 0.5*(y0+y1); + }// end if x0==x1 + Double_t m = (y0-y1)/(x0-x1); + return m*(x-x0)+y0; +} + +Double_t AliITSv11Geometry::Xfrom2Points(Double_t x0,Double_t y0, + Double_t x1,Double_t y1, + Double_t y)const{ + // Given the two points (x0,y0) and (x1,y1) and the location y, returns + // the value x corresponding to that point y on the line defined by the + // two points. + // Inputs: + // Double_t x0 The first x value defining the line + // Double_t y0 The first y value defining the line + // Double_t x1 The second x value defining the line + // Double_t y1 The second y value defining the line + // Double_t y The y value for which the x value is wanted. + // Outputs: + // none. + // Return: + // The value x corresponding to the point y on the line defined by + // the two points (x0,y0) and (x1,y1). + + if(x0==x1 && y0==y1) { + printf("Error: AliITSv11Geometry::Yfrom2Ponts The two points are " + "the same (%e,%e) and (%e,%e)",x0,y0,x1,y1); + return 0.0; + } // end if + if(y0==y1){ + printf("Warrning: AliITSv11Geometry::Yfrom2Points y0=%e == y1=%e. " + "line horizontal returning mean x",y0,y1); + return 0.5*(x0+x1); + }// end if y0==y1 + Double_t m = (x0-x1)/(y0-y1); + return m*(y-y0)+x0; +} + +Double_t AliITSv11Geometry::RmaxFrom2Points(const TGeoPcon *p,Int_t i1, + Int_t i2,Double_t z)const{ + // functions Require at parts of Volume A to be already defined. + // Retruns the value of Rmax corresponding to point z alone the line + // defined by the two points p.Rmax(i1),p-GetZ(i1) and p->GetRmax(i2), + // p->GetZ(i2). + // Inputs: + // TGeoPcon *p The Polycone where the two points come from + // Int_t i1 Point 1 + // Int_t i2 Point 2 + // Double_t z The value of z for which Rmax is to be found + // Outputs: + // none. + // Return: + // Double_t Rmax the value corresponding to z + Double_t d0,d1,d2,r; + + d0 = p->GetRmax(i1)-p->GetRmax(i2);// cout <<"L263: d0="<GetZ(i2);// cout <<"L264: d1="<GetZ(i1)-p->GetZ(i2);// cout <<"L265: d2="<GetRmax(i2) + d1*d0/d2;// cout <<"L266: r="<GetRmin(i1),p->GetZ(i1) and + // p->GetRmin(i2), p->GetZ(i2). + // Inputs: + // TGeoPcon *p The Polycone where the two points come from + // Int_t i1 Point 1 + // Int_t i2 Point 2 + // Double_t z The value of z for which Rmax is to be found + // Outputs: + // none. + // Return: + // Double_t Rmax the value corresponding to z + + return p->GetRmin(i2)+(p->GetRmin(i1)-p->GetRmin(i2))*(z-p->GetZ(i2))/ + (p->GetZ(i1)-p->GetZ(i2)); +} + +Double_t AliITSv11Geometry::RFrom2Points(const Double_t *p,const Double_t *az, + Int_t i1,Int_t i2,Double_t z)const{ + // Retruns the value of Rmin corresponding to point z alone the line + // defined by the two points p->GetRmin(i1),p->GetZ(i1) and + // p->GetRmin(i2), p->GetZ(i2). + // Inputs: + // Double_t az Array of z values + // Double_t r Array of r values + // Int_t i1 First Point in arrays + // Int_t i2 Second Point in arrays + // Double_t z Value z at which r is to be found + // Outputs: + // none. + // Return: + // The value r corresponding to z and the line defined by the two points + + return p[i2]+(p[i1]-p[i2])*(z-az[i2])/(az[i1]-az[i2]); +} + +Double_t AliITSv11Geometry::Zfrom2MinPoints(const TGeoPcon *p,Int_t i1, + Int_t i2,Double_t r)const{ + // Retruns the value of Z corresponding to point R alone the line + // defined by the two points p->GetRmin(i1),p->GetZ(i1) and + // p->GetRmin(i2),p->GetZ(i2) + // Inputs: + // TGeoPcon *p The Poly cone where the two points come from. + // Int_t i1 First Point in arrays + // Int_t i2 Second Point in arrays + // Double_t r Value r min at which z is to be found + // Outputs: + // none. + // Return: + // The value z corresponding to r min and the line defined by + // the two points + + return p->GetZ(i2)+(p->GetZ(i1)-p->GetZ(i2))*(r-p->GetRmin(i2))/ + (p->GetRmin(i1)-p->GetRmin(i2)); +} + +Double_t AliITSv11Geometry::Zfrom2MaxPoints(const TGeoPcon *p,Int_t i1, + Int_t i2,Double_t r)const{ + // Retruns the value of Z corresponding to point R alone the line + // defined by the two points p->GetRmax(i1),p->GetZ(i1) and + // p->GetRmax(i2),p->GetZ(i2) + // Inputs: + // TGeoPcon *p The Poly cone where the two points come from. + // Int_t i1 First Point in arrays + // Int_t i2 Second Point in arrays + // Double_t r Value r max at which z is to be found + // Outputs: + // none. + // Return: + // The value z corresponding to r max and the line defined by + // the two points + + return p->GetZ(i2)+(p->GetZ(i1)-p->GetZ(i2))*(r-p->GetRmax(i2))/ + (p->GetRmax(i1)-p->GetRmax(i2)); +} + +Double_t AliITSv11Geometry::Zfrom2Points(const Double_t *z,const Double_t *ar, + Int_t i1,Int_t i2,Double_t r)const{ + // Retruns the value of z corresponding to point R alone the line + // defined by the two points p->GetRmax(i1),p->GetZ(i1) and + // p->GetRmax(i2),p->GetZ(i2) + // Inputs: + // Double_t z Array of z values + // Double_t ar Array of r values + // Int_t i1 First Point in arrays + // Int_t i2 Second Point in arrays + // Double_t r Value r at which z is to be found + // Outputs: + // none. + // Return: + // The value z corresponding to r and the line defined by the two points + + return z[i2]+(z[i1]-z[i2])*(r-ar[i2])/(ar[i1]-ar[i2]); +} + +Double_t AliITSv11Geometry::RmaxFromZpCone(const TGeoPcon *p,int ip, + Double_t tc,Double_t z, + Double_t th)const{ + // General Outer Cone surface equation Rmax. + // Intputs: + // TGeoPcon *p The poly cone where the initial point comes from + // Int_t ip The index in p to get the point location + // Double_t tc The angle of that part of the cone is at + // Double_t z The value of z to compute Rmax from + // Double_t th The perpendicular distance the parralell line is + // from the point ip. + // Outputs: + // none. + // Return: + // The value Rmax correstponding to the line at angle th, offeset by + // th, and the point p->GetZ/Rmin[ip] at the location z. + Double_t tantc = TMath::Tan(tc*TMath::DegToRad()); + Double_t costc = TMath::Cos(tc*TMath::DegToRad()); + + return -tantc*(z-p->GetZ(ip))+p->GetRmax(ip)+th/costc; +} + +Double_t AliITSv11Geometry::RFromZpCone(const Double_t *ar, + const Double_t *az,int ip, + Double_t tc,Double_t z, + Double_t th)const{ + // General Cone surface equation R(z). + // Intputs: + // Double_t ar The array of R values + // Double_t az The array of Z values + // Int_t ip The index in p to get the point location + // Double_t tc The angle of that part of the cone is at + // Double_t z The value of z to compute R from + // Double_t th The perpendicular distance the parralell line is + // from the point ip. + // Outputs: + // none. + // Return: + // The value R correstponding to the line at angle th, offeset by + // th, and the point p->GetZ/Rmax[ip] at the locatin z. + Double_t tantc = TMath::Tan(tc*TMath::DegToRad()); + Double_t costc = TMath::Cos(tc*TMath::DegToRad()); + + return -tantc*(z-az[ip])+ar[ip]+th/costc; +} + +Double_t AliITSv11Geometry::RminFromZpCone(const TGeoPcon *p,Int_t ip, + Double_t tc,Double_t z, + Double_t th)const{ + // General Inner Cone surface equation Rmin. + // Intputs: + // TGeoPcon *p The poly cone where the initial point comes from + // Int_t ip The index in p to get the point location + // Double_t tc The angle of that part of the cone is at + // Double_t z The value of z to compute Rmin from + // Double_t th The perpendicular distance the parralell line is + // from the point ip. + // Outputs: + // none. + // Return: + // The value Rmin correstponding to the line at angle th, offeset by + // th, and the point p->GetZ/Rmin[ip] at the location z. + Double_t tantc = TMath::Tan(tc*TMath::DegToRad()); + Double_t costc = TMath::Cos(tc*TMath::DegToRad()); + + return -tantc*(z-p->GetZ(ip))+p->GetRmin(ip)+th/costc; +} + +Double_t AliITSv11Geometry::ZFromRmaxpCone(const TGeoPcon *p,int ip, + Double_t tc,Double_t r, + Double_t th)const{ + // General Outer cone Surface equation for z. + // Intputs: + // TGeoPcon *p The poly cone where the initial point comes from + // Int_t ip The index in p to get the point location + // Double_t tc The angle of that part of the cone is at + // Double_t r The value of Rmax to compute z from + // Double_t th The perpendicular distance the parralell line is + // from the point ip. + // Outputs: + // none. + // Return: + // The value Z correstponding to the line at angle th, offeset by + // th, and the point p->GetZ/Rmax[ip] at the location r. + Double_t tantc = TMath::Tan(tc*TMath::DegToRad()); + Double_t costc = TMath::Cos(tc*TMath::DegToRad()); + + return p->GetZ(ip)+(p->GetRmax(ip)+th/costc-r)/tantc; +} + +Double_t AliITSv11Geometry::ZFromRmaxpCone(const Double_t *ar, + const Double_t *az,int ip, + Double_t tc,Double_t r, + Double_t th)const{ + // General Outer cone Surface equation for z. + // Intputs: + // Double_t ar The array of R values + // Double_t az The array of Z values + // Int_t ip The index in p to get the point location + // Double_t tc The angle of that part of the cone is at + // Double_t r The value of Rmax to compute z from + // Double_t th The perpendicular distance the parralell line is + // from the point ip. + // Outputs: + // none. + // Return: + // The value Z correstponding to the line at angle th, offeset by + // th, and the point p->GetZ/Rmax[ip] at the locatin r. + Double_t tantc = TMath::Tan(tc*TMath::DegToRad()); + Double_t costc = TMath::Cos(tc*TMath::DegToRad()); + + return az[ip]+(ar[ip]+th/costc-r)/tantc; +} + +Double_t AliITSv11Geometry::ZFromRminpCone(const TGeoPcon *p,int ip, + Double_t tc,Double_t r, + Double_t th)const{ + // General Inner cone Surface equation for z. + // Intputs: + // TGeoPcon *p The poly cone where the initial point comes from + // Int_t ip The index in p to get the point location + // Double_t tc The angle of that part of the cone is at + // Double_t r The value of Rmin to compute z from + // Double_t th The perpendicular distance the parralell line is + // from the point ip. + // Outputs: + // none. + // Return: + // The value Z correstponding to the line at angle th, offeset by + // th, and the point p->GetZ/Rmin[ip] at the location r. + Double_t tantc = TMath::Tan(tc*TMath::DegToRad()); + Double_t costc = TMath::Cos(tc*TMath::DegToRad()); + + return p->GetZ(ip)+(p->GetRmin(ip)+th/costc-r)/tantc; +} + +void AliITSv11Geometry::RadiusOfCurvature(Double_t rc,Double_t theta0, + Double_t z0,Double_t r0, + Double_t theta1,Double_t &z1, + Double_t &r1)const{ + // Given a initial point z0,r0, the initial angle theta0, and the radius + // of curvature, returns the point z1, r1 at the angle theta1. Theta + // measured from the r axis in the clock wise direction [degrees]. + // Inputs: + // Double_t rc The radius of curvature + // Double_t theta0 The starting angle (degrees) + // Double_t z0 The value of z at theta0 + // Double_t r0 The value of r at theta0 + // Double_t theta1 The ending angle (degrees) + // Outputs: + // Double_t &z1 The value of z at theta1 + // Double_t &r1 The value of r at theta1 + // Return: + // none. + + z1 = rc*(TMath::Sin(theta1*TMath::DegToRad())-TMath::Sin(theta0*TMath::DegToRad()))+z0; + r1 = rc*(TMath::Cos(theta1*TMath::DegToRad())-TMath::Cos(theta0*TMath::DegToRad()))+r0; + return; +} + +void AliITSv11Geometry::InsidePoint(const TGeoPcon *p,Int_t i1,Int_t i2, + Int_t i3,Double_t c,TGeoPcon *q,Int_t j1, + Bool_t max)const{ + // Given two lines defined by the points i1, i2,i3 in the TGeoPcon + // class p that intersect at point p->GetZ(i2) return the point z,r + // that is Cthick away in the TGeoPcon class q. If points i1=i2 + // and max == kTRUE, then p->GetRmin(i1) and p->GetRmax(i2) are used. + // if points i2=i3 and max=kTRUE then points p->GetRmax(i2) and + // p->GetRmin(i3) are used. If i2=i3 and max=kFALSE, then p->GetRmin(i2) + // and p->GetRmax(i3) are used. + // Inputs: + // TGeoPcon *p Class where points i1, i2, and i3 are taken from + // Int_t i1 First point in class p + // Int_t i2 Second point in class p + // Int_t i3 Third point in class p + // Double_t c Distance inside the outer surface/inner suface + // that the point j1 is to be computed for. + // TGeoPcon *q Pointer to class for results to be put into. + // Int_t j1 Point in class q where data is to be stored. + // Bool_t max if kTRUE, then a Rmax value is computed, + // else a Rmin valule is computed. + // Output: + // TGeoPcon *q Pointer to class for results to be put into. + // Return: + // none. + Double_t x0,y0,x1,y1,x2,y2,x,y; + + if(max){ + c = -c; //cout <<"L394 c="<GetRmax(i1); + if(i1==i2) y0 = p->GetRmin(i1); //cout <<"L396 y0="<GetRmax(i2); //cout <<"L397 y1="<GetRmax(i3); //cout <<"L398 y2="<GetRmin(i3); //cout <<"L399 y2="<GetRmin(i1); //cout <<"L401 y0="<GetRmin(i2); //cout <<"L402 y1="<GetRmin(i3); + if(i2==i3) y2 = p->GetRmax(i3); //cout <<"L404 y2="<GetZ(i1); //cout <<"L406 x0="<GetZ(i2); //cout <<"L407 x1="<GetZ(i3); //cout <<"L408 x2="<Z(j1) = x; + if(max) q->Rmax(j1) = y; + else q->Rmin(j1) = y; + return; +} + +void AliITSv11Geometry::InsidePoint(Double_t x0,Double_t y0, + Double_t x1,Double_t y1, + Double_t x2,Double_t y2,Double_t c, + Double_t &x,Double_t &y)const{ + // Given two intersecting lines defined by the points (x0,y0), (x1,y1) and + // (x1,y1), (x2,y2) {intersecting at (x1,y1)} the point (x,y) a distance + // c away is returned such that two lines a distance c away from the + // lines defined above intersect at (x,y). + // Inputs: + // Double_t x0 X point on the first intersecting sets of lines + // Double_t y0 Y point on the first intersecting sets of lines + // Double_t x1 X point on the first/second intersecting sets of lines + // Double_t y1 Y point on the first/second intersecting sets of lines + // Double_t x2 X point on the second intersecting sets of lines + // Double_t y2 Y point on the second intersecting sets of lines + // Double_t c Distance the two sets of lines are from each other + // Output: + // Double_t x X point for the intersecting sets of parellel lines + // Double_t y Y point for the intersecting sets of parellel lines + // Return: + // none. + Double_t dx01,dx12,dy01,dy12,r01,r12,m; + + //printf("InsidePoint: x0=% #12.7g y0=% #12.7g x1=% #12.7g y1=% #12.7g " + // "x2=% #12.7g y2=% #12.7g c=% #12.7g ",x0,y0,x1,y2,x2,y2,c); + dx01 = x0-x1; //cout <<"L410 dx01="<GetName()); + a->InspectShape(); + return; +} + +void AliITSv11Geometry:: PrintPcon(const TGeoPcon *a)const{ + // Prints out the content of the TGeoPcon. Usefull for debugging. + // Inputs: + // TGeoPcon *a + // Outputs: + // none. + // Return: + // none. + + if(!GetDebug()) return; + cout << a->GetName() << ": N=" << a->GetNz() << " Phi1=" << a->GetPhi1() + << ", Dphi=" << a->GetDphi() << endl; + cout << "i\t Z \t Rmin \t Rmax" << endl; + for(Int_t iii=0;iiiGetNz();iii++){ + cout << iii << "\t" << a->GetZ(iii) << "\t" << a->GetRmin(iii) + << "\t" << a->GetRmax(iii) << endl; + } // end for iii + return; +} + +void AliITSv11Geometry::PrintTube(const TGeoTube *a)const{ + // Prints out the content of the TGeoTube. Usefull for debugging. + // Inputs: + // TGeoTube *a + // Outputs: + // none. + // Return: + // none. + + if(!GetDebug()) return; + cout << a->GetName() <<": Rmin="<GetRmin() + <<" Rmax=" <GetRmax()<<" Dz="<GetDz()<GetName() <<": Phi1="<GetPhi1()<< + " Phi2="<GetPhi2()<<" Rmin="<GetRmin() + <<" Rmax=" <GetRmax()<<" Dz="<GetDz()<GetName() <<": Phi1="<GetPhi1()<< + " Phi2="<GetPhi2()<<" Rmin1="<GetRmin1() + <<" Rmax1=" <GetRmax1()<<" Rmin2="<GetRmin2() + <<" Rmax2=" <GetRmax2()<<" Dz="<GetDz()<GetName() <<": Dx="<GetDX()<< + " Dy="<GetDY()<<" Dz="<GetDZ() <AddElement(itsN,w);// Nitorgen, atomic + w = 23.29E-2 + // O2 + 5.90E-4 * 2.*15.994/(12.0107+2.*15.994);// CO2. + itsAir->AddElement(itsO,w);// Oxygen, atomic + w = 1.28E-2; + itsAir->AddElement(itsAr,w);// Argon, atomic + w = 5.90E-4*12.0107/(12.0107+2.*15.994)+ // CO2 + 2.0E-5 *12.0107/(12.0107+4.* 1.00794); // CH4 + itsAir->AddElement(itsC,w);// Carbon, atomic + w = 1.818E-5; + itsAir->AddElement(itsNe,w);// Ne, atomic + w = 3.5E-8; + itsAir->AddElement(itsHe,w);// Helium, atomic + w = 7.0E-7; + itsAir->AddElement(itsKr,w);// Krypton, atomic + w = 3.0E-6; + itsAir->AddElement(itsH,w);// Hydrogen, atomic + w = 4.0E-7; + itsAir->AddElement(itsXe,w);// Xenon, atomic + itsAir->SetDensity(351.0*fgkKgm3); // + itsAir->SetPressure(101325*fgkPascal); + itsAir->SetTemperature(15.0*fgkCelsius); + itsAir->SetState(TGeoMaterial::kMatStateGas); + // + // Silicone + TGeoMaterial *itsSiDet = new TGeoMaterial("ITS_Si",itsSi,2.33*fgkgcm3); + itsSiDet->SetTemperature(15.0*fgkCelsius); + itsSiDet->SetState(TGeoMaterial::kMatStateSolid); + // + // Epoxy C18 H19 O3 + TGeoMixture *itsEpoxy = new TGeoMixture("ITS_Epoxy",3); + itsEpoxy->AddElement(itsC,18); + itsEpoxy->AddElement(itsH,19); + itsEpoxy->AddElement(itsO,3); + itsEpoxy->SetDensity(1.8*fgkgcm3); + itsEpoxy->SetTemperature(15.0*fgkCelsius); + itsEpoxy->SetState(TGeoMaterial::kMatStateSolid); + // + // Carbon Fiber, M55J, 60% fiber by volume. Fiber density + // 1.91 g/cm^3. See ToryaCA M55J data sheet. + //Begin_Html + /* + Data Sheet + + */ + //End_Html + TGeoMixture *itsCarbonFiber = new TGeoMixture("ITS_CarbonFiber-M55J",4); + // Assume that the epoxy fill in the space between the fibers and so + // no change in the total volume. To compute w, assume 1cm^3 total + // volume. + w = 1.91/(1.91+(1.-.60)*itsEpoxy->GetDensity()); + itsCarbonFiber->AddElement(itsC,w); + w = (1.-.60)*itsEpoxy->GetDensity()/(1.91+(1.-.06)*itsEpoxy->GetDensity()); + for(i=0;iGetNelements();i++) + itsCarbonFiber->AddElement(itsEpoxy->GetElement(i), + itsEpoxy->GetWmixt()[i]*w); + itsCarbonFiber->SetDensity((1.91+(1.-.60)*itsEpoxy->GetDensity())*fgkgcm3); + itsCarbonFiber->SetTemperature(22.0*fgkCelsius); + itsCarbonFiber->SetState(TGeoMaterial::kMatStateSolid); + // + // + // + // Rohacell 51A millable foam product. + // C9 H13 N1 O2 52Kg/m^3 + // Elemental composition, Private comunications with + // Bjorn S. Nilsen + //Begin_Html + /* + + Rohacell-A see Properties + + */ + //End_Html + TGeoMixture *itsFoam = new TGeoMixture("ITS_Foam",4); + itsFoam->AddElement(itsC,9); + itsFoam->AddElement(itsH,13); + itsFoam->AddElement(itsN,1); + itsFoam->AddElement(itsO,2); + itsFoam->SetTitle("Rohacell 51 A"); + itsFoam->SetDensity(52.*fgkKgm3); + itsFoam->SetTemperature(22.0*fgkCelsius); + itsFoam->SetState(TGeoMaterial::kMatStateSolid); + // + // Kapton % by weight, H 2.6362, C69.1133, N 7.3270, O 20.0235 + // Density 1.42 g/cm^3 + //Begin_Html + /* + + Kapton. also see + + + */ + //End_Html + TGeoMixture *itsKapton = new TGeoMixture("ITS_Kapton",4); + itsKapton->AddElement(itsH,0.026362); + itsKapton->AddElement(itsC,0.691133); + itsKapton->AddElement(itsN,0.073270); + itsKapton->AddElement(itsO,0.200235); + itsKapton->SetTitle("Kapton ribon and cable base"); + itsKapton->SetDensity(1.42*fgkgcm3); + itsKapton->SetTemperature(22.0*fgkCelsius); + itsKapton->SetState(TGeoMaterial::kMatStateSolid); + // + // UPILEX-S C16 H6 O4 N2 polymer (a Kapton like material) + // Density 1.47 g/cm^3 + //Begin_Html + /* + + UPILEX-S. also see + + + */ + //End_Html + TGeoMixture *itsUpilex = new TGeoMixture("ITS_Upilex",4); + itsUpilex->AddElement(itsC,16); + itsUpilex->AddElement(itsH,6); + itsUpilex->AddElement(itsN,2); + itsUpilex->AddElement(itsO,4); + itsUpilex->SetTitle("Upilex ribon, cable, and pcb base"); + itsUpilex->SetDensity(1.47*fgkgcm3); + itsUpilex->SetTemperature(22.0*fgkCelsius); + itsUpilex->SetState(TGeoMaterial::kMatStateSolid); + // + // Aluminum 6061 (Al used by US groups) + // % by weight, Cr 0.04-0.35 range [0.0375 nominal value used] + // Cu 0.15-0.4 [0.275], Fe Max 0.7 [0.35], Mg 0.8-1.2 [1.0], + // Mn Max 0.15 [0.075] Si 0.4-0.8 [0.6], Ti Max 0.15 [0.075], + // Zn Max 0.25 [0.125], Rest Al [97.4625]. Density 2.7 g/cm^3 + //Begin_Html + /* + + Aluminum 6061 specifications + + */ + //End_Html + TGeoMixture *itsAl6061 = new TGeoMixture("ITS_Al6061",9); + itsAl6061->AddElement(itsCr,0.000375); + itsAl6061->AddElement(itsCu,0.00275); + itsAl6061->AddElement(itsFe,0.0035); + itsAl6061->AddElement(itsMg,0.01); + itsAl6061->AddElement(itsMn,0.00075); + itsAl6061->AddElement(itsSi,0.006); + itsAl6061->AddElement(itsTi,0.00075); + itsAl6061->AddElement(itsZn,0.00125); + itsAl6061->AddElement(itsAl,0.974625); + itsAl6061->SetTitle("Aluminum Alloy 6061"); + itsAl6061->SetDensity(2.7*fgkgcm3); + itsAl6061->SetTemperature(22.0*fgkCelsius); + itsAl6061->SetState(TGeoMaterial::kMatStateSolid); + // + // Aluminum 7075 (Al used by Italian groups) + // % by weight, Cr 0.18-0.28 range [0.23 nominal value used] + // Cu 1.2-2.0 [1.6], Fe Max 0.5 [0.25], Mg 2.1-2.9 [2.5], + // Mn Max 0.3 [0.125] Si Max 0.4 [0.2], Ti Max 0.2 [0.1], + // Zn 5.1-6.1 [5.6], Rest Al [89.395]. Density 2.81 g/cm^3 + //Begin_Html + /* + + Aluminum 7075 specifications + + */ + //End_Html + TGeoMixture *itsAl7075 = new TGeoMixture("ITS_Al7075",9); + itsAl7075->AddElement(itsCr,0.0023); + itsAl7075->AddElement(itsCu,0.016); + itsAl7075->AddElement(itsFe,0.0025); + itsAl7075->AddElement(itsMg,0.025); + itsAl7075->AddElement(itsMn,0.00125); + itsAl7075->AddElement(itsSi,0.002); + itsAl7075->AddElement(itsTi,0.001); + itsAl7075->AddElement(itsZn,0.056); + itsAl7075->AddElement(itsAl,0.89395); + itsAl7075->SetTitle("Aluminum Alloy 7075"); + itsAl7075->SetDensity(2.81*fgkgcm3); + itsAl7075->SetTemperature(22.0*fgkCelsius); + itsAl7075->SetState(TGeoMaterial::kMatStateSolid); + // + // "Ruby" spheres, Al2 O3 + // "Ruby" Sphere posts, Ryton R-4 04 + //Begin_Html + /* + + Ruby Sphere Posts + + */ + //End_Html + TGeoMixture *itsRuby = new TGeoMixture("ITS_RubySphere",2); + itsRuby->AddElement(itsAl,2); + itsRuby->AddElement(itsO,3); + itsRuby->SetTitle("Ruby reference sphere"); + itsRuby->SetDensity(2.81*fgkgcm3); + itsRuby->SetTemperature(22.0*fgkCelsius); + itsRuby->SetState(TGeoMaterial::kMatStateSolid); + // + // + // Inox, AISI 304L, compoistion % by weight (assumed) + // C Max 0.03 [0.015], Mn Max 2.00 [1.00], Si Max 1.00 [0.50] + // P Max 0.045 [0.0225], S Max 0.03 [0.015], Ni 8.0-10.5 [9.25] + // Cr 18-20 [19.], Mo 2.-2.5 [2.25], rest Fe: density 7.93 Kg/dm^3 + //Begin_Html + /* + + Stainless steal (INOX) AISI 304L composition + + */ + //End_Html + TGeoMixture *itsInox304L = new TGeoMixture("ITS_Inox304L",9); + itsInox304L->AddElement(itsC,0.00015); + itsInox304L->AddElement(itsMn,0.010); + itsInox304L->AddElement(itsSi,0.005); + itsInox304L->AddElement(itsP,0.000225); + itsInox304L->AddElement(itsS,0.00015); + itsInox304L->AddElement(itsNi,0.0925); + itsInox304L->AddElement(itsCr,0.1900); + itsInox304L->AddElement(itsMo,0.0225); + itsInox304L->AddElement(itsFe,0.679475); // Rest Fe + itsInox304L->SetTitle("ITS Stainless Steal (Inox) type AISI 304L"); + itsInox304L->SetDensity(7.93*fgkKgdm3); + itsInox304L->SetTemperature(22.0*fgkCelsius); + itsInox304L->SetState(TGeoMaterial::kMatStateSolid); + // + // Inox, AISI 316L, composition % by weight (assumed) + // C Max 0.03 [0.015], Mn Max 2.00 [1.00], Si Max 1.00 [0.50] + // P Max 0.045 [0.0225], S Max 0.03 [0.015], Ni 10.0-14. [12.] + // Cr 16-18 [17.], Mo 2-3 [2.5]: density 7.97 Kg/dm^3 + //Begin_Html + /* + + Stainless steal (INOX) AISI 316L composition + + */ + //End_Html + TGeoMixture *itsInox316L = new TGeoMixture("ITS_Inox316L",9); + itsInox316L->AddElement(itsC,0.00015); + itsInox316L->AddElement(itsMn,0.010); + itsInox316L->AddElement(itsSi,0.005); + itsInox316L->AddElement(itsP,0.000225); + itsInox316L->AddElement(itsS,0.00015); + itsInox316L->AddElement(itsNi,0.12); + itsInox316L->AddElement(itsCr,0.17); + itsInox316L->AddElement(itsMo,0.025); + itsInox316L->AddElement(itsFe,0.66945); // Rest Fe + itsInox316L->SetTitle("ITS Stainless Steal (Inox) type AISI 316L"); + itsInox316L->SetDensity(7.97*fgkKgdm3); + itsInox316L->SetTemperature(22.0*fgkCelsius); + itsInox316L->SetState(TGeoMaterial::kMatStateSolid); + // + // Inox, Phynox or Elgiloy AMS 5833, composition % by weight + // C Max 0.15 [0.15], Mn Max 2.00 [2.00], Be max 0.0001 [none] + // Ni 18. [18.], Cr 21.5 [21.5], Mo 7.5 [7.5], Co 42 [42.]: + // density 8.3 Kg/dm^3 + //Begin_Html + /* + + Compostion of Phynox or Elgiloy AMS 5833, also see + + + under corss reference number [0024]. + + */ + //End_Html + TGeoMixture *itsPhynox = new TGeoMixture("ITS_Phynox",7); + itsPhynox->AddElement(itsC,0.0015); + itsPhynox->AddElement(itsMn,0.020); + itsPhynox->AddElement(itsNi,0.18); + itsPhynox->AddElement(itsCr,0.215); + itsPhynox->AddElement(itsMo,0.075); + itsPhynox->AddElement(itsCo,0.42); + itsPhynox->AddElement(itsFe,0.885); + itsPhynox->SetTitle("ITS Cooling tube alloy"); + itsPhynox->SetDensity(8.3*fgkgcm3); + itsPhynox->SetTemperature(22.0*fgkCelsius); + itsPhynox->SetState(TGeoMaterial::kMatStateSolid); + // + // G10FR4 + // + // Demineralized Water H2O SDD & SSD Cooling liquid + TGeoMixture *itsWater = new TGeoMixture("ITS_Water",2); + itsWater->AddElement(itsH,2); + itsWater->AddElement(itsO,1); + itsWater->SetTitle("ITS Cooling Water"); + itsWater->SetDensity(1.0*fgkgcm3); + itsWater->SetTemperature(22.0*fgkCelsius); + itsWater->SetState(TGeoMaterial::kMatStateLiquid); + // + // Freon SPD Cooling liquid PerFluorobuthane C4F10 + //Begin_Html + /* + + SPD 2 phase cooling using PerFluorobuthane + + */ + //End_Html + TGeoMixture *itsFreon = new TGeoMixture("ITS_SPD_Freon",2); + itsFreon->AddElement(itsC,4); + itsFreon->AddElement(itsF,10); + itsFreon->SetTitle("ITS SPD 2 phase Cooling freon"); + itsFreon->SetDensity(1.52*fgkgcm3); + itsFreon->SetTemperature(22.0*fgkCelsius); + itsFreon->SetState(TGeoMaterial::kMatStateLiquid); + // + // Int_t ifield = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ(); + // Float_t fieldm = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max(); + + // Float_t tmaxfd = 0.1;// 1.0;// Degree + // Float_t stemax = 1.0;// cm + // Float_t deemax = 0.1;// 30.0;// Fraction of particle's energy 0GetNz(); + if(n<=0) return; + m = 2*n+1; + z = new Double_t[m]; + r = new Double_t[m]; + + for(i=0;iGetZ(i); + r[i] = p->GetRmax(i); + z[i+n] = p->GetZ(n-1-i); + r[i+n] = p->GetRmin(n-1-i); + } // end for i + z[n-1] = z[0]; + r[n-1] = r[0]; + + line = new TPolyLine(n,z,r); + pts = new TPolyMarker(n,z,r); + + line->SetFillColor(fillc); + line->SetFillStyle(fills); + line->SetLineColor(linec); + line->SetLineStyle(lines); + line->SetLineWidth(linew); + pts->SetMarkerColor(markc); + pts->SetMarkerStyle(marks); + pts->SetMarkerSize(marksize); + + line->Draw("f"); + line->Draw(); + pts->Draw(); + + delete[] z; + delete[] r; + + cout<<"Hit Return to continue"<> n; + delete line; + delete pts; + return; +} + +Bool_t AliITSv11Geometry::AngleOfIntersectionWithLine(Double_t x0,Double_t y0, + Double_t x1,Double_t y1, + Double_t xc,Double_t yc, + Double_t rc,Double_t &t0, + Double_t &t1)const{ + // Computes the angles, t0 and t1 corresponding to the intersection of + // the line, defined by {x0,y0} {x1,y1}, and the circle, defined by + // its center {xc,yc} and radius r. If the line does not intersect the + // line, function returns kFALSE, otherwise it returns kTRUE. If the + // line is tangent to the circle, the angles t0 and t1 will be the same. + // Inputs: + // Double_t x0 X of first point defining the line + // Double_t y0 Y of first point defining the line + // Double_t x1 X of Second point defining the line + // Double_t y1 Y of Second point defining the line + // Double_t xc X of Circle center point defining the line + // Double_t yc Y of Circle center point defining the line + // Double_t r radius of circle + // Outputs: + // Double_t &t0 First angle where line intersects circle + // Double_t &t1 Second angle where line intersects circle + // Return: + // kTRUE, line intersects circle, kFALSE line does not intersect circle + // or the line is not properly defined point {x0,y0} and {x1,y1} + // are the same point. + Double_t dx,dy,cx,cy,s2,t[4]; + Double_t a0,b0,c0,a1,b1,c1,sinthp,sinthm,costhp,costhm; + Int_t i,j; + + t0 = 400.0; + t1 = 400.0; + dx = x1-x0; + dy = y1-y0; + cx = xc-x0; + cy = yc-y0; + s2 = dx*dx+dy*dy; + if(s2==0.0) return kFALSE; + + a0 = rc*rc*s2; + if(a0==0.0) return kFALSE; + b0 = 2.0*rc*dx*(dx*cy-cx*dy); + c0 = dx*dx*cy*cy-2.0*dy*dx*cy*cx+cx*cx*dy*dy-rc*rc*dy*dy; + c0 = 0.25*b0*b0/(a0*a0)-c0/a0; + if(c0<0.0) return kFALSE; + sinthp = -0.5*b0/a0+TMath::Sqrt(c0); + sinthm = -0.5*b0/a0-TMath::Sqrt(c0); + + a1 = rc*rc*s2; + if(a1==0.0) return kFALSE; + b1 = 2.0*rc*dy*(dy*cx-dx*cy); + c1 = dy*dy*cx*cx-2.0*dy*dx*cy*cx+dx*dx*cy*cy-rc*rc*dx*dx; + c1 = 0.25*b1*b1/(a1*a1)-c1/a1; + if(c1<0.0) return kFALSE; + costhp = -0.5*b1/a1+TMath::Sqrt(c1); + costhm = -0.5*b1/a1-TMath::Sqrt(c1); + + t[0] = t[1] = t[2] = t[3] = 400.; + a0 = TMath::ATan2(sinthp,costhp); if(a0<0.0) a0 += 2.0*TMath::Pi(); + a1 = TMath::ATan2(sinthp,costhm); if(a1<0.0) a1 += 2.0*TMath::Pi(); + b0 = TMath::ATan2(sinthm,costhp); if(b0<0.0) b0 += 2.0*TMath::Pi(); + b1 = TMath::ATan2(sinthm,costhm); if(b1<0.0) b1 += 2.0*TMath::Pi(); + x1 = xc+rc*TMath::Cos(a0); + y1 = yc+rc*TMath::Sin(a0); + s2 = dx*(y1-y0)-dy*(x1-x0); + if(s2*s2t[j]) {t0 = t[i];t[i] = t[j];t[j] = t0;} + } // end for i,j + t0 = t[0]; + t1 = t[1]; + // + return kTRUE; +} + +Double_t AliITSv11Geometry::AngleForRoundedCorners0(Double_t dx,Double_t dy, + Double_t sdr)const{ + // Basic function used to determine the ending angle and starting angles + // for rounded corners given the relative distance between the centers + // of the circles and the difference/sum of their radii. Case 0. + // Inputs: + // Double_t dx difference in x locations of the circle centers + // Double_t dy difference in y locations of the circle centers + // Double_t sdr difference or sum of the circle radii + // Outputs: + // none. + // Return: + // the angle in Degrees + Double_t a,b; + + b = dy*dy+dx*dx-sdr*sdr; + if(b<0.0) Error("AngleForRoundedCorners0", + "dx^2(%e)+dy^2(%e)-sdr^2(%e)=b=%e<0",dx,dy,sdr,b); + b = TMath::Sqrt(b); + a = -sdr*dy+dx*b; + b = -sdr*dx-dy*b; + return TMath::ATan2(a,b)*TMath::RadToDeg(); + +} + +Double_t AliITSv11Geometry::AngleForRoundedCorners1(Double_t dx,Double_t dy, + Double_t sdr)const{ + // Basic function used to determine the ending angle and starting angles + // for rounded corners given the relative distance between the centers + // of the circles and the difference/sum of their radii. Case 1. + // Inputs: + // Double_t dx difference in x locations of the circle centers + // Double_t dy difference in y locations of the circle centers + // Double_t sdr difference or sum of the circle radii + // Outputs: + // none. + // Return: + // the angle in Degrees + Double_t a,b; + + b = dy*dy+dx*dx-sdr*sdr; + if(b<0.0) Error("AngleForRoundedCorners1", + "dx^2(%e)+dy^2(%e)-sdr^2(%e)=b=%e<0",dx,dy,sdr,b); + b = TMath::Sqrt(b); + a = -sdr*dy-dx*b; + b = -sdr*dx+dy*b; + return TMath::ATan2(a,b)*TMath::RadToDeg(); + +} + +void AliITSv11Geometry::AnglesForRoundedCorners(Double_t x0,Double_t y0, + Double_t r0,Double_t x1, + Double_t y1,Double_t r1, + Double_t &t0,Double_t &t1) + const{ + // Function to compute the ending angle, for arc 0, and starting angle, + // for arc 1, such that a straight line will connect them with no + // discontinuities. + //Begin_Html + /* + + */ + //End_Html + // Inputs: + // Double_t x0 X Coordinate of arc 0 center. + // Double_t y0 Y Coordinate of arc 0 center. + // Double_t r0 Radius of curvature of arc 0. For signe see figure. + // Double_t x1 X Coordinate of arc 1 center. + // Double_t y1 Y Coordinate of arc 1 center. + // Double_t r1 Radius of curvature of arc 1. For signe see figure. + // Outputs: + // Double_t t0 Ending angle of arch 0, with respect to x axis, Degrees. + // Double_t t1 Starting angle of arch 1, with respect to x axis, + // Degrees. + // Return: + // none. + Double_t t; + + if(r0>=0.0&&r1>=0.0) { // Inside to inside ++ + t = AngleForRoundedCorners1(x1-x0,y1-y0,r1-r0); + t0 = t1 = t; + return; + }else if(r0>=0.0&&r1<=0.0){ // Inside to Outside +- + r1 = -r1; // make positive + t = AngleForRoundedCorners0(x1-x0,y1-y0,r1+r0); + t0 = 180.0 + t; + if(t0<0.0) t += 360.; + if(t<0.0) t += 360.; + t1 = t; + return; + }else if(r0<=0.0&&r1>=0.0){ // Outside to Inside -+ + r0 = - r0; // make positive + t = AngleForRoundedCorners1(x1-x0,y1-y0,r1+r0); + t0 = 180.0 + t; + if(t0>180.) t0 -= 360.; + if(t >180.) t -= 360.; + t1 = t; + return; + }else if(r0<=0.0&&r1<=0.0) { // Outside to outside -- + r0 = -r0; // make positive + r1 = -r1; // make positive + t = AngleForRoundedCorners0(x1-x0,y1-y0,r1-r0); + t0 = t1 = t; + return; + } // end if + return; +} + +void AliITSv11Geometry::MakeFigure1(Double_t x0,Double_t y0,Double_t r0, + Double_t x1,Double_t y1,Double_t r1){ + // Function to create the figure discribing how the function + // AnglesForRoundedCorners works. + // + // Inputs: + // Double_t x0 X Coordinate of arc 0 center. + // Double_t y0 Y Coordinate of arc 0 center. + // Double_t r0 Radius of curvature of arc 0. For signe see figure. + // Double_t x1 X Coordinate of arc 1 center. + // Double_t y1 Y Coordinate of arc 1 center. + // Double_t r1 Radius of curvature of arc 1. For signe see figure. + // Outputs: + // none. + // Return: + // none. + Double_t t0[4],t1[4],xa0[4],ya0[4],xa1[4],ya1[4],ra0[4],ra1[4]; + Double_t xmin,ymin,xmax,ymax,h; + Int_t j; + + for(j=0;j<4;j++) { + ra0[j] = r0; if(j%2) ra0[j] = -r0; + ra1[j] = r1; if(j>1) ra1[j] = -r1; + AnglesForRoundedCorners(x0,y0,ra0[j],x1,y1,ra1[j],t0[j],t1[j]); + xa0[j] = TMath::Abs(r0)*CosD(t0[j])+x0; + ya0[j] = TMath::Abs(r0)*SinD(t0[j])+y0; + xa1[j] = TMath::Abs(r1)*CosD(t1[j])+x1; + ya1[j] = TMath::Abs(r1)*SinD(t1[j])+y1; + } // end for j + if(r0<0.0) r0 = -r0; + if(r1<0.0) r1 = -r1; + xmin = TMath::Min(x0 - r0,x1-r1); + ymin = TMath::Min(y0 - r0,y1-r1); + xmax = TMath::Max(x0 + r0,x1+r1); + ymax = TMath::Max(y0 + r0,y1+r1); + for(j=1;j<4;j++) { + xmin = TMath::Min(xmin,xa0[j]); + xmin = TMath::Min(xmin,xa1[j]); + ymin = TMath::Min(ymin,ya0[j]); + ymin = TMath::Min(ymin,ya1[j]); + + xmax = TMath::Max(xmax,xa0[j]); + xmax = TMath::Max(xmax,xa1[j]); + ymax = TMath::Max(ymax,ya0[j]); + ymax = TMath::Max(ymax,ya1[j]); + } // end for j + if(xmin<0.0) xmin *= 1.1; else xmin *= 0.9; + if(ymin<0.0) ymin *= 1.1; else ymin *= 0.9; + if(xmax<0.0) xmax *= 0.9; else xmax *= 1.1; + if(ymax<0.0) ymax *= 0.9; else ymax *= 1.1; + j = (Int_t)(500.0*(ymax-ymin)/(xmax-xmin)); + TCanvas *can = new TCanvas("AliITSv11Geometry_AnglesForRoundedCorners", + "Figure for AliITSv11Geometry",500,j); + h = ymax-ymin; if(h<0) h = -h; + can->Range(xmin,ymin,xmax,ymax); + TArc *c0 = new TArc(x0,y0,r0); + TArc *c1 = new TArc(x1,y1,r1); + TLine *line[4]; + TArrow *ar0[4]; + TArrow *ar1[4]; + for(j=0;j<4;j++){ + ar0[j] = new TArrow(x0,y0,xa0[j],ya0[j]); + ar1[j] = new TArrow(x1,y1,xa1[j],ya1[j]); + line[j] = new TLine(xa0[j],ya0[j],xa1[j],ya1[j]); + ar0[j]->SetLineColor(j+1); + ar0[j]->SetArrowSize(0.1*r0/h); + ar1[j]->SetLineColor(j+1); + ar1[j]->SetArrowSize(0.1*r1/h); + line[j]->SetLineColor(j+1); + } // end for j + c0->Draw(); + c1->Draw(); + for(j=0;j<4;j++){ + ar0[j]->Draw(); + ar1[j]->Draw(); + line[j]->Draw(); + } // end for j + TText *t = new TText(); + t->SetTextSize(0.02); + Char_t txt[100]; + snprintf(txt,99,"(x0=%5.2f,y0=%5.2f)",x0,y0); + t->DrawText(x0,y0,txt); + snprintf(txt,99,"(x1=%5.2f,y1=%5.2f)",x1,y1); + for(j=0;j<4;j++) { + t->SetTextColor(j+1); + t->DrawText(x1,y1,txt); + snprintf(txt,99,"r0=%5.2f",ra0[j]); + t->DrawText(0.5*(x0+xa0[j]),0.5*(y0+ya0[j]),txt); + snprintf(txt,99,"r1=%5.2f",ra1[j]); + t->DrawText(0.5*(x1+xa1[j]),0.5*(y1+ya1[j]),txt); + } // end for j +} diff --git a/its/AliITSv11Geometry.h b/its/AliITSv11Geometry.h new file mode 100644 index 0000000000000..673ce41225833 --- /dev/null +++ b/its/AliITSv11Geometry.h @@ -0,0 +1,197 @@ +#ifndef ALIITSV11GEOMETRY_H +#define ALIITSV11GEOMETRY_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* + $Id$ + */ + +/* + Base class for defining large parts of the ITS geometry, v11. + */ +#include +#include +#include "FairLogger.h" + +class TGeoArb8; +class TGeoPcon; +class TGeoTube; +class TGeoTubeSeg; +class TGeoConeSeg; +class TGeoBBox; + +class AliITSv11Geometry : public TObject { + public: + AliITSv11Geometry():fDebug() {}; + AliITSv11Geometry(Int_t debug):fDebug(debug) {}; + virtual ~AliITSv11Geometry(){}; + // + // Sets the debug flag for debugging output + void SetDebug(Int_t level=5){fDebug=level;} + // Clears the debug flag so no debugging output will be generated + void SetNoDebug(){fDebug=0;} + // Returns the debug flag value + Bool_t GetDebug(Int_t level=1)const {return fDebug>=level;} + // + // Static functions + // + // Define Trig functions for use with degrees (standerd TGeo angles). + // Sine function + Double_t SinD(Double_t deg)const{return TMath::Sin(deg*TMath::DegToRad());} + // Cosine function + Double_t CosD(Double_t deg)const{return TMath::Cos(deg*TMath::DegToRad());} + // Tangent function + Double_t TanD(Double_t deg)const{return TMath::Tan(deg*TMath::DegToRad());} + // Determine the intersection of two lines + void IntersectLines(Double_t m, Double_t x0, Double_t y0, + Double_t n, Double_t x1, Double_t y1, + Double_t &xi, Double_t &yi)const; + // Determine the intersection of a line and a circle + static Bool_t IntersectCircle(Double_t m, Double_t x0, Double_t y0, + Double_t rr, Double_t xc, Double_t yc, + Double_t &xi1, Double_t &yi1, + Double_t &xi2, Double_t &yi2); + // Given the line, defined by the two points (x0,y0) and (x1,y1) and the + // point x, return the value of y. + Double_t Yfrom2Points(Double_t x0,Double_t y0, + Double_t x1,Double_t y1,Double_t x)const; + // Given the line, defined by the two points (x0,y0) and (x1,y1) and the + // point y, return the value of x. + Double_t Xfrom2Points(Double_t x0,Double_t y0, + Double_t x1,Double_t y1,Double_t y)const; + // Given 2 points from a TGeoPcon(z and Rmax) finds Rmax at given z + Double_t RmaxFrom2Points(const TGeoPcon *p,Int_t i1,Int_t i2, + Double_t z)const; + // Given 2 points from a TGeoPcon(z and Rmin) finds Rmin at given z + Double_t RminFrom2Points(const TGeoPcon *p,Int_t i1,Int_t i2, + Double_t z)const; + // Give two points in the array ar and az, returns the value r + // corresponding z along the line defined by those two points + Double_t RFrom2Points(const Double_t *ar,const Double_t *az, + Int_t i1,Int_t i2,Double_t z)const; + // Given 2 points from a TGeoPcon(z and Rmax) finds z at given Rmin + Double_t Zfrom2MinPoints(const TGeoPcon *p,Int_t i1,Int_t i2, + Double_t r)const; + // Given 2 points from a TGeoPcon(z and Rmax) finds z at given Rmax + Double_t Zfrom2MaxPoints(const TGeoPcon *p,Int_t i1,Int_t i2, + Double_t r)const; + // Give two points in the array ar and az, returns the value z + // corresponding r along the line defined by those two points + Double_t Zfrom2Points(const Double_t *az,const Double_t *ar, + Int_t i1,Int_t i2,Double_t r)const; + // Given 1 point from a TGeoPcon(z and Rmax) the angle tc returns r for + // a given z, an offset (distnace perpendicular to line at angle tc) of + // th may be applied. + Double_t RmaxFromZpCone(const TGeoPcon *p,int ip,Double_t tc, + Double_t z,Double_t th=0.0)const; + Double_t RFromZpCone(const Double_t *ar,const Double_t *az,int ip, + Double_t tc,Double_t z,Double_t th=0.0)const; + // Given 1 point from a TGeoPcon(z and Rmin) the angle tc returns r for + // a given z, an offset (distnace perpendicular to line at angle tc) of + // th may be applied. + Double_t RminFromZpCone(const TGeoPcon *p,Int_t ip,Double_t tc, + Double_t z,Double_t th=0.0)const; + // Given 1 point from a TGeoPcon(z and Rmax) the angle tc returns z for + // a given Rmax, an offset (distnace perpendicular to line at angle tc) of + // th may be applied. + Double_t ZFromRmaxpCone(const TGeoPcon *p,int ip,Double_t tc, + Double_t r,Double_t th=0.0)const; + // General Outer cone Surface equation for z. + Double_t ZFromRmaxpCone(const Double_t *ar,const Double_t *az, + Int_t ip,Double_t tc,Double_t r, + Double_t th=0.0)const; + // Given 1 point from a TGeoPcon(z and Rmin) the angle tc returns z for + // a given Rmin, an offset (distnace perpendicular to line at angle tc) of + // th may be applied. + Double_t ZFromRminpCone(const TGeoPcon *p,int ip,Double_t tc, + Double_t r,Double_t th=0.0)const; + // Given two lines defined by the points i1, i2,i3 in the TGeoPcon + // class p that intersect at point p->GetZ(i2) return the point z,r + // that is Cthick away in the TGeoPcon class q. If points i1=i2 + // and max == kTRUE, then p->GetRmin(i1) and p->GetRmax(i2) are used. + // if points i2=i3 and max=kTRUE then points p->GetRmax(i2) and + // p->GetRmin(i3) are used. If i2=i3 and max=kFALSE, then p->GetRmin(i2) + // and p->GetRmax(i3) are used. + void InsidePoint(const TGeoPcon *p,Int_t i1,Int_t i2,Int_t i3, + Double_t Cthick,TGeoPcon *q,Int_t j1,Bool_t max)const; + // Given two intersecting lines defined by the points (x0,y0), (x1,y1) and + // (x1,y1), (x2,y2) {intersecting at (x1,y1)} the point (x,y) a distance + // c away is returned such that two lines a distance c away from the + // lines defined above intersect at (x,y). + void InsidePoint(Double_t x0,Double_t y0,Double_t x1,Double_t y1, + Double_t x2,Double_t y2,Double_t c, + Double_t &x,Double_t &y)const; + // Given a initial point z0,r0, the initial angle theta0, and the radius + // of curvature, returns the point z1, r1 at the angle theta1. Theta + // measured from the r axis in the clock wise direction [degrees]. + void RadiusOfCurvature(Double_t rc,Double_t theta0,Double_t z0, + Double_t r0,Double_t theta1,Double_t &z1, + Double_t &r1)const; + // + // Output functions for debugging + // + // Prints out the contents of the TGeoArb8 + void PrintArb8(const TGeoArb8 *a) const; + // Prints out the contents of the TGeoPcon + void PrintPcon(const TGeoPcon *a) const; + // Prints out the contents of the TGeoTube + void PrintTube(const TGeoTube *a) const; + // Prints out the contents of the TGeoTubeSeg + void PrintTubeSeg(const TGeoTubeSeg *a) const; + // Prints out the contents of the TGeoConeSeg + void PrintConeSeg(const TGeoConeSeg *a) const; + // Prints out the contents of the TGeoBBox + void PrintBBox(const TGeoBBox *a) const; + // Draws a 2D crossection of the TGeoPcon r,z section + void DrawCrossSection(const TGeoPcon *p,Int_t fillc=7,Int_t fills=4050, + Int_t linec=3,Int_t lines=1,Int_t linew=4, + Int_t markc=2,Int_t marks=4, + Float_t marksize=1.0) const; + // Compute the angles where a line intersects a circle. + Bool_t AngleOfIntersectionWithLine(Double_t x0,Double_t y0, + Double_t x1,Double_t y1, + Double_t xc,Double_t yc, + Double_t rc,Double_t &t0, + Double_t &t1)const; + void AnglesForRoundedCorners(Double_t x0,Double_t y0,Double_t r0, + Double_t x1,Double_t y1,Double_t r1, + Double_t &t0,Double_t &t1)const; + // Define a general CreateMaterials function here so that if + // any specific subdetector does not define it this null function + // will due. This function is not declaired const so that a sub- + // detector's version may use class variables if they wish. + void CreateDefaultMaterials(); + virtual void CreateMaterials(){}; + // Function to create figure needed for this class' documentation + void MakeFigure1(Double_t x0=0.0,Double_t y0=0.0,Double_t r0=2.0, + Double_t x1=-4.0,Double_t y1=-2.0,Double_t r1=1.0); + protected: + + // Units, Convert from k?? to cm,degree,GeV,seconds, + static const Double_t fgkmicron; // Convert micron to TGeom's cm. + static const Double_t fgkmm; // Convert mm to TGeom's cm. + static const Double_t fgkcm; // Convert cm to TGeom's cm. + static const Double_t fgkDegree; //Convert degrees to TGeom's degrees + static const Double_t fgkRadian; //To Radians + static const Double_t fgkgcm3; // Density in g/cm^3 + static const Double_t fgkKgm3; // Density in kg/m^3 + static const Double_t fgkKgdm3; // Density in kg/dm^3 + static const Double_t fgkCelsius; // Temperature in degrees Celcius + static const Double_t fgkPascal; // Preasure in Pascal + static const Double_t fgkKPascal; // Preasure in KPascal + static const Double_t fgkeV; // Energy in eV + static const Double_t fgkKeV; // Energy in KeV + static const Double_t fgkMeV; // Energy in MeV + static const Double_t fgkGeV; // Energy in GeV + + private: + Double_t AngleForRoundedCorners0(Double_t dx,Double_t dy, + Double_t sdr)const; + Double_t AngleForRoundedCorners1(Double_t dx,Double_t dy, + Double_t sdr)const; + Int_t fDebug; //! Debug flag/level + ClassDef(AliITSv11Geometry,1) // Base class for ITS v11 geometry +}; + +#endif diff --git a/its/AliIts.cxx b/its/AliIts.cxx deleted file mode 100644 index b7c3bef315b75..0000000000000 --- a/its/AliIts.cxx +++ /dev/null @@ -1,225 +0,0 @@ -/******************************************************************************** - * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * - * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * - * copied verbatim in the file "LICENSE" * - ********************************************************************************/ -#include "AliIts.h" - -#include "AliItsPoint.h" -#include "AliItsGeo.h" -#include "AliItsGeoPar.h" - -#include "FairVolume.h" -#include "FairGeoVolume.h" -#include "FairGeoNode.h" -#include "FairRootManager.h" -#include "FairGeoLoader.h" -#include "FairGeoInterface.h" -#include "FairRun.h" -#include "FairRuntimeDb.h" -#include "AliDetectorList.h" -#include "AliStack.h" - -#include "TClonesArray.h" -#include "TVirtualMC.h" -#include "TGeoManager.h" -#include "TGeoBBox.h" -#include "TGeoCompositeShape.h" -#include "TGeoTube.h" -#include "TGeoMaterial.h" -#include "TGeoMedium.h" - -#include -using std::cout; -using std::endl; - -AliIts::AliIts() - : FairDetector("AliIts", kTRUE, kAliIts), - fTrackID(-1), - fVolumeID(-1), - fPos(), - fMom(), - fTime(-1.), - fLength(-1.), - fELoss(-1), - fAliItsPointCollection(new TClonesArray("AliItsPoint")) -{ -} - -AliIts::AliIts(const char* name, Bool_t active) - : FairDetector(name, active, kAliIts), - fTrackID(-1), - fVolumeID(-1), - fPos(), - fMom(), - fTime(-1.), - fLength(-1.), - fELoss(-1), - fAliItsPointCollection(new TClonesArray("AliItsPoint")) -{ -} - -AliIts::~AliIts() -{ - if (fAliItsPointCollection) { - fAliItsPointCollection->Delete(); - delete fAliItsPointCollection; - } -} - -void AliIts::Initialize() -{ - FairDetector::Initialize(); - FairRuntimeDb* rtdb= FairRun::Instance()->GetRuntimeDb(); - AliItsGeoPar* par=(AliItsGeoPar*)(rtdb->getContainer("AliItsGeoPar")); -} - -Bool_t AliIts::ProcessHits(FairVolume* vol) -{ - /** This method is called from the MC stepping */ - - //Set parameters at entrance of volume. Reset ELoss. - if ( gMC->IsTrackEntering() ) { - fELoss = 0.; - fTime = gMC->TrackTime() * 1.0e09; - fLength = gMC->TrackLength(); - gMC->TrackPosition(fPos); - gMC->TrackMomentum(fMom); - } - - // Sum energy loss for all steps in the active volume - fELoss += gMC->Edep(); - - // Create AliItsPoint at exit of active volume - if ( gMC->IsTrackExiting() || - gMC->IsTrackStop() || - gMC->IsTrackDisappeared() ) { - fTrackID = gMC->GetStack()->GetCurrentTrackNumber(); - fVolumeID = vol->getMCid(); - if (fELoss == 0. ) { return kFALSE; } - AddHit(fTrackID, fVolumeID, TVector3(fPos.X(), fPos.Y(), fPos.Z()), - TVector3(fMom.Px(), fMom.Py(), fMom.Pz()), fTime, fLength, - fELoss); - - // Increment number of AliIts det points in TParticle - AliStack* stack = (AliStack*) gMC->GetStack(); - stack->AddPoint(kAliIts); - } - - return kTRUE; -} - -void AliIts::EndOfEvent() -{ - - fAliItsPointCollection->Clear(); - -} - - - -void AliIts::Register() -{ - - /** This will create a branch in the output tree called - AliItsPoint, setting the last parameter to kFALSE means: - this collection will not be written to the file, it will exist - only during the simulation. - */ - - FairRootManager::Instance()->Register("AliItsPoint", "AliIts", - fAliItsPointCollection, kTRUE); - -} - - -TClonesArray* AliIts::GetCollection(Int_t iColl) const -{ - if (iColl == 0) { return fAliItsPointCollection; } - else { return NULL; } -} - -void AliIts::Reset() -{ - fAliItsPointCollection->Clear(); -} - -void AliIts::ConstructGeometry() -{ - - TGeoVolume *top=gGeoManager->GetTopVolume(); - TGeoMedium *Si =gGeoManager->GetMedium("Si"); - TGeoMedium *Carbon = gGeoManager->GetMedium("Carbon"); - - if(Si==0){ - TGeoMaterial *matSi = new TGeoMaterial("Si", 28.0855, 14, 2.33); - Si = new TGeoMedium("Si", 2, matSi); - } - if(Carbon==0){ - TGeoMaterial *matCarbon = new TGeoMaterial("C", 12.011, 6.0, 2.265); - Carbon = new TGeoMedium("C", 3, matCarbon); - } - - - TGeoVolume *det1= gGeoManager->MakeTubs("Det1",Si,5,80,0.1,0,360); - AddSensitiveVolume(det1); - TGeoRotation r1; - r1.SetAngles(0,0,0); - TGeoTranslation t1(0, 0, 0); - TGeoCombiTrans c1(t1, r1); - TGeoHMatrix *h1 = new TGeoHMatrix(c1); - top->AddNode(det1,1,h1); - det1->SetLineColor(kGreen); - - TGeoVolume *passive1= gGeoManager->MakeTubs("Pass1",Si,5,120,10,0,360); - TGeoRotation rp1; - rp1.SetAngles(0,0,0); - TGeoTranslation tp1(0, 0, 20); - TGeoCombiTrans cp1(tp1, rp1); - TGeoHMatrix *hp1 = new TGeoHMatrix(cp1); - top->AddNode(passive1,1,hp1); - passive1->SetLineColor(kRed); - - - - TGeoVolume *det2= gGeoManager->MakeTubs("Det2",Si,5,150,0.1,0,360); - AddSensitiveVolume(det2); - TGeoRotation r2; - r2.SetAngles(0,0,0); - TGeoTranslation t2(0, 0, 70); - TGeoCombiTrans c2(t2, r2); - TGeoHMatrix *h2 = new TGeoHMatrix(c2); - top->AddNode(det2,1,h2); - det2->SetLineColor(kGreen); - - TGeoVolume *det3= gGeoManager->MakeTubs("Det3",Si,5,150,0.1,0,360); - AddSensitiveVolume(det3); - TGeoRotation r3; - r3.SetAngles(0,0,0); - TGeoTranslation t3(0, 0, 150); - TGeoCombiTrans c3(t3, r3); - TGeoHMatrix *h3 = new TGeoHMatrix(c3); - top->AddNode(det3,1,h3); - det3->SetLineColor(kGreen); - - - - - - -} - -AliItsPoint* AliIts::AddHit(Int_t trackID, Int_t detID, - TVector3 pos, TVector3 mom, - Double_t time, Double_t length, - Double_t eLoss) -{ - TClonesArray& clref = *fAliItsPointCollection; - Int_t size = clref.GetEntriesFast(); - return new(clref[size]) AliItsPoint(trackID, detID, pos, mom, - time, length, eLoss); -} - -ClassImp(AliIts) diff --git a/its/AliIts.h b/its/AliIts.h deleted file mode 100644 index 08bf38134a8cf..0000000000000 --- a/its/AliIts.h +++ /dev/null @@ -1,106 +0,0 @@ -/******************************************************************************** - * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * - * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * - * copied verbatim in the file "LICENSE" * - ********************************************************************************/ -#ifndef NEWDETECTOR_H -#define NEWDETECTOR_H - -#include "FairDetector.h" - -#include "TVector3.h" -#include "TLorentzVector.h" - -class AliItsPoint; -class FairVolume; -class TClonesArray; - -class AliIts: public FairDetector -{ - - public: - - /** Name : Detector Name - * Active: kTRUE for active detectors (ProcessHits() will be called) - * kFALSE for inactive detectors - */ - AliIts(const char* Name, Bool_t Active); - - /** default constructor */ - AliIts(); - - /** destructor */ - virtual ~AliIts(); - - /** Initialization of the detector is done here */ - virtual void Initialize(); - - /** this method is called for each step during simulation - * (see FairMCApplication::Stepping()) - */ - virtual Bool_t ProcessHits( FairVolume* v=0); - - /** Registers the produced collections in FAIRRootManager. */ - virtual void Register(); - - /** Gets the produced collections */ - virtual TClonesArray* GetCollection(Int_t iColl) const ; - - /** has to be called after each event to reset the containers */ - virtual void Reset(); - - /** Create the detector geometry */ - void ConstructGeometry(); - - - - /** This method is an example of how to add your own point - * of type AliItsPoint to the clones array - */ - AliItsPoint* AddHit(Int_t trackID, Int_t detID, - TVector3 pos, TVector3 mom, - Double_t time, Double_t length, - Double_t eLoss); - - /** The following methods can be implemented if you need to make - * any optional action in your detector during the transport. - */ - - virtual void CopyClones( TClonesArray* cl1, TClonesArray* cl2 , - Int_t offset) {;} - virtual void SetSpecialPhysicsCuts() {;} - virtual void EndOfEvent(); - virtual void FinishPrimary() {;} - virtual void FinishRun() {;} - virtual void BeginPrimary() {;} - virtual void PostTrack() {;} - virtual void PreTrack() {;} - virtual void BeginEvent() {;} - - - private: - - /** Track information to be stored until the track leaves the - active volume. - */ - Int_t fTrackID; //! track index - Int_t fVolumeID; //! volume id - TLorentzVector fPos; //! position at entrance - TLorentzVector fMom; //! momentum at entrance - Double32_t fTime; //! time - Double32_t fLength; //! length - Double32_t fELoss; //! energy loss - - /** container for data points */ - - TClonesArray* fAliItsPointCollection; //! - - AliIts(const AliIts&); - AliIts& operator=(const AliIts&); - - ClassDef(AliIts,1) -}; - -#endif //NEWDETECTOR_H diff --git a/its/AliItsContFact.cxx b/its/AliItsContFact.cxx deleted file mode 100644 index a441d0f27cfbb..0000000000000 --- a/its/AliItsContFact.cxx +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************** - * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * - * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * - * copied verbatim in the file "LICENSE" * - ********************************************************************************/ -#include "AliItsContFact.h" - -#include "AliItsGeoPar.h" - -#include "FairRuntimeDb.h" - -#include - -ClassImp(AliItsContFact) - -static AliItsContFact gAliItsContFact; - -AliItsContFact::AliItsContFact() - : FairContFact() -{ - /** Constructor (called when the library is loaded) */ - fName="AliItsContFact"; - fTitle="Factory for parameter containers in libAliIts"; - setAllContainers(); - FairRuntimeDb::instance()->addContFactory(this); -} - -void AliItsContFact::setAllContainers() -{ - /** Creates the Container objects with all accepted - contexts and adds them to - the list of containers for the AliIts library. - */ - - FairContainer* p= new FairContainer("AliItsGeoPar", - "AliIts Geometry Parameters", - "TestDefaultContext"); - p->addContext("TestNonDefaultContext"); - - containers->Add(p); -} - -FairParSet* AliItsContFact::createContainer(FairContainer* c) -{ - /** Calls the constructor of the corresponding parameter container. - For an actual context, which is not an empty string and not - the default context - of this container, the name is concatinated with the context. - */ - const char* name=c->GetName(); - FairParSet* p=NULL; - if (strcmp(name,"AliItsGeoPar")==0) { - p=new AliItsGeoPar(c->getConcatName().Data(), - c->GetTitle(),c->getContext()); - } - return p; -} diff --git a/its/AliItsContFact.h b/its/AliItsContFact.h deleted file mode 100644 index d36cfbeb7d23e..0000000000000 --- a/its/AliItsContFact.h +++ /dev/null @@ -1,26 +0,0 @@ -/******************************************************************************** - * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * - * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * - * copied verbatim in the file "LICENSE" * - ********************************************************************************/ -#ifndef NEWDETECTORCONTFACT_H -#define NEWDETECTORCONTFACT_H - -#include "FairContFact.h" - -class FairContainer; - -class AliItsContFact : public FairContFact -{ - private: - void setAllContainers(); - public: - AliItsContFact(); - ~AliItsContFact() {} - FairParSet* createContainer(FairContainer*); - ClassDef( AliItsContFact,0) // Factory for all AliIts parameter containers -}; - -#endif diff --git a/its/AliItsGeo.cxx b/its/AliItsGeo.cxx deleted file mode 100644 index de64a2fd57ef5..0000000000000 --- a/its/AliItsGeo.cxx +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************** - * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * - * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * - * copied verbatim in the file "LICENSE" * - ********************************************************************************/ -#include "AliItsGeo.h" -#include "FairGeoNode.h" - -ClassImp(AliItsGeo) - -// ----- Default constructor ------------------------------------------- -AliItsGeo::AliItsGeo() - : FairGeoSet() -{ - // Constructor - // fName has to be the name used in the geometry for all volumes. - // If there is a mismatch the geometry cannot be build. - fName="newdetector"; - maxSectors=0; - maxModules=10; -} - -// ------------------------------------------------------------------------- - -const char* AliItsGeo::getModuleName(Int_t m) -{ - /** Returns the module name of AliIts number m - Setting AliIts here means that all modules names in the - ASCII file should start with AliIts otherwise they will - not be constructed - */ - sprintf(modName,"AliIts%i",m+1); - return modName; -} - -const char* AliItsGeo::getEleName(Int_t m) -{ - /** Returns the element name of Det number m */ - sprintf(eleName,"AliIts%i",m+1); - return eleName; -} diff --git a/its/AliItsGeo.h b/its/AliItsGeo.h deleted file mode 100644 index c903777ba8762..0000000000000 --- a/its/AliItsGeo.h +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************** - * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * - * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * - * copied verbatim in the file "LICENSE" * - ********************************************************************************/ -#ifndef NEWDETECTORGEO_H -#define NEWDETECTORGEO_H - -#include "FairGeoSet.h" - -class AliItsGeo : public FairGeoSet -{ - - protected: - char modName[20]; // name of module - char eleName[20]; // substring for elements in module - public: - AliItsGeo(); - ~AliItsGeo() {} - const char* getModuleName(Int_t); - const char* getEleName(Int_t); - inline Int_t getModNumInMod(const TString&); - ClassDef(AliItsGeo,1) -}; - -inline Int_t AliItsGeo::getModNumInMod(const TString& name) -{ - /** returns the module index from module name - ?? in name[??] has to be the length of the detector name in the - .geo file. For example if all nodes in this file starts with - newdetector ?? has to be 11. - */ - return (Int_t)(name[11]-'0')-1; // -} - -#endif diff --git a/its/AliItsGeoPar.cxx b/its/AliItsGeoPar.cxx deleted file mode 100644 index 57dd70d695ac7..0000000000000 --- a/its/AliItsGeoPar.cxx +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************** - * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * - * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * - * copied verbatim in the file "LICENSE" * - ********************************************************************************/ -#include "AliItsGeoPar.h" - -#include "FairParamList.h" - -#include "TObjArray.h" - -#include - -ClassImp(AliItsGeoPar) - -AliItsGeoPar ::AliItsGeoPar(const char* name, - const char* title, - const char* context) - : FairParGenericSet(name,title,context), - fGeoSensNodes(new TObjArray()), - fGeoPassNodes(new TObjArray()) -{ -} - -AliItsGeoPar::~AliItsGeoPar(void) -{ -} - -void AliItsGeoPar::clear(void) -{ - if(fGeoSensNodes) { delete fGeoSensNodes; } - if(fGeoPassNodes) { delete fGeoPassNodes; } -} - -void AliItsGeoPar::putParams(FairParamList* l) -{ - if (!l) { return; } - l->addObject("FairGeoNodes Sensitive List", fGeoSensNodes); - l->addObject("FairGeoNodes Passive List", fGeoPassNodes); -} - -Bool_t AliItsGeoPar::getParams(FairParamList* l) -{ - if (!l) { return kFALSE; } - if (!l->fillObject("FairGeoNodes Sensitive List", fGeoSensNodes)) { return kFALSE; } - if (!l->fillObject("FairGeoNodes Passive List", fGeoPassNodes)) { return kFALSE; } - return kTRUE; -} diff --git a/its/AliItsGeoPar.h b/its/AliItsGeoPar.h deleted file mode 100644 index 8b6969b09a043..0000000000000 --- a/its/AliItsGeoPar.h +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************** - * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * - * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * - * copied verbatim in the file "LICENSE" * - ********************************************************************************/ -#ifndef NEWDETECTORGEOPAR_H -#define NEWDETECTORGEOPAR_H - -#include "FairParGenericSet.h" - -class TObjArray; -class FairParamList; - -class AliItsGeoPar : public FairParGenericSet -{ - public: - - /** List of FairGeoNodes for sensitive volumes */ - TObjArray* fGeoSensNodes; - - /** List of FairGeoNodes for sensitive volumes */ - TObjArray* fGeoPassNodes; - - AliItsGeoPar(const char* name="AliItsGeoPar", - const char* title="AliIts Geometry Parameters", - const char* context="TestDefaultContext"); - ~AliItsGeoPar(void); - void clear(void); - void putParams(FairParamList*); - Bool_t getParams(FairParamList*); - TObjArray* GetGeoSensitiveNodes() {return fGeoSensNodes;} - TObjArray* GetGeoPassiveNodes() {return fGeoPassNodes;} - - private: - AliItsGeoPar(const AliItsGeoPar&); - AliItsGeoPar& operator=(const AliItsGeoPar&); - - ClassDef(AliItsGeoPar,1) -}; - -#endif diff --git a/its/AliItsLinkDef.h b/its/AliItsLinkDef.h deleted file mode 100644 index 438f8cae74452..0000000000000 --- a/its/AliItsLinkDef.h +++ /dev/null @@ -1,20 +0,0 @@ -/******************************************************************************** - * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * - * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * - * copied verbatim in the file "LICENSE" * - ********************************************************************************/ -#ifdef __CINT__ - -#pragma link off all globals; -#pragma link off all classes; -#pragma link off all functions; - -#pragma link C++ class AliItsContFact; -#pragma link C++ class AliItsGeo; -#pragma link C++ class AliItsGeoPar; -#pragma link C++ class AliIts; -#pragma link C++ class AliItsPoint+; - -#endif diff --git a/its/AliItsPoint.cxx b/its/AliItsPoint.cxx deleted file mode 100644 index ce99ca316c377..0000000000000 --- a/its/AliItsPoint.cxx +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************** - * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * - * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * - * copied verbatim in the file "LICENSE" * - ********************************************************************************/ -#include "AliItsPoint.h" - -#include -using std::cout; -using std::endl; - - -// ----- Default constructor ------------------------------------------- -AliItsPoint::AliItsPoint() - : FairMCPoint() -{ -} -// ------------------------------------------------------------------------- - -// ----- Standard constructor ------------------------------------------ -AliItsPoint::AliItsPoint(Int_t trackID, Int_t detID, - TVector3 pos, TVector3 mom, - Double_t tof, Double_t length, - Double_t eLoss) - : FairMCPoint(trackID, detID, pos, mom, tof, length, eLoss) -{ -} -// ------------------------------------------------------------------------- - -// ----- Destructor ---------------------------------------------------- -AliItsPoint::~AliItsPoint() { } -// ------------------------------------------------------------------------- - -// ----- Public method Print ------------------------------------------- -void AliItsPoint::Print(const Option_t* opt) const -{ - cout << "-I- AliItsPoint: AliIts point for track " << fTrackID - << " in detector " << fDetectorID << endl; - cout << " Position (" << fX << ", " << fY << ", " << fZ - << ") cm" << endl; - cout << " Momentum (" << fPx << ", " << fPy << ", " << fPz - << ") GeV" << endl; - cout << " Time " << fTime << " ns, Length " << fLength - << " cm, Energy loss " << fELoss*1.0e06 << " keV" << endl; -} -// ------------------------------------------------------------------------- - -ClassImp(AliItsPoint) - diff --git a/its/AliItsPoint.h b/its/AliItsPoint.h deleted file mode 100644 index 899cd29ba2335..0000000000000 --- a/its/AliItsPoint.h +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************** - * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * - * * - * This software is distributed under the terms of the * - * GNU Lesser General Public Licence version 3 (LGPL) version 3, * - * copied verbatim in the file "LICENSE" * - ********************************************************************************/ -#ifndef NEWDETECTORPOINT_H -#define NEWDETECTORPOINT_H 1 - - -#include "FairMCPoint.h" - -#include "TObject.h" -#include "TVector3.h" - -class AliItsPoint : public FairMCPoint -{ - - public: - - /** Default constructor **/ - AliItsPoint(); - - - /** Constructor with arguments - *@param trackID Index of MCTrack - *@param detID Detector ID - *@param pos Ccoordinates at entrance to active volume [cm] - *@param mom Momentum of track at entrance [GeV] - *@param tof Time since event start [ns] - *@param length Track length since creation [cm] - *@param eLoss Energy deposit [GeV] - **/ - AliItsPoint(Int_t trackID, Int_t detID, TVector3 pos, TVector3 mom, - Double_t tof, Double_t length, Double_t eLoss); - - - - - /** Destructor **/ - virtual ~AliItsPoint(); - - /** Output to screen **/ - virtual void Print(const Option_t* opt) const; - - private: - /** Copy constructor **/ - AliItsPoint(const AliItsPoint& point); - AliItsPoint operator=(const AliItsPoint& point); - - ClassDef(AliItsPoint,1) - -}; - -#endif diff --git a/its/CMakeLists.txt b/its/CMakeLists.txt index a1c83b647c3c8..c7530110030c9 100644 --- a/its/CMakeLists.txt +++ b/its/CMakeLists.txt @@ -1,21 +1,14 @@ - ################################################################################ - # Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH # - # # - # This software is distributed under the terms of the # - # GNU Lesser General Public Licence version 3 (LGPL) version 3, # - # copied verbatim in the file "LICENSE" # - ################################################################################ -# Create a library called "libAliIts" which includes the source files given in +# Create a library called "libO2its" which includes the source files given in # the array . # The extension is already found. Any number of sources could be listed here. set(INCLUDE_DIRECTORIES ${ROOT_INCLUDE_DIR} -${BASE_INCLUDE_DIRECTORIES} -#put here all directories where header files are located +${BASE_INCLUDE_DIRECTORIES} + ${CMAKE_SOURCE_DIR}/AliData +${CMAKE_SOURCE_DIR}/AliBase ${CMAKE_SOURCE_DIR}/its - ) include_directories( ${INCLUDE_DIRECTORIES}) @@ -23,22 +16,28 @@ include_directories( ${INCLUDE_DIRECTORIES}) set(LINK_DIRECTORIES ${ROOT_LIBRARY_DIR} ${FAIRROOT_LIBRARY_DIR} - -) +) link_directories( ${LINK_DIRECTORIES}) set(SRCS -#Put here your sourcefiles -AliIts.cxx -AliItsContFact.cxx -AliItsGeo.cxx -AliItsGeoPar.cxx -AliItsPoint.cxx +AliITSUGeomTGeo.cxx +AliITSv11Geometry.cxx +AliITSUv1Layer.cxx +AliITSsegmentation.cxx +AliITSUSegmentationPix.cxx +AliGeomManager.cxx +O2its.cxx +O2itsContFact.cxx +O2itsGeoHandler.cxx +O2itsMisalignPar.cxx +O2itsPoint.cxx +O2itsDigi.cxx +O2itsDigiTask.cxx ) -Set(LINKDEF AliItsLinkDef.h) -Set(LIBRARY_NAME AliIts) +Set(LINKDEF O2itsLinkDef.h) +Set(LIBRARY_NAME its) Set(DEPENDENCIES Base ) diff --git a/its/O2its.cxx b/its/O2its.cxx new file mode 100644 index 0000000000000..51cbc290008c2 --- /dev/null +++ b/its/O2its.cxx @@ -0,0 +1,968 @@ +#include "O2its.h" + +#include "AliDetectorList.h" +#include "O2itsPoint.h" +#include "AliStack.h" + +#include "FairVolume.h" +#include "FairGeoVolume.h" +#include "FairGeoNode.h" +#include "FairRootManager.h" +#include "FairGeoLoader.h" +#include "FairGeoInterface.h" +#include "FairRun.h" +#include "FairRuntimeDb.h" + +#include "AliITSUv1Layer.h" +#include "AliITSUGeomTGeo.h" + +#include "TClonesArray.h" +#include "TGeoManager.h" +#include "TGeoTube.h" +#include "TGeoVolume.h" +#include "TVirtualMC.h" + +#include +#include + +using std::cout; +using std::endl; + +O2its::O2its() + : O2Detector("O2its", kTRUE, kAliIts), + fIdSens(0), + fTrackID(-1), + fVolumeID(-1), + fStartPos(), + fPos(), + fMom(), + fStartTime(-1.), + fTime(-1.), + fLength(-1.), + fELoss(-1), + fShunt(), + fO2itsPointCollection(new TClonesArray("O2itsPoint")), + fGeoHandler(new O2itsGeoHandler()), + fMisalignPar(NULL), + fNrOfDetectors(-1), + fShiftX(), + fShiftY(), + fShiftZ(), + fRotX(), + fRotY(), + fRotZ(), + fModifyGeometry(kFALSE), + fNWrapVol(0), + fWrapRMin(0), + fWrapRMax(0), + fWrapZSpan(0), + fLay2WrapV(0), + fLayTurbo(0), + fLayPhi0(0), + fLayRadii(0), + fLayZLength(0), + fStavPerLay(0), + fUnitPerStave(0), + fStaveThick(0), + fStaveWidth(0), + fStaveTilt(0), + fDetThick(0), + fChipTypeID(0), + fBuildLevel(0), + fUpGeom(0), + fStaveModelIB(kIBModel0), + fStaveModelOB(kOBModel0) +{ +} + +O2its::O2its(const char* name, Bool_t active, const Int_t nlay) + : O2Detector(name, active, kAliIts), + fIdSens(0), + fTrackID(-1), + fVolumeID(-1), + fStartPos(), + fPos(), + fMom(), + fStartTime(-1.), + fTime(-1.), + fLength(-1.), + fELoss(-1), + fShunt(), + fO2itsPointCollection(new TClonesArray("O2itsPoint")), + fGeoHandler(new O2itsGeoHandler()), + fMisalignPar(NULL), + fNrOfDetectors(-1), + fShiftX(), + fShiftY(), + fShiftZ(), + fRotX(), + fRotY(), + fRotZ(), + fModifyGeometry(kFALSE), + fNWrapVol(0), + fWrapRMin(0), + fWrapRMax(0), + fWrapZSpan(0), + fLay2WrapV(0), + fLayTurbo(0), + fLayPhi0(0), + fLayRadii(0), + fLayZLength(0), + fStavPerLay(0), + fUnitPerStave(0), + fStaveThick(0), + fStaveWidth(0), + fStaveTilt(0), + fDetThick(0), + fChipTypeID(0), + fBuildLevel(0), + fUpGeom(0), + fNLayers(nlay), + fStaveModelIB(kIBModel0), + fStaveModelOB(kOBModel0) +{ + fLayerName = new TString[fNLayers]; + + for (Int_t j=0; j 0) { // if not, we'll Fatal-ize in CreateGeometry + for (Int_t j=0; jDelete(); + delete fO2itsPointCollection; + } + + delete[] fIdSens; +} + +O2its& O2its::operator=(const O2its &h){ + // The standard = operator + // Inputs: + // O2its &h the sourse of this copy + // Outputs: + // none. + // Return: + // A copy of the sourse hit h + + if(this == &h) return *this; + this->fStatus = h.fStatus; + this->fModule = h.fModule; + this->fPx = h.fPx; + this->fPy = h.fPy; + this->fPz = h.fPz; + this->fDestep = h.fDestep; + this->fTof = h.fTof; + this->fStatus0 = h.fStatus0; + this->fx0 = h.fx0; + this->fy0 = h.fy0; + this->fz0 = h.fz0; + this->ft0 = h.ft0; + return *this; +} + +void O2its::Initialize() +{ + if (!fIdSens) { + fIdSens = new Int_t[fNLayers]; + } + + for (int i=0;iVolId(fLayerName[i]) : 0; + } + + fGeomTGeo = new AliITSUGeomTGeo(kTRUE); + + FairDetector::Initialize(); + +// FairRuntimeDb* rtdb= FairRun::Instance()->GetRuntimeDb(); +// O2itsGeoPar* par=(O2itsGeoPar*)(rtdb->getContainer("O2itsGeoPar")); +} + +void O2its::InitParContainers() +{ + LOG(INFO)<< "Initialize aliitsdet missallign parameters"<GetNrOfDetectors(); + fShiftX=fMisalignPar->GetShiftX(); + fShiftY=fMisalignPar->GetShiftY(); + fShiftZ=fMisalignPar->GetShiftZ(); + fRotX=fMisalignPar->GetRotX(); + fRotY=fMisalignPar->GetRotY(); + fRotZ=fMisalignPar->GetRotZ(); +} + +void O2its::SetParContainers() +{ + LOG(INFO)<< "Set tutdet missallign parameters"<GetRuntimeDb(); + LOG_IF(FATAL, !rtdb) << "No runtime database"<getContainer("O2itsMissallignPar")); + +} + +Bool_t O2its::ProcessHits(FairVolume* vol) +{ + /** This method is called from the MC stepping */ + + if(!(gMC->TrackCharge())) { + return kFALSE; + } + + //FIXME: Is copy actually needed? + Int_t copy = vol->getCopyNo(); + Int_t id = vol->getMCid(); + Int_t lay = 0; + Int_t cpn0, cpn1, mod; + + //FIXME: Determine the layer number. Is this information available directly from the FairVolume? + while ((layIsTrackExiting()) { + AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kITS); + } // if Outer ITS mother Volume */ + + // Retrieve the indices with the volume path + copy = 1; + gMC->CurrentVolOffID(1, cpn1); + gMC->CurrentVolOffID(2, cpn0); + + mod = fGeomTGeo->GetChipIndex(lay, cpn0, cpn1); + + // Record information on the points + fELoss = gMC->Edep(); + fTime = gMC->TrackTime(); + fTrackID = gMC->GetStack()->GetCurrentTrackNumber(); + fVolumeID = vol->getMCid(); + + //FIXME: Set a temporary value to fShunt for now, determine its use at a later stage + fShunt = 0; + + gMC->TrackPosition(fPos); + gMC->TrackMomentum(fMom); + + //fLength = gMC->TrackLength(); + + if(gMC->IsTrackEntering()){ + fStartPos = fPos; + fStartTime = fTime; + return kFALSE; // don't save entering hit. + } + + // Create O2itsPoint on every step of the active volume + AddHit(fTrackID, fVolumeID, TVector3(fStartPos.X(), fStartPos.Y(), fStartPos.Z()), + TVector3(fPos.X(), fPos.Y(), fPos.Z()), TVector3(fMom.Px(), fMom.Py(), fMom.Pz()), + fStartTime, fTime, fLength, fELoss, fShunt); + + // Increment number of O2its det points in TParticle + AliStack* stack = (AliStack*) gMC->GetStack(); + stack->AddPoint(kAliIts); + + // Save old position for the next hit. + fStartPos = fPos; + fStartTime = fTime; + + return kTRUE; +} + +void O2its::CreateMaterials() +{ + //Int_t ifield = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ(); + //Float_t fieldm = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max(); + //FIXME: values taken from the AliMagF constructor. These must (?) be provided by the run_sim macro instead + Int_t ifield = 2; + Float_t fieldm = 10.; + + Float_t tmaxfd = 0.1; // 1.0; // Degree + Float_t stemax = 1.0; // cm + Float_t deemax = 0.1; // 30.0; // Fraction of particle's energy 0Clear(); +} + +void O2its::Register() +{ + /** This will create a branch in the output tree called + O2itsPoint, setting the last parameter to kFALSE means: + this collection will not be written to the file, it will exist + only during the simulation. + */ + + FairRootManager::Instance()->Register("O2itsPoint", "O2its", + fO2itsPointCollection, kTRUE); +} + +TClonesArray* O2its::GetCollection(Int_t iColl) const +{ + if (iColl == 0) { return fO2itsPointCollection; } + else { return NULL; } +} + +void O2its::Reset() +{ + fO2itsPointCollection->Clear(); +} + +void O2its::SetNWrapVolumes(Int_t n) +{ + // book arrays for wrapper volumes + if (fNWrapVol) { + LOG(FATAL) << fNWrapVol << " wrapper volumes already defined" << FairLogger::endl; + } + + if (n<1) { + return; + } + + fNWrapVol = n; + fWrapRMin = new Double_t[fNWrapVol]; + fWrapRMax = new Double_t[fNWrapVol]; + fWrapZSpan= new Double_t[fNWrapVol]; + + for (int i=fNWrapVol;i--;) { + fWrapRMin[i]=fWrapRMax[i]=fWrapZSpan[i]=-1; + } +} + +void O2its::DefineWrapVolume(Int_t id, Double_t rmin,Double_t rmax, Double_t zspan) +{ + // set parameters of id-th wrapper volume + if (id>=fNWrapVol||id<0) { + LOG(FATAL)<<"id "<= fNLayers || nlay < 0) { + LOG(ERROR) << "Wrong layer number " << nlay << FairLogger::endl; + return; + } + + fLayTurbo[nlay] = kFALSE; + fLayPhi0[nlay] = phi0; + fLayRadii[nlay] = r; + fLayZLength[nlay] = zlen; + fStavPerLay[nlay] = nstav; + fUnitPerStave[nlay] = nunit; + fStaveThick[nlay] = lthick; + fDetThick[nlay] = dthick; + fChipTypeID[nlay] = dettypeID; + fBuildLevel[nlay] = buildLevel; +} + +void O2its::DefineLayerTurbo(Int_t nlay, Double_t phi0, Double_t r, Double_t zlen, Int_t nstav, + Int_t nunit, Double_t width, Double_t tilt, + Double_t lthick,Double_t dthick, + UInt_t dettypeID, Int_t buildLevel) +{ + // Sets the layer parameters for a "turbo" layer + // (i.e. a layer whose staves overlap in phi) + // Inputs: + // nlay layer number + // phi0 phi of 1st stave + // r layer radius + // zlen layer length + // nstav number of staves + // nunit IB: number of chips per stave + // OB: number of modules per half stave + // width stave width + // tilt layer tilt angle (degrees) + // lthick stave thickness (if omitted, defaults to 0) + // dthick detector thickness (if omitted, defaults to 0) + // dettypeID ?? + // buildLevel (if 0, all geometry is build, used for material budget studies) + // Outputs: + // none. + // Return: + // none. + + LOG(INFO) << "L# " << nlay << " Phi:" << phi0 << " R:" << r << " DZ:" << zlen << " Nst:" + << nstav << " Nunit:" << nunit << " W:" << width << " Tilt:" << tilt << " Lthick:" + << lthick << " Dthick:" << dthick << " DetID:" << dettypeID << " B:" << buildLevel + << FairLogger::endl; + + if (nlay >= fNLayers || nlay < 0) { + LOG(ERROR) << "Wrong layer number " << nlay << FairLogger::endl; + return; + } + + fLayTurbo[nlay] = kTRUE; + fLayPhi0[nlay] = phi0; + fLayRadii[nlay] = r; + fLayZLength[nlay] = zlen; + fStavPerLay[nlay] = nstav; + fUnitPerStave[nlay] = nunit; + fStaveThick[nlay] = lthick; + fStaveWidth[nlay] = width; + fStaveTilt[nlay] = tilt; + fDetThick[nlay] = dthick; + fChipTypeID[nlay] = dettypeID; + fBuildLevel[nlay] = buildLevel; +} + +void O2its::GetLayerParameters(Int_t nlay, Double_t &phi0, + Double_t &r, Double_t &zlen, + Int_t &nstav, Int_t &nmod, + Double_t &width, Double_t &tilt, + Double_t <hick, Double_t &dthick, + UInt_t &dettype) const +{ + // Gets the layer parameters + // Inputs: + // nlay layer number + // Outputs: + // phi0 phi of 1st stave + // r layer radius + // zlen layer length + // nstav number of staves + // nmod IB: number of chips per stave + // OB: number of modules per half stave + // width stave width + // tilt stave tilt angle + // lthick stave thickness + // dthick detector thickness + // dettype detector type + // Return: + // none. + + if (nlay >= fNLayers || nlay < 0) { + LOG(ERROR) << "Wrong layer number " << nlay << FairLogger::endl; + return; + } + + phi0 = fLayPhi0[nlay]; + r = fLayRadii[nlay]; + zlen = fLayZLength[nlay]; + nstav = fStavPerLay[nlay]; + nmod = fUnitPerStave[nlay]; + width = fStaveWidth[nlay]; + tilt = fStaveTilt[nlay]; + lthick = fStaveThick[nlay]; + dthick = fDetThick[nlay]; + dettype= fChipTypeID[nlay]; +} + +TGeoVolume* O2its::CreateWrapperVolume(Int_t id) +{ + // Creates an air-filled wrapper cylindrical volume + + if (fWrapRMin[id]<0 || fWrapRMax[id]<0 || fWrapZSpan[id]<0) { + LOG(FATAL) << "Wrapper volume " << id << " was requested but not defined" << FairLogger::endl; + } + + // Now create the actual shape and volume + TGeoTube *tube = new TGeoTube(fWrapRMin[id], fWrapRMax[id], fWrapZSpan[id]/2.); + + TGeoMedium *medAir = gGeoManager->GetMedium("ITS_AIR$"); + + char volnam[30]; + snprintf(volnam, 29, "%s%d", AliITSUGeomTGeo::GetITSWrapVolPattern(),id); + + TGeoVolume *wrapper = new TGeoVolume(volnam, tube, medAir); + + return wrapper; +} + +void O2its::ConstructGeometry() +{ + // Create the detector materials + CreateMaterials(); + + // Construct the detector geometry + ConstructDetectorGeometry(); + + // Define the list of sensitive volumes + DefineSensitiveVolumes(); +} + +void O2its::ConstructDetectorGeometry() +{ + // Create the geometry and insert it in the mother volume ITSV + TGeoManager *geoManager = gGeoManager; + + TGeoVolume *vALIC = geoManager->GetVolume("cave"); + + if (!vALIC) { + LOG(FATAL) << "Could not find the top volume" << FairLogger::endl; + } + + new TGeoVolumeAssembly(AliITSUGeomTGeo::GetITSVolPattern()); + TGeoVolume *vITSV = geoManager->GetVolume(AliITSUGeomTGeo::GetITSVolPattern()); + vITSV->SetUniqueID(AliITSUGeomTGeo::GetUIDShift()); // store modID -> midUUID bitshift + vALIC->AddNode(vITSV, 2, 0); // Copy number is 2 to cheat AliGeoManager::CheckSymNamesLUT + + const Int_t kLength=100; + Char_t vstrng[kLength] = "xxxRS"; //? + vITSV->SetTitle(vstrng); + + // Check that we have all needed parameters + if (fNLayers <= 0) { + LOG(FATAL) << "Wrong number of layers (" << fNLayers << ")" << FairLogger::endl; + } + + for (Int_t j=0; j 0) { + if (fLayRadii[j]<=fLayRadii[j-1]) { + LOG(FATAL) << "Layer " << j << " radius (" << fLayRadii[j] << ") is smaller than layer " + << j-1 << " radius (" << fLayRadii[j-1] << ")" << FairLogger::endl; + } + } + + if (fStaveThick[j] == 0) { + LOG(INFO) << "Stave thickness for layer " << j << " not set, using default" + << FairLogger::endl; + } + if (fDetThick[j] == 0) { + LOG(INFO) << "Chip thickness for layer " << j << " not set, using default" + << FairLogger::endl; + } + } + + // Create the wrapper volumes + TGeoVolume **wrapVols = 0; + + if (fNWrapVol) { + wrapVols = new TGeoVolume*[fNWrapVol]; + for (int id=0;idAddNode(wrapVols[id], 1, 0); + } + } + + fLay2WrapV = new Int_t[fNLayers]; + + // Now create the actual geometry + for (Int_t j=0; jSetStaveWidth(fStaveWidth[j]); + fUpGeom[j]->SetStaveTilt(fStaveTilt[j]); + } else { + fUpGeom[j] = new AliITSUv1Layer(j,kFALSE); + } + + fUpGeom[j]->SetPhi0(fLayPhi0[j]); + fUpGeom[j]->SetRadius(fLayRadii[j]); + fUpGeom[j]->SetZLength(fLayZLength[j]); + fUpGeom[j]->SetNStaves(fStavPerLay[j]); + fUpGeom[j]->SetNUnits(fUnitPerStave[j]); + fUpGeom[j]->SetChipType(fChipTypeID[j]); + fUpGeom[j]->SetBuildLevel(fBuildLevel[j]); + + if (j < 3) { + fUpGeom[j]->SetStaveModel(fStaveModelIB); + } else { + fUpGeom[j]->SetStaveModel(fStaveModelOB); + } + + LOG(DEBUG1) << "fBuildLevel: " << fBuildLevel[j] << FairLogger::endl; + + if (fStaveThick[j] != 0) { + fUpGeom[j]->SetStaveThick(fStaveThick[j]); + } + if (fDetThick[j] != 0) { + fUpGeom[j]->SetSensorThick(fDetThick[j]); + } + + for (int iw=0;iwfWrapRMin[iw] && fLayRadii[j]=fWrapZSpan[iw]) { + LOG(FATAL) << "ZSpan " << fWrapZSpan[iw] << " of wrapper volume " << iw + << " is less than ZSpan " << fLayZLength[j] << " of layer " << j << FairLogger::endl; + } + + dest = wrapVols[iw]; + fLay2WrapV[j] = iw; + break; + } + } + fUpGeom[j]->CreateLayer(dest); + } + CreateSuppCyl(kTRUE,wrapVols[0]); + CreateSuppCyl(kFALSE,wrapVols[2]); + + delete[] wrapVols; // delete pointer only, not the volumes +} + +//Service Barrel +void O2its::CreateSuppCyl(const Bool_t innerBarrel,TGeoVolume *dest,const TGeoManager *mgr){ + // Creates the Service Barrel (as a simple cylinder) for IB and OB + // Inputs: + // innerBarrel : if true, build IB service barrel, otherwise for OB + // dest : the mother volume holding the service barrel + // mgr : the gGeoManager pointer (used to get the material) + // + + Double_t rminIB = 4.7; + Double_t rminOB = 43.4; + Double_t zLenOB ; + Double_t cInt = 0.22; //dimensioni cilindro di supporto interno + Double_t cExt = 1.00; //dimensioni cilindro di supporto esterno +// Double_t phi1 = 180; +// Double_t phi2 = 360; + + + TGeoMedium *medCarbonFleece = mgr->GetMedium("ITS_CarbonFleece$"); + + if (innerBarrel){ + zLenOB=((TGeoTube*)(dest->GetShape()))->GetDz(); +// TGeoTube*ibSuppSh = new TGeoTubeSeg(rminIB,rminIB+cInt,zLenOB,phi1,phi2); + TGeoTube*ibSuppSh = new TGeoTube(rminIB,rminIB+cInt,zLenOB); + TGeoVolume *ibSupp = new TGeoVolume("ibSuppCyl",ibSuppSh,medCarbonFleece); + dest->AddNode(ibSupp,1); + } + else { + zLenOB=((TGeoTube*)(dest->GetShape()))->GetDz(); + TGeoTube*obSuppSh=new TGeoTube(rminOB,rminOB+cExt,zLenOB); + TGeoVolume *obSupp=new TGeoVolume("obSuppCyl",obSuppSh,medCarbonFleece); + dest->AddNode(obSupp,1); + } + + return; +} + +void O2its::DefineSensitiveVolumes() +{ + TGeoManager *geoManager = gGeoManager; + TGeoVolume *v; + + TString volumeName; + + // The names of the ITS sensitive volumes have the format: ITSUSensor(0...fNLayers-1) + for (Int_t j=0; jGetVolume(volumeName.Data()); + AddSensitiveVolume(v); + } +} + +O2itsPoint* O2its::AddHit(Int_t trackID, Int_t detID, TVector3 startPos, TVector3 pos, TVector3 mom, + Double_t startTime, Double_t time, Double_t length, Double_t eLoss, + Int_t shunt) +{ + TClonesArray& clref = *fO2itsPointCollection; + Int_t size = clref.GetEntriesFast(); + return new(clref[size]) O2itsPoint(trackID, detID, startPos, pos, mom, + startTime, time, length, eLoss, shunt); +} + +TParticle* O2its::GetParticle() const +{ + // Returns the pointer to the TParticle for the particle that created + // this hit. From the TParticle all kinds of information about this + // particle can be found. See the TParticle class. + // Inputs: + // none. + // Outputs: + // none. + // Return: + // The TParticle of the track that created this hit. + + return ((AliStack*) gMC->GetStack())->GetParticle(GetTrack()); +} + +void O2its::Print(ostream *os) const +{ + // Standard output format for this class. + // Inputs: + // ostream *os The output stream + // Outputs: + // none. + // Return: + // none. + +#if defined __GNUC__ +#if __GNUC__ > 2 + ios::fmtflags fmt; +#else + Int_t fmt; +#endif +#else +#if defined __ICC || defined __ECC || defined __xlC__ + ios::fmtflags fmt; +#else + Int_t fmt; +#endif +#endif + + fmt = os->setf(ios::scientific); // set scientific floating point output + *os << fTrack << " " << fX << " " << fY << " " << fZ << " "; + fmt = os->setf(ios::hex); // set hex for fStatus only. + *os << fStatus << " "; + fmt = os->setf(ios::dec); // every thing else decimel. + *os << fModule << " "; + *os << fPx << " " << fPy << " " << fPz << " "; + *os << fDestep << " " << fTof; + *os << " " << fx0 << " " << fy0 << " " << fz0; +// *os << " " << endl; + os->flags(fmt); // reset back to old formating. + return; +} + +void O2its::Read(istream *is) +{ + // Standard input format for this class. + // Inputs: + // istream *is the input stream + // Outputs: + // none. + // Return: + // none. + + *is >> fTrack >> fX >> fY >> fZ; + *is >> fStatus >> fModule >> fPx >> fPy >> fPz >> fDestep >> fTof; + *is >> fx0 >> fy0 >> fz0; + return; +} + +ostream &operator<<(ostream &os, O2its &p) +{ + // Standard output streaming function. + // Inputs: + // ostream os The output stream + // O2its p The his to be printed out + // Outputs: + // none. + // Return: + // The input stream + + p.Print(&os); + return os; +} + +istream &operator>>(istream &is, O2its &r) +{ + // Standard input streaming function. + // Inputs: + // istream is The input stream + // O2its p The O2its class to be filled from this input stream + // Outputs: + // none. + // Return: + // The input stream + + r.Read(&is); + return is; +} + +ClassImp(O2its) diff --git a/its/O2its.h b/its/O2its.h new file mode 100644 index 0000000000000..175749ebc1933 --- /dev/null +++ b/its/O2its.h @@ -0,0 +1,237 @@ +#ifndef O2ITS_H +#define O2ITS_H + +#include "TParticle.h" +#include "TVector3.h" +#include "TLorentzVector.h" + +#include "O2Detector.h" +#include "O2itsGeoHandler.h" +#include "O2itsMisalignPar.h" + +#include "AliITSUGeomTGeo.h" + +class O2itsPoint; +class FairVolume; +class TClonesArray; +class AliITSUv1Layer; + +class O2its: public O2Detector +{ + + public: + + typedef enum { + kIBModelDummy=0, + kIBModel0=1, + kIBModel1=2, + kIBModel21=3, + kIBModel22=4, + kIBModel3=5, + kOBModelDummy=6, + kOBModel0=7, + kOBModel1=8 + } AliITSUModel_t; + + /** Name : Detector Name + * Active: kTRUE for active detectors (ProcessHits() will be called) + * kFALSE for inactive detectors + */ + O2its(const char* Name, Bool_t Active, const Int_t nlay); + + /** default constructor */ + O2its(); + + /** destructor */ + virtual ~O2its(); + + /** Initialization of the detector is done here */ + virtual void Initialize(); + + /** this method is called for each step during simulation + * (see FairMCApplication::Stepping()) + */ + virtual Bool_t ProcessHits( FairVolume* v=0); + + /** Registers the produced collections in FAIRRootManager. */ + virtual void Register(); + + /** Gets the produced collections */ + virtual TClonesArray* GetCollection(Int_t iColl) const ; + + /** has to be called after each event to reset the containers */ + virtual void Reset(); + + /** Base class to create the detector geometry */ + void ConstructGeometry(); + + void CreateSuppCyl(const Bool_t innerBarrel,TGeoVolume *dest,const TGeoManager *mgr=gGeoManager); + + /** Initialize the parameter containers */ + virtual void InitParContainers(); + + void SetParContainers(); + + virtual void DefineLayer(Int_t nlay,Double_t phi0,Double_t r,Double_t zlen,Int_t nladd, + Int_t nmod, Double_t lthick=0.,Double_t dthick=0.,UInt_t detType=0, Int_t buildFlag=0); + virtual void DefineLayerTurbo(Int_t nlay,Double_t phi0,Double_t r,Double_t zlen,Int_t nladd, + Int_t nmod,Double_t width,Double_t tilt, + Double_t lthick = 0.,Double_t dthick = 0.,UInt_t detType=0, Int_t buildFlag=0); + virtual void GetLayerParameters(Int_t nlay, Double_t &phi0,Double_t &r, Double_t &zlen, + Int_t &nladd, Int_t &nmod, + Double_t &width, Double_t &tilt, + Double_t <hick, Double_t &mthick, + UInt_t &dettype) const; + + /** This method is an example of how to add your own point + * of type O2itsPoint to the clones array + */ + O2itsPoint* AddHit(Int_t trackID, Int_t detID, TVector3 startPos, TVector3 pos, TVector3 mom, + Double_t startTime, Double_t time, Double_t length, Double_t eLoss, + Int_t shunt); + + /** Book arrays for wrapper volumes */ + virtual void SetNWrapVolumes(Int_t n); + + /** Set per wrapper volume parameters */ + virtual void DefineWrapVolume(Int_t id, Double_t rmin,Double_t rmax, Double_t zspan); + + /** The following methods can be implemented if you need to make + * any optional action in your detector during the transport. + */ + + virtual void CopyClones( TClonesArray* cl1, TClonesArray* cl2 , + Int_t offset) {;} + virtual void SetSpecialPhysicsCuts() {;} + virtual void EndOfEvent(); + virtual void FinishPrimary() {;} + virtual void FinishRun() {;} + virtual void BeginPrimary() {;} + virtual void PostTrack() {;} + virtual void PreTrack() {;} + virtual void BeginEvent() {;} + + /** Returns a ptr to this particle. */ + virtual TParticle * GetParticle() const; + + /** SetTrack and GetTrack methods From AliHit.h */ + virtual void SetTrack(Int_t track) {fTrack=track;} + virtual Int_t GetTrack() const {return fTrack;} + + /** Prints out the content of this class in ASCII format */ + void Print(ostream *os) const; + + /** Reads in the content of this class in the format of Print */ + void Read(istream *is); + + /** Returns the number of layers */ + Int_t GetNLayers() const {return fNLayers;} + + virtual void SetStaveModelIB(AliITSUModel_t model) {fStaveModelIB=model;} + virtual void SetStaveModelOB(AliITSUModel_t model) {fStaveModelOB=model;} + virtual AliITSUModel_t GetStaveModelIB() const {return fStaveModelIB;} + virtual AliITSUModel_t GetStaveModelOB() const {return fStaveModelOB;} + + AliITSUGeomTGeo* fGeomTGeo; //! access to geometry details + + protected: + + Int_t *fIdSens; //! [fNLayers] layer identifier + Int_t fNLayers; //! Number of layers + Int_t fStatus; //! Track Status + Int_t fModule; //! Module number + Float_t fPx; //! PX of particle at the point of the hit + Float_t fPy; //! PY of particle at the point of the hit + Float_t fPz; //! PZ of particle at the point of the hit + Float_t fDestep; //! Energy deposited in the current step + Float_t fTof; //! Time of flight at the point of the hit + Int_t fStatus0; //! Track Status of Starting point + Float_t fx0; //! Starting point of this step + Float_t fy0; //! Starting point of this step + Float_t fz0; //! Starting point of this step + Float_t ft0; //! Starting point of this step + + Int_t fTrack; //! Track number + Float_t fX; //! X position of the hit + Float_t fY; //! Y position of the hit + Float_t fZ; //! Z position of the hit + + TString *fLayerName; //![fNLayers] layer identifier + + private: + + /** Track information to be stored until the track leaves the + active volume. + */ + Int_t fTrackID; //! track index + Int_t fVolumeID; //! volume id + Int_t fShunt; //! shunt + TLorentzVector fPos; //! position + TLorentzVector fStartPos; //! position at entrance + TLorentzVector fMom; //! momentum + Double32_t fStartTime; //! time at entrance + Double32_t fTime; //! time + Double32_t fLength; //! length + Double32_t fELoss; //! energy loss + + Int_t fNrOfDetectors; + TArrayD fShiftX; + TArrayD fShiftY; + TArrayD fShiftZ; + TArrayD fRotX; + TArrayD fRotY; + TArrayD fRotZ; + + Bool_t fModifyGeometry; + + Int_t fNWrapVol; // number of wrapper volumes + Double_t* fWrapRMin; // min radius of wrapper volume + Double_t* fWrapRMax; // max radius of wrapper volume + Double_t* fWrapZSpan; // Z span of wrapper volume + Int_t* fLay2WrapV; // id of wrapper layer to which layer belongs (-1 if not wrapped) + Bool_t *fLayTurbo; // True for "turbo" layers + Double_t *fLayPhi0; // Vector of layer's 1st stave phi in lab + Double_t *fLayRadii; // Vector of layer radii + Double_t *fLayZLength; // Vector of layer length along Z + Int_t *fStavPerLay; // Vector of number of staves per layer + Int_t *fUnitPerStave; // Vector of number of "units" per stave + Double_t *fStaveThick; // Vector of stave thicknesses + Double_t *fStaveWidth; // Vector of stave width (only used for turbo) + Double_t *fStaveTilt; // Vector of stave tilt (only used for turbo) + Double_t *fDetThick; // Vector of detector thicknesses + UInt_t *fChipTypeID; // Vector of detector type id + Int_t *fBuildLevel; // Vector of Material Budget Studies + + /** Container for data points */ + TClonesArray* fO2itsPointCollection; + + /** Creates an air-filled wrapper cylindrical volume */ + TGeoVolume* CreateWrapperVolume(const Int_t nLay); + + /** Create the detector materials */ + virtual void CreateMaterials(); + + /** Construct the detector geometry */ + void ConstructDetectorGeometry(); + + /** Define the sensitive volumes of the geometry */ + void DefineSensitiveVolumes(); + + O2its(const O2its&); + O2its& operator=(const O2its&); + + O2itsGeoHandler* fGeoHandler; + O2itsMisalignPar* fMisalignPar; + + AliITSUv1Layer **fUpGeom; //! Geometry + AliITSUModel_t fStaveModelIB; //! The stave model for the Inner Barrel + AliITSUModel_t fStaveModelOB; //! The stave model for the Outer Barrel + + ClassDef(O2its,1) +}; + +// Input and output function for standard C++ input/output. +ostream& operator<<(ostream &os, O2its &source); +istream& operator>>(istream &os, O2its &source); + +#endif diff --git a/its/O2itsContFact.cxx b/its/O2itsContFact.cxx new file mode 100644 index 0000000000000..48024690f2a88 --- /dev/null +++ b/its/O2itsContFact.cxx @@ -0,0 +1,51 @@ +#include "O2itsContFact.h" +#include "FairRuntimeDb.h" + +#include + +ClassImp(O2itsContFact) + +static O2itsContFact gO2itsContFact; + +O2itsContFact::O2itsContFact() + : FairContFact() +{ + /** Constructor (called when the library is loaded) */ + fName="O2itsContFact"; + fTitle="Factory for parameter containers in libO2its"; + setAllContainers(); + FairRuntimeDb::instance()->addContFactory(this); +} + +void O2itsContFact::setAllContainers() +{ + /** Creates the Container objects with all accepted + contexts and adds them to + the list of containers for the O2its library. + */ +/* + FairContainer* p= new FairContainer("O2itsGeoPar", + "O2its Geometry Parameters", + "TestDefaultContext"); + p->addContext("TestNonDefaultContext"); + + containers->Add(p); +*/ + } + +FairParSet* O2itsContFact::createContainer(FairContainer* c) +{ + /** Calls the constructor of the corresponding parameter container. + For an actual context, which is not an empty string and not + the default context + of this container, the name is concatinated with the context. + */ + /* const char* name=c->GetName(); + FairParSet* p=NULL; + if (strcmp(name,"O2itsGeoPar")==0) { + p=new O2itsGeoPar(c->getConcatName().Data(), + c->GetTitle(),c->getContext()); + } + return p; +*/ + } diff --git a/its/O2itsContFact.h b/its/O2itsContFact.h new file mode 100644 index 0000000000000..a500d0305a316 --- /dev/null +++ b/its/O2itsContFact.h @@ -0,0 +1,19 @@ +#ifndef O2ITSCONTFACT_H +#define O2ITSCONTFACT_H + +#include "FairContFact.h" + +class FairContainer; + +class O2itsContFact : public FairContFact +{ + private: + void setAllContainers(); + public: + O2itsContFact(); + ~O2itsContFact() {} + FairParSet* createContainer(FairContainer*); + ClassDef( O2itsContFact,0) // Factory for all O2its parameter containers +}; + +#endif diff --git a/its/O2itsDigi.cxx b/its/O2itsDigi.cxx new file mode 100644 index 0000000000000..54e4cca343fa5 --- /dev/null +++ b/its/O2itsDigi.cxx @@ -0,0 +1,28 @@ +/* + * O2itsDigi.cxx + * + * Created on: 20.07.2012 + * Author: stockman + */ + +#include "O2itsDigi.h" + +ClassImp(O2itsDigi); + +O2itsDigi::O2itsDigi(): + FairTimeStamp(), fX(0), fY(0), fZ(0) +{ +} + + +O2itsDigi::O2itsDigi(Int_t x, Int_t y, Int_t z, Double_t timeStamp): + FairTimeStamp(timeStamp), fX(x), fY(y), fZ(z) +{ +} + +O2itsDigi::~O2itsDigi() +{ +} + + + diff --git a/its/O2itsDigi.h b/its/O2itsDigi.h new file mode 100644 index 0000000000000..a61fa99bd2bff --- /dev/null +++ b/its/O2itsDigi.h @@ -0,0 +1,73 @@ +/* + * O2itsDigi.h + * + * Created on: 20.07.2012 + * Author: stockman + */ + +#ifndef O2ITSDIGI_H_ +#define O2ITSDIGI_H_ + +#include "FairTimeStamp.h" // for FairTimeStamp + +#include "Riosfwd.h" // for ostream +#include "Rtypes.h" // for Int_t, etc + +#include // for operator<<, basic_ostream, etc + +class O2itsDigi : public FairTimeStamp +{ + public: + O2itsDigi(); + O2itsDigi(Int_t x, Int_t y, Int_t z, Double_t timeStamp); + virtual ~O2itsDigi(); + + void SetXYZ(Int_t x, Int_t y, Int_t z) { SetX(x); SetY(y); SetZ(z);} + void SetX(Int_t x) { fX=x; } + void SetY(Int_t y) { fY=y; } + void SetZ(Int_t z) { fZ=z; } + + Int_t GetX() const {return fX;} + Int_t GetY() const {return fY;} + Int_t GetZ() const {return fZ;} + + virtual bool equal(FairTimeStamp* data) { + O2itsDigi* myDigi = dynamic_cast (data); + if (myDigi != 0) { + if (fX == myDigi->GetX()) + if (fY == myDigi->GetY()) + if (fZ == myDigi->GetZ()) { + return true; + } + } + return false; + } + + virtual bool operator<(const O2itsDigi& myDigi) const { + if (fX < myDigi.GetX()) { return true; } + else if (fX > myDigi.GetX()) { return false; } + if (fY < myDigi.GetY()) { return true; } + else if (fY > myDigi.GetY()) { return false; } + if (fZ < myDigi.GetZ()) { return true; } + else if (fZ > myDigi.GetZ()) { return false; } + return false; + } + + friend std::ostream& operator<<(std::ostream& out, O2itsDigi& digi) { + out << "O2itsDigi at:" + << " (" << digi.GetX() << "/" << digi.GetY() << "/" << digi.GetZ() << ") " + << " with TimeStamp: " << digi.GetTimeStamp() + << std::endl; + return out; + } + + private: + Int_t fX; + Int_t fY; + Int_t fZ; + + + ClassDef(O2itsDigi,1); +}; + +#endif diff --git a/its/O2itsDigiTask.cxx b/its/O2itsDigiTask.cxx new file mode 100644 index 0000000000000..8826a551f67b2 --- /dev/null +++ b/its/O2itsDigiTask.cxx @@ -0,0 +1,99 @@ +#include "O2itsDigiTask.h" + +#include "FairLink.h" +#include "FairRootManager.h" + +#include "O2itsDigi.h" +#include "O2itsPoint.h" + +#include "Riosfwd.h" // for ostream +#include "TClonesArray.h" // for TClonesArray +#include "TMath.h" // for Sqrt +#include "TRandom.h" // for TRandom, gRandom + +#include // for NULL +#include // for operator<<, basic_ostream, etc + +O2itsDigiTask::O2itsDigiTask(): + FairTask("O2itsDigiTask"), + fTimeResolution(0.), + fPointArray(NULL), + fDigiArray(NULL) +{ +} + +O2itsDigiTask::~O2itsDigiTask() +{ +} + +InitStatus O2itsDigiTask::Init() +{ + FairRootManager* ioman = FairRootManager::Instance(); + if (!ioman) { + std::cout << "-E- O2itsDigiTask::Init: " ///todo replace with logger! + << "RootManager not instantiated!" << std::endl; + return kFATAL; + } + + fPointArray = (TClonesArray*) ioman->GetObject("O2itsPoint"); + if (!fPointArray) { + std::cout << "-W- O2itsDigiTask::Init: " + << "No Point array!" << std::endl; + return kERROR; + } + + // Create and register output array + fDigiArray = new TClonesArray("O2itsDigi"); + ioman->Register("O2itsDigi", "O2its", fDigiArray, kTRUE); + + return kSUCCESS; +} + +void O2itsDigiTask::Exec(Option_t* opt) +{ + + fDigiArray->Delete(); + + // fill the map + for(int ipnt = 0; ipnt < fPointArray->GetEntries(); ipnt++) { + O2itsPoint* point = (O2itsPoint*) fPointArray->At(ipnt); + if(!point) { continue; } + + Int_t xPad = CalcPad(point->GetX(), point->GetXOut()); + Int_t yPad = CalcPad(point->GetY(), point->GetYOut()); + Int_t zPad = CalcPad(point->GetZ(), point->GetZOut()); + + Double_t timestamp = CalcTimeStamp(point->GetTime()); + + O2itsDigi* digi = new ((*fDigiArray)[ipnt]) O2itsDigi(xPad, yPad, zPad, timestamp); + if (fTimeResolution > 0) { + digi->SetTimeStampError(fTimeResolution/TMath::Sqrt(fTimeResolution)); + } else { + digi->SetTimeStampError(0); + } + + digi->SetLink(FairLink("O2itsPoint", ipnt)); + } +} + +Int_t O2itsDigiTask::CalcPad(Double_t posIn, Double_t posOut) +{ + Int_t result = (Int_t)(posIn + posOut)/2; + return result; +} + +Double_t O2itsDigiTask::CalcTimeStamp(Double_t timeOfFlight) +{ + Double_t eventTime = FairRootManager::Instance()->GetEventTime(); + Double_t detectionTime = gRandom->Gaus(0, fTimeResolution); + + Double_t result = eventTime + timeOfFlight + detectionTime; + + if (result < 0) { + return 0; + } else { + return result; + } +} + +ClassImp(O2itsDigiTask) diff --git a/its/O2itsDigiTask.h b/its/O2itsDigiTask.h new file mode 100644 index 0000000000000..5eb3743cbfed0 --- /dev/null +++ b/its/O2itsDigiTask.h @@ -0,0 +1,45 @@ +#ifndef O2ITSDIGITASK_H_ +#define O2ITSDIGITASK_H_ + +#include "FairTask.h" // for FairTask, InitStatus + +#include "Rtypes.h" // for Double_t, etc + +class TClonesArray; + +class O2itsDigiTask : public FairTask +{ + public: + + /** Default constructor **/ + O2itsDigiTask(); + + /** Destructor **/ + ~O2itsDigiTask(); + + /** Virtual method Init **/ + virtual InitStatus Init(); + + /** Virtual method Exec **/ + virtual void Exec(Option_t* opt); + + void SetTimeResolution(Double_t timeInNs) { fTimeResolution = timeInNs; } + Double_t GetTimeResolution() { return fTimeResolution; } + + private: + + Int_t CalcPad(Double_t posIn, Double_t posOut); + Double_t CalcTimeStamp(Double_t timeOfFlight); + + Double_t fTimeResolution; + + TClonesArray* fPointArray; + TClonesArray* fDigiArray; + + O2itsDigiTask(const O2itsDigiTask&); + O2itsDigiTask& operator=(const O2itsDigiTask&); + + ClassDef(O2itsDigiTask,1); +}; + +#endif diff --git a/its/O2itsGeoHandler.cxx b/its/O2itsGeoHandler.cxx new file mode 100644 index 0000000000000..d6a8a66e41bdb --- /dev/null +++ b/its/O2itsGeoHandler.cxx @@ -0,0 +1,197 @@ +#include "O2itsGeoHandler.h" + +#include "FairLogger.h" // for FairLogger, etc + +#include "TGeoBBox.h" // for TGeoBBox +#include "TGeoManager.h" // for TGeoManager, gGeoManager +#include "TGeoNode.h" // for TGeoNode +#include "TGeoVolume.h" // for TGeoVolume +#include "TVirtualMC.h" // for TVirtualMC, gMC + +#include // for printf +#include // for NULL, strlen, strncpy +#include // for cout, endl +#include // for map +#include // for pair + +using std::map; +using std::pair; +using std::cout; +using std::endl; + +O2itsGeoHandler::O2itsGeoHandler() + : TObject(), + fIsSimulation(kFALSE), + fLastUsedDetectorID(0), + fGeoPathHash(0), + fCurrentVolume(NULL), + fVolumeShape(NULL), + fGlobal(), + fGlobalMatrix(NULL) +{ +} + +Int_t O2itsGeoHandler::Init(Bool_t isSimulation) +{ +// Int_t geoVersion = CheckGeometryVersion(); + + fIsSimulation=isSimulation; + + return 1; +} + +void O2itsGeoHandler::LocalToGlobal(Double_t* local, Double_t* global, Int_t detID) +{ + TString path=ConstructFullPathFromDetID(detID); + NavigateTo(path); + gGeoManager->LocalToMaster(local, global); +} + +TString O2itsGeoHandler::ConstructFullPathFromDetID(Int_t detID) +{ + TString volStr = "/cave_1/tutorial4_0/tut4_det_"; + TString volPath = volStr; + volPath += detID; + return volPath; +} + +Int_t O2itsGeoHandler::GetUniqueDetectorId(TString volName) +{ + if (fGeoPathHash != volName.Hash()) { + NavigateTo(volName); + } + return GetUniqueDetectorId(); +} + + +Int_t O2itsGeoHandler::GetUniqueDetectorId() +{ + + Int_t detectorNr=0; + + CurrentVolOffID(0, detectorNr); + + return detectorNr; + + +} + + +Int_t O2itsGeoHandler::VolIdGeo(const char* name) const +{ + // + // Return the unique numeric identifier for volume name + // + + Int_t uid = gGeoManager->GetUID(name); + if (uid<0) { + printf("VolId: Volume %s not found\n",name); + return 0; + } + return uid; +} + +Int_t O2itsGeoHandler::VolId(const Text_t* name) const +{ + if (fIsSimulation) { + return gMC->VolId(name); + } else { + // + // Return the unique numeric identifier for volume name + // + char sname[20]; + Int_t len = strlen(name)-1; + if (name[len] != ' ') { return VolIdGeo(name); } + strncpy(sname, name, len); + sname[len] = 0; + return VolIdGeo(sname); + } +} + +Int_t O2itsGeoHandler::CurrentVolID(Int_t& copy) const +{ + if (fIsSimulation) { + return gMC->CurrentVolID(copy); + } else { + // + // Returns the current volume ID and copy number + // + if (gGeoManager->IsOutside()) { return 0; } + TGeoNode* node = gGeoManager->GetCurrentNode(); + copy = node->GetNumber(); + Int_t id = node->GetVolume()->GetNumber(); + return id; + } +} + +//_____________________________________________________________________________ +Int_t O2itsGeoHandler::CurrentVolOffID(Int_t off, Int_t& copy) const +{ + if (fIsSimulation) { + return gMC->CurrentVolOffID(off, copy); + } else { + // + // Return the current volume "off" upward in the geometrical tree + // ID and copy number + // + if (off<0 || off>gGeoManager->GetLevel()) { return 0; } + if (off==0) { return CurrentVolID(copy); } + TGeoNode* node = gGeoManager->GetMother(off); + if (!node) { return 0; } + copy = node->GetNumber(); + return node->GetVolume()->GetNumber(); + } +} + +//_____________________________________________________________________________ +const char* O2itsGeoHandler::CurrentVolName() const +{ + if (fIsSimulation) { + return gMC->CurrentVolName(); + } else { + // + // Returns the current volume name + // + if (gGeoManager->IsOutside()) { return gGeoManager->GetTopVolume()->GetName(); } + return gGeoManager->GetCurrentVolume()->GetName(); + } +} + +//_____________________________________________________________________________ +const char* O2itsGeoHandler::CurrentVolOffName(Int_t off) const +{ + if (fIsSimulation) { + return gMC->CurrentVolOffName(off); + } else { + // + // Return the current volume "off" upward in the geometrical tree + // ID, name and copy number + // if name=0 no name is returned + // + if (off<0 || off>gGeoManager->GetLevel()) { return 0; } + if (off==0) { return CurrentVolName(); } + TGeoNode* node = gGeoManager->GetMother(off); + if (!node) { return 0; } + return node->GetVolume()->GetName(); + } +} + + +void O2itsGeoHandler::NavigateTo(TString volName) +{ + if (fIsSimulation) { + LOG(FATAL)<<"This methode is not supported in simulation mode"<cd(volName.Data()); + fGeoPathHash = volName.Hash(); + fCurrentVolume = gGeoManager->GetCurrentVolume(); + fVolumeShape = (TGeoBBox*)fCurrentVolume->GetShape(); + Double_t local[3] = {0., 0., 0.}; // Local centre of volume + gGeoManager->LocalToMaster(local, fGlobal); + LOG(DEBUG2)<<"Pos: "<GetCurrentMatrix(); + } +} + + +ClassImp(O2itsGeoHandler) diff --git a/its/O2itsGeoHandler.h b/its/O2itsGeoHandler.h new file mode 100644 index 0000000000000..0fffa1162eb9d --- /dev/null +++ b/its/O2itsGeoHandler.h @@ -0,0 +1,82 @@ +// ------------------------------------------------------------------------- +// ----- O2itsGeoHandler header file ----- +// ----- Created 20/11/12 by F. Uhlig ----- +// ------------------------------------------------------------------------- + + +/** O2itsGeoHandler.h + ** Helper class to extract information from the GeoManager which is + ** needed in many other TOF classes. This helper class should be a + ** single place to hold all these functions. + ** @author F. Uhlig + **/ + +#ifndef O2ITSGEOHANDLER_H +#define O2ITSGEOHANDLER_H + +#include "TObject.h" // for TObject + +#include "Rtypes.h" // for Int_t, Double_t, Bool_t, etc +#include "TString.h" // for TString + +class TGeoBBox; +class TGeoVolume; +class TGeoHMatrix; + +class O2itsGeoHandler : public TObject +{ + public: + + /** Constructor **/ + O2itsGeoHandler(); + + /** Destructor **/ + ~O2itsGeoHandler() {}; + + Int_t GetUniqueDetectorId(); + Int_t GetUniqueDetectorId(TString volName); + +// Int_t GetDetectorId(Int_t uniqueId); + + Int_t Init(Bool_t isSimulation=kFALSE); + + void FillDetectorInfoArray(Int_t uniqueId); + void NavigateTo(TString volName); + + // Implement Interface functions to the TGeoManager to be + // the same as for the VMC + Int_t CurrentVolOffID(Int_t off, Int_t& copy) const; + Int_t CurrentVolID(Int_t& copy) const; + Int_t VolId(const Text_t* name) const; + Int_t VolIdGeo(const char* name) const; + const char* CurrentVolName() const; + const char* CurrentVolOffName(Int_t off) const; + + void LocalToGlobal(Double_t* local, Double_t* global, Int_t detID); + +// Int_t CheckGeometryVersion(); + + private: + + Bool_t fIsSimulation; //! + + Int_t fLastUsedDetectorID; //! + + UInt_t fGeoPathHash; //! + TGeoVolume* fCurrentVolume; //! + TGeoBBox* fVolumeShape; //! + Double_t fGlobal[3]; //! Global centre of volume + TGeoHMatrix* fGlobalMatrix; //! + + + TString ConstructFullPathFromDetID(Int_t detID); + + O2itsGeoHandler(const O2itsGeoHandler&); + O2itsGeoHandler operator=(const O2itsGeoHandler&); + + ClassDef(O2itsGeoHandler,1) + +}; + + +#endif diff --git a/its/O2itsLinkDef.h b/its/O2itsLinkDef.h new file mode 100644 index 0000000000000..0ae404b314dec --- /dev/null +++ b/its/O2itsLinkDef.h @@ -0,0 +1,21 @@ +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class AliITSUGeomTGeo+; +#pragma link C++ class AliITSv11Geometry+; +#pragma link C++ class AliITSUv1Layer+; +#pragma link C++ class AliITSsegmentation+; +#pragma link C++ class AliITSUSegmentationPix+; +#pragma link C++ class AliGeomManager+; +#pragma link C++ class O2its+; +#pragma link C++ class O2itsContFact; +#pragma link C++ class O2itsGeoHandler+; +#pragma link C++ class O2itsMisalignPar+; +#pragma link C++ class O2itsPoint+; +#pragma link C++ class O2itsDigi+; +#pragma link C++ class O2itsDigiTask+; + +#endif diff --git a/its/O2itsMisalignPar.cxx b/its/O2itsMisalignPar.cxx new file mode 100644 index 0000000000000..ed13eb845f3d2 --- /dev/null +++ b/its/O2itsMisalignPar.cxx @@ -0,0 +1,70 @@ +#include "O2itsMisalignPar.h" + +#include "FairParamList.h" + +//#include + +ClassImp(O2itsMisalignPar) + +O2itsMisalignPar ::O2itsMisalignPar(const char* name, + const char* title, + const char* context) + : FairParGenericSet(name,title,context), + fShiftX(), + fShiftY(), + fShiftZ(), + fRotX(), + fRotY(), + fRotZ(), + fNrOfDetectors(0) +{ +} + +O2itsMisalignPar::~O2itsMisalignPar(void) +{ +} + +void O2itsMisalignPar::clear(void) +{ +} + +void O2itsMisalignPar::putParams(FairParamList* l) +{ + if (!l) { return; } + + l->add("NrOfDetectors", fNrOfDetectors); + l->add("ShiftX", fShiftX); + l->add("ShiftY", fShiftY); + l->add("ShiftZ", fShiftZ); + l->add("RotationX", fRotX); + l->add("RotationY", fRotY); + l->add("RotationZ", fRotZ); + +} + +Bool_t O2itsMisalignPar::getParams(FairParamList* l) +{ + if (!l) { return kFALSE; } + + if ( ! l->fill("NrOfDetectors", &fNrOfDetectors) ) { return kFALSE; } + + fShiftX.Set(fNrOfDetectors); + if ( ! l->fill("ShiftX", &fShiftX )) { return kFALSE; } + + fShiftY.Set(fNrOfDetectors); + if ( ! l->fill("ShiftY", &fShiftY )) { return kFALSE; } + + fShiftZ.Set(fNrOfDetectors); + if ( ! l->fill("ShiftZ", &fShiftZ )) { return kFALSE; } + + fRotX.Set(fNrOfDetectors); + if ( ! l->fill("RotationX", &fRotX )) { return kFALSE; } + + fRotY.Set(fNrOfDetectors); + if ( ! l->fill("RotationY", &fRotY )) { return kFALSE; } + + fRotZ.Set(fNrOfDetectors); + if ( ! l->fill("RotationZ", &fRotZ )) { return kFALSE; } + + return kTRUE; +} diff --git a/its/O2itsMisalignPar.h b/its/O2itsMisalignPar.h new file mode 100644 index 0000000000000..a726e0aa58e7a --- /dev/null +++ b/its/O2itsMisalignPar.h @@ -0,0 +1,48 @@ +#ifndef O2ITSMISSALLIGNPAR_H +#define O2ITSMISSALLIGNPAR_H + +#include "FairParGenericSet.h" // for FairParGenericSet + +#include "Rtypes.h" // for ClassDef + +#include "TArrayD.h" // for TArrayD + +class FairParamList; + +class O2itsMisalignPar : public FairParGenericSet +{ + public: + + O2itsMisalignPar(const char* name="O2itsMissallignPar", + const char* title="Missalignment parameter for O2itsHitProducerIdealMissallign Parameters", + const char* context="TestDefaultContext"); + ~O2itsMisalignPar(void); + void clear(void); + void putParams(FairParamList*); + Bool_t getParams(FairParamList*); + + TArrayD GetShiftX() {return fShiftX;} + TArrayD GetShiftY() {return fShiftY;} + TArrayD GetShiftZ() {return fShiftZ;} + TArrayD GetRotX() {return fRotX;} + TArrayD GetRotY() {return fRotY;} + TArrayD GetRotZ() {return fRotZ;} + Int_t GetNrOfDetectors() {return fNrOfDetectors;} + + private: + + TArrayD fShiftX; // Array to hold the misalignment in x-direction + TArrayD fShiftY; // Array to hold the misalignment in y-direction + TArrayD fShiftZ; // Array to hold the misalignment in z-direction + TArrayD fRotX; // Array to hold the rotation in x-direction + TArrayD fRotY; // Array to hold the rotation in y-direction + TArrayD fRotZ; // Array to hold the rotation in z-direction + Int_t fNrOfDetectors; // Total number of detectors + + O2itsMisalignPar(const O2itsMisalignPar&); + O2itsMisalignPar& operator=(const O2itsMisalignPar&); + + ClassDef(O2itsMisalignPar,1) +}; + +#endif diff --git a/its/O2itsPoint.cxx b/its/O2itsPoint.cxx new file mode 100644 index 0000000000000..f715a8211c98d --- /dev/null +++ b/its/O2itsPoint.cxx @@ -0,0 +1,49 @@ +#include "O2itsPoint.h" + +#include +using std::cout; +using std::endl; + + +// ----- Default constructor ------------------------------------------- +O2itsPoint::O2itsPoint() + : FairMCPoint(), + fX_out(0.), + fY_out(0.), + fZ_out(0.), + fPx_out(0.), + fPy_out(0.), + fPz_out(0.) +{ +} +// ------------------------------------------------------------------------- + +// ----- Standard constructor ------------------------------------------ +O2itsPoint::O2itsPoint(Int_t trackID, Int_t detID, TVector3 startPos, TVector3 pos, TVector3 mom, + Double_t startTime, Double_t time, Double_t length, + Double_t eLoss, Int_t shunt) + : FairMCPoint(trackID, detID, pos, mom, time, length, eLoss) +{ +} +// ------------------------------------------------------------------------- + +// ----- Destructor ---------------------------------------------------- +O2itsPoint::~O2itsPoint() { } +// ------------------------------------------------------------------------- + +// ----- Public method Print ------------------------------------------- +void O2itsPoint::Print(const Option_t* opt) const +{ + cout << "-I- O2itsPoint: O2its point for track " << fTrackID + << " in detector " << fDetectorID << endl; + cout << " Position (" << fX << ", " << fY << ", " << fZ + << ") cm" << endl; + cout << " Momentum (" << fPx << ", " << fPy << ", " << fPz + << ") GeV" << endl; + cout << " Time " << fTime << " ns, Length " << fLength + << " cm, Energy loss " << fELoss*1.0e06 << " keV" << endl; +} +// ------------------------------------------------------------------------- + +ClassImp(O2itsPoint) + diff --git a/its/O2itsPoint.h b/its/O2itsPoint.h new file mode 100644 index 0000000000000..89091e946a0cc --- /dev/null +++ b/its/O2itsPoint.h @@ -0,0 +1,70 @@ +#ifndef O2ITSPOINT_H +#define O2ITSPOINT_H + + +#include "FairMCPoint.h" + +#include "TObject.h" +#include "TVector3.h" + +class O2itsPoint : public FairMCPoint +{ + + public: + + /** Default constructor **/ + O2itsPoint(); + + /** Constructor with arguments + *@param trackID Index of MCTrack + *@param detID Detector ID + *@param startPos Coordinates at entrance to active volume [cm] + *@param pos Coordinates to active volume [cm] + *@param mom Momentum of track at entrance [GeV] + *@param startTime Time at entrance [ns] + *@param time Time since event start [ns] + *@param length Track length since creation [cm] + *@param eLoss Energy deposit [GeV] + *@param shunt Shunt value + **/ + O2itsPoint(Int_t trackID, Int_t detID, TVector3 startPos, TVector3 pos, TVector3 mom, + Double_t startTime, Double_t time, Double_t length, Double_t eLoss, + Int_t shunt); + + /** Destructor **/ + virtual ~O2itsPoint(); + + /** Output to screen **/ + virtual void Print(const Option_t* opt) const; + + /** Accessors **/ + Double_t GetXIn() const { return fX; } + Double_t GetYIn() const { return fY; } + Double_t GetZIn() const { return fZ; } + Double_t GetXOut() const { return fX_out; } + Double_t GetYOut() const { return fY_out; } + Double_t GetZOut() const { return fZ_out; } + Double_t GetPxOut() const { return fPx_out; } + Double_t GetPyOut() const { return fPy_out; } + Double_t GetPzOut() const { return fPz_out; } + Double_t GetPxIn() const { return fPx; } + Double_t GetPyIn() const { return fPy; } + Double_t GetPzIn() const { return fPz; } + + private: + + Double32_t fX_out; + Double32_t fY_out; + Double32_t fZ_out; + Double32_t fPx_out; + Double32_t fPy_out; + Double32_t fPz_out; + + /** Copy constructor **/ + O2itsPoint(const O2itsPoint& point); + O2itsPoint operator=(const O2itsPoint& point); + + ClassDef(O2itsPoint,1) +}; + +#endif diff --git a/macro/run_sim.C b/macro/run_sim.C old mode 100755 new mode 100644 index a00e08330f9da..d2ef62ebb19f4 --- a/macro/run_sim.C +++ b/macro/run_sim.C @@ -1,122 +1,194 @@ -void run_sim(Int_t nEvents = 100, TString mcEngine = "TGeant4") -{ - - // Output file name - TString outFile ="test.root"; - - // Parameter file name - TString parFile="params.root"; - - // ----- Timer -------------------------------------------------------- - TStopwatch timer; - timer.Start(); - // ------------------------------------------------------------------------ - - // ----- Create simulation run ---------------------------------------- - FairRunSim* run = new FairRunSim(); - run->SetName(mcEngine); // Transport engine - run->SetOutputFile(outFile); // Output file - FairRuntimeDb* rtdb = run->GetRuntimeDb(); - // ------------------------------------------------------------------------ - - // ----- Create media ------------------------------------------------- - run->SetMaterials("media.geo"); // Materials - // ------------------------------------------------------------------------ - - // ----- Create geometry ---------------------------------------------- - - FairModule* cave= new AliCave("CAVE"); - cave->SetGeometryFileName("cave.geo"); - run->AddModule(cave); - - FairModule* magnet = new AliMagnet("Magnet"); - run->AddModule(magnet); - - FairModule* pipe = new AliPipe("Pipe"); - run->AddModule(pipe); - - FairDetector* NewDet = new AliIts("TestDetector", kTRUE); - run->AddModule(NewDet); - - // ------------------------------------------------------------------------ - - - // ----- Magnetic field ------------------------------------------- - // Constant Field - AliConstField *fMagField = new AliConstField(); - fMagField->SetField(0., 20. ,0. ); // values are in kG - fMagField->SetFieldRegion(-200, 200,-200, 200, -200, 200); // values are in cm - // (xmin,xmax,ymin,ymax,zmin,zmax) - run->SetField(fMagField); - // -------------------------------------------------------------------- - - - - // ----- Create PrimaryGenerator -------------------------------------- - FairPrimaryGenerator* primGen = new FairPrimaryGenerator(); - - - // Pythia8 - Pythia8Generator* P8gen = new Pythia8Generator(); - P8gen->UseRandom3(); //# TRandom1 or TRandom3 ? - P8gen->SetParameters("SoftQCD:inelastic = on"); - P8gen->SetParameters("PhotonCollision:gmgm2mumu = on"); - P8gen->SetParameters("PromptPhoton:all = on"); - P8gen->SetParameters("WeakBosonExchange:all = on"); - P8gen->SetMom(40); //# beam momentum in GeV - primGen->AddGenerator(P8gen); - - - // Add a box generator also to the run - FairBoxGenerator* boxGen = new FairBoxGenerator(13, 5); // 13 = muon; 1 = multipl. - boxGen->SetPRange(20,25); // GeV/c - boxGen->SetPhiRange(0., 360.); // Azimuth angle range [degree] - boxGen->SetThetaRange(0., 90.); // Polar angle in lab system range [degree] - boxGen->SetXYZ(0., 0., 0.); // cm - primGen->AddGenerator(boxGen); - - - run->SetGenerator(primGen); -// ------------------------------------------------------------------------ - - //---Store the visualiztion info of the tracks, this make the output file very large!! - //--- Use it only to display but not for production! - run->SetStoreTraj(kTRUE); - - - - // ----- Initialize simulation run ------------------------------------ - run->Init(); - // ------------------------------------------------------------------------ - - // ----- Runtime database --------------------------------------------- - - Bool_t kParameterMerged = kTRUE; - FairParRootFileIo* parOut = new FairParRootFileIo(kParameterMerged); - parOut->open(parFile.Data()); - rtdb->setOutput(parOut); - rtdb->saveOutput(); - rtdb->print(); - // ------------------------------------------------------------------------ - - // ----- Start run ---------------------------------------------------- - run->Run(nEvents); - - //You can export your ROOT geometry ot a separate file - run->CreateGeometryFile("geofile_full.root"); - // ------------------------------------------------------------------------ - - // ----- Finish ------------------------------------------------------- - timer.Stop(); - Double_t rtime = timer.RealTime(); - Double_t ctime = timer.CpuTime(); - cout << endl << endl; - cout << "Macro finished succesfully." << endl; - cout << "Output file is " << outFile << endl; - cout << "Parameter file is " << parFile << endl; - cout << "Real time " << rtime << " s, CPU time " << ctime - << "s" << endl << endl; - // ------------------------------------------------------------------------ -} - - +double radii2Turbo(double rMin,double rMid,double rMax, double sensW) +{ + // compute turbo angle from radii and sensor width + return TMath::ASin((rMax*rMax-rMin*rMin)/(2*rMid*sensW))*TMath::RadToDeg(); +} + +void run_sim(Int_t nEvents = 10, TString mcEngine = "TGeant3") +{ + // Output file name + const char fileout[100]; + sprintf(fileout, "AliceO2_%s.mc_%i_event.root", mcEngine.Data(), nEvents); + TString outFile = fileout; + + // Parameter file name + const char filepar[100]; + sprintf(filepar, "AliceO2_%s.params_%i.root", mcEngine.Data(), nEvents); + TString parFile = filepar; + + // In general, the following parts need not be touched + // ======================================================================== + + // ---- Debug option ------------------------------------------------- + gDebug = 0; + // ------------------------------------------------------------------------ + + // ----- Timer -------------------------------------------------------- + TStopwatch timer; + timer.Start(); + // ------------------------------------------------------------------------ + + gSystem->Load("libO2Base"); + gSystem->Load("libits"); + + // ----- Create simulation run ---------------------------------------- + FairRunSim* run = new FairRunSim(); + run->SetName(mcEngine); // Transport engine + run->SetOutputFile(outFile); // Output file + FairRuntimeDb* rtdb = run->GetRuntimeDb(); + // ------------------------------------------------------------------------ + + // ----- Create media ------------------------------------------------- + run->SetMaterials("media.geo"); // Materials + // ------------------------------------------------------------------------ + + // ----- Create geometry ---------------------------------------------- + + FairModule* cave= new AliCave("CAVE"); + cave->SetGeometryFileName("cave.geo"); + run->AddModule(cave); +/* + FairDetector* tpc = new O2tpc("TPCV2"); + tpc->SetGeometry(); + run->AddModule(tpc); +*/ + + O2Detector* its = new O2its("ITS", kTRUE, 7); + run->AddModule(its); + + // build ITS upgrade detector + // sensitive area 13x15mm (X,Z) with 20x20 micron pitch, 2mm dead zone on readout side and 50 micron guardring + const double kSensThick = 18e-4; + const double kPitchX = 20e-4; + const double kPitchZ = 20e-4; + const int kNRow = 650; + const int kNCol = 1500; + const double kSiThickIB = 150e-4; + const double kSiThickOB = 150e-4; + // const double kSensThick = 120e-4; // -> sensor Si thickness + + const double kReadOutEdge = 0.2; // width of the readout edge (passive bottom) + const double kGuardRing = 50e-4; // width of passive area on left/right/top of the sensor + + const int kNLr = 7; + const int kNLrInner = 3; + const int kBuildLevel = 0; + enum {kRmn,kRmd,kRmx,kNModPerStave,kPhi0,kNStave,kNPar}; + // Radii are from last TDR (ALICE-TDR-017.pdf Tab. 1.1, rMid is mean value) + const double tdr5dat[kNLr][kNPar] = { + {2.24, 2.34, 2.67, 9., 16.37, 12}, // for each inner layer: rMin,rMid,rMax,NChip/Stave, phi0, nStaves + {3.01, 3.15, 3.46, 9., 12.03, 16}, + {3.78, 3.93, 4.21, 9., 10.02, 20}, + {-1, 19.6 , -1, 4., 0. , 24}, // for others: -, rMid, -, NMod/HStave, phi0, nStaves // 24 was 49 + {-1, 24.55, -1, 4., 0. , 30}, // 30 was 61 + {-1, 34.39, -1, 7., 0. , 42}, // 42 was 88 + {-1, 39.34, -1, 7., 0. , 48} // 48 was 100 + }; + const int nChipsPerModule = 7; // For OB: how many chips in a row + + // Delete the segmentations from previous runs + gSystem->Exec(" rm itsSegmentations.root "); + + // create segmentations: + AliITSUSegmentationPix* seg0 = new AliITSUSegmentationPix(0, // segID (0:9) + 1, // chips per module + kNCol, // ncols (total for module) + kNRow, // nrows + kPitchX, // default row pitch in cm + kPitchZ, // default col pitch in cm + kSensThick, // sensor thickness in cm + -1, // no special left col between chips + -1, // no special right col between chips + kGuardRing, // left + kGuardRing, // right + kGuardRing, // top + kReadOutEdge // bottom + ); // see AliITSUSegmentationPix.h for extra options + seg0->Store(AliITSUGeomTGeo::GetITSsegmentationFileName()); + seg0->Print(); + + double dzLr,rLr,phi0,turbo; + int nStaveLr,nModPerStaveLr,idLr; + + its->SetStaveModelIB(O2its::kIBModel22); + its->SetStaveModelOB(O2its::kOBModel1); + + const int kNWrapVol = 3; + const double wrpRMin[kNWrapVol] = { 2.1, 15.0, 32.0}; + const double wrpRMax[kNWrapVol] = { 7.0, 27.0+2.5, 43.0+1.5}; + const double wrpZSpan[kNWrapVol] = {28.0, 86.0, 150.0}; + + its->SetNWrapVolumes(kNWrapVol); // define wrapper volumes for layers + + for (int iw=0;iwDefineWrapVolume(iw, wrpRMin[iw], wrpRMax[iw], wrpZSpan[iw]); + } + + for (int idLr=0;idLr=kNLrInner) { + nChipsPerStaveLr *= nChipsPerModule; + its->DefineLayer(idLr, phi0, rLr, nChipsPerStaveLr*seg0->Dz(), nStaveLr, nModPerStaveLr, + kSiThickOB, seg0->Dy(), seg0->GetChipTypeID(),kBuildLevel); + // printf("Add Lr%d: R=%6.2f DZ:%6.2f Staves:%3d NMod/Stave:%3d\n", + // idLr,rLr,nChipsPerStaveLr*seg0->Dz(),nStaveLr,nModPerStaveLr); + } else { + turbo = -radii2Turbo(tdr5dat[idLr][kRmn],rLr,tdr5dat[idLr][kRmx],seg0->Dx()); + its->DefineLayerTurbo(idLr, phi0, rLr, nChipsPerStaveLr*seg0->Dz(), nStaveLr, nChipsPerStaveLr, + seg0->Dx(), turbo, kSiThickIB, seg0->Dy(), seg0->GetChipTypeID(),kBuildLevel); + // printf("Add Lr%d: R=%6.2f DZ:%6.2f Turbo:%+6.2f Staves:%3d NMod/Stave:%3d\n", + // idLr,rLr,nChipsPerStaveLr*seg0->Dz(),turbo,nStaveLr,nModPerStaveLr); + } + } + + // ----- Create PrimaryGenerator -------------------------------------- + FairPrimaryGenerator* primGen = new FairPrimaryGenerator(); + FairBoxGenerator* boxGen = new FairBoxGenerator(2212, 1); /*protons*/ + + boxGen->SetThetaRange (0.0, 90.0); + boxGen->SetPRange (100,100.01); + boxGen->SetPhiRange (0.,360.); + boxGen->SetDebug(kTRUE); + + primGen->AddGenerator(boxGen); + + run->SetGenerator(primGen); + // ------------------------------------------------------------------------ + + // ----- Initialize simulation run ------------------------------------ + run->Init(); + // ------------------------------------------------------------------------ + + // ----- Runtime database --------------------------------------------- + + Bool_t kParameterMerged = kTRUE; + FairParRootFileIo* parOut = new FairParRootFileIo(kParameterMerged); + parOut->open(parFile.Data()); + rtdb->setOutput(parOut); + rtdb->saveOutput(); + rtdb->print(); + // ------------------------------------------------------------------------ + + // ----- Start run ---------------------------------------------------- + run->Run(nEvents); + run->CreateGeometryFile("geofile_full.root"); + // ------------------------------------------------------------------------ + + // ----- Finish ------------------------------------------------------- + timer.Stop(); + Double_t rtime = timer.RealTime(); + Double_t ctime = timer.CpuTime(); + cout << endl << endl; + cout << "Macro finished succesfully." << endl; + cout << "Output file is " << outFile << endl; + cout << "Parameter file is " << parFile << endl; + cout << "Real time " << rtime << " s, CPU time " << ctime + << "s" << endl << endl; + // ------------------------------------------------------------------------ + +}