diff --git a/its/AliGeomManager.cxx b/its/AliGeomManager.cxx deleted file mode 100644 index 0f53df916818a..0000000000000 --- a/its/AliGeomManager.cxx +++ /dev/null @@ -1,141 +0,0 @@ -/************************************************************************** - * 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 deleted file mode 100644 index 73c49132bd699..0000000000000 --- a/its/AliGeomManager.h +++ /dev/null @@ -1,54 +0,0 @@ -#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 deleted file mode 100644 index 1eeb487a8e096..0000000000000 --- a/its/AliITSUGeomTGeo.cxx +++ /dev/null @@ -1,1020 +0,0 @@ -/************************************************************************** - * 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 deleted file mode 100644 index f2ea7da2b8231..0000000000000 --- a/its/AliITSUGeomTGeo.h +++ /dev/null @@ -1,382 +0,0 @@ -#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 deleted file mode 100644 index 86e288a13755d..0000000000000 --- a/its/AliITSUSegmentationPix.cxx +++ /dev/null @@ -1,575 +0,0 @@ -/************************************************************************** - * 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 deleted file mode 100644 index 2b01612673dcd..0000000000000 --- a/its/AliITSUv1Layer.h +++ /dev/null @@ -1,184 +0,0 @@ -#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 deleted file mode 100644 index c36638abec7ad..0000000000000 --- a/its/AliITSsegmentation.cxx +++ /dev/null @@ -1,59 +0,0 @@ -//////////////////////////////////////////////// -// 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 deleted file mode 100644 index 8c00eea156714..0000000000000 --- a/its/AliITSsegmentation.h +++ /dev/null @@ -1,112 +0,0 @@ -#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 deleted file mode 100644 index 5f9db06bec8c4..0000000000000 --- a/its/AliITSv11Geometry.cxx +++ /dev/null @@ -1,1549 +0,0 @@ -/************************************************************************** - * 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 deleted file mode 100644 index 673ce41225833..0000000000000 --- a/its/AliITSv11Geometry.h +++ /dev/null @@ -1,197 +0,0 @@ -#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/CMakeLists.txt b/its/CMakeLists.txt index c7530110030c9..0beca0800a3d3 100644 --- a/its/CMakeLists.txt +++ b/its/CMakeLists.txt @@ -3,8 +3,8 @@ # The extension is already found. Any number of sources could be listed here. set(INCLUDE_DIRECTORIES -${ROOT_INCLUDE_DIR} -${BASE_INCLUDE_DIRECTORIES} +${ROOT_INCLUDE_DIR} +${BASE_INCLUDE_DIRECTORIES} ${CMAKE_SOURCE_DIR}/AliData ${CMAKE_SOURCE_DIR}/AliBase @@ -21,19 +21,17 @@ ${FAIRROOT_LIBRARY_DIR} link_directories( ${LINK_DIRECTORIES}) set(SRCS -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 +UpgradeGeometryTGeo.cxx +V11Geometry.cxx +UpgradeV1Layer.cxx +Segmentation.cxx +UpgradeSegmentationPixel.cxx +GeometryManager.cxx +Detector.cxx +ContainerFactory.cxx +GeometryHandler.cxx +MisalignmentParameter.cxx +Point.cxx ) Set(LINKDEF O2itsLinkDef.h) diff --git a/its/ContainerFactory.cxx b/its/ContainerFactory.cxx new file mode 100644 index 0000000000000..b82a54e215696 --- /dev/null +++ b/its/ContainerFactory.cxx @@ -0,0 +1,44 @@ +/// \file ContainerFactory.cxx +/// \brief Implementation of the ContainerFactory class + +#include "ContainerFactory.h" +#include "FairRuntimeDb.h" + +#include + +using namespace AliceO2::ITS; + +ClassImp(ContainerFactory) + +static ContainerFactory gO2itsContFact; + +ContainerFactory::ContainerFactory() + : FairContFact() +{ + fName = "ContainerFactory"; + fTitle = "Factory for parameter containers in libO2its"; + mSetAllContainers(); + FairRuntimeDb::instance()->addContFactory(this); +} + +void ContainerFactory::mSetAllContainers() +{ + //FairContainer* p= new FairContainer("O2itsGeoPar", + // "O2its Geometry Parameters", + // "TestDefaultContext"); + //p->addContext("TestNonDefaultContext"); + // + //containers->Add(p); + +} + +FairParSet* ContainerFactory::createContainer(FairContainer* c) +{ + //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/ContainerFactory.h b/its/ContainerFactory.h new file mode 100644 index 0000000000000..6b4f4d64b7702 --- /dev/null +++ b/its/ContainerFactory.h @@ -0,0 +1,41 @@ +/// \file GeometryHandler.h +/// \brief Definition of the ContainerFactory class + +#ifndef ALICEO2_ITS_CONTAINERFACTORY_H_ +#define ALICEO2_ITS_CONTAINERFACTORY_H_ + +#include "FairContFact.h" + +class FairContainer; + +namespace AliceO2 { +namespace ITS { + +class ContainerFactory : public FairContFact { +private: + /// Creates the Container objects with all accepted + /// contexts and adds them to + /// the list of containers for the O2its library. + void mSetAllContainers(); + +public: + /// Default constructor + ContainerFactory(); + + /// Default destructor + ~ContainerFactory() + { + } + + /// 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. + FairParSet* createContainer(FairContainer*); + + ClassDef(ContainerFactory, 0) // Factory for all AliceO2 ITS parameter containers +}; +} +} + +#endif diff --git a/its/Detector.cxx b/its/Detector.cxx new file mode 100644 index 0000000000000..da9bedd716a39 --- /dev/null +++ b/its/Detector.cxx @@ -0,0 +1,890 @@ +/// \file Detector.cxx +/// \brief Implementation of the Detector class + +#include "Detector.h" + +#include "AliDetectorList.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 "Point.h" +#include "UpgradeV1Layer.h" +#include "UpgradeGeometryTGeo.h" + +#include "TClonesArray.h" +#include "TGeoManager.h" +#include "TGeoTube.h" +#include "TGeoVolume.h" +#include "TVirtualMC.h" + +#include +#include + +using std::cout; +using std::endl; + +using namespace AliceO2::ITS; + +AliceO2::ITS::Detector::Detector() + : O2Detector("ITS", kTRUE, kAliIts) + , mLayerID(0) + , mTrackNumberID(-1) + , mVolumeID(-1) + , mEntrancePosition() + , mPosition() + , mMomentum() + , mEntranceTime(-1.) + , mTime(-1.) + , mLength(-1.) + , mEnergyLoss(-1) + , mShunt() + , mPointCollection(new TClonesArray("AliceO2::ITS::Point")) + , mGeometryHandler(new GeometryHandler()) + , mMisalignmentParameter(NULL) + , mNumberOfDetectors(-1) + , mShiftX() + , mShiftY() + , mShiftZ() + , mRotX() + , mRotY() + , mRotZ() + , mModifyGeometry(kFALSE) + , mNumberOfWrapperVolumes(0) + , mWrapperMinRadius(0) + , mWrapperMaxRadius(0) + , mWrapperZSpan(0) + , mWrapperLayerId(0) + , mTurboLayer(0) + , mLayerPhi0(0) + , mLayerRadii(0) + , mLayerZLength(0) + , mStavePerLayer(0) + , mUnitPerStave(0) + , mStaveThickness(0) + , mStaveWidth(0) + , mStaveTilt(0) + , mDetectorThickness(0) + , mChipTypeID(0) + , mBuildLevel(0) + , mUpgradeGeometry(0) + , mStaveModelInnerBarrel(kIBModel0) + , mStaveModelOuterBarrel(kOBModel0) +{ +} + +AliceO2::ITS::Detector::Detector(const char* name, Bool_t active, const Int_t layerNumber) + : O2Detector(name, active, kAliIts) + , mLayerID(0) + , mTrackNumberID(-1) + , mVolumeID(-1) + , mEntrancePosition() + , mPosition() + , mMomentum() + , mEntranceTime(-1.) + , mTime(-1.) + , mLength(-1.) + , mEnergyLoss(-1) + , mShunt() + , mPointCollection(new TClonesArray("AliceO2::ITS::Point")) + , mGeometryHandler(new GeometryHandler()) + , mMisalignmentParameter(NULL) + , mNumberOfDetectors(-1) + , mShiftX() + , mShiftY() + , mShiftZ() + , mRotX() + , mRotY() + , mRotZ() + , mModifyGeometry(kFALSE) + , mNumberOfWrapperVolumes(0) + , mWrapperMinRadius(0) + , mWrapperMaxRadius(0) + , mWrapperZSpan(0) + , mWrapperLayerId(0) + , mTurboLayer(0) + , mLayerPhi0(0) + , mLayerRadii(0) + , mLayerZLength(0) + , mStavePerLayer(0) + , mUnitPerStave(0) + , mStaveThickness(0) + , mStaveWidth(0) + , mStaveTilt(0) + , mDetectorThickness(0) + , mChipTypeID(0) + , mBuildLevel(0) + , mUpgradeGeometry(0) + , mNumberLayers(layerNumber) + , mStaveModelInnerBarrel(kIBModel0) + , mStaveModelOuterBarrel(kOBModel0) +{ + mLayerName = new TString[mNumberLayers]; + + for (Int_t j = 0; j < mNumberLayers; j++) { + mLayerName[j].Form("%s%d", UpgradeGeometryTGeo::GetITSSensorPattern(), j); // See UpgradeV1Layer + } + + mTurboLayer = new Bool_t[mNumberLayers]; + mLayerPhi0 = new Double_t[mNumberLayers]; + mLayerRadii = new Double_t[mNumberLayers]; + mLayerZLength = new Double_t[mNumberLayers]; + mStavePerLayer = new Int_t[mNumberLayers]; + mUnitPerStave = new Int_t[mNumberLayers]; + mStaveThickness = new Double_t[mNumberLayers]; + mStaveWidth = new Double_t[mNumberLayers]; + mStaveTilt = new Double_t[mNumberLayers]; + mDetectorThickness = new Double_t[mNumberLayers]; + mChipTypeID = new UInt_t[mNumberLayers]; + mBuildLevel = new Int_t[mNumberLayers]; + + mUpgradeGeometry = new UpgradeV1Layer* [mNumberLayers]; + + if (mNumberLayers > 0) { // if not, we'll Fatal-ize in CreateGeometry + for (Int_t j = 0; j < mNumberLayers; j++) { + mLayerPhi0[j] = 0; + mLayerRadii[j] = 0.; + mLayerZLength[j] = 0.; + mStavePerLayer[j] = 0; + mUnitPerStave[j] = 0; + mStaveWidth[j] = 0.; + mDetectorThickness[j] = 0.; + mChipTypeID[j] = 0; + mBuildLevel[j] = 0; + mUpgradeGeometry[j] = 0; + } + } +} + +AliceO2::ITS::Detector::~Detector() +{ + delete[] mTurboLayer; + delete[] mLayerPhi0; + delete[] mLayerRadii; + delete[] mLayerZLength; + delete[] mStavePerLayer; + delete[] mUnitPerStave; + delete[] mStaveThickness; + delete[] mStaveWidth; + delete[] mStaveTilt; + delete[] mDetectorThickness; + delete[] mChipTypeID; + delete[] mBuildLevel; + delete[] mUpgradeGeometry; + delete[] mWrapperMinRadius; + delete[] mWrapperMaxRadius; + delete[] mWrapperZSpan; + delete[] mWrapperLayerId; + + if (mPointCollection) { + mPointCollection->Delete(); + delete mPointCollection; + } + + delete[] mLayerID; +} + +AliceO2::ITS::Detector& AliceO2::ITS::Detector::operator=(const AliceO2::ITS::Detector& h) +{ + // The standard = operator + // Inputs: + // Detector &h the sourse of this copy + // Outputs: + // none. + // Return: + // A copy of the sourse hit h + + if (this == &h) { + return *this; + } + this->mStatus = h.mStatus; + this->mModule = h.mModule; + this->mParticlePx = h.mParticlePx; + this->mParticlePy = h.mParticlePy; + this->mParticlePz = h.mParticlePz; + this->mEnergyDepositionStep = h.mEnergyDepositionStep; + this->mTof = h.mTof; + this->mStatus0 = h.mStatus0; + this->mStartingStepX = h.mStartingStepX; + this->mStartingStepY = h.mStartingStepY; + this->mStartingStepZ = h.mStartingStepZ; + this->mStartingStepT = h.mStartingStepT; + return *this; +} + +void AliceO2::ITS::Detector::Initialize() +{ + if (!mLayerID) { + mLayerID = new Int_t[mNumberLayers]; + } + + for (int i = 0; i < mNumberLayers; i++) { + mLayerID[i] = gMC ? gMC->VolId(mLayerName[i]) : 0; + } + + mGeometryTGeo = new UpgradeGeometryTGeo(kTRUE); + + FairDetector::Initialize(); + + // FairRuntimeDb* rtdb= FairRun::Instance()->GetRuntimeDb(); + // O2itsGeoPar* par=(O2itsGeoPar*)(rtdb->getContainer("O2itsGeoPar")); +} + +void AliceO2::ITS::Detector::InitParameterContainers() +{ + LOG(INFO) << "Initialize ITS misalignment parameters" << FairLogger::endl; + mNumberOfDetectors = mMisalignmentParameter->GetNumberOfDetectors(); + mShiftX = mMisalignmentParameter->GetShiftX(); + mShiftY = mMisalignmentParameter->GetShiftY(); + mShiftZ = mMisalignmentParameter->GetShiftZ(); + mRotX = mMisalignmentParameter->GetRotX(); + mRotY = mMisalignmentParameter->GetRotY(); + mRotZ = mMisalignmentParameter->GetRotZ(); +} + +void AliceO2::ITS::Detector::SetParameterContainers() +{ + LOG(INFO) << "Set ITS misalignment parameters" << FairLogger::endl; + + // Get Base Container + FairRun* sim = FairRun::Instance(); + LOG_IF(FATAL, !sim) << "No run object" << FairLogger::endl; + FairRuntimeDb* rtdb = sim->GetRuntimeDb(); + LOG_IF(FATAL, !rtdb) << "No runtime database" << FairLogger::endl; + + mMisalignmentParameter = (MisalignmentParameter*)(rtdb->getContainer("MisalignmentParameter")); +} + +Bool_t AliceO2::ITS::Detector::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 ((lay < mNumberLayers) && id != mLayerID[lay]) { + ++lay; + } + + // FIXME: Is it needed to keep a track reference when the outer ITS volume is encountered? + // if(gMC->IsTrackExiting()) { + // AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kITS); + // } + + // Retrieve the indices with the volume path + copy = 1; + gMC->CurrentVolOffID(1, cpn1); + gMC->CurrentVolOffID(2, cpn0); + + mod = mGeometryTGeo->GetChipIndex(lay, cpn0, cpn1); + + // Record information on the points + mEnergyLoss = gMC->Edep(); + mTime = gMC->TrackTime(); + mTrackNumberID = gMC->GetStack()->GetCurrentTrackNumber(); + mVolumeID = vol->getMCid(); + + // FIXME: Set a temporary value to mShunt for now, determine its use at a later stage + mShunt = 0; + + gMC->TrackPosition(mPosition); + gMC->TrackMomentum(mMomentum); + + // mLength = gMC->TrackLength(); + + if (gMC->IsTrackEntering()) { + mEntrancePosition = mPosition; + mEntranceTime = mTime; + return kFALSE; // don't save entering hit. + } + + // Create Point on every step of the active volume + AddHit(mTrackNumberID, mVolumeID, + TVector3(mEntrancePosition.X(), mEntrancePosition.Y(), mEntrancePosition.Z()), + TVector3(mPosition.X(), mPosition.Y(), mPosition.Z()), + TVector3(mMomentum.Px(), mMomentum.Py(), mMomentum.Pz()), mEntranceTime, mTime, mLength, + mEnergyLoss, mShunt); + + // Increment number of Detector det points in TParticle + AliStack* stack = (AliStack*)gMC->GetStack(); + stack->AddPoint(kAliIts); + + // Save old position for the next hit. + mEntrancePosition = mPosition; + mEntranceTime = mTime; + + return kTRUE; +} + +void AliceO2::ITS::Detector::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(); +} + +/// Creates a branch in the output tree called Point. Setting the last parameter to kFALSE means +/// that this collection will not be written to the file, it will exist only during the simulation +void AliceO2::ITS::Detector::Register() +{ + FairRootManager::Instance()->Register("AliceO2::ITS::Point", "ITS", mPointCollection, kTRUE); +} + +TClonesArray* AliceO2::ITS::Detector::GetCollection(Int_t iColl) const +{ + if (iColl == 0) { + return mPointCollection; + } + else { + return NULL; + } +} + +void AliceO2::ITS::Detector::Reset() +{ + mPointCollection->Clear(); +} + +void AliceO2::ITS::Detector::SetNumberOfWrapperVolumes(Int_t n) +{ + // book arrays for wrapper volumes + if (mNumberOfWrapperVolumes) { + LOG(FATAL) << mNumberOfWrapperVolumes << " wrapper volumes already defined" << FairLogger::endl; + } + + if (n < 1) { + return; + } + + mNumberOfWrapperVolumes = n; + mWrapperMinRadius = new Double_t[mNumberOfWrapperVolumes]; + mWrapperMaxRadius = new Double_t[mNumberOfWrapperVolumes]; + mWrapperZSpan = new Double_t[mNumberOfWrapperVolumes]; + + for (int i = mNumberOfWrapperVolumes; i--;) { + mWrapperMinRadius[i] = mWrapperMaxRadius[i] = mWrapperZSpan[i] = -1; + } +} + +void AliceO2::ITS::Detector::DefineWrapVolume(Int_t id, Double_t rmin, Double_t rmax, + Double_t zspan) +{ + // set parameters of id-th wrapper volume + if (id >= mNumberOfWrapperVolumes || id < 0) { + LOG(FATAL) << "id " << id << " of wrapper volume is not in 0-" << mNumberOfWrapperVolumes - 1 + << " range" << FairLogger::endl; + } + + mWrapperMinRadius[id] = rmin; + mWrapperMaxRadius[id] = rmax; + mWrapperZSpan[id] = zspan; +} + +void AliceO2::ITS::Detector::DefineLayer(Int_t layerNumber, double phi0, Double_t r, Double_t zlen, + Int_t nstav, Int_t nunit, Double_t lthick, Double_t dthick, + UInt_t dettypeID, Int_t buildLevel) +{ + LOG(INFO) << "L# " << layerNumber << " Phi:" << phi0 << " R:" << r << " DZ:" << zlen << " Nst:" << nstav + << " Nunit:" << nunit << " Lthick:" << lthick << " Dthick:" << dthick + << " DetID:" << dettypeID << " B:" << buildLevel << FairLogger::endl; + + if (layerNumber >= mNumberLayers || layerNumber < 0) { + LOG(ERROR) << "Wrong layer number " << layerNumber << FairLogger::endl; + return; + } + + mTurboLayer[layerNumber] = kFALSE; + mLayerPhi0[layerNumber] = phi0; + mLayerRadii[layerNumber] = r; + mLayerZLength[layerNumber] = zlen; + mStavePerLayer[layerNumber] = nstav; + mUnitPerStave[layerNumber] = nunit; + mStaveThickness[layerNumber] = lthick; + mDetectorThickness[layerNumber] = dthick; + mChipTypeID[layerNumber] = dettypeID; + mBuildLevel[layerNumber] = buildLevel; +} + +void AliceO2::ITS::Detector::DefineLayerTurbo(Int_t layerNumber, 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) +{ + LOG(INFO) << "L# " << layerNumber << " 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 (layerNumber >= mNumberLayers || layerNumber < 0) { + LOG(ERROR) << "Wrong layer number " << layerNumber << FairLogger::endl; + return; + } + + mTurboLayer[layerNumber] = kTRUE; + mLayerPhi0[layerNumber] = phi0; + mLayerRadii[layerNumber] = r; + mLayerZLength[layerNumber] = zlen; + mStavePerLayer[layerNumber] = nstav; + mUnitPerStave[layerNumber] = nunit; + mStaveThickness[layerNumber] = lthick; + mStaveWidth[layerNumber] = width; + mStaveTilt[layerNumber] = tilt; + mDetectorThickness[layerNumber] = dthick; + mChipTypeID[layerNumber] = dettypeID; + mBuildLevel[layerNumber] = buildLevel; +} + +void AliceO2::ITS::Detector::GetLayerParameters(Int_t layerNumber, Double_t& phi0, Double_t& r, + Double_t& zlen, Int_t& nstav, Int_t& nmod, + Double_t& width, Double_t& tilt, Double_t& lthick, + Double_t& dthick, UInt_t& dettype) const +{ + if (layerNumber >= mNumberLayers || layerNumber < 0) { + LOG(ERROR) << "Wrong layer number " << layerNumber << FairLogger::endl; + return; + } + + phi0 = mLayerPhi0[layerNumber]; + r = mLayerRadii[layerNumber]; + zlen = mLayerZLength[layerNumber]; + nstav = mStavePerLayer[layerNumber]; + nmod = mUnitPerStave[layerNumber]; + width = mStaveWidth[layerNumber]; + tilt = mStaveTilt[layerNumber]; + lthick = mStaveThickness[layerNumber]; + dthick = mDetectorThickness[layerNumber]; + dettype = mChipTypeID[layerNumber]; +} + +TGeoVolume* AliceO2::ITS::Detector::CreateWrapperVolume(Int_t id) +{ + if (mWrapperMinRadius[id] < 0 || mWrapperMaxRadius[id] < 0 || mWrapperZSpan[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(mWrapperMinRadius[id], mWrapperMaxRadius[id], mWrapperZSpan[id] / 2.); + + TGeoMedium* medAir = gGeoManager->GetMedium("ITS_AIR$"); + + char volnam[30]; + snprintf(volnam, 29, "%s%d", UpgradeGeometryTGeo::GetITSWrapVolPattern(), id); + + TGeoVolume* wrapper = new TGeoVolume(volnam, tube, medAir); + + return wrapper; +} + +void AliceO2::ITS::Detector::ConstructGeometry() +{ + // Create the detector materials + CreateMaterials(); + + // Construct the detector geometry + ConstructDetectorGeometry(); + + // Define the list of sensitive volumes + DefineSensitiveVolumes(); +} + +void AliceO2::ITS::Detector::ConstructDetectorGeometry() +{ + // Create the geometry and insert it in the mother volume "cave" + TGeoManager* geoManager = gGeoManager; + + TGeoVolume* vALIC = geoManager->GetVolume("cave"); + + if (!vALIC) { + LOG(FATAL) << "Could not find the top volume" << FairLogger::endl; + } + + new TGeoVolumeAssembly(UpgradeGeometryTGeo::GetITSVolPattern()); + TGeoVolume* vITSV = geoManager->GetVolume(UpgradeGeometryTGeo::GetITSVolPattern()); + vITSV->SetUniqueID(UpgradeGeometryTGeo::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 (mNumberLayers <= 0) { + LOG(FATAL) << "Wrong number of layers (" << mNumberLayers << ")" << FairLogger::endl; + } + + for (Int_t j = 0; j < mNumberLayers; j++) { + if (mLayerRadii[j] <= 0) { + LOG(FATAL) << "Wrong layer radius for layer " << j << " (" << mLayerRadii[j] << ")" + << FairLogger::endl; + } + if (mLayerZLength[j] <= 0) { + LOG(FATAL) << "Wrong layer length for layer " << j << " (" << mLayerZLength[j] << ")" + << FairLogger::endl; + } + if (mStavePerLayer[j] <= 0) { + LOG(FATAL) << "Wrong number of staves for layer " << j << " (" << mStavePerLayer[j] << ")" + << FairLogger::endl; + } + if (mUnitPerStave[j] <= 0) { + LOG(FATAL) << "Wrong number of chips for layer " << j << " (" << mUnitPerStave[j] << ")" + << FairLogger::endl; + } + if (mStaveThickness[j] < 0) { + LOG(FATAL) << "Wrong stave thickness for layer " << j << " (" << mStaveThickness[j] << ")" + << FairLogger::endl; + } + if (mTurboLayer[j] && mStaveWidth[j] <= 0) { + LOG(FATAL) << "Wrong stave width for layer " << j << " (" << mStaveWidth[j] << ")" + << FairLogger::endl; + } + if (mDetectorThickness[j] < 0) { + LOG(FATAL) << "Wrong chip thickness for layer " << j << " (" << mDetectorThickness[j] << ")" + << FairLogger::endl; + } + + if (j > 0) { + if (mLayerRadii[j] <= mLayerRadii[j - 1]) { + LOG(FATAL) << "Layer " << j << " radius (" << mLayerRadii[j] << ") is smaller than layer " + << j - 1 << " radius (" << mLayerRadii[j - 1] << ")" << FairLogger::endl; + } + } + if (mStaveThickness[j] == 0) { + LOG(INFO) << "Stave thickness for layer " << j << " not set, using default" + << FairLogger::endl; + } + if (mDetectorThickness[j] == 0) { + LOG(INFO) << "Chip thickness for layer " << j << " not set, using default" + << FairLogger::endl; + } + } + + // Create the wrapper volumes + TGeoVolume** wrapVols = 0; + + if (mNumberOfWrapperVolumes) { + wrapVols = new TGeoVolume* [mNumberOfWrapperVolumes]; + for (int id = 0; id < mNumberOfWrapperVolumes; id++) { + wrapVols[id] = CreateWrapperVolume(id); + vITSV->AddNode(wrapVols[id], 1, 0); + } + } + + mWrapperLayerId = new Int_t[mNumberLayers]; + + // Now create the actual geometry + for (Int_t j = 0; j < mNumberLayers; j++) { + TGeoVolume* dest = vITSV; + mWrapperLayerId[j] = -1; + + if (mTurboLayer[j]) { + mUpgradeGeometry[j] = new UpgradeV1Layer(j, kTRUE, kFALSE); + mUpgradeGeometry[j]->SetStaveWidth(mStaveWidth[j]); + mUpgradeGeometry[j]->SetStaveTilt(mStaveTilt[j]); + } + else { + mUpgradeGeometry[j] = new UpgradeV1Layer(j, kFALSE); + } + + mUpgradeGeometry[j]->SetPhi0(mLayerPhi0[j]); + mUpgradeGeometry[j]->SetRadius(mLayerRadii[j]); + mUpgradeGeometry[j]->SetZLength(mLayerZLength[j]); + mUpgradeGeometry[j]->SetNumberOfStaves(mStavePerLayer[j]); + mUpgradeGeometry[j]->SetNumberOfUnits(mUnitPerStave[j]); + mUpgradeGeometry[j]->SetChipType(mChipTypeID[j]); + mUpgradeGeometry[j]->SetBuildLevel(mBuildLevel[j]); + + if (j < 3) { + mUpgradeGeometry[j]->SetStaveModel(mStaveModelInnerBarrel); + } + else { + mUpgradeGeometry[j]->SetStaveModel(mStaveModelOuterBarrel); + } + + LOG(DEBUG1) << "mBuildLevel: " << mBuildLevel[j] << FairLogger::endl; + + if (mStaveThickness[j] != 0) { + mUpgradeGeometry[j]->SetStaveThick(mStaveThickness[j]); + } + if (mDetectorThickness[j] != 0) { + mUpgradeGeometry[j]->SetSensorThick(mDetectorThickness[j]); + } + + for (int iw = 0; iw < mNumberOfWrapperVolumes; iw++) { + if (mLayerRadii[j] > mWrapperMinRadius[iw] && mLayerRadii[j] < mWrapperMaxRadius[iw]) { + LOG(INFO) << "Will embed layer " << j << " in wrapper volume " << iw << FairLogger::endl; + + if (mLayerZLength[j] >= mWrapperZSpan[iw]) { + LOG(FATAL) << "ZSpan " << mWrapperZSpan[iw] << " of wrapper volume " << iw + << " is less than ZSpan " << mLayerZLength[j] << " of layer " << j + << FairLogger::endl; + } + + dest = wrapVols[iw]; + mWrapperLayerId[j] = iw; + break; + } + } + mUpgradeGeometry[j]->CreateLayer(dest); + } + CreateServiceBarrel(kTRUE, wrapVols[0]); + CreateServiceBarrel(kFALSE, wrapVols[2]); + + delete[] wrapVols; // delete pointer only, not the volumes +} + +// Service Barrel +void AliceO2::ITS::Detector::CreateServiceBarrel(const Bool_t innerBarrel, TGeoVolume* dest, + const TGeoManager* mgr) +{ + 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 AliceO2::ITS::Detector::DefineSensitiveVolumes() +{ + TGeoManager* geoManager = gGeoManager; + TGeoVolume* v; + + TString volumeName; + + // The names of the ITS sensitive volumes have the format: ITSUSensor(0...mNumberLayers-1) + for (Int_t j = 0; j < mNumberLayers; j++) { + volumeName = UpgradeGeometryTGeo::GetITSSensorPattern() + TString::Itoa(j, 10); + v = geoManager->GetVolume(volumeName.Data()); + AddSensitiveVolume(v); + } +} + +Point* AliceO2::ITS::Detector::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 = *mPointCollection; + Int_t size = clref.GetEntriesFast(); + return new (clref[size]) + Point(trackID, detID, startPos, pos, mom, startTime, time, length, eLoss, shunt); +} + +TParticle* AliceO2::ITS::Detector::GetParticle() const +{ + return ((AliStack*)gMC->GetStack())->GetParticle(GetTrack()); +} + +void AliceO2::ITS::Detector::Print(ostream* os) const +{ +#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 << mTrackNumber << " " << mPositionX << " " << mPositionY << " " << mPositionZ << " "; + fmt = os->setf(ios::hex); // set hex for mStatus only. + *os << mStatus << " "; + fmt = os->setf(ios::dec); // every thing else decimel. + *os << mModule << " "; + *os << mParticlePx << " " << mParticlePy << " " << mParticlePz << " "; + *os << mEnergyDepositionStep << " " << mTof; + *os << " " << mStartingStepX << " " << mStartingStepY << " " << mStartingStepZ; + // *os << " " << endl; + os->flags(fmt); // reset back to old formating. + return; +} + +void AliceO2::ITS::Detector::Read(istream* is) +{ + *is >> mTrackNumber >> mPositionX >> mPositionY >> mPositionZ; + *is >> mStatus >> mModule >> mParticlePx >> mParticlePy >> mParticlePz >> mEnergyDepositionStep >> + mTof; + *is >> mStartingStepX >> mStartingStepY >> mStartingStepZ; + return; +} + +ostream& operator<<(ostream& os, AliceO2::ITS::Detector& p) +{ + // Standard output streaming function. + // Inputs: + // ostream os The output stream + // Detector p The his to be printed out + // Outputs: + // none. + // Return: + // The input stream + + p.Print(&os); + return os; +} + +istream& operator>>(istream& is, AliceO2::ITS::Detector& r) +{ + // Standard input streaming function. + // Inputs: + // istream is The input stream + // Detector p The Detector class to be filled from this input stream + // Outputs: + // none. + // Return: + // The input stream + + r.Read(&is); + return is; +} + +ClassImp(AliceO2::ITS::Detector) diff --git a/its/Detector.h b/its/Detector.h new file mode 100644 index 0000000000000..bb6e3f1c16532 --- /dev/null +++ b/its/Detector.h @@ -0,0 +1,340 @@ +/// \file Detector.h +/// \brief Definition of the Detector class + +#ifndef ALICEO2_ITS_DETECTOR_H_ +#define ALICEO2_ITS_DETECTOR_H_ + +#include "TParticle.h" +#include "TVector3.h" +#include "TLorentzVector.h" + +#include "O2Detector.h" +#include "GeometryHandler.h" +#include "MisalignmentParameter.h" +#include "UpgradeGeometryTGeo.h" + +class FairVolume; +class TClonesArray; + +namespace AliceO2 { +namespace ITS { + +class Point; +class UpgradeV1Layer; + +class Detector : public O2Detector { + +public: + enum Model { + kIBModelDummy = 0, + kIBModel0 = 1, + kIBModel1 = 2, + kIBModel21 = 3, + kIBModel22 = 4, + kIBModel3 = 5, + kOBModelDummy = 6, + kOBModel0 = 7, + kOBModel1 = 8 + }; + + /// Name : Detector Name + /// Active: kTRUE for active detectors (ProcessHits() will be called) + /// kFALSE for inactive detectors + Detector(const char* Name, Bool_t Active, const Int_t nlay); + + /// Default constructor + Detector(); + + /// Default destructor + virtual ~Detector(); + + /// 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(); + + /// Creates the Service Barrel (as a simple cylinder) for IB and OB + /// \param innerBarrel if true, build IB service barrel, otherwise for OB + /// \param dest the mother volume holding the service barrel + /// \param mgr the gGeoManager pointer (used to get the material) + void CreateServiceBarrel(const Bool_t innerBarrel, TGeoVolume* dest, + const TGeoManager* mgr = gGeoManager); + + /// Initialize the parameter containers + virtual void InitParameterContainers(); + + void SetParameterContainers(); + + /// Sets the layer parameters + /// \param nlay layer number + /// \param phi0 layer phi0 + /// \param r layer radius + /// \param zlen layer length + /// \param nstav number of staves + /// \param nunit IB: number of chips per stave + /// \param OB: number of modules per half stave + /// \param lthick stave thickness (if omitted, defaults to 0) + /// \param dthick detector thickness (if omitted, defaults to 0) + /// \param dettypeID ?? + /// \param buildLevel (if 0, all geometry is build, used for material budget studies) + 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); + + + /// Sets the layer parameters for a "turbo" layer + /// (i.e. a layer whose staves overlap in phi) + /// \param nlay layer number + /// \param phi0 phi of 1st stave + /// \param r layer radius + /// \param zlen layer length + /// \param nstav number of staves + /// \param nunit IB: number of chips per stave + /// \param OB: number of modules per half stave + /// \param width stave width + /// \param tilt layer tilt angle (degrees) + /// \param lthick stave thickness (if omitted, defaults to 0) + /// \param dthick detector thickness (if omitted, defaults to 0) + /// \param dettypeID ?? + /// \param buildLevel (if 0, all geometry is build, used for material budget studies) + 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); + + /// Gets the layer parameters + /// \param nlay layer number + /// \param phi0 phi of 1st stave + /// \param r layer radius + /// \param zlen layer length + /// \param nstav number of staves + /// \param nmod IB: number of chips per stave + /// \param OB: number of modules per half stave + /// \param width stave width + /// \param tilt stave tilt angle + /// \param lthick stave thickness + /// \param dthick detector thickness + /// \param dettype detector type + 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& lthick, Double_t& mthick, UInt_t& dettype) const; + + /// This method is an example of how to add your own point of type Point to the clones array + Point* 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 SetNumberOfWrapperVolumes(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 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. + virtual TParticle* GetParticle() const; + + /// SetTrack and GetTrack methods from AliHit.h + virtual void SetTrack(Int_t track) + { + mTrackNumber = track; + } + + virtual Int_t GetTrack() const + { + return mTrackNumber; + } + + /// Prints out the content of this class in ASCII format + /// \param ostream *os The output stream + void Print(ostream* os) const; + + /// Reads in the content of this class in the format of Print + /// \param istream *is The input stream + void Read(istream* is); + + /// Returns the number of layers + Int_t GetNumberOfLayers() const + { + return mNumberLayers; + } + + virtual void SetStaveModelIB(Model model) + { + mStaveModelInnerBarrel = model; + } + + virtual void SetStaveModelOB(Model model) + { + mStaveModelOuterBarrel = model; + } + + virtual Model GetStaveModelIB() const + { + return mStaveModelInnerBarrel; + } + + virtual Model GetStaveModelOB() const + { + return mStaveModelOuterBarrel; + } + + UpgradeGeometryTGeo* mGeometryTGeo; ///< access to geometry details + +protected: + Int_t* mLayerID; ///< [mNumberLayers] layer identifier + Int_t mNumberLayers; ///< Number of layers + Int_t mStatus; ///< Track Status + Int_t mModule; ///< Module number + Float_t mParticlePx; ///< PX of particle at the point of the hit + Float_t mParticlePy; ///< PY of particle at the point of the hit + Float_t mParticlePz; ///< PZ of particle at the point of the hit + Float_t mEnergyDepositionStep; ///< Energy deposited in the current step + Float_t mTof; ///< Time of flight at the point of the hit + Int_t mStatus0; ///< Track Status of Starting point + Float_t mStartingStepX; ///< Starting point of this step + Float_t mStartingStepY; ///< Starting point of this step + Float_t mStartingStepZ; ///< Starting point of this step + Float_t mStartingStepT; ///< Starting point of this step + + Int_t mTrackNumber; ///< Track number + Float_t mPositionX; ///< X position of the hit + Float_t mPositionY; ///< Y position of the hit + Float_t mPositionZ; ///< Z position of the hit + + TString* mLayerName; ///<[mNumberLayers] layer identifier + +private: + /// Track information to be stored until the track leaves the + /// active volume. + + Int_t mTrackNumberID; ///< track index + Int_t mVolumeID; ///< volume id + Int_t mShunt; ///< shunt + TLorentzVector mPosition; ///< position + TLorentzVector mEntrancePosition; ///< position at entrance + TLorentzVector mMomentum; ///< momentum + Double32_t mEntranceTime; ///< time at entrance + Double32_t mTime; ///< time + Double32_t mLength; ///< length + Double32_t mEnergyLoss; ///< energy loss + + Int_t mNumberOfDetectors; + TArrayD mShiftX; + TArrayD mShiftY; + TArrayD mShiftZ; + TArrayD mRotX; + TArrayD mRotY; + TArrayD mRotZ; + + Bool_t mModifyGeometry; + + Int_t mNumberOfWrapperVolumes; ///< number of wrapper volumes + Double_t* mWrapperMinRadius; ///< min radius of wrapper volume + Double_t* mWrapperMaxRadius; ///< max radius of wrapper volume + Double_t* mWrapperZSpan; ///< Z span of wrapper volume + Int_t* mWrapperLayerId; ///< id of wrapper layer to which layer belongs (-1 if not wrapped) + Bool_t* mTurboLayer; ///< True for "turbo" layers + Double_t* mLayerPhi0; ///< Vector of layer's 1st stave phi in lab + Double_t* mLayerRadii; ///< Vector of layer radii + Double_t* mLayerZLength; ///< Vector of layer length along Z + Int_t* mStavePerLayer; ///< Vector of number of staves per layer + Int_t* mUnitPerStave; ///< Vector of number of "units" per stave + Double_t* mStaveThickness; ///< Vector of stave thicknesses + Double_t* mStaveWidth; ///< Vector of stave width (only used for turbo) + Double_t* mStaveTilt; ///< Vector of stave tilt (only used for turbo) + Double_t* mDetectorThickness; ///< Vector of detector thicknesses + UInt_t* mChipTypeID; ///< Vector of detector type id + Int_t* mBuildLevel; ///< Vector of Material Budget Studies + + /// Container for data points + TClonesArray* mPointCollection; + + /// 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(); + + Detector(const Detector&); + Detector& operator=(const Detector&); + + GeometryHandler* mGeometryHandler; + MisalignmentParameter* mMisalignmentParameter; + + UpgradeV1Layer** mUpgradeGeometry; ///< Geometry + Model mStaveModelInnerBarrel; ///< The stave model for the Inner Barrel + Model mStaveModelOuterBarrel; ///< The stave model for the Outer Barrel + + ClassDef(Detector, 1) +}; + +// Input and output function for standard C++ input/output. +ostream& operator<<(ostream& os, Detector& source); +istream& operator>>(istream& os, Detector& source); +} +} + +#endif diff --git a/its/GeometryHandler.cxx b/its/GeometryHandler.cxx new file mode 100644 index 0000000000000..5fb3b98e1cbaa --- /dev/null +++ b/its/GeometryHandler.cxx @@ -0,0 +1,208 @@ +/// \file GeometryHandler.cxx +/// \brief Implementation of the GeometryHandler class +/// \author F. Uhlig + +#include "GeometryHandler.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; + +using namespace AliceO2::ITS; + +GeometryHandler::GeometryHandler() + : TObject() + , mIsSimulation(kFALSE) + , mLastUsedDetectorId(0) + , mGeometryPathHash(0) + , mCurrentVolume(NULL) + , mVolumeShape(NULL) + , mGlobalCentre() + , mGlobalMatrix(NULL) +{ +} + +Int_t GeometryHandler::Init(Bool_t isSimulation) +{ + // Int_t geoVersion = CheckGeometryVersion(); + + mIsSimulation = isSimulation; + + return 1; +} + +void GeometryHandler::LocalToGlobal(Double_t* local, Double_t* global, Int_t detectorId) +{ + TString path = ConstructFullPathFromDetectorId(detectorId); + NavigateTo(path); + gGeoManager->LocalToMaster(local, global); +} + +TString GeometryHandler::ConstructFullPathFromDetectorId(Int_t detectorId) +{ + TString volumeString = "/cave_1/tutorial4_0/tut4_det_"; + TString volumePath = volumeString; + volumePath += detectorId; + return volumePath; +} + +Int_t GeometryHandler::GetUniqueDetectorId(TString volumeName) +{ + if (mGeometryPathHash != volumeName.Hash()) { + NavigateTo(volumeName); + } + return GetUniqueDetectorId(); +} + +Int_t GeometryHandler::GetUniqueDetectorId() +{ + Int_t detectorNumber = 0; + + CurrentVolumeOffId(0, detectorNumber); + + return detectorNumber; +} + +Int_t GeometryHandler::VolumeIdGeo(const char* name) const +{ + Int_t uid = gGeoManager->GetUID(name); + if (uid < 0) { + printf("VolId: Volume %s not found\n", name); + return 0; + } + return uid; +} + +Int_t GeometryHandler::VolumeId(const Text_t* name) const +{ + if (mIsSimulation) { + return gMC->VolId(name); + } + else { + char sname[20]; + Int_t length = strlen(name) - 1; + + if (name[length] != ' ') { + return VolumeIdGeo(name); + } + + strncpy(sname, name, length); + sname[length] = 0; + return VolumeIdGeo(sname); + } +} + +Int_t GeometryHandler::CurrentVolumeId(Int_t& copy) const +{ + if (mIsSimulation) { + return gMC->CurrentVolID(copy); + } + else { + if (gGeoManager->IsOutside()) { + return 0; + } + TGeoNode* node = gGeoManager->GetCurrentNode(); + copy = node->GetNumber(); + Int_t id = node->GetVolume()->GetNumber(); + return id; + } +} + +//_____________________________________________________________________________ +Int_t GeometryHandler::CurrentVolumeOffId(Int_t off, Int_t& copy) const +{ + if (mIsSimulation) { + return gMC->CurrentVolOffID(off, copy); + } + else { + if (off < 0 || off > gGeoManager->GetLevel()) { + return 0; + } + + if (off == 0) { + return CurrentVolumeId(copy); + } + + TGeoNode* node = gGeoManager->GetMother(off); + + if (!node) { + return 0; + } + + copy = node->GetNumber(); + return node->GetVolume()->GetNumber(); + } +} + +const char* GeometryHandler::CurrentVolumeName() const +{ + if (mIsSimulation) { + return gMC->CurrentVolName(); + } + else { + if (gGeoManager->IsOutside()) { + return gGeoManager->GetTopVolume()->GetName(); + } + + return gGeoManager->GetCurrentVolume()->GetName(); + } +} + +const char* GeometryHandler::CurrentVolumeOffName(Int_t off) const +{ + if (mIsSimulation) { + return gMC->CurrentVolOffName(off); + } + else { + if (off < 0 || off > gGeoManager->GetLevel()) { + return 0; + } + + if (off == 0) { + return CurrentVolumeName(); + } + + TGeoNode* node = gGeoManager->GetMother(off); + + if (!node) { + return 0; + } + + return node->GetVolume()->GetName(); + } +} + +void GeometryHandler::NavigateTo(TString volumeName) +{ + if (mIsSimulation) { + LOG(FATAL) << "This method is not supported in simulation mode" << FairLogger::endl; + } + else { + gGeoManager->cd(volumeName.Data()); + mGeometryPathHash = volumeName.Hash(); + mCurrentVolume = gGeoManager->GetCurrentVolume(); + mVolumeShape = (TGeoBBox*)mCurrentVolume->GetShape(); + Double_t local[3] = { 0., 0., 0. }; // Local centre of volume + gGeoManager->LocalToMaster(local, mGlobalCentre); + LOG(DEBUG2) << "Pos: " << mGlobalCentre[0] << " , " << mGlobalCentre[1] << " , " + << mGlobalCentre[2] << FairLogger::endl; + // mGlobalMatrix = gGeoManager->GetCurrentMatrix(); + } +} + +ClassImp(GeometryHandler) diff --git a/its/GeometryHandler.h b/its/GeometryHandler.h new file mode 100644 index 0000000000000..b9b3a597d410e --- /dev/null +++ b/its/GeometryHandler.h @@ -0,0 +1,90 @@ +/// \file GeometryHandler.h +/// \brief Definition of the GeometryHandler class +/// \author F. Uhlig + +#ifndef ALICEO2_ITS_GEOMETRYHANDLER_H_ +#define ALICEO2_ITS_GEOMETRYHANDLER_H_ + +#include "Rtypes.h" // for Int_t, Double_t, Bool_t, etc +#include "TObject.h" // for TObject +#include "TString.h" // for TString + +class TGeoBBox; +class TGeoVolume; +class TGeoHMatrix; + +namespace AliceO2 { +namespace ITS { + +/// 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. +class GeometryHandler : public TObject { + +public: + /// Default constructor + GeometryHandler(); + + /// Default destructor + ~GeometryHandler() {}; + + Int_t GetUniqueDetectorId(); + + Int_t GetUniqueDetectorId(TString volumeName); + + // Int_t GetDetectorId(Int_t uniqueId); + + Int_t Init(Bool_t isSimulation = kFALSE); + + void FillDetectorInfoArray(Int_t uniqueId); + + void NavigateTo(TString volumeName); + + // Implement Interface functions to the TGeoManager to be + // the same as for the VMC + + /// Return the current volume "off" upward in the geometrical tree ID and copy number + Int_t CurrentVolumeOffId(Int_t off, Int_t& copy) const; + + /// Returns the current volume ID and copy number + Int_t CurrentVolumeId(Int_t& copy) const; + + /// Returns the unique numeric identifier for volume name + Int_t VolumeId(const Text_t* name) const; + + /// Returns the unique numeric identifier for volume name + Int_t VolumeIdGeo(const char* name) const; + + /// Returns the current volume name + const char* CurrentVolumeName() const; + + /// Returns the current volume "off" upward in the geometrical tree ID, name and copy number + /// if name=0 no name is returned + const char* CurrentVolumeOffName(Int_t off) const; + + void LocalToGlobal(Double_t* local, Double_t* global, Int_t detectorId); + + // Int_t CheckGeometryVersion(); + +private: + Bool_t mIsSimulation; + + Int_t mLastUsedDetectorId; + + UInt_t mGeometryPathHash; + TGeoVolume* mCurrentVolume; + TGeoBBox* mVolumeShape; + Double_t mGlobalCentre[3]; ///< Global centre of volume + TGeoHMatrix* mGlobalMatrix; + + TString ConstructFullPathFromDetectorId(Int_t detectorId); + + GeometryHandler(const GeometryHandler&); + + GeometryHandler operator=(const GeometryHandler&); + + ClassDef(GeometryHandler, 1) +}; +} +} + +#endif diff --git a/its/GeometryManager.cxx b/its/GeometryManager.cxx new file mode 100644 index 0000000000000..6a6e2ea561b97 --- /dev/null +++ b/its/GeometryManager.cxx @@ -0,0 +1,125 @@ +/// \file GeometryManager.cxx +/// \brief Implementation of the GeometryManager class + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GeometryManager.h" + +#include "FairLogger.h" + +using namespace AliceO2::ITS; + +ClassImp(GeometryManager) + +TGeoManager* GeometryManager::mGeometry = 0x0; + +/// Implementation of GeometryManager, 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 +GeometryManager::GeometryManager() + : TObject() +{ +} + +GeometryManager::~GeometryManager() +{ +} + +Bool_t GeometryManager::GetOriginalGlobalMatrix(const char* symname, TGeoHMatrix& m) +{ + m.Clear(); + + if (!mGeometry || !mGeometry->IsClosed()) { + LOG(ERROR) << "No active geometry or geometry not yet closed!" << FairLogger::endl; + return kFALSE; + } + + if (!mGeometry->GetListOfPhysicalNodes()) { + LOG(WARNING) << "gGeoManager doesn't contain any aligned nodes!" << FairLogger::endl; + + if (!mGeometry->cd(symname)) { + LOG(ERROR) << "Volume path " << symname << " not valid!" << FairLogger::endl; + return kFALSE; + } + else { + m = *mGeometry->GetCurrentMatrix(); + return kTRUE; + } + } + + TGeoPNEntry* pne = mGeometry->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 GetOriginalGlobalMatrixFromPath(path, m); +} + +Bool_t GeometryManager::GetOriginalGlobalMatrixFromPath(const char* path, TGeoHMatrix& m) +{ + m.Clear(); + + if (!mGeometry || !mGeometry->IsClosed()) { + LOG(ERROR) + << "Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!" + << FairLogger::endl; + return kFALSE; + } + + if (!mGeometry->CheckPath(path)) { + LOG(ERROR) << "Volume path " << path << " not valid!" << FairLogger::endl; + return kFALSE; + } + + TIter next(mGeometry->GetListOfPhysicalNodes()); + mGeometry->cd(path); + + while (mGeometry->GetLevel()) { + TGeoPhysicalNode* physNode = NULL; + next.Reset(); + TGeoNode* node = mGeometry->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); + + mGeometry->CdUp(); + } + return kTRUE; +} diff --git a/its/GeometryManager.h b/its/GeometryManager.h new file mode 100644 index 0000000000000..017c64cacaea6 --- /dev/null +++ b/its/GeometryManager.h @@ -0,0 +1,77 @@ +/// \file GeometryManager.h +/// \brief Definition of the GeometryManager class + +#ifndef ALICEO2_ITS_GEOMETRYMANAGER_H_ +#define ALICEO2_ITS_GEOMETRYMANAGER_H_ + +#include + +class TGeoManager; +class TGeoPNEntry; +class TGeoHMatrix; +class TObjArray; + +namespace AliceO2 { +namespace ITS { + +/// 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 +class GeometryManager : 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 + }; + + /// 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. + static Bool_t GetOriginalGlobalMatrix(const char* symname, TGeoHMatrix& m); + + /// Default destructor + ~GeometryManager(); + +private: + /// Default constructor + GeometryManager(); + + /// 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. + static Bool_t GetOriginalGlobalMatrixFromPath(const char* path, TGeoHMatrix& m); + + static TGeoManager* mGeometry; + + ClassDef(GeometryManager, 0); // Manager of geometry information for alignment +}; +} +} + +#endif diff --git a/its/MisalignmentParameter.cxx b/its/MisalignmentParameter.cxx new file mode 100644 index 0000000000000..1c5903d288d42 --- /dev/null +++ b/its/MisalignmentParameter.cxx @@ -0,0 +1,89 @@ +/// \file MisalignmentParameter.cxx +/// \brief Implementation of the MisalignmentParameter class + +#include "MisalignmentParameter.h" + +#include "FairParamList.h" + +using namespace AliceO2::ITS; + +ClassImp(MisalignmentParameter) + +MisalignmentParameter::MisalignmentParameter(const char* name, const char* title, + const char* context) + : FairParGenericSet(name, title, context) + , mShiftX() + , mShiftY() + , mShiftZ() + , mRotX() + , mRotY() + , mRotZ() + , mNumberOfDetectors(0) +{ +} + +MisalignmentParameter::~MisalignmentParameter(void) +{ +} + +void MisalignmentParameter::Clear(void) +{ +} + +void MisalignmentParameter::PutParams(FairParamList* list) +{ + if (!list) { + return; + } + + list->add("NumberOfDetectors", mNumberOfDetectors); + list->add("ShiftX", mShiftX); + list->add("ShiftY", mShiftY); + list->add("ShiftZ", mShiftZ); + list->add("RotationX", mRotX); + list->add("RotationY", mRotY); + list->add("RotationZ", mRotZ); +} + +Bool_t MisalignmentParameter::GetParams(FairParamList* list) +{ + if (!list) { + return kFALSE; + } + + if (!list->fill("NumberOfDetectors", &mNumberOfDetectors)) { + return kFALSE; + } + + mShiftX.Set(mNumberOfDetectors); + if (!list->fill("ShiftX", &mShiftX)) { + return kFALSE; + } + + mShiftY.Set(mNumberOfDetectors); + if (!list->fill("ShiftY", &mShiftY)) { + return kFALSE; + } + + mShiftZ.Set(mNumberOfDetectors); + if (!list->fill("ShiftZ", &mShiftZ)) { + return kFALSE; + } + + mRotX.Set(mNumberOfDetectors); + if (!list->fill("RotationX", &mRotX)) { + return kFALSE; + } + + mRotY.Set(mNumberOfDetectors); + if (!list->fill("RotationY", &mRotY)) { + return kFALSE; + } + + mRotZ.Set(mNumberOfDetectors); + if (!list->fill("RotationZ", &mRotZ)) { + return kFALSE; + } + + return kTRUE; +} diff --git a/its/MisalignmentParameter.h b/its/MisalignmentParameter.h new file mode 100644 index 0000000000000..c824d02ea0f19 --- /dev/null +++ b/its/MisalignmentParameter.h @@ -0,0 +1,78 @@ +/// \file MisalignmentParameter.h +/// \brief Definition of the MisalignmentParameter class + +#ifndef ALICEO2_ITS_MISALIGNMENTPARAMETER_H_ +#define ALICEO2_ITS_MISALIGNMENTPARAMETER_H_ + +#include "FairParGenericSet.h" // for FairParGenericSet + +#include "Rtypes.h" // for ClassDef + +#include "TArrayD.h" // for TArrayD + +class FairParamList; + +namespace AliceO2 { +namespace ITS { + +class MisalignmentParameter : public FairParGenericSet { + +public: + MisalignmentParameter( + const char* name = "MisalignmentParameter", + const char* title = + "Misalignment parameter for AliceO2ITSHitProducerIdealMisallign Parameters", + const char* context = "TestDefaultContext"); + ~MisalignmentParameter(void); + + void Clear(void); + void PutParams(FairParamList*); + Bool_t GetParams(FairParamList*); + + TArrayD GetShiftX() + { + return mShiftX; + } + TArrayD GetShiftY() + { + return mShiftY; + } + TArrayD GetShiftZ() + { + return mShiftZ; + } + TArrayD GetRotX() + { + return mRotX; + } + TArrayD GetRotY() + { + return mRotY; + } + TArrayD GetRotZ() + { + return mRotZ; + } + Int_t GetNumberOfDetectors() + { + return mNumberOfDetectors; + } + +private: + TArrayD mShiftX; ///< Array to hold the misalignment in x-direction + TArrayD mShiftY; ///< Array to hold the misalignment in y-direction + TArrayD mShiftZ; ///< Array to hold the misalignment in z-direction + TArrayD mRotX; ///< Array to hold the rotation in x-direction + TArrayD mRotY; ///< Array to hold the rotation in y-direction + TArrayD mRotZ; ///< Array to hold the rotation in z-direction + Int_t mNumberOfDetectors; ///< Total number of detectors + + MisalignmentParameter(const MisalignmentParameter&); + MisalignmentParameter& operator=(const MisalignmentParameter&); + + ClassDef(MisalignmentParameter, 1) +}; +} +} + +#endif diff --git a/its/O2its.cxx b/its/O2its.cxx deleted file mode 100644 index 51cbc290008c2..0000000000000 --- a/its/O2its.cxx +++ /dev/null @@ -1,968 +0,0 @@ -#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 deleted file mode 100644 index 175749ebc1933..0000000000000 --- a/its/O2its.h +++ /dev/null @@ -1,237 +0,0 @@ -#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 deleted file mode 100644 index 48024690f2a88..0000000000000 --- a/its/O2itsContFact.cxx +++ /dev/null @@ -1,51 +0,0 @@ -#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 deleted file mode 100644 index a500d0305a316..0000000000000 --- a/its/O2itsContFact.h +++ /dev/null @@ -1,19 +0,0 @@ -#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 deleted file mode 100644 index 54e4cca343fa5..0000000000000 --- a/its/O2itsDigi.cxx +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 deleted file mode 100644 index a61fa99bd2bff..0000000000000 --- a/its/O2itsDigi.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 deleted file mode 100644 index 8826a551f67b2..0000000000000 --- a/its/O2itsDigiTask.cxx +++ /dev/null @@ -1,99 +0,0 @@ -#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 deleted file mode 100644 index 5eb3743cbfed0..0000000000000 --- a/its/O2itsDigiTask.h +++ /dev/null @@ -1,45 +0,0 @@ -#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 deleted file mode 100644 index d6a8a66e41bdb..0000000000000 --- a/its/O2itsGeoHandler.cxx +++ /dev/null @@ -1,197 +0,0 @@ -#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 deleted file mode 100644 index 0fffa1162eb9d..0000000000000 --- a/its/O2itsGeoHandler.h +++ /dev/null @@ -1,82 +0,0 @@ -// ------------------------------------------------------------------------- -// ----- 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 index 0ae404b314dec..2585fd1632848 100644 --- a/its/O2itsLinkDef.h +++ b/its/O2itsLinkDef.h @@ -4,18 +4,16 @@ #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+; +#pragma link C++ class AliceO2::ITS::UpgradeGeometryTGeo+; +#pragma link C++ class AliceO2::ITS::V11Geometry+; +#pragma link C++ class AliceO2::ITS::UpgradeV1Layer+; +#pragma link C++ class AliceO2::ITS::Segmentation+; +#pragma link C++ class AliceO2::ITS::UpgradeSegmentationPixel+; +#pragma link C++ class AliceO2::ITS::GeometryManager+; +#pragma link C++ class AliceO2::ITS::Detector+; +#pragma link C++ class AliceO2::ITS::ContainerFactory; +#pragma link C++ class AliceO2::ITS::GeometryHandler+; +#pragma link C++ class AliceO2::ITS::MisalignmentParameter+; +#pragma link C++ class AliceO2::ITS::Point+; #endif diff --git a/its/O2itsMisalignPar.cxx b/its/O2itsMisalignPar.cxx deleted file mode 100644 index ed13eb845f3d2..0000000000000 --- a/its/O2itsMisalignPar.cxx +++ /dev/null @@ -1,70 +0,0 @@ -#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 deleted file mode 100644 index a726e0aa58e7a..0000000000000 --- a/its/O2itsMisalignPar.h +++ /dev/null @@ -1,48 +0,0 @@ -#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 deleted file mode 100644 index f715a8211c98d..0000000000000 --- a/its/O2itsPoint.cxx +++ /dev/null @@ -1,49 +0,0 @@ -#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 deleted file mode 100644 index 89091e946a0cc..0000000000000 --- a/its/O2itsPoint.h +++ /dev/null @@ -1,70 +0,0 @@ -#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/its/Point.cxx b/its/Point.cxx new file mode 100644 index 0000000000000..0846e0b7eac4c --- /dev/null +++ b/its/Point.cxx @@ -0,0 +1,36 @@ +/// \file Point.cxx +/// \brief Implementation of the Point class + +#include "Point.h" + +#include + +using std::cout; +using std::endl; +using namespace AliceO2::ITS; + +Point::Point() + : FairMCPoint() +{ +} + +Point::Point(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) +{ +} + +Point::~Point() +{ +} + +void Point::Print(const Option_t* opt) const +{ + cout << "-I- Point: 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(Point) diff --git a/its/Point.h b/its/Point.h new file mode 100644 index 0000000000000..f1758954c3c4f --- /dev/null +++ b/its/Point.h @@ -0,0 +1,51 @@ +/// \file Point.h +/// \brief Definition of the Point class + +#ifndef ALICEO2_ITS_POINT_H_ +#define ALICEO2_ITS_POINT_H_ + +#include "FairMCPoint.h" + +#include "TObject.h" +#include "TVector3.h" + +namespace AliceO2 { +namespace ITS { + +class Point : public FairMCPoint { + +public: + /// Default constructor + Point(); + + /// Class Constructor + /// \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 + Point(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); + + // Default Destructor + virtual ~Point(); + + /// Output to screen + virtual void Print(const Option_t* opt) const; + +private: + /// Copy constructor + Point(const Point& point); + Point operator=(const Point& point); + + ClassDef(Point, 1) +}; +} +} + +#endif diff --git a/its/Segmentation.cxx b/its/Segmentation.cxx new file mode 100644 index 0000000000000..d0e41ca4a061c --- /dev/null +++ b/its/Segmentation.cxx @@ -0,0 +1,59 @@ +/// \file Segmentation.cxx +/// \brief Implementation of the Segmentation class + +#include +#include "Segmentation.h" + +using namespace AliceO2::ITS; + +ClassImp(Segmentation) + +Segmentation::Segmentation() + : mDx(0) + , mDz(0) + , mDy(0) + , mCorrection(0) +{ +} + +Segmentation::~Segmentation() +{ + if (mCorrection) { + delete mCorrection; + } +} + +void Segmentation::Copy(TObject& obj) const +{ + // copy this to obj + ((Segmentation&)obj).mDz = mDz; + ((Segmentation&)obj).mDx = mDx; + ((Segmentation&)obj).mDy = mDy; + + if (mCorrection) { + ((Segmentation&)obj).mCorrection = new TF1(*mCorrection); // make a proper copy + } + else { + ((Segmentation&)obj).mCorrection = 0; + } +} + +Segmentation& Segmentation::operator=(const Segmentation& source) +{ + // Operator = + if (this != &source) { + source.Copy(*this); + } + return *this; +} + +Segmentation::Segmentation(const Segmentation& source) + : TObject(source) + , mDx(0) + , mDz(0) + , mDy(0) + , mCorrection(0) +{ + // copy constructor + source.Copy(*this); +} diff --git a/its/Segmentation.h b/its/Segmentation.h new file mode 100644 index 0000000000000..8127cb5afa9c9 --- /dev/null +++ b/its/Segmentation.h @@ -0,0 +1,201 @@ +/// \file Segmentation.h +/// \brief Definition of the Segmentation class + +#ifndef ALICEO2_ITS_SEGMENTATION_H_ +#define ALICEO2_ITS_SEGMENTATION_H_ + +#include + +class TF1; + +namespace AliceO2 { +namespace ITS { + +/// ITS segmentation virtual base class +/// 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 +class Segmentation : public TObject { + +public: + /// Default constructor + Segmentation(); + + Segmentation(const Segmentation& source); + + /// Default destructor + virtual ~Segmentation(); + + AliceO2::ITS::Segmentation& operator=(const AliceO2::ITS::Segmentation& source); + + /// Set Detector Segmentation Parameters + + /// Detector size + virtual void SetDetSize(Float_t p1, Float_t p2, Float_t p3) + { + mDx = p1; + mDz = p2; + mDy = 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 LocalToDetector(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 DetectorToLocal(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 mDx; + } + + /// Detector width + virtual Float_t Dz() const + { + return mDz; + } + + /// Detector thickness + virtual Float_t Dy() const + { + return mDy; + } + + /// 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) + { + mCorrection = fc; + } + + /// Get the correction Function + virtual TF1* CorrFunc() + { + return mCorrection; + } + + /// Print Default parameters + virtual void PrintDefaultParameters() const = 0; + +protected: + virtual void Copy(TObject& obj) const; + + Float_t mDx; // 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 mDz; // 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 mDy; // 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* mCorrection; // correction function + + ClassDef(Segmentation, 1) // Segmentation virtual base class +}; +} +} +#endif diff --git a/its/UpgradeGeometryTGeo.cxx b/its/UpgradeGeometryTGeo.cxx new file mode 100644 index 0000000000000..25ae141c74581 --- /dev/null +++ b/its/UpgradeGeometryTGeo.cxx @@ -0,0 +1,1028 @@ +/// \file UpgradeGeometryTGeo.cxx +/// \brief Implementation of the UpgradeGeometryTGeo class +/// \author cvetan.cheshkov@cern.ch - 15/02/2007 +/// \author ruben.shahoyan@cern.ch - adapted to ITSupg 18/07/2012 + +// ATTENTION: In opposite to old AliITSgeomTGeo, all indices start from 0, not from 1!!! + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GeometryManager.h" +#include "Segmentation.h" +#include "UpgradeGeometryTGeo.h" +#include "UpgradeSegmentationPixel.h" + +#include "FairLogger.h" + +using namespace TMath; +using namespace AliceO2::ITS; + +ClassImp(UpgradeGeometryTGeo) + +UInt_t UpgradeGeometryTGeo::mUIDShift = 16; // bit shift to go from mod.id to modUUID for TGeo +TString UpgradeGeometryTGeo::mVolumeName = "ITSV"; +TString UpgradeGeometryTGeo::mLayerName = "ITSULayer"; +TString UpgradeGeometryTGeo::mStaveName = "ITSUStave"; +TString UpgradeGeometryTGeo::mHalfStaveName = "ITSUHalfStave"; +TString UpgradeGeometryTGeo::mModuleName = "ITSUModule"; +TString UpgradeGeometryTGeo::mChipName = "ITSUChip"; +TString UpgradeGeometryTGeo::mSensorName = "ITSUSensor"; +TString UpgradeGeometryTGeo::mWrapperVolumeName = "ITSUWrapVol"; +TString UpgradeGeometryTGeo::mChipTypeName[UpgradeGeometryTGeo::kNChipTypes] = { "Pix" }; + +TString UpgradeGeometryTGeo::mSegmentationFileName = "itsSegmentations.root"; + +UpgradeGeometryTGeo::UpgradeGeometryTGeo(Bool_t build, Bool_t loadSegmentations) + : mVersion(kITSVNA) + , mNumberOfLayers(0) + , mNumberOfChips(0) + , mNumberOfStaves(0) + , mNumberOfHalfStaves(0) + , mNumberOfModules(0) + , mNumberOfChipsPerModule(0) + , mNumberOfChipRowsPerModule(0) + , mNumberOfChipsPerHalfStave(0) + , mNumberOfChipsPerStave(0) + , mNumberOfChipsPerLayer(0) + , mLayerChipType(0) + , mLastChipIndex(0) + , mSensorMatrices(0) + , mTrackingToLocalMatrices(0) + , mSegmentations(0) +{ + // default c-tor + for (int i = gMaxLayers; i--;) { + mLayerToWrapper[i] = -1; + } + if (build) { + Build(loadSegmentations); + } +} + +UpgradeGeometryTGeo::UpgradeGeometryTGeo(const UpgradeGeometryTGeo& src) + : TObject(src) + , mVersion(src.mVersion) + , mNumberOfLayers(src.mNumberOfLayers) + , mNumberOfChips(src.mNumberOfChips) + , mNumberOfStaves(0) + , mNumberOfHalfStaves(0) + , mNumberOfModules(0) + , mNumberOfChipsPerModule(0) + , mNumberOfChipRowsPerModule(0) + , mNumberOfChipsPerHalfStave(0) + , mNumberOfChipsPerStave(0) + , mNumberOfChipsPerLayer(0) + , mLayerChipType(0) + , mLastChipIndex(0) + , mSensorMatrices(0) + , mTrackingToLocalMatrices(0) + , mSegmentations(0) +{ + // copy c-tor + if (mNumberOfLayers) { + mNumberOfStaves = new Int_t[mNumberOfLayers]; + mNumberOfChipsPerModule = new Int_t[mNumberOfLayers]; + mNumberOfChipRowsPerModule = new Int_t[mNumberOfLayers]; + mLayerChipType = new Int_t[mNumberOfLayers]; + mLastChipIndex = new Int_t[mNumberOfLayers]; + mNumberOfChipsPerHalfStave = new Int_t[mNumberOfLayers]; + mNumberOfChipsPerStave = new Int_t[mNumberOfLayers]; + mNumberOfChipsPerLayer = new Int_t[mNumberOfLayers]; + + for (int i = mNumberOfLayers; i--;) { + mNumberOfStaves[i] = src.mNumberOfStaves[i]; + mNumberOfHalfStaves[i] = src.mNumberOfHalfStaves[i]; + mNumberOfModules[i] = src.mNumberOfModules[i]; + mNumberOfChipsPerModule[i] = src.mNumberOfChipsPerModule[i]; + mNumberOfChipRowsPerModule[i] = src.mNumberOfChipRowsPerModule[i]; + mNumberOfChipsPerHalfStave[i] = src.mNumberOfChipsPerHalfStave[i]; + mNumberOfChipsPerStave[i] = src.mNumberOfChipsPerStave[i]; + mNumberOfChipsPerLayer[i] = src.mNumberOfChipsPerLayer[i]; + mLayerChipType[i] = src.mLayerChipType[i]; + mLastChipIndex[i] = src.mLastChipIndex[i]; + } + if (src.mSensorMatrices) { + mSensorMatrices = new TObjArray(mNumberOfChips); + mSensorMatrices->SetOwner(kTRUE); + for (int i = 0; i < mNumberOfChips; i++) { + const TGeoHMatrix* mat = (TGeoHMatrix*)src.mSensorMatrices->At(i); + mSensorMatrices->AddAt(new TGeoHMatrix(*mat), i); + } + } + if (src.mTrackingToLocalMatrices) { + mTrackingToLocalMatrices = new TObjArray(mNumberOfChips); + mTrackingToLocalMatrices->SetOwner(kTRUE); + for (int i = 0; i < mNumberOfChips; i++) { + const TGeoHMatrix* mat = (TGeoHMatrix*)src.mTrackingToLocalMatrices->At(i); + mTrackingToLocalMatrices->AddAt(new TGeoHMatrix(*mat), i); + } + } + if (src.mSegmentations) { + int sz = src.mSegmentations->GetEntriesFast(); + mSegmentations = new TObjArray(sz); + mSegmentations->SetOwner(kTRUE); + for (int i = 0; i < sz; i++) { + Segmentation* sg = (Segmentation*)src.mSegmentations->UncheckedAt(i); + if (!sg) { + continue; + } + mSegmentations->AddAt(sg->Clone(), i); + } + } + } + for (int i = gMaxLayers; i--;) { + mLayerToWrapper[i] = src.mLayerToWrapper[i]; + } +} + +UpgradeGeometryTGeo::~UpgradeGeometryTGeo() +{ + // d-tor + delete[] mNumberOfStaves; + delete[] mNumberOfHalfStaves; + delete[] mNumberOfModules; + delete[] mLayerChipType; + delete[] mNumberOfChipsPerModule; + delete[] mNumberOfChipRowsPerModule; + delete[] mNumberOfChipsPerHalfStave; + delete[] mNumberOfChipsPerStave; + delete[] mNumberOfChipsPerLayer; + delete[] mLastChipIndex; + delete mTrackingToLocalMatrices; + delete mSensorMatrices; + delete mSegmentations; +} + +UpgradeGeometryTGeo& UpgradeGeometryTGeo::operator=(const UpgradeGeometryTGeo& src) +{ + // cp op. + if (this != &src) { + delete[] mNumberOfStaves; + delete[] mNumberOfHalfStaves; + delete[] mNumberOfModules; + delete[] mLayerChipType; + delete[] mNumberOfChipsPerModule; + delete[] mNumberOfChipRowsPerModule; + delete[] mNumberOfChipsPerHalfStave; + delete[] mNumberOfChipsPerStave; + delete[] mNumberOfChipsPerLayer; + delete[] mLastChipIndex; + mNumberOfStaves = mNumberOfHalfStaves = mNumberOfModules = mLayerChipType = + mNumberOfChipsPerModule = mLastChipIndex = 0; + mVersion = src.mVersion; + mNumberOfLayers = src.mNumberOfLayers; + mNumberOfChips = src.mNumberOfChips; + if (src.mSensorMatrices) { + delete mSensorMatrices; + mSensorMatrices = new TObjArray(mNumberOfChips); + mSensorMatrices->SetOwner(kTRUE); + for (int i = 0; i < mNumberOfChips; i++) { + const TGeoHMatrix* mat = (TGeoHMatrix*)src.mSensorMatrices->At(i); + mSensorMatrices->AddAt(new TGeoHMatrix(*mat), i); + } + } + if (src.mTrackingToLocalMatrices) { + delete mTrackingToLocalMatrices; + mTrackingToLocalMatrices = new TObjArray(mNumberOfChips); + mTrackingToLocalMatrices->SetOwner(kTRUE); + for (int i = 0; i < mNumberOfChips; i++) { + const TGeoHMatrix* mat = (TGeoHMatrix*)src.mTrackingToLocalMatrices->At(i); + mTrackingToLocalMatrices->AddAt(new TGeoHMatrix(*mat), i); + } + } + if (src.mSegmentations) { + int sz = src.mSegmentations->GetEntriesFast(); + mSegmentations = new TObjArray(sz); + mSegmentations->SetOwner(kTRUE); + for (int i = 0; i < sz; i++) { + Segmentation* sg = (Segmentation*)src.mSegmentations->UncheckedAt(i); + if (!sg) { + continue; + } + mSegmentations->AddAt(sg->Clone(), i); + } + } + + if (mNumberOfLayers) { + mNumberOfStaves = new Int_t[mNumberOfLayers]; + mNumberOfHalfStaves = new Int_t[mNumberOfLayers]; + mNumberOfModules = new Int_t[mNumberOfLayers]; + mNumberOfChipsPerModule = new Int_t[mNumberOfLayers]; + mNumberOfChipRowsPerModule = new Int_t[mNumberOfLayers]; + mNumberOfChipsPerHalfStave = new Int_t[mNumberOfLayers]; + mNumberOfChipsPerStave = new Int_t[mNumberOfLayers]; + mNumberOfChipsPerLayer = new Int_t[mNumberOfLayers]; + mLayerChipType = new Int_t[mNumberOfLayers]; + mLastChipIndex = new Int_t[mNumberOfLayers]; + for (int i = mNumberOfLayers; i--;) { + mNumberOfStaves[i] = src.mNumberOfStaves[i]; + mNumberOfHalfStaves[i] = src.mNumberOfHalfStaves[i]; + mNumberOfModules[i] = src.mNumberOfModules[i]; + mNumberOfChipsPerModule[i] = src.mNumberOfChipsPerModule[i]; + mNumberOfChipRowsPerModule[i] = src.mNumberOfChipRowsPerModule[i]; + mNumberOfChipsPerHalfStave[i] = src.mNumberOfChipsPerHalfStave[i]; + mNumberOfChipsPerStave[i] = src.mNumberOfChipsPerStave[i]; + mNumberOfChipsPerLayer[i] = src.mNumberOfChipsPerLayer[i]; + mLayerChipType[i] = src.mLayerChipType[i]; + mLastChipIndex[i] = src.mLastChipIndex[i]; + } + } + } + return *this; +} + +Int_t UpgradeGeometryTGeo::GetChipIndex(Int_t lay, Int_t sta, Int_t chipInStave) const +{ + return GetFirstChipIndex(lay) + mNumberOfChipsPerStave[lay] * sta + chipInStave; +} + +Int_t UpgradeGeometryTGeo::GetChipIndex(Int_t lay, Int_t sta, Int_t substa, Int_t chipInSStave) + const +{ + int n = GetFirstChipIndex(lay) + mNumberOfChipsPerStave[lay] * sta + chipInSStave; + if (mNumberOfHalfStaves[lay] && substa > 0) { + n += mNumberOfChipsPerHalfStave[lay] * substa; + } + return n; +} + +Int_t UpgradeGeometryTGeo::GetChipIndex(Int_t lay, Int_t sta, Int_t substa, Int_t md, + Int_t chipInMod) const +{ + int n = GetFirstChipIndex(lay) + mNumberOfChipsPerStave[lay] * sta + chipInMod; + if (mNumberOfHalfStaves[lay] && substa > 0) { + n += mNumberOfChipsPerHalfStave[lay] * substa; + } + if (mNumberOfModules[lay] && md > 0) { + n += mNumberOfChipsPerModule[lay] * md; + } + return n; +} + +Bool_t UpgradeGeometryTGeo::GetLayer(Int_t index, Int_t& lay, Int_t& indexInLr) const +{ + lay = GetLayer(index); + indexInLr = index - GetFirstChipIndex(lay); + return kTRUE; +} + +Int_t UpgradeGeometryTGeo::GetLayer(Int_t index) const +{ + int lay = 0; + while (index > mLastChipIndex[lay]) { + lay++; + } + return lay; +} + +Int_t UpgradeGeometryTGeo::GetStave(Int_t index) const +{ + int lay = 0; + while (index > mLastChipIndex[lay]) { + lay++; + } + index -= GetFirstChipIndex(lay); + return index / mNumberOfChipsPerStave[lay]; +} + +Int_t UpgradeGeometryTGeo::GetHalfStave(Int_t index) const +{ + int lay = 0; + while (index > mLastChipIndex[lay]) { + lay++; + } + if (mNumberOfHalfStaves[lay] < 0) { + return -1; + } + index -= GetFirstChipIndex(lay); + index %= mNumberOfChipsPerStave[lay]; + return index / mNumberOfChipsPerHalfStave[lay]; +} + +Int_t UpgradeGeometryTGeo::GetModule(Int_t index) const +{ + int lay = 0; + while (index > mLastChipIndex[lay]) { + lay++; + } + if (mNumberOfModules[lay] < 0) { + return 0; + } + index -= GetFirstChipIndex(lay); + index %= mNumberOfChipsPerStave[lay]; + if (mNumberOfHalfStaves[lay]) { + index %= mNumberOfChipsPerHalfStave[lay]; + } + return index / mNumberOfChipsPerModule[lay]; +} + +Int_t UpgradeGeometryTGeo::GetChipIdInLayer(Int_t index) const +{ + int lay = 0; + while (index > mLastChipIndex[lay]) { + lay++; + } + index -= GetFirstChipIndex(lay); + return index; +} + +Int_t UpgradeGeometryTGeo::GetChipIdInStave(Int_t index) const +{ + int lay = 0; + while (index > mLastChipIndex[lay]) { + lay++; + } + index -= GetFirstChipIndex(lay); + return index % mNumberOfChipsPerStave[lay]; +} + +Int_t UpgradeGeometryTGeo::GetChipIdInHalfStave(Int_t index) const +{ + int lay = 0; + while (index > mLastChipIndex[lay]) { + lay++; + } + index -= GetFirstChipIndex(lay); + return index % mNumberOfChipsPerHalfStave[lay]; +} + +Int_t UpgradeGeometryTGeo::GetChipIdInModule(Int_t index) const +{ + int lay = 0; + while (index > mLastChipIndex[lay]) { + lay++; + } + index -= GetFirstChipIndex(lay); + return index % mNumberOfChipsPerModule[lay]; +} + +Bool_t UpgradeGeometryTGeo::GetChipId(Int_t index, Int_t& lay, Int_t& sta, Int_t& hsta, Int_t& mod, + Int_t& chip) const +{ + lay = GetLayer(index); + index -= GetFirstChipIndex(lay); + sta = index / mNumberOfChipsPerStave[lay]; + index %= mNumberOfChipsPerStave[lay]; + hsta = mNumberOfHalfStaves[lay] > 0 ? index / mNumberOfChipsPerHalfStave[lay] : -1; + index %= mNumberOfChipsPerHalfStave[lay]; + mod = mNumberOfModules[lay] > 0 ? index / mNumberOfChipsPerModule[lay] : -1; + chip = index % mNumberOfChipsPerModule[lay]; + + return kTRUE; +} + +const char* UpgradeGeometryTGeo::GetSymbolicName(Int_t index) const +{ + Int_t lay, index2; + if (!GetLayer(index, lay, index2)) { + return NULL; + } + // return + // GeometryManager::SymName((GeometryManager::ELayerID)((lay-1)+GeometryManager::kSPD1),index2); + // RS: this is not optimal, but we cannod access directly GeometryManager, since the latter has + // hardwired layers + // TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( + // GeometryManager::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* UpgradeGeometryTGeo::ComposeSymNameITS() +{ + return "ITS"; +} + +const char* UpgradeGeometryTGeo::ComposeSymNameLayer(Int_t lr) +{ + return Form("%s/%s%d", ComposeSymNameITS(), GetITSLayerPattern(), lr); +} + +const char* UpgradeGeometryTGeo::ComposeSymNameStave(Int_t lr, Int_t stave) +{ + return Form("%s/%s%d", ComposeSymNameLayer(lr), GetITSStavePattern(), stave); +} + +const char* UpgradeGeometryTGeo::ComposeSymNameHalfStave(Int_t lr, Int_t stave, Int_t substave) +{ + return substave >= 0 + ? Form("%s/%s%d", ComposeSymNameStave(lr, stave), GetITSHalfStavePattern(), substave) + : ComposeSymNameStave(lr, stave); +} + +const char* UpgradeGeometryTGeo::ComposeSymNameModule(Int_t lr, Int_t stave, Int_t substave, + Int_t mod) +{ + return mod >= 0 ? Form("%s/%s%d", ComposeSymNameHalfStave(lr, stave, substave), + GetITSModulePattern(), mod) + : ComposeSymNameHalfStave(lr, stave, substave); +} + +const char* UpgradeGeometryTGeo::ComposeSymNameChip(Int_t lr, Int_t sta, Int_t substave, Int_t mod, + Int_t chip) +{ + return Form("%s/%s%d", ComposeSymNameModule(lr, sta, substave, mod), GetITSChipPattern(), chip); +} + +TGeoHMatrix* UpgradeGeometryTGeo::GetMatrix(Int_t index) const +{ + 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 UpgradeGeometryTGeo::GetTranslation(Int_t index, Double_t t[3]) const +{ + 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 UpgradeGeometryTGeo::GetRotation(Int_t index, Double_t r[9]) const +{ + 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 UpgradeGeometryTGeo::GetOriginalMatrix(Int_t index, TGeoHMatrix& m) const +{ + m.Clear(); + + const char* symname = GetSymbolicName(index); + if (!symname) { + return kFALSE; + } + + return GeometryManager::GetOriginalGlobalMatrix(symname, m); +} + +Bool_t UpgradeGeometryTGeo::GetOriginalTranslation(Int_t index, Double_t t[3]) const +{ + TGeoHMatrix m; + if (!GetOriginalMatrix(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 UpgradeGeometryTGeo::GetOriginalRotation(Int_t index, Double_t r[9]) const +{ + TGeoHMatrix m; + if (!GetOriginalMatrix(index, m)) { + return kFALSE; + } + + Double_t* rot = m.GetRotationMatrix(); + for (Int_t i = 0; i < 9; i++) { + r[i] = rot[i]; + } + + return kTRUE; +} + +TGeoHMatrix* UpgradeGeometryTGeo::ExtractMatrixTrackingToLocal(Int_t index) const +{ + 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 UpgradeGeometryTGeo::GetTrackingMatrix(Int_t index, TGeoHMatrix& m) +{ + 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* UpgradeGeometryTGeo::ExtractMatrixSensor(Int_t index) const +{ + Int_t lay, stav, sstav, mod, chipInMod; + GetChipId(index, lay, stav, sstav, mod, chipInMod); + + int wrID = mLayerToWrapper[lay]; + + TString path = Form("/cave_1/%s_2/", UpgradeGeometryTGeo::GetITSVolPattern()); + + if (wrID >= 0) { + path += Form("%s%d_1/", GetITSWrapVolPattern(), wrID); + } + + path += Form("%s%d_1/%s%d_%d/", UpgradeGeometryTGeo::GetITSLayerPattern(), lay, + UpgradeGeometryTGeo::GetITSStavePattern(), lay, stav); + + if (mNumberOfHalfStaves[lay] > 0) { + path += Form("%s%d_%d/", UpgradeGeometryTGeo::GetITSHalfStavePattern(), lay, sstav); + } + if (mNumberOfModules[lay] > 0) { + path += Form("%s%d_%d/", UpgradeGeometryTGeo::GetITSModulePattern(), lay, mod); + } + path += Form("%s%d_%d/%s%d_1", UpgradeGeometryTGeo::GetITSChipPattern(), lay, chipInMod, + UpgradeGeometryTGeo::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(); + // Restore the modeler state. + gGeoManager->PopPath(); + return &matTmp; +} + +TGeoPNEntry* UpgradeGeometryTGeo::GetPNEntry(Int_t index) const +{ + if (index >= mNumberOfChips) { + LOG(ERROR) << "Invalid ITS chip index: " << index << " (0 -> " << mNumberOfChips << ") !" + << 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(GetSymbolicName(index)); + + if (!pne) { + LOG(ERROR) << "The index " << index << " does not correspond to a physical entry!" + << FairLogger::endl; + } + return pne; +} + +void UpgradeGeometryTGeo::Build(Bool_t loadSegmentations) +{ + if (mVersion != kITSVNA) { + LOG(WARNING) << "Already built" << FairLogger::endl; + return; // already initialized + } + if (!gGeoManager) { + LOG(FATAL) << "Geometry is not loaded" << FairLogger::endl; + } + + mNumberOfLayers = ExtractNumberOfLayers(); + if (!mNumberOfLayers) { + return; + } + + mNumberOfStaves = new Int_t[mNumberOfLayers]; + mNumberOfHalfStaves = new Int_t[mNumberOfLayers]; + mNumberOfModules = new Int_t[mNumberOfLayers]; + mNumberOfChipsPerModule = new Int_t[mNumberOfLayers]; + mNumberOfChipRowsPerModule = new Int_t[mNumberOfLayers]; + mNumberOfChipsPerHalfStave = new Int_t[mNumberOfLayers]; + mNumberOfChipsPerStave = new Int_t[mNumberOfLayers]; + mNumberOfChipsPerLayer = new Int_t[mNumberOfLayers]; + mLayerChipType = new Int_t[mNumberOfLayers]; + mLastChipIndex = new Int_t[mNumberOfLayers]; + mNumberOfChips = 0; + + for (int i = 0; i < mNumberOfLayers; i++) { + mLayerChipType[i] = ExtractLayerChipType(i); + mNumberOfStaves[i] = ExtractNumberOfStaves(i); + mNumberOfHalfStaves[i] = ExtractNumberOfHalfStaves(i); + mNumberOfModules[i] = ExtractNumberOfModules(i); + mNumberOfChipsPerModule[i] = ExtractNumberOfChipsPerModule(i, mNumberOfChipRowsPerModule[i]); + mNumberOfChipsPerHalfStave[i] = mNumberOfChipsPerModule[i] * Max(1, mNumberOfModules[i]); + mNumberOfChipsPerStave[i] = mNumberOfChipsPerHalfStave[i] * Max(1, mNumberOfHalfStaves[i]); + mNumberOfChipsPerLayer[i] = mNumberOfChipsPerStave[i] * mNumberOfStaves[i]; + mNumberOfChips += mNumberOfChipsPerLayer[i]; + mLastChipIndex[i] = mNumberOfChips - 1; + } + + FetchMatrices(); + mVersion = kITSVUpg; + + if (loadSegmentations) { // fetch segmentations + mSegmentations = new TObjArray(); + UpgradeSegmentationPixel::LoadSegmentations(mSegmentations, GetITSsegmentationFileName()); + } +} + +Int_t UpgradeGeometryTGeo::ExtractNumberOfLayers() +{ + Int_t numberOfLayers = 0; + + TGeoVolume* itsV = gGeoManager->GetVolume(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; j < nNodes; j++) { + int lrID = -1; + TGeoNode* nd = (TGeoNode*)nodes->At(j); + const char* name = nd->GetName(); + + if (strstr(name, GetITSLayerPattern())) { + numberOfLayers++; + if ((lrID = ExtractVolumeCopy(name, UpgradeGeometryTGeo::GetITSLayerPattern())) < 0) { + LOG(FATAL) << "Failed to extract layer ID from the " << name << FairLogger::endl; + exit(1); + } + + mLayerToWrapper[lrID] = -1; // not wrapped + } + else if (strstr(name, + GetITSWrapVolPattern())) { // this is a wrapper volume, may cointain layers + int wrID = -1; + if ((wrID = ExtractVolumeCopy(name, UpgradeGeometryTGeo::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; jw < nNodesW; jw++) { + TGeoNode* ndW = (TGeoNode*)nodesW->At(jw); + if (strstr(ndW->GetName(), GetITSLayerPattern())) { + if ((lrID = ExtractVolumeCopy(ndW->GetName(), + UpgradeGeometryTGeo::GetITSLayerPattern())) < 0) { + LOG(FATAL) << "Failed to extract layer ID from the " << name << FairLogger::endl; + exit(1); + } + numberOfLayers++; + mLayerToWrapper[lrID] = wrID; + } + } + } + } + return numberOfLayers; +} + +Int_t UpgradeGeometryTGeo::ExtractNumberOfStaves(Int_t lay) const +{ + 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; j < nNodes; j++) { + // LOG(INFO) << "L" << lay << " " << j << " of " << nNodes << " " + // << volLr->GetNodes()->At(j)->GetName() << " " + // << GetITSStavePattern() << " -> " << numberOfStaves << FairLogger::endl; + if (strstr(volLr->GetNodes()->At(j)->GetName(), GetITSStavePattern())) { + numberOfStaves++; + } + } + return numberOfStaves; +} + +Int_t UpgradeGeometryTGeo::ExtractNumberOfHalfStaves(Int_t lay) const +{ + if (mHalfStaveName.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; j < nNodes; j++) { + if (strstr(volLd->GetNodes()->At(j)->GetName(), GetITSHalfStavePattern())) { + nSS++; + } + } + return nSS; +} + +Int_t UpgradeGeometryTGeo::ExtractNumberOfModules(Int_t lay) const +{ + if (mModuleName.IsNull()) { + return 0; + } + + char stavnam[30]; + TGeoVolume* volLd = 0; + + if (!mHalfStaveName.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; j < nNodes; j++) { + if (strstr(volLd->GetNodes()->At(j)->GetName(), GetITSModulePattern())) { + nMod++; + } + } + return nMod; +} + +Int_t UpgradeGeometryTGeo::ExtractNumberOfChipsPerModule(Int_t lay, int& nrow) const +{ + Int_t numberOfChips = 0; + char stavnam[30]; + TGeoVolume* volLd = 0; + + if (!mModuleName.IsNull()) { + snprintf(stavnam, 30, "%s%d", GetITSModulePattern(), lay); + volLd = gGeoManager->GetVolume(stavnam); + } + if (!volLd) { // no modules on this layer, check substaves + if (!mHalfStaveName.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 < nNodes; j++) { + // AliInfo(Form("L%d %d of %d %s %s -> + // %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] < xmin) { + xmin = lab[0]; + } + if (lab[2] > zmax) { + zmax = lab[2]; + } + if (lab[2] < zmin) { + zmin = lab[2]; + } + + numberOfChips++; + + if (dx < 0) { + TGeoShape* chShape = node->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 UpgradeGeometryTGeo::ExtractLayerChipType(Int_t lay) const +{ + 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 UpgradeGeometryTGeo::ComposeChipTypeId(UInt_t segmId) +{ + if (segmId >= kMaxSegmPerChipType) { + LOG(FATAL) << "Id=" << segmId << " is >= max.allowed " << kMaxSegmPerChipType + << FairLogger::endl; + } + return segmId + kChipTypePix * kMaxSegmPerChipType; +} + +void UpgradeGeometryTGeo::Print(Option_t*) const +{ + printf("Geometry version %d, NLayers:%d NChips:%d\n", mVersion, mNumberOfLayers, mNumberOfChips); + if (mVersion == kITSVNA) { + return; + } + for (int i = 0; i < mNumberOfLayers; i++) { + printf("Lr%2d\tNStav:%2d\tNChips:%2d " + "(%dx%-2d)\tNMod:%d\tNSubSt:%d\tNSt:%3d\tChipType:%3d\tChip#:%5d:%-5d\tWrapVol:%d\n", + i, mNumberOfStaves[i], mNumberOfChipsPerModule[i], mNumberOfChipRowsPerModule[i], + mNumberOfChipRowsPerModule[i] + ? mNumberOfChipsPerModule[i] / mNumberOfChipRowsPerModule[i] + : 0, + mNumberOfModules[i], mNumberOfHalfStaves[i], mNumberOfStaves[i], mLayerChipType[i], + GetFirstChipIndex(i), GetLastChipIndex(i), mLayerToWrapper[i]); + } +} + +void UpgradeGeometryTGeo::FetchMatrices() +{ + if (!gGeoManager) { + LOG(FATAL) << "Geometry is not loaded" << FairLogger::endl; + } + mSensorMatrices = new TObjArray(mNumberOfChips); + mSensorMatrices->SetOwner(kTRUE); + for (int i = 0; i < mNumberOfChips; i++) { + mSensorMatrices->AddAt(new TGeoHMatrix(*ExtractMatrixSensor(i)), i); + } + CreateT2LMatrices(); +} + +void UpgradeGeometryTGeo::CreateT2LMatrices() +{ + // create tracking to local (Sensor!) matrices + mTrackingToLocalMatrices = new TObjArray(mNumberOfChips); + mTrackingToLocalMatrices->SetOwner(kTRUE); + TGeoHMatrix matLtoT; + double locA[3] = { -100, 0, 0 }, locB[3] = { 100, 0, 0 }, gloA[3], gloB[3]; + for (int isn = 0; isn < mNumberOfChips; isn++) { + const TGeoHMatrix* matSens = GetMatrixSensor(isn); + if (!matSens) { + LOG(FATAL) << "Failed to get matrix for sensor " << isn << FairLogger::endl; + return; + } + matSens->LocalToMaster(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()); + mTrackingToLocalMatrices->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 + mTrackingToLocalMatrices->AddAt(new TGeoHMatrix(matLtoT.Inverse()),isn); + */ + } +} + +//______________________________________________________________________ +Int_t UpgradeGeometryTGeo::ExtractVolumeCopy(const char* name, const char* prefix) const +{ + 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/UpgradeGeometryTGeo.h b/its/UpgradeGeometryTGeo.h new file mode 100644 index 0000000000000..ab79bca1aec45 --- /dev/null +++ b/its/UpgradeGeometryTGeo.h @@ -0,0 +1,613 @@ +/// \file UpgradeGeometryTGeo.h +/// \brief Definition of the UpgradeGeometryTGeo class +/// \author cvetan.cheshkov@cern.ch - 15/02/2007 +/// \author ruben.shahoyan@cern.ch - adapted to ITSupg 18/07/2012 + +#ifndef ALICEO2_ITS_UPGRADEGEOMETRYTGEO_H_ +#define ALICEO2_ITS_UPGRADEGEOMETRYTGEO_H_ + +#include +#include +#include +#include + +// FIXME: This is temporary and you have to remove it to avoid cyclic deps +#include + +class TGeoPNEntry; +class TDatime; + +namespace AliceO2 { +namespace ITS { + +// Adapted from the AliITSUAux class +const UInt_t gMaxLayers = 15; ///< max number of active layers + +class Segmentation; + +/// UpgradeGeometryTGeo is a simple interface class to TGeoManager. It is used in the simulation +/// and reconstruction in order to query the TGeo ITS geometry. +/// 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 +/// Segmentation derived class (like UpgradeSegmentationPixel). 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 +class UpgradeGeometryTGeo : public TObject { + +public: + enum { + kITSVNA, + kITSVUpg + }; // ITS version + + enum { + kChipTypePix = 0, + kNChipTypes, + kMaxSegmPerChipType = 10 + }; // defined detector chip types (each one can have different segmentations) + + UpgradeGeometryTGeo(Bool_t build = kFALSE, Bool_t loadSegmentationsentations = kTRUE); + + /// Default destructor + virtual ~UpgradeGeometryTGeo(); + + UpgradeGeometryTGeo(const UpgradeGeometryTGeo& src); + + UpgradeGeometryTGeo& operator=(const UpgradeGeometryTGeo& geom); + + Int_t GetNumberOfChips() const + { + return mNumberOfChips; + } + Int_t GetNumberOfChipRowsPerModule(Int_t lay) const + { + return mNumberOfChipRowsPerModule[lay]; + } + Int_t GetNumberOfChipColsPerModule(Int_t lay) const + { + return mNumberOfChipRowsPerModule[lay] + ? mNumberOfChipsPerModule[lay] / mNumberOfChipRowsPerModule[lay] + : -1; + } + Int_t GetNumberOfChipsPerModule(Int_t lay) const + { + return mNumberOfChipsPerModule[lay]; + } + Int_t GetNumberOfChipsPerHalfStave(Int_t lay) const + { + return mNumberOfChipsPerHalfStave[lay]; + } + Int_t GetNumberOfChipsPerStave(Int_t lay) const + { + return mNumberOfChipsPerStave[lay]; + } + Int_t GetNumberOfChipsPerLayer(Int_t lay) const + { + return mNumberOfChipsPerLayer[lay]; + } + Int_t GetNumberOfModules(Int_t lay) const + { + return mNumberOfModules[lay]; + } + Int_t GetNumberOfHalfStaves(Int_t lay) const + { + return mNumberOfHalfStaves[lay]; + } + Int_t GetNumberOfStaves(Int_t lay) const + { + return mNumberOfStaves[lay]; + } + Int_t GetNumberOfLayers() const + { + return mNumberOfLayers; + } + + Int_t GetChipIndex(Int_t lay, int detInLay) const + { + return GetFirstChipIndex(lay) + detInLay; + } + + /// This routine computes the chip index number from the layer, stave, and chip number in stave + /// \param Int_t lay The layer number. Starting from 0. + /// \param Int_t sta The stave number. Starting from 0 + /// \param Int_t chipInStave The chip number in the stave. Starting from 0 + Int_t GetChipIndex(Int_t lay, Int_t sta, Int_t detInSta) const; + + /// This routine computes the chip index number from the layer, stave, substave and chip number + /// in substave + /// \param Int_t lay The layer number. Starting from 0. + /// \param Int_t sta The stave number. Starting from 0 + /// \param Int_t substa The substave number. Starting from 0 + /// \param Int_t chipInSStave The chip number in the sub stave. Starting from 0 + Int_t GetChipIndex(Int_t lay, Int_t sta, Int_t subSta, Int_t detInSubSta) const; + + /// This routine computes the chip index number from the layer,stave, substave module and + /// chip number in module. + /// \param Int_t lay The layer number. Starting from 0. + /// \param Int_t sta The stave number. Starting from 0 + /// \param Int_t substa The substave number. Starting from 0 + /// \param Int_t module The module number ... + /// \param Int_t chipInSStave The chip number in the module. Starting from 0 + Int_t GetChipIndex(Int_t lay, Int_t sta, Int_t subSta, Int_t md, Int_t detInMod) const; + + /// This routine computes the layer, stave, substave, module and chip number + /// given the chip index number + /// \param Int_t index The chip index number, starting from zero. + /// \param Int_t lay The layer number. Starting from 0 + /// \param Int_t sta The stave number. Starting from 0 + /// \param Int_t ssta The halfstave number. Starting from 0 + /// \param Int_t mod The module number. Starting from 0 + /// \param Int_t chip The detector number. Starting from 0 + Bool_t GetChipId(Int_t index, Int_t& lay, Int_t& sta, Int_t& ssta, Int_t& mod, Int_t& chip) const; + + /// Get chip layer, from 0 + Int_t GetLayer(Int_t index) const; + + /// Get chip stave, from 0 + Int_t GetStave(Int_t index) const; + + /// Get chip substave id in stave, from 0 + Int_t GetHalfStave(Int_t index) const; + + /// Get chip module id in substave, from 0 + Int_t GetModule(Int_t index) const; + + /// Get chip number within layer, from 0 + Int_t GetChipIdInLayer(Int_t index) const; + + /// Get chip number within stave, from 0 + Int_t GetChipIdInStave(Int_t index) const; + + /// Get chip number within stave, from 0 + Int_t GetChipIdInHalfStave(Int_t index) const; + + /// Get chip number within module, from 0 + Int_t GetChipIdInModule(Int_t index) const; + + Int_t GetLastChipIndex(Int_t lay) const + { + return mLastChipIndex[lay]; + } + Int_t GetFirstChipIndex(Int_t lay) const + { + return (lay == 0) ? 0 : mLastChipIndex[lay - 1] + 1; + } + + /// Get the TGeoPNEntry symbolic name for a given chip identified by 'index' + const char* GetSymbolicName(Int_t index) const; + + const char* GetSymbolicName(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 + + /// Get the transformation matrix for a given chip 'index' by quering the TGeoManager + TGeoHMatrix* GetMatrix(Int_t index) const; + TGeoHMatrix* GetMatrix(Int_t lay, Int_t sta, Int_t det) const; + + /// Get the translation vector for a given chip 'index' by quering the TGeoManager + 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; + + /// Get the rotation matrix for a given chip 'index' by quering the TGeoManager + 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; + + /// 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 + Bool_t GetOriginalMatrix(Int_t index, TGeoHMatrix& m) const; + Bool_t GetOriginalMatrix(Int_t lay, Int_t sta, Int_t det, TGeoHMatrix& m) const; + + /// Get the original translation vector (ideal geometry) + /// for a given chip 'index' by quering the TGeoManager + Bool_t GetOriginalTranslation(Int_t index, Double_t t[3]) const; + Bool_t GetOriginalTranslation(Int_t lay, Int_t sta, Int_t det, Double_t t[3]) const; + + /// Get the original rotation matrix (ideal geometry) + /// for a given chip 'index' by quering the TGeoManager + Bool_t GetOriginalRotation(Int_t index, Double_t r[9]) const; + Bool_t GetOriginalRotation(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* GetMatrixSensor(Int_t index); + const TGeoHMatrix* GetMatrixSensor(Int_t lay, Int_t sta, Int_t det) + { + return GetMatrixSensor(GetChipIndex(lay, sta, det)); + } + + /// Get the matrix which transforms from the tracking r.s. to the global one + /// Returns kFALSE in case of error. + 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 LocalToGlobalVector(Int_t index, const Double_t* loc, Double_t* glob); + void GlobalToLocalVector(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 Segmentation* GetSegmentationById(Int_t id) const; + const Segmentation* GetSegmentation(Int_t lr) const; + + TObjArray* GetSegmentations() const + { + return (TObjArray*)mSegmentations; + } + virtual void Print(Option_t* opt = "") const; + + static UInt_t GetUIDShift() + { + return mUIDShift; + } + static void SetUIDShift(UInt_t s = 16) + { + mUIDShift = s < 16 ? s : 16; + } + + static const char* GetITSVolPattern() + { + return mVolumeName.Data(); + } + static const char* GetITSLayerPattern() + { + return mLayerName.Data(); + } + static const char* GetITSWrapVolPattern() + { + return mWrapperVolumeName.Data(); + } + static const char* GetITSStavePattern() + { + return mStaveName.Data(); + } + static const char* GetITSHalfStavePattern() + { + return mHalfStaveName.Data(); + } + static const char* GetITSModulePattern() + { + return mModuleName.Data(); + } + static const char* GetITSChipPattern() + { + return mChipName.Data(); + } + static const char* GetITSSensorPattern() + { + return mSensorName.Data(); + } + static const char* GetITSsegmentationFileName() + { + return mSegmentationFileName.Data(); + } + static const char* GetChipTypeName(Int_t i); + + static void SetITSVolPattern(const char* nm) + { + mVolumeName = nm; + } + static void SetITSLayerPattern(const char* nm) + { + mLayerName = nm; + } + static void SetITSWrapVolPattern(const char* nm) + { + mWrapperVolumeName = nm; + } + static void SetITSStavePattern(const char* nm) + { + mStaveName = nm; + } + static void SetITSHalfStavePattern(const char* nm) + { + mHalfStaveName = nm; + } + static void SetITSModulePattern(const char* nm) + { + mModuleName = nm; + } + static void SetITSChipPattern(const char* nm) + { + mChipName = nm; + } + static void SetITSSensorPattern(const char* nm) + { + mSensorName = nm; + } + static void SetChipTypeName(Int_t i, const char* nm); + static void SetITSsegmentationFileName(const char* nm) + { + mSegmentationFileName = nm; + } + static UInt_t ComposeChipTypeId(UInt_t segmId); + + /// sym name of the layer + static const char* ComposeSymNameITS(); + + /// sym name of the layer + static const char* ComposeSymNameLayer(Int_t lr); + + /// Sym name of the stave at given layer + static const char* ComposeSymNameStave(Int_t lr, Int_t sta); + + /// Sym name of the stave at given layer + static const char* ComposeSymNameHalfStave(Int_t lr, Int_t sta, Int_t ssta); + + /// Sym name of the substave at given layer/stave + static const char* ComposeSymNameModule(Int_t lr, Int_t sta, Int_t ssta, Int_t mod); + + /// Sym name of the chip in the given layer/stave/substave/module + 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) << mUIDShift; + } + +protected: + /// Store pointer on often used matrices for faster access + void FetchMatrices(); + void CreateT2LMatrices(); + + /// Get the matrix which transforms from the tracking to local r.s. + /// The method queries directly the TGeoPNEntry + TGeoHMatrix* ExtractMatrixTrackingToLocal(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 + TGeoHMatrix* ExtractMatrixSensor(Int_t index) const; + + /// This routine computes the layer number a given the chip index + /// \param Int_t index The chip index number, starting from zero. + /// \param Int_t indexInLr The chip index inside a layer, starting from zero. + /// \param Int_t lay The layer number. Starting from 0. + Bool_t GetLayer(Int_t index, Int_t& lay, Int_t& index2) 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 + TGeoPNEntry* GetPNEntry(Int_t index) 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 + /// \param lay: layer number from 0 + Int_t ExtractNumberOfChipsPerModule(Int_t lay, Int_t& nrow) const; + + /// Determines the number of layers in the Upgrade Geometry + /// \param lay: layer number, starting from 0 + Int_t ExtractNumberOfStaves(Int_t lay) const; + + /// Determines the number of substaves in the stave of the layer + /// \param lay: layer number, starting from 0 + Int_t ExtractNumberOfHalfStaves(Int_t lay) const; + + /// Determines the number of modules in substave in the stave of the layer + /// \param 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 + Int_t ExtractNumberOfModules(Int_t lay) const; + + /// Determines the layer detector type the Upgrade Geometry and + /// returns the detector type id for the layer + /// \param lay: layer number from 0 + Int_t ExtractLayerChipType(Int_t lay) const; + + /// Determines the number of layers in the Upgrade Geometry + Int_t ExtractNumberOfLayers(); + + /// Exract ITS Upgrade parameters from TGeo + void Build(Bool_t loadSegmentations); + + /// Extract number following the prefix in the name string + Int_t ExtractVolumeCopy(const char* name, const char* prefix) const; + +protected: + Int_t mVersion; ///< ITS Version + Int_t mNumberOfLayers; ///< number of layers + Int_t mNumberOfChips; ///< The total number of chips + Int_t* mNumberOfStaves; ///< [mNumberOfLayers] Array of the number of staves/layer(layer) + Int_t* mNumberOfHalfStaves; ///< [mNumberOfLayers] Array of the number of substaves/stave(layer) + Int_t* mNumberOfModules; ///< [mNumberOfLayers] Array of the number of modules/substave(layer) + Int_t* mNumberOfChipsPerModule; ///< [mNumberOfLayers] Array of the number of chips per module + ///< (group of chips on the substaves) + Int_t* mNumberOfChipRowsPerModule; ///< [mNumberOfLayers] Array of the number of chips rows per + ///< module (relevant for OB modules) + Int_t* mNumberOfChipsPerHalfStave; ///< [mNumberOfLayers] Array of number of chips per substave + Int_t* mNumberOfChipsPerStave; ///< [mNumberOfLayers] Array of the number of chips per stave + Int_t* mNumberOfChipsPerLayer; ///< [mNumberOfLayers] Array of the number of chips per stave + Int_t* mLayerChipType; ///< [mNumberOfLayers] Array of layer chip types + Int_t* mLastChipIndex; ///< [mNumberOfLayers] max ID of the detctor in the layer + Char_t mLayerToWrapper[gMaxLayers]; ///< Layer to wrapper correspondence + TObjArray* mSensorMatrices; ///< Sensor's matrices pointers in the geometry + TObjArray* mTrackingToLocalMatrices; ///< Tracking to Local matrices pointers in the geometry + TObjArray* mSegmentations; ///< segmentations + + static UInt_t mUIDShift; ///< bit shift to go from mod.id to modUUID for TGeo + static TString mVolumeName; ///< Mother volume name + static TString mLayerName; ///< Layer name + static TString mStaveName; ///< Stave name + static TString mHalfStaveName; ///< HalfStave name + static TString mModuleName; ///< Module name + static TString mChipName; ///< Chip name + static TString mSensorName; ///< Sensor name + static TString mWrapperVolumeName; ///< Wrapper volume name + static TString mChipTypeName[kNChipTypes]; ///< upg detType Names + + static TString mSegmentationFileName; ///< file name for segmentations + + ClassDef(UpgradeGeometryTGeo, 1) // ITS geometry based on TGeo +}; + +/// Symbolic name +inline const char* UpgradeGeometryTGeo::GetSymbolicName(Int_t lay, Int_t sta, Int_t det) const +{ + return GetSymbolicName(GetChipIndex(lay, sta, det)); +} + +/// Chip current matrix +inline TGeoHMatrix* UpgradeGeometryTGeo::GetMatrix(Int_t lay, Int_t sta, Int_t det) const +{ + return GetMatrix(GetChipIndex(lay, sta, det)); +} + +/// Translation +inline Bool_t UpgradeGeometryTGeo::GetTranslation(Int_t lay, Int_t sta, Int_t det, Double_t t[3]) + const +{ + return GetTranslation(GetChipIndex(lay, sta, det), t); +} + +/// Rotation +inline Bool_t UpgradeGeometryTGeo::GetRotation(Int_t lay, Int_t sta, Int_t det, Double_t r[9]) const +{ + return GetRotation(GetChipIndex(lay, sta, det), r); +} + +/// Original matrix +inline Bool_t UpgradeGeometryTGeo::GetOriginalMatrix(Int_t lay, Int_t sta, Int_t det, TGeoHMatrix& m) + const +{ + return GetOriginalMatrix(GetChipIndex(lay, sta, det), m); +} + +/// Original translation +inline Bool_t UpgradeGeometryTGeo::GetOriginalTranslation(Int_t lay, Int_t sta, Int_t det, + Double_t t[3]) const +{ + return GetOriginalTranslation(GetChipIndex(lay, sta, det), t); +} + +/// Original rotation +inline Bool_t UpgradeGeometryTGeo::GetOriginalRotation(Int_t lay, Int_t sta, Int_t det, Double_t r[9]) + const +{ + return GetOriginalRotation(GetChipIndex(lay, sta, det), r); +} + +/// Tracking matrix +inline Bool_t UpgradeGeometryTGeo::GetTrackingMatrix(Int_t lay, Int_t sta, Int_t det, + TGeoHMatrix& m) +{ + return GetTrackingMatrix(GetChipIndex(lay, sta, det), m); +} + +/// Detector type ID of layer +inline Int_t UpgradeGeometryTGeo::GetLayerChipTypeId(Int_t lr) const +{ + return mLayerChipType[lr]; +} + +// Detector type ID of chip +inline Int_t UpgradeGeometryTGeo::GetChipChipTypeId(Int_t id) const +{ + return GetLayerChipTypeId(GetLayer(id)); +} + +/// Access global to sensor matrix +inline const TGeoHMatrix* UpgradeGeometryTGeo::GetMatrixSensor(Int_t index) +{ + if (!mSensorMatrices) { + FetchMatrices(); + } + return (TGeoHMatrix*)mSensorMatrices->At(index); +} + +/// Access tracking to local matrix +inline const TGeoHMatrix* UpgradeGeometryTGeo::GetMatrixT2L(Int_t index) +{ + if (!mTrackingToLocalMatrices) { + FetchMatrices(); + } + return (TGeoHMatrix*)mTrackingToLocalMatrices->At(index); +} + +/// Sensor local to global +inline void UpgradeGeometryTGeo::LocalToGlobal(Int_t index, const Double_t* loc, Double_t* glob) +{ + GetMatrixSensor(index)->LocalToMaster(loc, glob); +} + +/// Global to sensor local +inline void UpgradeGeometryTGeo::GlobalToLocal(Int_t index, const Double_t* glob, Double_t* loc) +{ + GetMatrixSensor(index)->MasterToLocal(glob, loc); +} + +/// Sensor local to global +inline void UpgradeGeometryTGeo::LocalToGlobalVector(Int_t index, const Double_t* loc, Double_t* glob) +{ + GetMatrixSensor(index)->LocalToMasterVect(loc, glob); +} + +/// Global to sensor local +inline void UpgradeGeometryTGeo::GlobalToLocalVector(Int_t index, const Double_t* glob, Double_t* loc) +{ + GetMatrixSensor(index)->MasterToLocalVect(glob, loc); +} + +/// Local2Master (sensor) +inline void UpgradeGeometryTGeo::LocalToGlobal(Int_t lay, Int_t sta, Int_t det, const Double_t* loc, + Double_t* glob) +{ + LocalToGlobal(GetChipIndex(lay, sta, det), loc, glob); +} + +/// Master2local (sensor) +inline void UpgradeGeometryTGeo::GlobalToLocal(Int_t lay, Int_t sta, Int_t det, + const Double_t* glob, Double_t* loc) +{ + GlobalToLocal(GetChipIndex(lay, sta, det), glob, loc); +} + +inline const char* UpgradeGeometryTGeo::GetChipTypeName(Int_t i) +{ + if (i >= kNChipTypes) { + i /= kMaxSegmPerChipType; // full type is provided + } + return mChipTypeName[i].Data(); +} + +inline void UpgradeGeometryTGeo::SetChipTypeName(Int_t i, const char* nm) +{ + if (i >= kNChipTypes) { + i /= kMaxSegmPerChipType; // full type is provided + } + mChipTypeName[i] = nm; +} + +/// Get segmentation by ID +inline const Segmentation* UpgradeGeometryTGeo::GetSegmentationById(Int_t id) const +{ + return mSegmentations ? (Segmentation*)mSegmentations->At(id) : 0; +} + +// Get segmentation of layer +inline const Segmentation* UpgradeGeometryTGeo::GetSegmentation(Int_t lr) const +{ + return mSegmentations ? (Segmentation*)mSegmentations->At(GetLayerChipTypeId(lr)) : 0; +} +} +} + +#endif diff --git a/its/UpgradeSegmentationPixel.cxx b/its/UpgradeSegmentationPixel.cxx new file mode 100644 index 0000000000000..defe4f16fcf8f --- /dev/null +++ b/its/UpgradeSegmentationPixel.cxx @@ -0,0 +1,577 @@ +/// \file UpgradeSegmentationPixel.cxx +/// \brief Implementation of the UpgradeSegmentationPixel class + +#include +#include +#include +#include +#include +#include +#include + +#include "UpgradeGeometryTGeo.h" +#include "UpgradeSegmentationPixel.h" + +using namespace TMath; +using namespace AliceO2::ITS; + +ClassImp(UpgradeSegmentationPixel) + +const char* UpgradeSegmentationPixel::sSegmentationsListName = "UpgradeSegmentations"; + +UpgradeSegmentationPixel::UpgradeSegmentationPixel(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) + : Segmentation() + , mGuardLeft(edgL) + , mGuardRight(edgR) + , mGuardTop(edgT) + , mGuardBottom(edgB) + , mShiftLocalX(0.5 * (edgT - edgB)) + , mShiftLocalZ(0.5 * (edgR - edgL)) + , mDxActive(0) + , mDzActive(0) + , mPitchX(pitchX) + , mPitchZ(pitchZ) + , mPitchZLeftColumn(pitchLftC < 0 ? pitchZ : pitchLftC) + , mPitchZRightColumn(pitchRgtC < 0 ? pitchZ : pitchRgtC) + , mChipSizeDZ(0) + , mNumberOfChips(nchips) + , mNumberOfColumnsPerChip(nchips > 0 ? ncol / nchips : 0) + , mNumberOfRows(nrow) + , mNumberOfColumns(ncol) + , mDiodShiftMatNColumn(0) + , mDiodShiftMatNRow(0) + , mDiodShiftMatDimension(0) + , mDiodShiftMatX(0) + , mDiodShiftMatZ(0) +{ + // Default constructor, sizes in cm + if (nchips) { + SetUniqueID(UpgradeGeometryTGeo::ComposeChipTypeId(id)); + } + mChipSizeDZ = (mNumberOfColumnsPerChip - 2) * mPitchZ + mPitchZLeftColumn + mPitchZRightColumn; + mDxActive = mNumberOfRows * mPitchX; + mDzActive = mNumberOfChips * mChipSizeDZ; + SetDetSize(mDxActive + mGuardTop + mGuardBottom, mDzActive + mGuardLeft + mGuardRight, thickness); +} + +UpgradeSegmentationPixel::~UpgradeSegmentationPixel() +{ + // d-tor + delete[] mDiodShiftMatX; + delete[] mDiodShiftMatZ; +} + +void UpgradeSegmentationPixel::GetPadIxz(Float_t x, Float_t z, Int_t& ix, Int_t& iz) const +{ + ix = int(x / mPitchX); + iz = int(ZToColumn(z)); + + if (iz < 0) { + LOG(WARNING) << "Z=" << z << " gives col=" << iz << " outside [0:" << mNumberOfColumns << ")" + << FairLogger::endl; + iz = 0; + } + else if (iz >= mNumberOfColumns) { + LOG(WARNING) << "Z=" << z << " gives col=" << iz << " outside [0:" << mNumberOfColumns << ")" + << FairLogger::endl; + iz = mNumberOfColumns - 1; + } + if (ix < 0) { + LOG(WARNING) << "X=" << x << " gives row=" << ix << " outside [0:" << mNumberOfRows << ")" + << FairLogger::endl; + ix = 0; + } + else if (ix >= mNumberOfRows) { + LOG(WARNING) << "X=" << x << " gives row=" << ix << " outside [0:" << mNumberOfRows << ")" + << FairLogger::endl; + ix = mNumberOfRows - 1; + } +} + +void UpgradeSegmentationPixel::GetPadTxz(Float_t& x, Float_t& z) const +{ + x /= mPitchX; + z = ZToColumn(z); +} + +void UpgradeSegmentationPixel::GetPadCxz(Int_t ix, Int_t iz, Float_t& x, Float_t& z) const +{ + x = Float_t((ix + 0.5) * mPitchX); + z = ColumnToZ(iz); +} + +Float_t UpgradeSegmentationPixel::ZToColumn(Float_t z) const +{ + int chip = int(z / mChipSizeDZ); + float col = chip * mNumberOfColumnsPerChip; + z -= chip * mChipSizeDZ; + if (z > mPitchZLeftColumn) { + col += 1 + (z - mPitchZLeftColumn) / mPitchZ; + } + return col; +} + +Float_t UpgradeSegmentationPixel::ColumnToZ(Int_t col) const +{ + int nchip = col / mNumberOfColumnsPerChip; + col %= mNumberOfColumnsPerChip; + float z = nchip * mChipSizeDZ; + if (col > 0) { + if (col < mNumberOfColumnsPerChip - 1) { + z += mPitchZLeftColumn + (col - 0.5) * mPitchZ; + } + else { + z += mChipSizeDZ - mPitchZRightColumn / 2; + } + } + else { + z += mPitchZLeftColumn / 2; + } + return z; +} + +UpgradeSegmentationPixel& UpgradeSegmentationPixel::operator=(const UpgradeSegmentationPixel& src) +{ + if (this == &src) { + return *this; + } + Segmentation::operator=(src); + mNumberOfColumns = src.mNumberOfColumns; + mNumberOfRows = src.mNumberOfRows; + mNumberOfColumnsPerChip = src.mNumberOfColumnsPerChip; + mNumberOfChips = src.mNumberOfChips; + mChipSizeDZ = src.mChipSizeDZ; + mPitchZRightColumn = src.mPitchZRightColumn; + mPitchZLeftColumn = src.mPitchZLeftColumn; + mPitchZ = src.mPitchZ; + mPitchX = src.mPitchX; + mShiftLocalX = src.mShiftLocalX; + mShiftLocalZ = src.mShiftLocalZ; + mDxActive = src.mDxActive; + mDzActive = src.mDzActive; + + mGuardBottom = src.mGuardBottom; + mGuardTop = src.mGuardTop; + mGuardRight = src.mGuardRight; + mGuardLeft = src.mGuardLeft; + + mDiodShiftMatNColumn = src.mDiodShiftMatNColumn; + mDiodShiftMatNRow = src.mDiodShiftMatNRow; + mDiodShiftMatDimension = src.mDiodShiftMatDimension; + delete mDiodShiftMatX; + mDiodShiftMatX = 0; + delete mDiodShiftMatZ; + mDiodShiftMatZ = 0; + if (mDiodShiftMatDimension) { + mDiodShiftMatX = new Float_t[mDiodShiftMatDimension]; + mDiodShiftMatZ = new Float_t[mDiodShiftMatDimension]; + for (int i = mDiodShiftMatDimension; i--;) { + mDiodShiftMatX[i] = src.mDiodShiftMatX[i]; + mDiodShiftMatZ[i] = src.mDiodShiftMatZ[i]; + } + } + return *this; +} + +UpgradeSegmentationPixel::UpgradeSegmentationPixel(const UpgradeSegmentationPixel& src) + : Segmentation(src) + , mGuardLeft(src.mGuardLeft) + , mGuardRight(src.mGuardRight) + , mGuardTop(src.mGuardTop) + , mGuardBottom(src.mGuardBottom) + , mShiftLocalX(src.mShiftLocalX) + , mShiftLocalZ(src.mShiftLocalZ) + , mDxActive(src.mDxActive) + , mDzActive(src.mDzActive) + , mPitchX(src.mPitchX) + , mPitchZ(src.mPitchZ) + , mPitchZLeftColumn(src.mPitchZLeftColumn) + , mPitchZRightColumn(src.mPitchZRightColumn) + , mChipSizeDZ(src.mChipSizeDZ) + , mNumberOfChips(src.mNumberOfChips) + , mNumberOfColumnsPerChip(src.mNumberOfColumnsPerChip) + , mNumberOfRows(src.mNumberOfRows) + , mNumberOfColumns(src.mNumberOfColumns) + , mDiodShiftMatNColumn(src.mDiodShiftMatNColumn) + , mDiodShiftMatNRow(src.mDiodShiftMatNRow) + , mDiodShiftMatDimension(src.mDiodShiftMatDimension) + , mDiodShiftMatX(0) + , mDiodShiftMatZ(0) +{ + // copy constructor + if (mDiodShiftMatDimension) { + mDiodShiftMatX = new Float_t[mDiodShiftMatDimension]; + mDiodShiftMatZ = new Float_t[mDiodShiftMatDimension]; + for (int i = mDiodShiftMatDimension; i--;) { + mDiodShiftMatX[i] = src.mDiodShiftMatX[i]; + mDiodShiftMatZ[i] = src.mDiodShiftMatZ[i]; + } + } +} + +Float_t UpgradeSegmentationPixel::Dpx(Int_t) const +{ + return mPitchX; +} + +Float_t UpgradeSegmentationPixel::Dpz(Int_t col) const +{ + col %= mNumberOfColumnsPerChip; + if (!col) { + return mPitchZLeftColumn; + } + if (col == mNumberOfColumnsPerChip - 1) { + return mPitchZRightColumn; + } + return mPitchZ; +} + +void UpgradeSegmentationPixel::Neighbours(Int_t iX, Int_t iZ, Int_t* nlist, Int_t xlist[8], + Int_t zlist[8]) const +{ + *nlist = 8; + xlist[0] = xlist[1] = iX; + xlist[2] = iX - 1; + xlist[3] = iX + 1; + zlist[0] = iZ - 1; + zlist[1] = iZ + 1; + zlist[2] = zlist[3] = iZ; + + // Diagonal elements + xlist[4] = iX + 1; + zlist[4] = iZ + 1; + + xlist[5] = iX - 1; + zlist[5] = iZ - 1; + + xlist[6] = iX - 1; + zlist[6] = iZ + 1; + + xlist[7] = iX + 1; + zlist[7] = iZ - 1; +} + +Bool_t UpgradeSegmentationPixel::LocalToDetector(Float_t x, Float_t z, Int_t& ix, Int_t& iz) const +{ + x += 0.5 * DxActive() + mShiftLocalX; // get X,Z wrt bottom/left corner + z += 0.5 * DzActive() + mShiftLocalZ; + ix = iz = -1; + if (x < 0 || x > DxActive()) { + return kFALSE; // outside x range. + } + if (z < 0 || z > DzActive()) { + return kFALSE; // outside z range. + } + ix = int(x / mPitchX); + iz = ZToColumn(z); + return kTRUE; // Found ix and iz, return. +} + +void UpgradeSegmentationPixel::DetectorToLocal(Int_t ix, Int_t iz, Float_t& x, Float_t& z) const +{ + x = -0.5 * DxActive(); // default value. + z = -0.5 * DzActive(); // default value. + if (ix < 0 || ix >= mNumberOfRows) { + LOG(WARNING) << "Obtained row " << ix << " is not in range [0:" << mNumberOfRows << ")" + << FairLogger::endl; + return; + } // outside of detector + if (iz < 0 || iz >= mNumberOfColumns) { + LOG(WARNING) << "Obtained col " << ix << " is not in range [0:" << mNumberOfColumns << ")" + << FairLogger::endl; + return; + } // outside of detector + x += (ix + 0.5) * mPitchX - + mShiftLocalX; // RS: we go to the center of the pad, i.e. + pitch/2, not + // to the boundary as in SPD + z += ColumnToZ(iz) - mShiftLocalZ; + return; // Found x and z, return. +} + +void UpgradeSegmentationPixel::CellBoundries(Int_t ix, Int_t iz, Double_t& xl, Double_t& xu, + Double_t& zl, Double_t& zu) const +{ + Float_t x, z; + DetectorToLocal(ix, iz, x, z); + + if (ix < 0 || ix >= mNumberOfRows || iz < 0 || iz >= mNumberOfColumns) { + 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 = mPitchX * 0.5; + xl -= xpitchH; + xu += xpitchH; + zl -= zpitchH; + zu += zpitchH; + return; // Found x and z, return. +} + +Int_t UpgradeSegmentationPixel::GetChipFromChannel(Int_t, Int_t iz) const +{ + if (iz >= mNumberOfColumns || iz < 0) { + LOG(WARNING) << "Bad cell number" << FairLogger::endl; + return -1; + } + return iz / mNumberOfColumnsPerChip; +} + +Int_t UpgradeSegmentationPixel::GetChipFromLocal(Float_t, Float_t zloc) const +{ + Int_t ix0, iz; + if (!LocalToDetector(0, zloc, ix0, iz)) { + LOG(WARNING) << "Bad local coordinate" << FairLogger::endl; + return -1; + } + return GetChipFromChannel(ix0, iz); +} + +Int_t UpgradeSegmentationPixel::GetChipsInLocalWindow(Int_t* array, Float_t zmin, Float_t zmax, + Float_t, Float_t) const +{ + if (zmin > zmax) { + LOG(WARNING) << "Bad coordinate limits: zmin>zmax!" << FairLogger::endl; + return -1; + } + + Int_t nChipInW = 0; + + Float_t zminDet = -0.5 * DzActive() - mShiftLocalZ; + Float_t zmaxDet = 0.5 * DzActive() - mShiftLocalZ; + if (zmin < zminDet) { + zmin = zminDet; + } + if (zmax > zmaxDet) { + 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 UpgradeSegmentationPixel::Init() +{ + // init settings +} + +Bool_t UpgradeSegmentationPixel::Store(const char* outf) +{ + 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(sSegmentationsListName); + + 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, sSegmentationsListName, "kSingleKey"); + fout->Close(); + delete fout; + arr->RemoveAt(id); + delete arr; + LOG(INFO) << "Stored segmentation " << id << " in " << outf << FairLogger::endl; + return kTRUE; +} + +UpgradeSegmentationPixel* UpgradeSegmentationPixel::LoadWithId(UInt_t id, const char* inpf) +{ + 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(sSegmentationsListName); + if (!arr) { + LOG(FATAL) << "LoadWithId: Failed to find segmenation array " << sSegmentationsListName + << " in " << inpf << FairLogger::endl; + return 0; + } + UpgradeSegmentationPixel* 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 UpgradeSegmentationPixel::LoadSegmentations(TObjArray* dest, const char* inpf) +{ + 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(sSegmentationsListName); + if (!arr) { + LOG(FATAL) << "LoadWithId: Failed to find segmentation array " << sSegmentationsListName + << " 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 UpgradeSegmentationPixel::SetDiodShiftMatrix(Int_t nrow, Int_t ncol, const Float_t* shiftX, + const Float_t* shiftZ) +{ + if (mDiodShiftMatDimension) { + delete mDiodShiftMatX; + delete mDiodShiftMatZ; + mDiodShiftMatX = mDiodShiftMatZ = 0; + } + mDiodShiftMatNColumn = ncol; + mDiodShiftMatNRow = nrow; + mDiodShiftMatDimension = mDiodShiftMatNColumn * mDiodShiftMatNRow; + if (mDiodShiftMatDimension) { + mDiodShiftMatX = new Float_t[mDiodShiftMatDimension]; + mDiodShiftMatZ = new Float_t[mDiodShiftMatDimension]; + for (int ir = 0; ir < mDiodShiftMatNRow; ir++) { + for (int ic = 0; ic < mDiodShiftMatNColumn; ic++) { + int cnt = ic + ir * mDiodShiftMatNColumn; + mDiodShiftMatX[cnt] = shiftX ? shiftX[cnt] : 0.; + mDiodShiftMatZ[cnt] = shiftZ ? shiftZ[cnt] : 0.; + } + } + } +} + +void UpgradeSegmentationPixel::SetDiodShiftMatrix(Int_t nrow, Int_t ncol, const Double_t* shiftX, + const Double_t* shiftZ) +{ + if (mDiodShiftMatDimension) { + delete mDiodShiftMatX; + delete mDiodShiftMatZ; + mDiodShiftMatX = mDiodShiftMatZ = 0; + } + + mDiodShiftMatNColumn = ncol; + mDiodShiftMatNRow = nrow; + mDiodShiftMatDimension = mDiodShiftMatNColumn * mDiodShiftMatNRow; + if (mDiodShiftMatDimension) { + mDiodShiftMatX = new Float_t[mDiodShiftMatDimension]; + mDiodShiftMatZ = new Float_t[mDiodShiftMatDimension]; + for (int ir = 0; ir < mDiodShiftMatNRow; ir++) { + for (int ic = 0; ic < mDiodShiftMatNColumn; ic++) { + int cnt = ic + ir * mDiodShiftMatNColumn; + mDiodShiftMatX[cnt] = shiftX ? shiftX[cnt] : 0.; + mDiodShiftMatZ[cnt] = shiftZ ? shiftZ[cnt] : 0.; + } + } + } +} + +void UpgradeSegmentationPixel::Print(Option_t* /*option*/) const +{ + const double kmc = 1e4; + printf("Segmentation %d: Active Size: DX: %.1f DY: %.1f DZ: %.1f | Pitch: X:%.1f Z:%.1f\n", + GetUniqueID(), kmc * DxActive(), kmc * Dy(), kmc * DzActive(), kmc * Dpx(1), kmc * Dpz(1)); + printf("Passive Edges: Bottom: %.1f Right: %.1f Top: %.1f Left: %.1f -> DX: %.1f DZ: %.1f Shift: " + "x:%.1f z:%.1f\n", + kmc * mGuardBottom, kmc * mGuardRight, kmc * mGuardTop, kmc * mGuardLeft, kmc * Dx(), + kmc * Dz(), kmc * mShiftLocalX, kmc * mShiftLocalZ); + printf("%d chips along Z: chip Ncol=%d Nrow=%d\n", mNumberOfChips, mNumberOfColumnsPerChip, + mNumberOfRows); + if (Abs(mPitchZLeftColumn - mPitchZ) > 1e-5) { + printf("Special left column pitch: %.1f\n", mPitchZLeftColumn * kmc); + } + if (Abs(mPitchZRightColumn - mPitchZ) > 1e-5) { + printf("Special right column pitch: %.1f\n", mPitchZRightColumn * kmc); + } + + if (mDiodShiftMatDimension) { + double dx, dz = 0; + printf("Diod shift (fraction of pitch) periodicity pattern (X,Z[row][col])\n"); + for (int irow = 0; irow < mDiodShiftMatNRow; irow++) { + for (int icol = 0; icol < mDiodShiftMatNColumn; icol++) { + GetDiodShift(irow, icol, dx, dz); + printf("%.1f/%.1f |", dx, dz); + } + printf("\n"); + } + } +} + +void UpgradeSegmentationPixel::GetDiodShift(Int_t row, Int_t col, Float_t& dx, Float_t& dz) const +{ + // obtain optional diod shift + if (!mDiodShiftMatDimension) { + dx = dz = 0; + return; + } + int cnt = (col % mDiodShiftMatNColumn) + (row % mDiodShiftMatNRow) * mDiodShiftMatNColumn; + dx = mDiodShiftMatX[cnt]; + dz = mDiodShiftMatZ[cnt]; +} diff --git a/its/UpgradeSegmentationPixel.h b/its/UpgradeSegmentationPixel.h new file mode 100644 index 0000000000000..068ff9179fb30 --- /dev/null +++ b/its/UpgradeSegmentationPixel.h @@ -0,0 +1,266 @@ +/// \file UpgradeSegmentationPixel.h +/// \brief Definition of the UpgradeSegmentationPixel class + +#ifndef ALICEO2_ITS_UPGRADESEGMENTATIONPIXEL_H_ +#define ALICEO2_ITS_UPGRADESEGMENTATIONPIXEL_H_ + +#include "FairLogger.h" + +#include "Segmentation.h" + +namespace AliceO2 { +namespace ITS { + +/// Segmentation and response for pixels in ITS upgrade +/// 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 mGuardLeft and mGuardBottom +/// from the local Z,X coordinates +class UpgradeSegmentationPixel : public AliceO2::ITS::Segmentation { + +public: + UpgradeSegmentationPixel(UInt_t id = 0, int nchips = 0, int ncol = 0, int nrow = 0, + float pitchX = 0, float pitchZ = 0, float thickness = 0, + float pitchLftC = -1, float pitchRgtC = -1, float edgL = 0, + float edgR = 0, float edgT = 0, float edgB = 0); + + // UpgradeSegmentationPixel(Option_t *opt="" ); + UpgradeSegmentationPixel(const UpgradeSegmentationPixel& source); + virtual ~UpgradeSegmentationPixel(); + UpgradeSegmentationPixel& operator=(const UpgradeSegmentationPixel& source); + + virtual void Init(); + + virtual void SetNPads(Int_t, Int_t) + { + MayNotUse("SetPadSize"); + } + + virtual Int_t GetNPads() const + { + return mNumberOfColumns * mNumberOfRows; + } + + /// Returns pixel coordinates (ix,iz) for given coordinates (x,z counted from corner of col/row + /// 0:0). Expects x, z in cm + virtual void GetPadIxz(Float_t x, Float_t z, Int_t& ix, Int_t& iz) const; + + /// Transform from pixel to real local coordinates + /// Eeturns x, z in cm. wrt corner of col/row 0:0 + virtual void GetPadCxz(Int_t ix, Int_t iz, 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 + virtual void GetPadTxz(Float_t& x, Float_t& z) const; + + /// Transformation from Geant detector centered local coordinates (cm) to + /// Pixel cell numbers ix and iz. + /// Returns kTRUE if point x,z is inside sensitive volume, kFALSE otherwise. + /// A value of -1 for ix or iz indicates that this point is outside of the + /// detector segmentation as defined. + /// \param Float_t x Detector local coordinate x in cm with respect to + /// the center of the sensitive volume. + /// \param Float_t z Detector local coordinate z in cm with respect to + /// the center of the sensitive volulme. + /// \param Int_t ix Detector x cell coordinate. Has the range 0 <= ix < mNumberOfRows + /// \param Int_t iz Detector z cell coordinate. Has the range 0 <= iz < mNumberOfColumns + virtual Bool_t LocalToDetector(Float_t x, Float_t z, Int_t& ix, Int_t& iz) const; + + /// Transformation from Detector cell coordiantes to Geant detector centered + /// local coordinates (cm) + /// \param Int_t ix Detector x cell coordinate. Has the range 0 <= ix < mNumberOfRows + /// \param Int_t iz Detector z cell coordinate. Has the range 0 <= iz < mNumberOfColumns + /// \param Float_t x Detector local coordinate x in cm with respect to the + /// center of the sensitive volume. + /// \param Float_t z Detector local coordinate z in cm with respect to the + /// center of the sensitive volulme. + /// If ix and or iz is outside of the segmentation range a value of -0.5*Dx() + /// or -0.5*Dz() is returned. + virtual void DetectorToLocal(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) + /// \param Int_t ix Detector x cell coordinate. Has the range 0<=ix +/// \author Chinorat Kobdaj (kobdaj@g.sut.ac.th) + +#include +#include +#include +#include +#include +#include // contaings TGeoTubeSeg +#include +#include +#include +#include +#include +#include +#include + +#include "UpgradeV1Layer.h" +#include "UpgradeGeometryTGeo.h" + +#include "FairLogger.h" + +using namespace TMath; +using namespace AliceO2::ITS; + +// General Parameters +const Int_t AliceO2::ITS::UpgradeV1Layer::sNumberOmInnerLayers = 3; + +const Double_t AliceO2::ITS::UpgradeV1Layer::sDefaultSensorThick = 300 * sMicron; +const Double_t AliceO2::ITS::UpgradeV1Layer::sDefaultStaveThick = 1 * sCm; + +// Inner Barrel Parameters +const Int_t AliceO2::ITS::UpgradeV1Layer::sIBChipsPerRow = 9; +const Int_t AliceO2::ITS::UpgradeV1Layer::sIBNChipRows = 1; + +// Outer Barrel Parameters +const Int_t AliceO2::ITS::UpgradeV1Layer::sOBChipsPerRow = 7; +const Int_t AliceO2::ITS::UpgradeV1Layer::sOBNChipRows = 2; + +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBHalfStaveWidth = 3.01 * sCm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBModuleWidth = sOBHalfStaveWidth; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBModuleGap = 0.01 * sCm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBChipXGap = 0.01 * sCm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBChipZGap = 0.01 * sCm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBFlexCableAlThick = 0.005 * sCm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBFlexCableKapThick = 0.01 * sCm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBBusCableAlThick = 0.02 * sCm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBBusCableKapThick = 0.02 * sCm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBColdPlateThick = 0.012 * sCm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBCarbonPlateThick = 0.012 * sCm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBGlueThick = 0.03 * sCm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBModuleZLength = 21.06 * sCm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBHalfStaveYTrans = 1.76 * sMm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBHalfStaveXOverlap = 4.3 * sMm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBGraphiteFoilThick = 30.0 * sMicron; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBCoolTubeInnerD = 2.052 * sMm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBCoolTubeThick = 32.0 * sMicron; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBCoolTubeXDist = 11.1 * sMm; + +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBSpaceFrameWidth = 42.0 * sMm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBSpaceFrameTotHigh = 43.1 * sMm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBSFrameBeamRadius = 0.6 * sMm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBSpaceFrameLa = 3.0 * sMm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBSpaceFrameHa = 0.721979 * sMm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBSpaceFrameLb = 3.7 * sMm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBSpaceFrameHb = 0.890428 * sMm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBSpaceFrameL = 0.25 * sMm; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBSFBotBeamAngle = 56.5; +const Double_t AliceO2::ITS::UpgradeV1Layer::sOBSFrameBeamSidePhi = 65.0; + +ClassImp(AliceO2::ITS::UpgradeV1Layer) + +#define SQ(A) (A) * (A) + +AliceO2::ITS::UpgradeV1Layer::UpgradeV1Layer() + : V11Geometry() + , mLayerNumber(0) + , mPhi0(0) + , mLayerRadius(0) + , mZLength(0) + , mSensorThickness(0) + , mStaveThickness(0) + , mStaveWidth(0) + , mStaveTilt(0) + , mNumberOfStaves(0) + , mNumberOfModules(0) + , mNumberOfChips(0) + , mChipTypeID(0) + , mIsTurbo(0) + , mBuildLevel(0) + , mStaveModel(AliceO2::ITS::Detector::kIBModelDummy) +{ + for (int i = kNHLevels; i--;) { + mHierarchy[i] = 0; + } +} + +AliceO2::ITS::UpgradeV1Layer::UpgradeV1Layer(Int_t debug) + : V11Geometry(debug) + , mLayerNumber(0) + , mPhi0(0) + , mLayerRadius(0) + , mZLength(0) + , mSensorThickness(0) + , mStaveThickness(0) + , mStaveWidth(0) + , mStaveTilt(0) + , mNumberOfStaves(0) + , mNumberOfModules(0) + , mNumberOfChips(0) + , mChipTypeID(0) + , mIsTurbo(0) + , mBuildLevel(0) + , mStaveModel(AliceO2::ITS::Detector::kIBModelDummy) +{ + for (int i = kNHLevels; i--;) { + mHierarchy[i] = 0; + } +} + +AliceO2::ITS::UpgradeV1Layer::UpgradeV1Layer(Int_t lay, Int_t debug) + : V11Geometry(debug) + , mLayerNumber(lay) + , mPhi0(0) + , mLayerRadius(0) + , mZLength(0) + , mSensorThickness(0) + , mStaveThickness(0) + , mStaveWidth(0) + , mStaveTilt(0) + , mNumberOfStaves(0) + , mNumberOfModules(0) + , mNumberOfChips(0) + , mChipTypeID(0) + , mIsTurbo(0) + , mBuildLevel(0) + , mStaveModel(AliceO2::ITS::Detector::kIBModelDummy) +{ + for (int i = kNHLevels; i--;) { + mHierarchy[i] = 0; + } +} + +AliceO2::ITS::UpgradeV1Layer::UpgradeV1Layer(Int_t lay, Bool_t turbo, Int_t debug) + : V11Geometry(debug) + , mLayerNumber(lay) + , mPhi0(0) + , mLayerRadius(0) + , mZLength(0) + , mSensorThickness(0) + , mStaveThickness(0) + , mStaveWidth(0) + , mStaveTilt(0) + , mNumberOfStaves(0) + , mNumberOfModules(0) + , mNumberOfChips(0) + , mChipTypeID(0) + , mIsTurbo(turbo) + , mBuildLevel(0) + , mStaveModel(AliceO2::ITS::Detector::kIBModelDummy) +{ + for (int i = kNHLevels; i--;) { + mHierarchy[i] = 0; + } +} + +AliceO2::ITS::UpgradeV1Layer::UpgradeV1Layer(const AliceO2::ITS::UpgradeV1Layer& s) + : V11Geometry(s.GetDebug()) + , mLayerNumber(s.mLayerNumber) + , mPhi0(s.mPhi0) + , mLayerRadius(s.mLayerRadius) + , mZLength(s.mZLength) + , mSensorThickness(s.mSensorThickness) + , mStaveThickness(s.mStaveThickness) + , mStaveWidth(s.mStaveWidth) + , mStaveTilt(s.mStaveTilt) + , mNumberOfStaves(s.mNumberOfStaves) + , mNumberOfModules(s.mNumberOfModules) + , mNumberOfChips(s.mNumberOfChips) + , mChipTypeID(s.mChipTypeID) + , mIsTurbo(s.mIsTurbo) + , mBuildLevel(s.mBuildLevel) + , mStaveModel(s.mStaveModel) +{ + for (int i = kNHLevels; i--;) { + mHierarchy[i] = s.mHierarchy[i]; + } +} + +AliceO2::ITS::UpgradeV1Layer& AliceO2::ITS::UpgradeV1Layer::operator=( + const AliceO2::ITS::UpgradeV1Layer& s) +{ + if (&s == this) { + return *this; + } + + mLayerNumber = s.mLayerNumber; + mPhi0 = s.mPhi0; + mLayerRadius = s.mLayerRadius; + mZLength = s.mZLength; + mSensorThickness = s.mSensorThickness; + mStaveThickness = s.mStaveThickness; + mStaveWidth = s.mStaveWidth; + mStaveTilt = s.mStaveTilt; + mNumberOfStaves = s.mNumberOfStaves; + mNumberOfModules = s.mNumberOfModules; + mNumberOfChips = s.mNumberOfChips; + mIsTurbo = s.mIsTurbo; + mChipTypeID = s.mChipTypeID; + mBuildLevel = s.mBuildLevel; + mStaveModel = s.mStaveModel; + for (int i = kNHLevels; i--;) { + mHierarchy[i] = s.mHierarchy[i]; + } + + return *this; +} + +AliceO2::ITS::UpgradeV1Layer::~UpgradeV1Layer() +{ +} + +void AliceO2::ITS::UpgradeV1Layer::CreateLayer(TGeoVolume* motherVolume) +{ + char volumeName[30]; + Double_t xpos, ypos, zpos; + Double_t alpha; + + // Check if the user set the proper parameters + if (mLayerRadius <= 0) { + LOG(FATAL) << "Wrong layer radius " << mLayerRadius << FairLogger::endl; + } + + if (mZLength <= 0) { + LOG(FATAL) << "Wrong layer length " << mZLength << FairLogger::endl; + } + + if (mNumberOfStaves <= 0) { + LOG(FATAL) << "Wrong number of staves " << mNumberOfStaves << FairLogger::endl; + } + + if (mNumberOfChips <= 0) { + LOG(FATAL) << "Wrong number of chips " << mNumberOfChips << FairLogger::endl; + } + + if (mLayerNumber >= sNumberOmInnerLayers && mNumberOfModules <= 0) { + LOG(FATAL) << "Wrong number of modules " << mNumberOfModules << FairLogger::endl; + } + + if (mStaveThickness <= 0) { + LOG(INFO) << "Stave thickness wrong or not set " << mStaveThickness << " using default " + << sDefaultStaveThick << FairLogger::endl; + mStaveThickness = sDefaultStaveThick; + } + + if (mSensorThickness <= 0) { + LOG(INFO) << "Sensor thickness wrong or not set " << mSensorThickness << " using default " + << sDefaultSensorThick << FairLogger::endl; + mSensorThickness = sDefaultSensorThick; + } + + if (mSensorThickness > mStaveThickness) { + LOG(WARNING) << "Sensor thickness " << mSensorThickness << " is greater than stave thickness " + << mStaveThickness << " fixing" << FairLogger::endl; + mSensorThickness = mStaveThickness; + } + + // If a Turbo layer is requested, do it and exit + if (mIsTurbo) { + CreateLayerTurbo(motherVolume); + return; + } + + // First create the stave container + alpha = (360. / (2 * mNumberOfStaves)) * DegToRad(); + + // mStaveWidth = mLayerRadius*Tan(alpha); + + snprintf(volumeName, 30, "%s%d", UpgradeGeometryTGeo::GetITSLayerPattern(), mLayerNumber); + TGeoVolume* layerVolume = new TGeoVolumeAssembly(volumeName); + layerVolume->SetUniqueID(mChipTypeID); + + // layerVolume->SetVisibility(kFALSE); + layerVolume->SetVisibility(kTRUE); + layerVolume->SetLineColor(1); + + TGeoVolume* stavVol = CreateStave(); + + // Now build up the layer + alpha = 360. / mNumberOfStaves; + Double_t r = mLayerRadius + ((TGeoBBox*)stavVol->GetShape())->GetDY(); + for (Int_t j = 0; j < mNumberOfStaves; j++) { + Double_t phi = j * alpha + mPhi0; + xpos = r * CosD(phi); // r*SinD(-phi); + ypos = r * SinD(phi); // r*CosD(-phi); + zpos = 0.; + phi += 90; + layerVolume->AddNode(stavVol, j, + new TGeoCombiTrans(xpos, ypos, zpos, new TGeoRotation("", phi, 0, 0))); + } + + // Finally put everything in the mother volume + motherVolume->AddNode(layerVolume, 1, 0); + + // Upgrade geometry is served + return; +} + +void AliceO2::ITS::UpgradeV1Layer::CreateLayerTurbo(TGeoVolume* motherVolume) +{ + char volumeName[30]; + Double_t xpos, ypos, zpos; + Double_t alpha; + + // Check if the user set the proper (remaining) parameters + if (mStaveWidth <= 0) { + LOG(FATAL) << "Wrong stave width " << mStaveWidth << FairLogger::endl; + } + + if (Abs(mStaveTilt) > 45) { + LOG(WARNING) << "Stave tilt angle (" << mStaveTilt << ") greater than 45deg" + << FairLogger::endl; + } + + snprintf(volumeName, 30, "%s%d", UpgradeGeometryTGeo::GetITSLayerPattern(), mLayerNumber); + TGeoVolume* layerVolume = new TGeoVolumeAssembly(volumeName); + layerVolume->SetUniqueID(mChipTypeID); + layerVolume->SetVisibility(kTRUE); + layerVolume->SetLineColor(1); + TGeoVolume* stavVol = CreateStave(); + + // Now build up the layer + alpha = 360. / mNumberOfStaves; + Double_t r = mLayerRadius /* +chip thick ?! */; + for (Int_t j = 0; j < mNumberOfStaves; j++) { + Double_t phi = j * alpha + mPhi0; + xpos = r * CosD(phi); // r*SinD(-phi); + ypos = r * SinD(phi); // r*CosD(-phi); + zpos = 0.; + phi += 90; + layerVolume->AddNode(stavVol, j, new TGeoCombiTrans(xpos, ypos, zpos, + new TGeoRotation("", phi - mStaveTilt, 0, 0))); + } + + // Finally put everything in the mother volume + motherVolume->AddNode(layerVolume, 1, 0); + + return; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateStave(const TGeoManager* /*mgr*/) +{ + char volumeName[30]; + + Double_t xlen, ylen, zlen; + Double_t xpos, ypos; + Double_t alpha; + + // First create all needed shapes + alpha = (360. / (2 * mNumberOfStaves)) * DegToRad(); + + // The stave + xlen = mLayerRadius * Tan(alpha); + if (mIsTurbo) { + xlen = 0.5 * mStaveWidth; + } + ylen = 0.5 * mStaveThickness; + zlen = 0.5 * mZLength; + + 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 - mSensorThickness, -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(volumeName, 30, "%s%d", UpgradeGeometryTGeo::GetITSStavePattern(), mLayerNumber); + // TGeoVolume *staveVol = new TGeoVolume(volumeName, stave, medAir); + TGeoVolume* staveVol = new TGeoVolumeAssembly(volumeName); + + // staveVol->SetVisibility(kFALSE); + staveVol->SetVisibility(kTRUE); + staveVol->SetLineColor(2); + TGeoVolume* mechStaveVol = 0; + + // Now build up the stave + if (mLayerNumber < sNumberOmInnerLayers) { + TGeoVolume* modVol = CreateStaveInnerB(xlen, ylen, zlen); + staveVol->AddNode(modVol, 0); + mHierarchy[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 (mStaveModel == + AliceO2::ITS::Detector::kOBModel0) { // Create simplified stave struct as in v0 + staveVol->AddNode(hstaveVol, 0); + mHierarchy[kHalfStave] = 1; + } + else { // (if mStaveModel) Create new stave struct as in TDR + xpos = ((TGeoBBox*)(hstaveVol->GetShape()))->GetDX() - sOBHalfStaveXOverlap / 2; + // ypos is CF height as computed in CreateSpaceFrameOuterB1 + ypos = (sOBSpaceFrameTotHigh - sOBHalfStaveYTrans) / 2; + staveVol->AddNode(hstaveVol, 0, new TGeoTranslation(-xpos, ypos, 0)); + staveVol->AddNode(hstaveVol, 1, new TGeoTranslation(xpos, ypos + sOBHalfStaveYTrans, 0)); + mHierarchy[kHalfStave] = 2; // RS + mechStaveVol = CreateSpaceFrameOuterB(); + + if (mechStaveVol) { + staveVol->AddNode(mechStaveVol, 1, + new TGeoCombiTrans(0, 0, 0, new TGeoRotation("", 180, 0, 0))); + } + } + } + // Done, return the stave + return staveVol; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateStaveInnerB(const Double_t xsta, + const Double_t ysta, + const Double_t zsta, + const TGeoManager* mgr) +{ + Double_t xmod, ymod, zmod; + char volumeName[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(volumeName, 30, "%s%d", UpgradeGeometryTGeo::GetITSHalfStavePattern(), mLayerNumber); + TGeoVolume* hstaveVol = new TGeoVolume(volumeName, hstave, medAir); + + // Finally build it up + hstaveVol->AddNode(moduleVol, 0); + mHierarchy[kModule] = 1; + + // Done, return the stave structure + return hstaveVol; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateModuleInnerB(Double_t xmod, Double_t ymod, + Double_t zmod, const TGeoManager* mgr) +{ + Double_t zchip; + Double_t zpos; + char volumeName[30]; + + // First create the single chip + zchip = zmod / sIBChipsPerRow; + 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(volumeName, 30, "%s%d", UpgradeGeometryTGeo::GetITSModulePattern(), mLayerNumber); + TGeoVolume* modVol = new TGeoVolume(volumeName, module, medAir); + + // mm (not used) zlen = ((TGeoBBox*)chipVol->GetShape())->GetDZ(); + for (Int_t j = 0; j < sIBChipsPerRow; j++) { + zpos = -zmod + j * 2 * zchip + zchip; + modVol->AddNode(chipVol, j, new TGeoTranslation(0, 0, zpos)); + mHierarchy[kChip]++; + } + // Done, return the module + return modVol; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateStaveStructInnerB(const Double_t xsta, + const Double_t zsta, + const TGeoManager* mgr) +{ + TGeoVolume* mechStavVol = 0; + + switch (mStaveModel) { + case AliceO2::ITS::Detector::kIBModelDummy: + mechStavVol = CreateStaveModelInnerBDummy(xsta, zsta, mgr); + break; + case AliceO2::ITS::Detector::kIBModel0: + mechStavVol = CreateStaveModelInnerB0(xsta, zsta, mgr); + break; + case AliceO2::ITS::Detector::kIBModel1: + mechStavVol = CreateStaveModelInnerB1(xsta, zsta, mgr); + break; + case AliceO2::ITS::Detector::kIBModel21: + mechStavVol = CreateStaveModelInnerB21(xsta, zsta, mgr); + break; + case AliceO2::ITS::Detector::kIBModel22: + mechStavVol = CreateStaveModelInnerB22(xsta, zsta, mgr); + break; + case AliceO2::ITS::Detector::kIBModel3: + mechStavVol = CreateStaveModelInnerB3(xsta, zsta, mgr); + break; + default: + LOG(FATAL) << "Unknown stave model " << mStaveModel << FairLogger::endl; + break; + } + return mechStavVol; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateStaveModelInnerBDummy(const Double_t, + const Double_t, + const TGeoManager*) const +{ + // Done, return the stave structur + return 0; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateStaveModelInnerB0(const Double_t xsta, + const Double_t zsta, + const TGeoManager* mgr) +{ + // Materials defined in Detector + 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 " << mBuildLevel << FairLogger::endl; + + char volumeName[30]; + snprintf(volumeName, 30, "%s%d_StaveStruct", UpgradeGeometryTGeo::GetITSStavePattern(), + mLayerNumber); + + Double_t z = 0, y = -0.011 + 0.0150, x = 0; + + TGeoVolume* mechStavVol = 0; + + if (mBuildLevel < 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(volumeName, 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 (mBuildLevel < 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 (mBuildLevel < 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; i < loop; i++) { // i<60;i++){ + mechStavVol->AddNode( + 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; i < loop; i++) { + mechStavVol->AddNode( + 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 (mBuildLevel < 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; i < loop; i++) { // i<60;i++){ + mechStavVol->AddNode( + 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 - mSensorThickness - 0.005, z, + new TGeoRotation("", 0, 0, 0))); + } + + if (mBuildLevel < 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 - mSensorThickness - 0.005 - 0.01, + z, new TGeoRotation("", 0, 0, 0))); + } + // Done, return the stave structur + return mechStavVol; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateStaveModelInnerB1(const Double_t xsta, + const Double_t zsta, + const TGeoManager* mgr) +{ + // Materials defined in Detector + 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 volumeName[30]; + snprintf(volumeName, 30, "%s%d_StaveStruct", UpgradeGeometryTGeo::GetITSStavePattern(), + mLayerNumber); + + // 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 (mBuildLevel < 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(volumeName, 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; ib < nb; ib++) { + mechStavVol->AddNode(volTM0b, ib, new TGeoCombiTrans(x + ib * 0.1 - xstaMC + 0.01, yMC, z, + new TGeoRotation("", 0, 0, 0))); + } + } + + if (mBuildLevel < 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 (mBuildLevel < 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; i < loop; i++) { // i<30;i++){ + mechStavVol->AddNode(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; i < loop; i++) { // i<30;i++){ + mechStavVol->AddNode( + 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 (mBuildLevel < 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; i < loop; i++) { // i<30;i++){ + mechStavVol->AddNode(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 - mSensorThickness - 0.005, z, + new TGeoRotation("", 0, 0, 0))); + } + + if (mBuildLevel < 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 - mSensorThickness - 0.005 - 0.01, + z, new TGeoRotation("", 0, 0, 0))); + } + // Done, return the stave structur + return mechStavVol; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateStaveModelInnerB21(const Double_t xsta, + const Double_t zsta, + const TGeoManager* mgr) +{ + // Materials defined in Detector + 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 volumeName[30]; + snprintf(volumeName, 30, "%s%d_StaveStruct", UpgradeGeometryTGeo::GetITSStavePattern(), + mLayerNumber); + + Double_t z = 0, y = -(kConeOutRadius + 0.03) + 0.0385, x = 0; + + TGeoVolume* mechStavVol = 0; + + if (mBuildLevel < 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(volumeName, 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 (mBuildLevel < 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 (mBuildLevel < 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; i < loop; i++) { // i<28;i++){ + mechStavVol->AddNode( + 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 (mBuildLevel < 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 + + mSensorThickness + (0.01 / 2)), + z, new TGeoRotation("", 0, 0, 0))); + } + + if (mBuildLevel < 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 + + mSensorThickness + 0.01 + (0.01 / 2)), + z, new TGeoRotation("", 0, 0, 0))); + } + // Done, return the stave structure + return mechStavVol; +} +// new model22 +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateStaveModelInnerB22(const Double_t xsta, + const Double_t zsta, + const TGeoManager* mgr) +{ + // Materials defined in Detector + 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 volumeName[30]; + snprintf(volumeName, 30, "%s%d_StaveStruct", UpgradeGeometryTGeo::GetITSStavePattern(), + mLayerNumber); + + Double_t z = 0, y = -(2 * kConeOutRadius) + klay1 + klay2 + mSensorThickness / 2 - 0.0004, x = 0; + + TGeoVolume* mechStavVol = 0; + + if (mBuildLevel < 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+mSensorThickness+klay5), + // 0-0.02,kStaveHeight+0.01,kStaveHeight+0.01,0-0.02, + // -2*(kConeOutRadius+klay1+1.5*klay2+klay3+klay4+mSensorThickness+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(volumeName, 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 (mBuildLevel < 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 (mBuildLevel < 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; i < loop; i++) { // i<28;i++){ + // 1) Front Left Top Filament + mechStavVol->AddNode( + 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 (mBuildLevel < 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 (mBuildLevel < 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+mSensorThickness+(klay5)/2)+0.0002, z, new TGeoRotation("",0, + // 0, 0))); + mechStavVol->AddNode( + volCable, 0, + new TGeoCombiTrans( + x, y - (kConeOutRadius + klay3 + klay2 + klay4 + mSensorThickness + (klay5) / 2) + 0.01185, + z, new TGeoRotation("", 0, 0, 0))); + } + // Done, return the stave structe + return mechStavVol; +} + +// model3 +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateStaveModelInnerB3(const Double_t xsta, + const Double_t zsta, + const TGeoManager* mgr) +{ + // Materials defined in Detector + 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 volumeName[30]; + snprintf(volumeName, 30, "%s%d_StaveStruct", UpgradeGeometryTGeo::GetITSStavePattern(), + mLayerNumber); + + // 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 (mBuildLevel < 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(volumeName, 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; ib < nb; ib++) { + // mechStavVol->AddNode(volTM0b, ib, new TGeoCombiTrans(x+ib*0.1-xstaMC+0.01,yMC, z, new + // TGeoRotation("",0, 0, 0))); + } + } + + if (mBuildLevel < 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 (mBuildLevel < 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; i < loop; i++) { // i<30;i++){ + mechStavVol->AddNode(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; i < loop; i++) { // i<30;i++){ + mechStavVol->AddNode( + 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 (mBuildLevel < 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 - mSensorThickness - klay4 / 2, z, + new TGeoRotation("", 0, 0, 0))); + } + + if (mBuildLevel < 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 - mSensorThickness - klay4 - klay5 / 2, z, + new TGeoRotation("", 0, 0, 0))); + } + // Done, return the stave structure + return mechStavVol; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateStaveOuterB(const TGeoManager* mgr) +{ + TGeoVolume* mechStavVol = 0; + + switch (mStaveModel) { + case AliceO2::ITS::Detector::kOBModelDummy: + mechStavVol = CreateStaveModelOuterBDummy(mgr); + break; + case AliceO2::ITS::Detector::kOBModel0: + mechStavVol = CreateStaveModelOuterB0(mgr); + break; + case AliceO2::ITS::Detector::kOBModel1: + mechStavVol = CreateStaveModelOuterB1(mgr); + break; + default: + LOG(FATAL) << "Unknown stave model " << mStaveModel << FairLogger::endl; + break; + } + return mechStavVol; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateStaveModelOuterBDummy(const TGeoManager*) const +{ + // Done, return the stave structure + return 0; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateStaveModelOuterB0(const TGeoManager* mgr) +{ + Double_t xmod, ymod, zmod; + Double_t xlen, ylen, zlen; + Double_t ypos, zpos; + char volumeName[30]; + + // First create all needed shapes + // The chip + xlen = sOBHalfStaveWidth; + ylen = 0.5 * mStaveThickness; // TO BE CHECKED + zlen = sOBModuleZLength / 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 = sOBModuleZLength * mNumberOfModules; + TGeoBBox* hstave = new TGeoBBox(xlen, ylen, zlen / 2); + + // We have all shapes: now create the real volumes + TGeoMedium* medAir = mgr->GetMedium("ITS_AIR$"); + + snprintf(volumeName, 30, "%s%d", UpgradeGeometryTGeo::GetITSModulePattern(), mLayerNumber); + TGeoVolume* modVol = new TGeoVolume(volumeName, module, medAir); + modVol->SetVisibility(kTRUE); + + snprintf(volumeName, 30, "%s%d", UpgradeGeometryTGeo::GetITSHalfStavePattern(), mLayerNumber); + TGeoVolume* hstaveVol = new TGeoVolume(volumeName, hstave, medAir); + + // Finally build it up + modVol->AddNode(chipVol, 0); + mHierarchy[kChip] = 1; + + for (Int_t j = 0; j < mNumberOfModules; j++) { + ypos = 0.021; // Remove small overlap - M.S: 21may13 + zpos = -hstave->GetDZ() + j * 2 * zmod + zmod; + hstaveVol->AddNode(modVol, j, new TGeoTranslation(0, ypos, zpos)); + mHierarchy[kModule]++; + } + // Done, return the stave structure + return hstaveVol; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateStaveModelOuterB1(const TGeoManager* mgr) +{ + Double_t yFlex1 = sOBFlexCableAlThick; + Double_t yFlex2 = sOBFlexCableKapThick; + Double_t flexOverlap = 5; // to be checked + Double_t xHalmSt = sOBHalfStaveWidth / 2; + Double_t rCoolMin = sOBCoolTubeInnerD / 2; + Double_t rCoolMax = rCoolMin + sOBCoolTubeThick; + Double_t kLay1 = 0.004; // to be checked + Double_t kLay2 = sOBGraphiteFoilThick; + + 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 volumeName[30]; + + zlen = (mNumberOfModules * sOBModuleZLength + (mNumberOfModules - 1) * sOBModuleGap) / 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", xHalmSt, sOBBusCableAlThick / 2, zlen); + TGeoBBox* busKap = new TGeoBBox("BusKap", xHalmSt, sOBBusCableKapThick / 2, zlen); + + TGeoBBox* coldPlate = + new TGeoBBox("ColdPlate", sOBHalfStaveWidth / 2, sOBColdPlateThick / 2, zlen); + + TGeoTube* coolTube = new TGeoTube("CoolingTube", rCoolMin, rCoolMax, zlen); + TGeoTube* coolWater = new TGeoTube("CoolingWater", 0., rCoolMin, zlen); + + xlen = xHalmSt - sOBCoolTubeXDist / 2 - coolTube->GetRmax(); + TGeoBBox* graphlat = new TGeoBBox("GraphLateral", xlen / 2, kLay2 / 2, zlen); + + xlen = sOBCoolTubeXDist / 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 = xHalmSt - sOBCoolTubeXDist / 2 - coolTube->GetRmax() - kLay2; + TGeoBBox* fleeclat = new TGeoBBox("FleecLateral", xlen / 2, kLay1 / 2, zlen); + + xlen = sOBCoolTubeXDist / 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", xHalmSt, yFlex1 / 2, flexOverlap / 2); + TGeoBBox* flex2_5cm = new TGeoBBox("Flex2MV_5cm", xHalmSt, yFlex2 / 2, flexOverlap / 2); + + // The half stave container (an XTru to avoid overlaps between neightbours) + xtru[0] = xHalmSt; + ytru[0] = 0; + xtru[1] = xtru[0]; + ytru[1] = -2 * (ymod + busAl->GetDY() + busKap->GetDY() + coldPlate->GetDY() + graphlat->GetDY() + + fleeclat->GetDY()); + xtru[2] = sOBCoolTubeXDist / 2 + fleectub->GetRmax(); + ytru[2] = ytru[1]; + xtru[3] = xtru[2]; + ytru[3] = ytru[2] - (coolTube->GetRmax() + fleectub->GetRmax()); + xtru[4] = sOBCoolTubeXDist / 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* halmStave = new TGeoXtru(2); + halmStave->DefinePolygon(12, xtru, ytru); + halmStave->DefineSection(0, -mZLength / 2); + halmStave->DefineSection(1, mZLength / 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(volumeName, 30, "%s%d", UpgradeGeometryTGeo::GetITSHalfStavePattern(), mLayerNumber); + TGeoVolume* halmStaveVol = new TGeoVolume(volumeName, halmStave, medAir); + // halmStaveVol->SetLineColor(12); + // halmStaveVol->SetFillColor(12); + // halmStaveVol->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(); + halmStaveVol->AddNode(busKapVol, 1, new TGeoTranslation(0, ypos, 0)); + + ypos -= (busKap->GetDY() + busAl->GetDY()); + halmStaveVol->AddNode(busAlVol, 1, new TGeoTranslation(0, ypos, 0)); + + ypos -= (busAl->GetDY() + ymod); + for (Int_t j = 0; j < mNumberOfModules; j++) { + zpos = -zlen + j * (2 * zmod + sOBModuleGap) + zmod; + halmStaveVol->AddNode(moduleVol, j, new TGeoTranslation(0, ypos, zpos)); + mHierarchy[kModule]++; + } + + ypos -= (ymod + coldPlate->GetDY()); + halmStaveVol->AddNode(coldPlateVol, 1, new TGeoTranslation(0, ypos, 0)); + + coolTubeVol->AddNode(coolWaterVol, 1, 0); + + xpos = sOBCoolTubeXDist / 2; + ypos1 = ypos - (coldPlate->GetDY() + coolTube->GetRmax()); + halmStaveVol->AddNode(coolTubeVol, 1, new TGeoTranslation(-xpos, ypos1, 0)); + halmStaveVol->AddNode(coolTubeVol, 2, new TGeoTranslation(xpos, ypos1, 0)); + + halmStaveVol->AddNode(graphtubVol, 1, new TGeoTranslation(-xpos, ypos1, 0)); + halmStaveVol->AddNode(graphtubVol, 2, new TGeoTranslation(xpos, ypos1, 0)); + + halmStaveVol->AddNode(fleectubVol, 1, new TGeoTranslation(-xpos, ypos1, 0)); + halmStaveVol->AddNode(fleectubVol, 2, new TGeoTranslation(xpos, ypos1, 0)); + + xpos = xHalmSt - graphlat->GetDX(); + ypos1 = ypos - (coldPlate->GetDY() + graphlat->GetDY()); + halmStaveVol->AddNode(graphlatVol, 1, new TGeoTranslation(-xpos, ypos1, 0)); + halmStaveVol->AddNode(graphlatVol, 2, new TGeoTranslation(xpos, ypos1, 0)); + + halmStaveVol->AddNode(graphmidVol, 1, new TGeoTranslation(0, ypos1, 0)); + + xpos = xHalmSt - 2 * graphlat->GetDX() + graphvert->GetDX(); + ypos1 = ypos - (coldPlate->GetDY() + 2 * graphlat->GetDY() + graphvert->GetDY()); + halmStaveVol->AddNode(graphvertVol, 1, new TGeoTranslation(-xpos, ypos1, 0)); + halmStaveVol->AddNode(graphvertVol, 2, new TGeoTranslation(xpos, ypos1, 0)); + xpos = graphmid->GetDX() - graphvert->GetDX(); + halmStaveVol->AddNode(graphvertVol, 3, new TGeoTranslation(-xpos, ypos1, 0)); + halmStaveVol->AddNode(graphvertVol, 4, new TGeoTranslation(xpos, ypos1, 0)); + + xpos = xHalmSt - fleeclat->GetDX(); + ypos1 = ypos - (coldPlate->GetDY() + 2 * graphlat->GetDY() + fleeclat->GetDY()); + halmStaveVol->AddNode(fleeclatVol, 1, new TGeoTranslation(-xpos, ypos1, 0)); + halmStaveVol->AddNode(fleeclatVol, 2, new TGeoTranslation(xpos, ypos1, 0)); + + halmStaveVol->AddNode(fleecmidVol, 1, new TGeoTranslation(0, ypos1, 0)); + + xpos = xHalmSt - 2 * fleeclat->GetDX() + fleecvert->GetDX(); + ypos1 = ypos - + (coldPlate->GetDY() + 2 * graphlat->GetDY() + 2 * fleeclat->GetDY() + fleecvert->GetDY()); + halmStaveVol->AddNode(fleecvertVol, 1, new TGeoTranslation(-xpos, ypos1, 0)); + halmStaveVol->AddNode(fleecvertVol, 2, new TGeoTranslation(xpos, ypos1, 0)); + xpos = fleecmid->GetDX() - fleecvert->GetDX(); + halmStaveVol->AddNode(fleecvertVol, 3, new TGeoTranslation(-xpos, ypos1, 0)); + halmStaveVol->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)); + // halmStaveVol->AddNode(moduleVol, mNumberOfChips+j, new TGeoTranslation(-xPos, -ylen + yPos + + // 2*rCoolMax + yCPlate + yGlue + yModPlate + ymod +deltaY, zpos)); + + // if((j+1)!=mNumberOfChips){ + // halmStaveVol->AddNode(flex1_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rCoolMax + + // yCPlate + yGlue + yModPlate + 2*ymod + yFlex1 + yFlex2 + yFlex1/2,zpos5cm)); + // halmStaveVol->AddNode(flex1_5cmVol,mNumberOfChips+j,new TGeoTranslation(-xPos,-ylen + yPos + + // 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1 + yFlex2 + yFlex1/2 + // +deltaY,zpos5cm)); + // halmStaveVol->AddNode(flex2_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rCoolMax + + // yCPlate + yGlue + yModPlate + 2*ymod + 2*yFlex1 + 3*yFlex2/2,zpos5cm)); + // halmStaveVol->AddNode(flex2_5cmVol,mNumberOfChips+j,new TGeoTranslation(-xPos,-ylen + yPos + + // 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + 2*yFlex1 + 3*yFlex2/2 +deltaY,zpos5cm)); + // } + // else { + // halmStaveVol->AddNode(flex1_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rCoolMax + + // yCPlate + yGlue + yModPlate + 2*ymod + yFlex1/2,zpos5cm-modGap)); + // halmStaveVol->AddNode(flex1_5cmVol,mNumberOfChips+j,new TGeoTranslation(-xPos,-ylen + yPos + + // 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1/2 +deltaY,zpos5cm-modGap)); + // halmStaveVol->AddNode(flex2_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rCoolMax + + // yCPlate + yGlue + yModPlate +2*ymod + yFlex1 + yFlex2/2,zpos5cm-modGap)); + // halmStaveVol->AddNode(flex2_5cmVol,mNumberOfChips+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 halmStaveVol; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateSpaceFrameOuterB(const TGeoManager* mgr) +{ + TGeoVolume* mechStavVol = 0; + + switch (mStaveModel) { + case AliceO2::ITS::Detector::kOBModelDummy: + case AliceO2::ITS::Detector::kOBModel0: + mechStavVol = CreateSpaceFrameOuterBDummy(mgr); + break; + case AliceO2::ITS::Detector::kOBModel1: + mechStavVol = CreateSpaceFrameOuterB1(mgr); + break; + default: + LOG(FATAL) << "Unknown stave model " << mStaveModel << FairLogger::endl; + break; + } + + return mechStavVol; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateSpaceFrameOuterBDummy(const TGeoManager*) const +{ + // Done, return the stave structur + return 0; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateSpaceFrameOuterB1(const TGeoManager* mgr) +{ + // Materials defined in Detector + TGeoMedium* medCarbon = mgr->GetMedium("ITS_CARBON$"); + TGeoMedium* medAir = mgr->GetMedium("ITS_AIR$"); + + // Local parameters + Double_t sframeWidth = sOBSpaceFrameWidth; + Double_t sframeHeight = sOBSpaceFrameTotHigh - sOBHalfStaveYTrans; + Double_t staveBeamRadius = sOBSFrameBeamRadius; + Double_t staveLa = sOBSpaceFrameLa; + Double_t staveHa = sOBSpaceFrameHa; + Double_t staveLb = sOBSpaceFrameLb; + Double_t staveHb = sOBSpaceFrameHb; + Double_t stavel = sOBSpaceFrameL; + Double_t bottomBeamAngle = sOBSFBotBeamAngle; + Double_t triangleHeight = sframeHeight - staveBeamRadius; + Double_t halmTheta = TMath::ATan(0.5 * sframeWidth / triangleHeight); + // Double_t alpha = TMath::Pi()*3./4. - halmTheta/2.; + Double_t beta = (TMath::Pi() - 2. * halmTheta) / 4.; + // Double_t distCenterSideDown = 0.5*sframeWidth/TMath::Cos(beta); + + Double_t zlen; + Double_t xpos, ypos, zpos; + Double_t seglen; + char volumeName[30]; + + zlen = mNumberOfModules * sOBModuleZLength + (mNumberOfModules - 1) * sOBModuleGap; + + snprintf(volumeName, 30, "%s%d", UpgradeGeometryTGeo::GetITSHalfStavePattern(), mLayerNumber); + if (gGeoManager->GetVolume(volumeName)) { // Should always be so + sframeHeight -= ((TGeoBBox*)gGeoManager->GetVolume(volumeName)->GetShape())->GetDY() * 2; + zlen = ((TGeoBBox*)gGeoManager->GetVolume(volumeName)->GetShape())->GetDZ() * 2; + } + seglen = zlen / mNumberOfModules; + + // 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* cmStavTop1 = CreateStaveSide("CFstavTopCornerVol1shape", seglen / 2., halmTheta, -1, + staveLa, staveHa, stavel); + TGeoVolume* cmStavTopVol1 = new TGeoVolume("CFstavTopCornerVol1", cmStavTop1, medCarbon); + cmStavTopVol1->SetLineColor(35); + + TGeoArb8* cmStavTop2 = CreateStaveSide("CFstavTopCornerVol2shape", seglen / 2., halmTheta, 1, + staveLa, staveHa, stavel); + TGeoVolume* cmStavTopVol2 = new TGeoVolume("CFstavTopCornerVol2", cmStavTop2, medCarbon); + cmStavTopVol2->SetLineColor(35); + + TGeoTranslation* trTop1 = new TGeoTranslation(0, sframeHeight / 2, 0); + + //--- the 2 side V + TGeoArb8* cmStavSide1 = + CreateStaveSide("CFstavSideCornerVol1shape", seglen / 2., beta, -1, staveLb, staveHb, stavel); + TGeoVolume* cmStavSideVol1 = new TGeoVolume("CFstavSideCornerVol1", cmStavSide1, medCarbon); + cmStavSideVol1->SetLineColor(35); + + TGeoArb8* cmStavSide2 = + CreateStaveSide("CFstavSideCornerVol2shape", seglen / 2., beta, 1, staveLb, staveHb, stavel); + TGeoVolume* cmStavSideVol2 = new TGeoVolume("CFstavSideCornerVol2", cmStavSide2, medCarbon); + cmStavSideVol2->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(cmStavTopVol1, 1, trTop1); + segmentVol->AddNode(cmStavTopVol2, 1, trTop1); + segmentVol->AddNode(cmStavSideVol1, 1, ctSideR); + segmentVol->AddNode(cmStavSideVol1, 2, ctSideL); + segmentVol->AddNode(cmStavSideVol2, 1, ctSideR); + segmentVol->AddNode(cmStavSideVol2, 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(sOBSFrameBeamSidePhi) * TanD(sOBSFrameBeamSidePhi))))); + 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*/ halmTheta * 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(halmTheta); // 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; i < mNumberOfModules; i++) { + zpos = -spaceFrame->GetDZ() + (1 + 2 * i) * segment->GetDZ(); + spaceFrameVol->AddNode(segmentVol, i, new TGeoTranslation(0, 0, zpos)); + } + + // Done, return the space frame structure + return spaceFrameVol; +} + +TGeoVolume* AliceO2::ITS::UpgradeV1Layer::CreateChipInnerB(const Double_t xchip, + const Double_t ychip, + const Double_t zchip, + const TGeoManager* mgr) +{ + char volumeName[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 * mSensorThickness; + 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(volumeName, 30, "%s%d", UpgradeGeometryTGeo::GetITSChipPattern(), mLayerNumber); + TGeoVolume* chipVol = new TGeoVolume(volumeName, chip, medSi); + chipVol->SetVisibility(kTRUE); + chipVol->SetLineColor(1); + + snprintf(volumeName, 30, "%s%d", UpgradeGeometryTGeo::GetITSSensorPattern(), mLayerNumber); + TGeoVolume* sensVol = new TGeoVolume(volumeName, 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* AliceO2::ITS::UpgradeV1Layer::CreateModuleOuterB(const TGeoManager* mgr) +{ + char volumeName[30]; + + Double_t xGap = sOBChipXGap; + Double_t zGap = sOBChipZGap; + + 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 = (sOBHalfStaveWidth / 2 - xGap / 2) / sOBNChipRows; + ylen = 0.5 * mStaveThickness; // TO BE CHECKED + zlen = (sOBModuleZLength - (sOBChipsPerRow - 1) * zGap) / (2 * sOBChipsPerRow); + + 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 = sOBHalfStaveWidth / 2; + ylen = sOBCarbonPlateThick / 2; + zlen = sOBModuleZLength / 2; + TGeoBBox* modPlate = new TGeoBBox("CarbonPlate", xlen, ylen, zlen); + + // The glue + ylen = sOBGlueThick / 2; + TGeoBBox* glue = new TGeoBBox("Glue", xlen, ylen, zlen); + + // The flex cables + ylen = sOBFlexCableAlThick / 2; + TGeoBBox* flexAl = new TGeoBBox("FlexAl", xlen, ylen, zlen); + + ylen = sOBFlexCableKapThick / 2; + TGeoBBox* flexKap = new TGeoBBox("FlexKap", xlen, ylen, zlen); + + // The module + xlen = sOBHalfStaveWidth / 2; + ylen = ychip + modPlate->GetDY() + glue->GetDY() + flexAl->GetDY() + flexKap->GetDY(); + zlen = sOBModuleZLength / 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(volumeName, 30, "%s%d", UpgradeGeometryTGeo::GetITSModulePattern(), mLayerNumber); + TGeoVolume* modVol = new TGeoVolume(volumeName, 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; k < sOBChipsPerRow; k++) {// put 7x2 chip into one module + zpos = -module->GetDZ() + 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))); + mHierarchy[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 AliceO2::ITS::UpgradeV1Layer::RadiusOmTurboContainer() +{ + Double_t rr, delta, z, lstav, rstav; + + if (mStaveThickness > 89.) { // Very big angle: avoid overflows since surely + return -1; // the radius from lower vertex is the right value + } + + rstav = mLayerRadius + 0.5 * mStaveThickness; + delta = (0.5 * mStaveThickness) / CosD(mStaveTilt); + z = (0.5 * mStaveThickness) * TanD(mStaveTilt); + + rr = rstav - delta; + lstav = (0.5 * mStaveWidth) - z; + + if ((rr * SinD(mStaveTilt) < lstav)) { + return (rr * CosD(mStaveTilt)); + } + else { + return -1; + } +} + +void AliceO2::ITS::UpgradeV1Layer::SetNumberOfUnits(Int_t u) +{ + if (mLayerNumber < sNumberOmInnerLayers) { + mNumberOfChips = u; + } + else { + mNumberOfModules = u; + mNumberOfChips = sOBChipsPerRow; + } +} + +void AliceO2::ITS::UpgradeV1Layer::SetStaveTilt(const Double_t t) +{ + if (mIsTurbo) { + mStaveTilt = t; + } + else { + LOG(ERROR) << "Not a Turbo layer" << FairLogger::endl; + } +} + +void AliceO2::ITS::UpgradeV1Layer::SetStaveWidth(const Double_t w) +{ + if (mIsTurbo) { + mStaveWidth = w; + } + else { + LOG(ERROR) << "Not a Turbo layer" << FairLogger::endl; + } +} + +TGeoArb8* AliceO2::ITS::UpgradeV1Layer::CreateStaveSide(const char* name, Double_t dz, + Double_t angle, Double_t xSign, Double_t L, + Double_t H, Double_t l) +{ + // Create one half of the V shape corner of CF stave + + TGeoArb8* cmStavSide = new TGeoArb8(dz); + cmStavSide->SetName(name); + + // Points must be in clockwise order + cmStavSide->SetVertex(0, 0, 0); + cmStavSide->SetVertex(2, xSign * (L * TMath::Sin(angle) - l * TMath::Cos(angle)), + -L * TMath::Cos(angle) - l * TMath::Sin(angle)); + cmStavSide->SetVertex(4, 0, 0); + cmStavSide->SetVertex(6, xSign * (L * TMath::Sin(angle) - l * TMath::Cos(angle)), + -L * TMath::Cos(angle) - l * TMath::Sin(angle)); + if (xSign < 0) { + cmStavSide->SetVertex(1, 0, -H); + cmStavSide->SetVertex(3, xSign * L * TMath::Sin(angle), -L * TMath::Cos(angle)); + cmStavSide->SetVertex(5, 0, -H); + cmStavSide->SetVertex(7, xSign * L * TMath::Sin(angle), -L * TMath::Cos(angle)); + } + else { + cmStavSide->SetVertex(1, xSign * L * TMath::Sin(angle), -L * TMath::Cos(angle)); + cmStavSide->SetVertex(3, 0, -H); + cmStavSide->SetVertex(5, xSign * L * TMath::Sin(angle), -L * TMath::Cos(angle)); + cmStavSide->SetVertex(7, 0, -H); + } + return cmStavSide; +} + +TGeoCombiTrans* AliceO2::ITS::UpgradeV1Layer::CreateCombiTrans(const char* name, Double_t dy, + Double_t dz, Double_t dphi, + Bool_t planeSym) +{ + 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 AliceO2::ITS::UpgradeV1Layer::AddTranslationToCombiTrans(TGeoCombiTrans* ct, Double_t dx, + Double_t dy, Double_t dz) const +{ + // 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/UpgradeV1Layer.h b/its/UpgradeV1Layer.h new file mode 100644 index 0000000000000..9c186c90f8f20 --- /dev/null +++ b/its/UpgradeV1Layer.h @@ -0,0 +1,386 @@ +/// \file AliITSUv1Layer.cxx +/// \brief Definition of the AliITSUv1Layer class +/// \author Mario Sitta +/// \author Chinorat Kobdaj (kobdaj@g.sut.ac.th) + +#ifndef ALICEO2_ITS_UPGRADEV1LAYER_H_ +#define ALICEO2_ITS_UPGRADEV1LAYER_H_ + +#include "V11Geometry.h" +#include "Detector.h" +#include +#include +#include + +class TGeoVolume; + +namespace AliceO2 { +namespace ITS { + +/// 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 +class UpgradeV1Layer : public V11Geometry { + +public: + enum { kStave, kHalfStave, kModule, kChip, kNHLevels }; + + // Default constructor + UpgradeV1Layer(); + + // Constructor setting debugging level + UpgradeV1Layer(Int_t debug); + + // Constructor setting layer number and debugging level + UpgradeV1Layer(Int_t lay, Int_t debug); + + /// Constructor setting layer number and debugging level + /// for a "turbo" layer (i.e. where staves overlap in phi) + UpgradeV1Layer(Int_t lay, Bool_t turbo, Int_t debug); + + ///Copy constructor + UpgradeV1Layer(const UpgradeV1Layer& source); + + ///Assignment operator + UpgradeV1Layer& operator=(const UpgradeV1Layer& source); + + /// Default destructor + virtual ~UpgradeV1Layer(); + + Bool_t IsTurbo() const + { + return mIsTurbo; + }; + + Double_t GetStaveThick() const + { + return mStaveThickness; + }; + Double_t GetStaveTilt() const + { + return mStaveTilt; + }; + Double_t GetStaveWidth() const + { + return mStaveWidth; + }; + Double_t GetSensorThick() const + { + return mSensorThickness; + }; + Double_t GetNStaves() const + { + return mNumberOfStaves; + }; + Double_t GetNChips() const + { + return mNumberOfChips; + }; + Double_t GetRadius() const + { + return mLayerRadius; + }; + Double_t GetPhi0() const + { + return mPhi0; + }; + Double_t GetZLength() const + { + return mZLength; + }; + Int_t GetChipType() const + { + return mChipTypeID; + } + + Int_t GetNStavesPerParent() const + { + return mHierarchy[kStave]; + } + Int_t GetNHalfStavesPerParent() const + { + return mHierarchy[kHalfStave]; + } + Int_t GetNModulesPerParent() const + { + return mHierarchy[kModule]; + } + Int_t GetNChipsPerParent() const + { + return mHierarchy[kChip]; + } + + AliceO2::ITS::Detector::Model GetStaveModel() const + { + return mStaveModel; + } + + void SetStaveThick(Double_t t) + { + mStaveThickness = t; + }; + + /// Sets the Stave tilt angle (for turbo layers only) + /// \param t The stave tilt angle + void SetStaveTilt(Double_t t); + + /// Sets the Stave width (for turbo layers only) + /// \param w The stave width + void SetStaveWidth(Double_t w); + void SetSensorThick(Double_t t) + { + mSensorThickness = t; + }; + void SetNumberOfStaves(Int_t n) + { + mHierarchy[kStave] = mNumberOfStaves = n; + }; + + /// 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 + /// \param u the number of units + void SetNumberOfUnits(Int_t u); + + void SetRadius(Double_t r) + { + mLayerRadius = r; + }; + void SetPhi0(Double_t phi) + { + mPhi0 = phi; + } + void SetZLength(Double_t z) + { + mZLength = z; + }; + void SetChipType(Int_t tp) + { + mChipTypeID = tp; + } + void SetBuildLevel(Int_t buildLevel) + { + mBuildLevel = buildLevel; + } + void SetStaveModel(AliceO2::ITS::Detector::Model model) + { + mStaveModel = model; + } + + /// Creates the actual Layer and places inside its mother volume + /// \param motherVolume the TGeoVolume owing the volume structure + virtual void CreateLayer(TGeoVolume* motherVolume); + +private: + /// 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 + /// \param motherVolume The TGeoVolume owing the volume structure + void CreateLayerTurbo(TGeoVolume* motherVolume); + + /// 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. Returns the radius of the container + /// if >0, else flag to use the lower vertex + Double_t RadiusOmTurboContainer(); + + /// Creates the actual Stave + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateStave(const TGeoManager* mgr = gGeoManager); + + // TGeoVolume* CreateChip(Double_t x, Double_t z, const TGeoManager *mgr=gGeoManager); + + /// Creates the IB Module: (only the chips for the time being) + /// Returns the module as a TGeoVolume + /// \param xmod, ymod, zmod X, Y, Z module half lengths + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateModuleInnerB(Double_t x, Double_t y, Double_t z, + const TGeoManager* mgr = gGeoManager); + + /// Creates the actual Chip + /// \param xchip,ychip,zchip The chip dimensions + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateChipInnerB(Double_t x, Double_t y, Double_t z, + const TGeoManager* mgr = gGeoManager); + + /// Creates the OB Module: HIC + FPC + Carbon plate + /// Returns the module as a TGeoVolume + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateModuleOuterB(const TGeoManager* mgr = gGeoManager); + + /// 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) + /// \param xsta, ysta, zsta X, Y, Z stave half lengths + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateStaveInnerB(Double_t x, Double_t y, Double_t z, + const TGeoManager* mgr = gGeoManager); + + /// Create the mechanical stave structure + /// \param xsta X length + /// \param zsta Z length + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateStaveStructInnerB(Double_t x, Double_t z, const TGeoManager* mgr = gGeoManager); + + /// Create a dummy stave + /// \param xsta X length + /// \param zsta Z length + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateStaveModelInnerBDummy(Double_t x, Double_t z, + const TGeoManager* mgr = gGeoManager) const; + + /// Create the mechanical stave structure for Model 0 of TDR + /// \param xsta X length + /// \param zsta Z length + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateStaveModelInnerB0(Double_t x, Double_t z, const TGeoManager* mgr = gGeoManager); + + /// Create the mechanical stave structure for Model 1 of TDR + /// \param xsta X length + /// \param zsta Z length + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateStaveModelInnerB1(Double_t x, Double_t z, const TGeoManager* mgr = gGeoManager); + + /// Create the mechanical stave structure for Model 2.1 of TDR + /// \param xsta X length + /// \param zsta Z length + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateStaveModelInnerB21(Double_t x, Double_t z, + const TGeoManager* mgr = gGeoManager); + + /// Create the mechanical stave structure for Model 2.2 of TDR + /// \param xsta X length + /// \param zsta Z length + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateStaveModelInnerB22(Double_t x, Double_t z, + const TGeoManager* mgr = gGeoManager); + + /// Create the mechanical stave structure for Model 3 of TDR + /// \param xsta X length + /// \param zsta Z length + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateStaveModelInnerB3(Double_t x, Double_t z, const TGeoManager* mgr = gGeoManager); + + /// Create the chip stave for the Outer Barrel + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateStaveOuterB(const TGeoManager* mgr = gGeoManager); + + /// Create dummy stave + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateStaveModelOuterBDummy(const TGeoManager* mgr = gGeoManager) const; + + /// 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) + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateStaveModelOuterB0(const TGeoManager* mgr = gGeoManager); + + /// Create the mechanical half stave structure or the Outer Barrel as in TDR + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateStaveModelOuterB1(const TGeoManager* mgr = gGeoManager); + + /// Create the space frame for the Outer Barrel + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateSpaceFrameOuterB(const TGeoManager* mgr = gGeoManager); + + /// Create dummy stave + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateSpaceFrameOuterBDummy(const TGeoManager* mgr = gGeoManager) const; + + /// Create the space frame for the Outer Barrel (Model 1) + /// Returns a TGeoVolume with the Space Frame of a stave + /// \param mgr The GeoManager (used only to get the proper material) + TGeoVolume* CreateSpaceFrameOuterB1(const TGeoManager* mgr = gGeoManager); + + /// Creates the V-shaped sides of the OB space frame (from a similar method with same + /// name and function in V11GeometrySDD class by L.Gaudichet) + TGeoArb8* CreateStaveSide(const char* name, Double_t dz, Double_t angle, Double_t xSign, + Double_t L, Double_t H, Double_t l); + + /// Help method to create a TGeoCombiTrans matrix from a similar method with same name and + /// function in V11GeometrySDD class by L.Gaudichet) + /// Returns 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 + TGeoCombiTrans* CreateCombiTrans(const char* name, Double_t dy, Double_t dz, Double_t dphi, + Bool_t planeSym = kFALSE); + + /// Help method to add a translation to a TGeoCombiTrans matrix (from a similar method + /// with same name and function in V11GeometrySDD class by L.Gaudichet) + void AddTranslationToCombiTrans(TGeoCombiTrans* ct, Double_t dx = 0, Double_t dy = 0, + Double_t dz = 0) const; + + Int_t mLayerNumber; ///< Current layer number + Double_t mPhi0; ///< lab phi of 1st stave, in degrees!!! + Double_t mLayerRadius; ///< Inner radius of this layer + Double_t mZLength; ///< Z length of this layer + Double_t mSensorThickness; ///< Sensor thickness + Double_t mStaveThickness; ///< Stave thickness + Double_t mStaveWidth; ///< Stave width (for turbo layers only) + Double_t mStaveTilt; ///< Stave tilt angle (for turbo layers only) in degrees + Int_t mNumberOfStaves; ///< Number of staves in this layer + Int_t mNumberOfModules; ///< Number of modules per container if defined (HalfStave, Stave, whatever is + ///< container) + Int_t mNumberOfChips; ///< Number chips per container (module, HalfStave, Stave, whatever is container) + Int_t mHierarchy + [kNHLevels]; ///< array to query number of staves, hstaves, modules, chips per its parent volume + + UInt_t mChipTypeID; ///< detector type id + Bool_t mIsTurbo; ///< True if this layer is a "turbo" layer + Int_t mBuildLevel; ///< Used for material studies + + AliceO2::ITS::Detector::Model mStaveModel; ///< The stave model + + // Parameters for the Upgrade geometry + + // General Parameters + static const Int_t sNumberOmInnerLayers; ///< Number of IB Layers + + static const Double_t sDefaultSensorThick; ///< Default sensor thickness + static const Double_t sDefaultStaveThick; ///< Default stave thickness + + // Inner Barrel Parameters + static const Int_t sIBChipsPerRow; ///< IB chips per row in module + static const Int_t sIBNChipRows; ///< IB chip rows in module + + // Outer Barrel Parameters + static const Int_t sOBChipsPerRow; ///< OB chips per row in module + static const Int_t sOBNChipRows; ///< OB chip rows in module + + static const Double_t sOBHalfStaveWidth; ///< OB Half Stave Width + static const Double_t sOBModuleWidth; ///< OB Module Width + static const Double_t sOBModuleGap; ///< Gap between OB modules + static const Double_t sOBChipXGap; ///< Gap between OB chips on X + static const Double_t sOBChipZGap; ///< Gap between OB chips on Z + static const Double_t sOBFlexCableAlThick; ///< Thickness of FPC Aluminum + static const Double_t sOBFlexCableKapThick; ///< Thickness of FPC Kapton + static const Double_t sOBBusCableAlThick; ///< Thickness of Bus Aluminum + static const Double_t sOBBusCableKapThick; ///< Thickness of Bus Kapton + static const Double_t sOBCarbonPlateThick; ///< OB Carbon Plate Thickness + static const Double_t sOBColdPlateThick; ///< OB Cold Plate Thickness + static const Double_t sOBGlueThick; ///< OB Glue total Thickness + static const Double_t sOBModuleZLength; ///< OB Chip Length along Z + static const Double_t sOBHalfStaveYTrans; ///< OB half staves Y transl. + static const Double_t sOBHalfStaveXOverlap; ///< OB half staves X overlap + static const Double_t sOBGraphiteFoilThick; ///< OB graphite foil thickness + static const Double_t sOBCoolTubeInnerD; ///< OB cooling inner diameter + static const Double_t sOBCoolTubeThick; ///< OB cooling tube thickness + static const Double_t sOBCoolTubeXDist; ///< OB cooling tube separation + + static const Double_t sOBSpaceFrameWidth; ///< OB Space Frame Width + static const Double_t sOBSpaceFrameTotHigh; ///< OB Total Y Height + static const Double_t sOBSFrameBeamRadius; ///< OB Space Frame Beam Radius + static const Double_t sOBSpaceFrameLa; ///< Parameters defining... + static const Double_t sOBSpaceFrameHa; ///< ...the V side shape... + static const Double_t sOBSpaceFrameLb; ///< ...of the carbon... + static const Double_t sOBSpaceFrameHb; ///< ...OB Space Frame + static const Double_t sOBSpaceFrameL; ///< OB SF + static const Double_t sOBSFBotBeamAngle; ///< OB SF bottom beam angle + static const Double_t sOBSFrameBeamSidePhi; ///< OB SF side beam angle + + ClassDef(UpgradeV1Layer, 0) // ITS Upgrade v1 geometry +}; +} +} + +#endif diff --git a/its/V11Geometry.cxx b/its/V11Geometry.cxx new file mode 100644 index 0000000000000..414768dd810e6 --- /dev/null +++ b/its/V11Geometry.cxx @@ -0,0 +1,1222 @@ +/// \file V11Geometry.cxx +/// \brief Implementation of the V11Geometry class + +#include +#include +#include +#include +#include +#include + +#include +#include +#include // contaings TGeoTubeSeg +#include +#include +#include +#include +#include + +#include "V11Geometry.h" + +using std::endl; +using std::cout; +using std::cin; + +using namespace AliceO2::ITS; + +ClassImp(V11Geometry) + +const Double_t V11Geometry::sMicron = 1.0E-4; +const Double_t V11Geometry::sMm = 0.10; +const Double_t V11Geometry::sCm = 1.00; +const Double_t V11Geometry::sDegree = 1.0; +const Double_t V11Geometry::sRadian = 180. / 3.14159265358979323846; +const Double_t V11Geometry::sGCm3 = 1.0; // assume default is g/cm^3 +const Double_t V11Geometry::sKgm3 = 1.0E+3; // assume Kg/m^3 +const Double_t V11Geometry::sKgdm3 = 1.0; // assume Kg/dm^3 +const Double_t V11Geometry::sCelsius = 1.0; // Assume default is C +const Double_t V11Geometry::sPascal = 1.0E-3; // Assume kPascal +const Double_t V11Geometry::sKPascal = 1.0; // Asume kPascal +const Double_t V11Geometry::sEV = 1.0E-9; // GeV default +const Double_t V11Geometry::sKEV = 1.0e-6; // GeV default +const Double_t V11Geometry::sMEV = 1.0e-3; // GeV default +const Double_t V11Geometry::sGEV = 1.0; // GeV default + +void V11Geometry::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 +{ + 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 V11Geometry::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) +{ + 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 V11Geometry::Yfrom2Points(Double_t x0, Double_t y0, Double_t x1, Double_t y1, Double_t x) + const +{ + if (x0 == x1 && y0 == y1) { + printf("Error: V11Geometry::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: V11Geometry::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 V11Geometry::Xfrom2Points(Double_t x0, Double_t y0, Double_t x1, Double_t y1, Double_t y) + const +{ + if (x0 == x1 && y0 == y1) { + printf("Error: V11Geometry::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: V11Geometry::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 V11Geometry::RmaxFrom2Points(const TGeoPcon* p, Int_t i1, Int_t i2, Double_t z) const +{ + 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(i2) + + (p->GetRmin(i1) - p->GetRmin(i2)) * (z - p->GetZ(i2)) / (p->GetZ(i1) - p->GetZ(i2)); +} + +Double_t V11Geometry::RFrom2Points(const Double_t* p, const Double_t* az, Int_t i1, Int_t i2, + Double_t z) const +{ + return p[i2] + (p[i1] - p[i2]) * (z - az[i2]) / (az[i1] - az[i2]); +} + +Double_t V11Geometry::Zfrom2MinPoints(const TGeoPcon* p, Int_t i1, Int_t i2, Double_t r) const +{ + return p->GetZ(i2) + + (p->GetZ(i1) - p->GetZ(i2)) * (r - p->GetRmin(i2)) / (p->GetRmin(i1) - p->GetRmin(i2)); +} + +Double_t V11Geometry::Zfrom2MaxPoints(const TGeoPcon* p, Int_t i1, Int_t i2, Double_t r) const +{ + return p->GetZ(i2) + + (p->GetZ(i1) - p->GetZ(i2)) * (r - p->GetRmax(i2)) / (p->GetRmax(i1) - p->GetRmax(i2)); +} + +Double_t V11Geometry::Zfrom2Points(const Double_t* z, const Double_t* ar, Int_t i1, Int_t i2, + Double_t r) const +{ + return z[i2] + (z[i1] - z[i2]) * (r - ar[i2]) / (ar[i1] - ar[i2]); +} + +Double_t V11Geometry::RmaxFromZpCone(const TGeoPcon* p, int ip, Double_t tc, Double_t z, + Double_t th) const +{ + 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 V11Geometry::RFromZpCone(const Double_t* ar, const Double_t* az, int ip, Double_t tc, + Double_t z, Double_t th) const +{ + 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 V11Geometry::RminFromZpCone(const TGeoPcon* p, Int_t ip, Double_t tc, Double_t z, + Double_t th) const +{ + 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 V11Geometry::ZFromRmaxpCone(const TGeoPcon* p, int ip, Double_t tc, Double_t r, + Double_t th) const +{ + 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 V11Geometry::ZFromRmaxpCone(const Double_t* ar, const Double_t* az, int ip, Double_t tc, + Double_t r, Double_t th) const +{ + 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 V11Geometry::ZFromRminpCone(const TGeoPcon* p, int ip, Double_t tc, Double_t r, + Double_t th) const +{ + 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 V11Geometry::RadiusOfCurvature(Double_t rc, Double_t theta0, Double_t z0, Double_t r0, + Double_t theta1, Double_t& z1, Double_t& r1) const +{ + 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 V11Geometry::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 +{ + 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 V11Geometry::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 +{ + 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 V11Geometry::PrintPcon(const TGeoPcon* a) const +{ + 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; iii < a->GetNz(); iii++) { + cout << iii << "\t" << a->GetZ(iii) << "\t" << a->GetRmin(iii) << "\t" << a->GetRmax(iii) + << endl; + } // end for iii + return; +} + +void V11Geometry::PrintTube(const TGeoTube* a) const +{ + if (!GetDebug()) { + return; + } + cout << a->GetName() << ": Rmin=" << a->GetRmin() << " Rmax=" << a->GetRmax() + << " Dz=" << a->GetDz() << endl; + return; +} + +void V11Geometry::PrintTubeSeg(const TGeoTubeSeg* a) const +{ + if (!GetDebug()) { + return; + } + cout << a->GetName() << ": Phi1=" << a->GetPhi1() << " Phi2=" << a->GetPhi2() + << " Rmin=" << a->GetRmin() << " Rmax=" << a->GetRmax() << " Dz=" << a->GetDz() << endl; + return; +} + +void V11Geometry::PrintConeSeg(const TGeoConeSeg* a) const +{ + if (!GetDebug()) { + return; + } + cout << a->GetName() << ": Phi1=" << a->GetPhi1() << " Phi2=" << a->GetPhi2() + << " Rmin1=" << a->GetRmin1() << " Rmax1=" << a->GetRmax1() << " Rmin2=" << a->GetRmin2() + << " Rmax2=" << a->GetRmax2() << " Dz=" << a->GetDz() << endl; + return; +} + +void V11Geometry::PrintBBox(const TGeoBBox* a) const +{ + if (!GetDebug()) { + return; + } + cout << a->GetName() << ": Dx=" << a->GetDX() << " Dy=" << a->GetDY() << " Dz=" << a->GetDZ() + << endl; + return; +} + +void V11Geometry::CreateDefaultMaterials() +{ + Int_t i; + Double_t w; + + // Define some elements + TGeoElement* itsH = new TGeoElement("ITS_H", "Hydrogen", 1, 1.00794); + TGeoElement* itsHe = new TGeoElement("ITS_He", "Helium", 2, 4.002602); + TGeoElement* itsC = new TGeoElement("ITS_C", "Carbon", 6, 12.0107); + TGeoElement* itsN = new TGeoElement("ITS_N", "Nitrogen", 7, 14.0067); + TGeoElement* itsO = new TGeoElement("ITS_O", "Oxygen", 8, 15.994); + TGeoElement* itsF = new TGeoElement("ITS_F", "Florine", 9, 18.9984032); + TGeoElement* itsNe = new TGeoElement("ITS_Ne", "Neon", 10, 20.1797); + TGeoElement* itsMg = new TGeoElement("ITS_Mg", "Magnesium", 12, 24.3050); + TGeoElement* itsAl = new TGeoElement("ITS_Al", "Aluminum", 13, 26981538); + TGeoElement* itsSi = new TGeoElement("ITS_Si", "Silicon", 14, 28.0855); + TGeoElement* itsP = new TGeoElement("ITS_P", "Phosphorous", 15, 30.973761); + TGeoElement* itsS = new TGeoElement("ITS_S", "Sulfur", 16, 32.065); + TGeoElement* itsAr = new TGeoElement("ITS_Ar", "Argon", 18, 39.948); + TGeoElement* itsTi = new TGeoElement("ITS_Ti", "Titanium", 22, 47.867); + TGeoElement* itsCr = new TGeoElement("ITS_Cr", "Chromium", 24, 51.9961); + TGeoElement* itsMn = new TGeoElement("ITS_Mn", "Manganese", 25, 54.938049); + TGeoElement* itsFe = new TGeoElement("ITS_Fe", "Iron", 26, 55.845); + TGeoElement* itsCo = new TGeoElement("ITS_Co", "Cobalt", 27, 58.933200); + TGeoElement* itsNi = new TGeoElement("ITS_Ni", "Nickrl", 28, 56.6930); + TGeoElement* itsCu = new TGeoElement("ITS_Cu", "Copper", 29, 63.546); + TGeoElement* itsZn = new TGeoElement("ITS_Zn", "Zinc", 30, 65.39); + TGeoElement* itsKr = new TGeoElement("ITS_Kr", "Krypton", 36, 83.80); + TGeoElement* itsMo = new TGeoElement("ITS_Mo", "Molylibdium", 42, 95.94); + TGeoElement* itsXe = new TGeoElement("ITS_Xe", "Zeon", 54, 131.293); + + // Start with the Materials since for any one material there + // can be defined more than one Medium. + // Air, dry. at 15degree C, 101325Pa at sea-level, % by volume + // (% by weight). Density is 351 Kg/m^3 + // N2 78.084% (75.47%), O2 20.9476% (23.20%), Ar 0.934 (1.28%)%, + // C02 0.0314% (0.0590%), Ne 0.001818% (0.0012%, CH4 0.002% (), + // He 0.000524% (0.00007%), Kr 0.000114% (0.0003%), H2 0.00005% (3.5E-6%), + // Xe 0.0000087% (0.00004 %), H2O 0.0% (dry) + trace amounts at the ppm + // levels. + TGeoMixture* itsAir = new TGeoMixture("ITS_Air", 9); + w = 75.47E-2; + itsAir->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 * sKgm3); + itsAir->SetPressure(101325 * sPascal); + itsAir->SetTemperature(15.0 * sCelsius); + itsAir->SetState(TGeoMaterial::kMatStateGas); + + // Silicone + TGeoMaterial* itsSiDet = new TGeoMaterial("ITS_Si", itsSi, 2.33 * sGCm3); + itsSiDet->SetTemperature(15.0 * sCelsius); + 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 * sGCm3); + itsEpoxy->SetTemperature(15.0 * sCelsius); + 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; i < itsEpoxy->GetNelements(); i++) { + itsCarbonFiber->AddElement(itsEpoxy->GetElement(i), itsEpoxy->GetWmixt()[i] * w); + } + + itsCarbonFiber->SetDensity((1.91 + (1. - .60) * itsEpoxy->GetDensity()) * sGCm3); + itsCarbonFiber->SetTemperature(22.0 * sCelsius); + 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. * sKgm3); + itsFoam->SetTemperature(22.0 * sCelsius); + 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 * sGCm3); + itsKapton->SetTemperature(22.0 * sCelsius); + 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 * sGCm3); + itsUpilex->SetTemperature(22.0 * sCelsius); + 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 * sGCm3); + itsAl6061->SetTemperature(22.0 * sCelsius); + 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 * sGCm3); + itsAl7075->SetTemperature(22.0 * sCelsius); + 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 * sGCm3); + itsRuby->SetTemperature(22.0 * sCelsius); + 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 * sKgdm3); + itsInox304L->SetTemperature(22.0 * sCelsius); + 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 * sKgdm3); + itsInox316L->SetTemperature(22.0 * sCelsius); + 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 * sGCm3); + itsPhynox->SetTemperature(22.0 * sCelsius); + 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 * sGCm3); + itsWater->SetTemperature(22.0 * sCelsius); + 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 * sGCm3); + itsFreon->SetTemperature(22.0 * sCelsius); + 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; i < n; i++) { + z[i] = p->GetZ(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" << endl; + cin >> n; + delete line; + delete pts; + return; +} + +Bool_t V11Geometry::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 +{ + 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 * s2 < DBL_EPSILON) { + t[0] = a0 * TMath::RadToDeg(); + } + x1 = xc + rc * TMath::Cos(a1); + y1 = yc + rc * TMath::Sin(a1); + s2 = dx * (y1 - y0) - dy * (x1 - x0); + if (s2 * s2 < DBL_EPSILON) { + t[1] = a1 * TMath::RadToDeg(); + } + x1 = xc + rc * TMath::Cos(b0); + y1 = yc + rc * TMath::Sin(b0); + s2 = dx * (y1 - y0) - dy * (x1 - x0); + if (s2 * s2 < DBL_EPSILON) { + t[2] = b0 * TMath::RadToDeg(); + } + x1 = xc + rc * TMath::Cos(b1); + y1 = yc + rc * TMath::Sin(b1); + s2 = dx * (y1 - y0) - dy * (x1 - x0); + if (s2 * s2 < DBL_EPSILON) { + t[3] = b1 * TMath::RadToDeg(); + } + for (i = 0; i < 4; i++) { + for (j = i + 1; j < 4; j++) { + if (t[i] > t[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 V11Geometry::AngleForRoundedCorners0(Double_t dx, Double_t dy, Double_t sdr) const +{ + 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 V11Geometry::AngleForRoundedCorners1(Double_t dx, Double_t dy, Double_t sdr) const +{ + 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 V11Geometry::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 +{ + 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; + } + return; +} + +void V11Geometry::MakeFigure1(Double_t x0, Double_t y0, Double_t r0, Double_t x1, Double_t y1, + Double_t r1) +{ + 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; + } + 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]); + } + 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("V11Geometry_AnglesForRoundedCorners", "Figure for V11Geometry", 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); + } + c0->Draw(); + c1->Draw(); + + for (j = 0; j < 4; j++) { + ar0[j]->Draw(); + ar1[j]->Draw(); + line[j]->Draw(); + } + + 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); + } +} diff --git a/its/V11Geometry.h b/its/V11Geometry.h new file mode 100644 index 0000000000000..b00466d76b0e3 --- /dev/null +++ b/its/V11Geometry.h @@ -0,0 +1,454 @@ +/// \file V11Geometry.h +/// \brief Definition of the V11Geometry class + +#ifndef ALICEO2_ITS_V11GEOMETRY_H_ +#define ALICEO2_ITS_V11GEOMETRY_H_ + +#include +#include +#include "FairLogger.h" + +class TGeoArb8; +class TGeoPcon; +class TGeoTube; +class TGeoTubeSeg; +class TGeoConeSeg; +class TGeoBBox; + +namespace AliceO2 { +namespace ITS { + +/// 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 values such, +/// to cm and degrees, such that the most useful units, those used in the Engineering drawings, +/// can be used. +class V11Geometry : public TObject { + +public: + V11Geometry() + : mDebug() {}; + V11Geometry(Int_t debug) + : mDebug(debug) {}; + virtual ~V11Geometry() {}; + + /// Sets the debug flag for debugging output + void SetDebug(Int_t level = 5) + { + mDebug = level; + } + + /// Clears the debug flag so no debugging output will be generated + void SetNoDebug() + { + mDebug = 0; + } + + /// Returns the debug flag value + Bool_t GetDebug(Int_t level = 1) const + { + return mDebug >= 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 + /// 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) + /// \param Double_t m The slope of the first line + /// \param Double_t x0,y0 The x and y coord. of the first point + /// \param Double_t n The slope of the second line + /// \param Double_t x1,y1 The x and y coord. of the second point + /// As an output it gives the coordinates xi and yi of the intersection point + 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 + /// Given a line 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) + /// \param Double_t m The slope of the line + /// \param Double_t x0,y0 The x and y coord. of the point + /// \param Double_t rr The radius of the circle + /// \param Double_t xc,yc The x and y coord. of the center of circle + /// As an output it gives the coordinates xi and yi of the intersection points + /// Returns kFALSE if the line does not intercept the circle, otherwise kTRUE + 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 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. Returns the value y corresponding to the point x on the line defined by + /// the two points (x0,y0) and (x1,y1). + /// \param Double_t x0 The first x value defining the line + /// \param Double_t y0 The first y value defining the line + /// \param Double_t x1 The second x value defining the line + /// \param Double_t y1 The second y value defining the line + /// \param Double_t x The x value for which the y value is wanted. + Double_t 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 y, returns + /// the value x corresponding to that point y on the line defined by the + /// two points. Returns the value x corresponding to the point y on the line defined by + /// the two points (x0,y0) and (x1,y1). + /// \param Double_t x0 The first x value defining the line + /// \param Double_t y0 The first y value defining the line + /// \param Double_t x1 The second x value defining the line + /// \param Double_t y1 The second y value defining the line + /// \param Double_t y The y value for which the x value is wanted. + Double_t Xfrom2Points(Double_t x0, Double_t y0, Double_t x1, Double_t y1, Double_t y) const; + + /// Functions require at parts of Volume A to be already defined. + /// Returns 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). + /// \param TGeoPcon *p The Polycone where the two points come from + /// \param Int_t i1 Point 1 + /// \param Int_t i2 Point 2 + /// \param Double_t z The value of z for which Rmax is to be found + /// \param Double_t Rmx the value corresponding to z + Double_t RmaxFrom2Points(const TGeoPcon* p, Int_t i1, Int_t i2, Double_t z) const; + + /// Returns 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). + /// \param TGeoPcon *p The Polycone where the two points come from + /// \param Int_t i1 Point 1 + /// \param Int_t i2 Point 2 + /// \param Double_t z The value of z for which Rmax is to be found + /// \param Double_t Rmx the value corresponding to z + Double_t RminFrom2Points(const TGeoPcon* p, Int_t i1, Int_t i2, Double_t z) const; + + /// Returns 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). Returns the value r corresponding to z and the + /// line defined by the two points + /// \param Double_t az Array of z values + /// \param Double_t r Array of r values + /// \param Int_t i1 First Point in arrays + /// \param Int_t i2 Second Point in arrays + /// \param Double_t z Value z at which r is to be found + Double_t RFrom2Points(const Double_t* ar, const Double_t* az, Int_t i1, Int_t i2, + Double_t z) const; + + /// Returns 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). Returns the value z corresponding to r min + /// and the line defined by the two points + /// \param TGeoPcon *p The Poly cone where the two points come from. + /// \param Int_t i1 First Point in arrays + /// \param Int_t i2 Second Point in arrays + /// \param Double_t r Value r min at which z is to be found + Double_t Zfrom2MinPoints(const TGeoPcon* p, Int_t i1, Int_t i2, Double_t r) const; + + /// Returns 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). Returns the value z corresponding to + /// r max and the line defined by the two points + /// \param TGeoPcon *p The Poly cone where the two points come from. + /// \param Int_t i1 First Point in arrays + /// \param Int_t i2 Second Point in arrays + /// \param Double_t r Value r max at which z is to be found + Double_t Zfrom2MaxPoints(const TGeoPcon* p, Int_t i1, Int_t i2, Double_t r) const; + + /// Returns 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). Returns the value z corresponding to r + /// and the line defined by the two points + /// \param Double_t z Array of z values + /// \param Double_t ar Array of r values + /// \param Int_t i1 First Point in arrays + /// \param Int_t i2 Second Point in arrays + /// \param Double_t r Value r at which z is to be found + Double_t Zfrom2Points(const Double_t* az, const Double_t* ar, Int_t i1, Int_t i2, + Double_t r) const; + + /// General Outer Cone surface equation Rmax + /// 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. Returns the value Rmax corresponding to the line at angle th, offset by + /// th, and the point p->GetZ/Rmin[ip] at the location z. + /// \param TGeoPcon *p The poly cone where the initial point comes from + /// \param Int_t ip The index in p to get the point location + /// \param Double_t tc The angle of that part of the cone is at + /// \param Double_t z The value of z to compute Rmax from + /// \param Double_t th The perpendicular distance the parralell line is from the point ip + Double_t RmaxFromZpCone(const TGeoPcon* p, int ip, Double_t tc, Double_t z, + Double_t th = 0.0) const; + + // General Cone surface equation R(z). Returns the value R correstponding to the line at + // angle th, offset by th, and the point p->GetZ/Rmax[ip] at the location z. + // \param Double_t ar The array of R values + // \param Double_t az The array of Z values + // \param Int_t ip The index in p to get the point location + // \param Double_t tc The angle of that part of the cone is at + // \param Double_t z The value of z to compute R from + // \param Double_t th The perpendicular distance the parralell line is from the point ip + 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; + + /// General Inner Cone surface equation Rmin. + /// 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. Returns the value Rmin correstponding to the line at angle th, + /// offset by th, and the point p->GetZ/Rmin[ip] at the location z. + /// \param TGeoPcon *p The poly cone where the initial point comes from + /// \param Int_t ip The index in p to get the point location + /// \param Double_t tc The angle of that part of the cone is at + /// \param Double_t z The value of z to compute Rmin from + /// \param Double_t th The perpendicular distance the parralell line is from the point ip + Double_t RminFromZpCone(const TGeoPcon* p, Int_t ip, Double_t tc, Double_t z, + Double_t th = 0.0) const; + + /// General Outer cone Surface equation for z. + /// 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. Returns thevalue Z correstponding to the line at angle th, + /// offset by th, and the point p->GetZ/Rmax[ip] at the location r. + /// \param TGeoPcon *p The poly cone where the initial point comes from + /// \param Int_t ip The index in p to get the point location + /// \param Double_t tc The angle of that part of the cone is at + /// \param Double_t r The value of Rmax to compute z from + /// \param Double_t th The perpendicular distance the parralell line is from the point ip + 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. + /// Returns the value Z correstponding to the line at angle th, offeset by + /// th, and the point p->GetZ/Rmax[ip] at the locatin r. + /// \param Double_t ar The array of R values + /// \param Double_t az The array of Z values + /// \param Int_t ip The index in p to get the point location + /// \param Double_t tc The angle of that part of the cone is at + /// \param Double_t r The value of Rmax to compute z from + /// \param Double_t th The perpendicular distance the parralell line is from the point ip + 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; + + /// General Inner cone Surface equation for z. + /// 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. Returns the value Z correstponding to the line at angle th, offeset by + /// th, and the point p->GetZ/Rmin[ip] at the location r. + /// \param TGeoPcon *p The poly cone where the initial point comes from + /// \param Int_t ip The index in p to get the point location + /// \param Double_t tc The angle of that part of the cone is at + /// \param Double_t r The value of Rmin to compute z from + /// \param Double_t th The perpendicular distance the parralell line is from the point ip + 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. + /// \param TGeoPcon *p Class where points i1, i2, and i3 are taken from + /// \param Int_t i1 First point in class p + /// \param Int_t i2 Second point in class p + /// \param Int_t i3 Third point in class p + /// \param Double_t c Distance inside the outer/inner surface that the point j1 + /// is to be computed for + /// \param TGeoPcon *q Pointer to class for results to be put into. + /// \param Int_t j1 Point in class q where data is to be stored. + /// \param Bool_t ma if kTRUE, then a Rmax value is computed, else a Rmin valule is computed + /// \param TGeoPcon *q Pointer to class for results to be put into. + 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). + /// \param Double_t x0 X point on the first intersecting sets of lines + /// \param Double_t y0 Y point on the first intersecting sets of lines + /// \param Double_t x1 X point on the first/second intersecting sets of lines + /// \param Double_t y1 Y point on the first/second intersecting sets of lines + /// \param Double_t x2 X point on the second intersecting sets of lines + /// \param Double_t y2 Y point on the second intersecting sets of lines + /// \param Double_t c Distance the two sets of lines are from each other + /// \param Double_t x X point for the intersecting sets of parellel lines + /// \param Double_t y Y point for the intersecting sets of parellel lines + 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 an 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]. + /// \param Double_t rc The radius of curvature + /// \param Double_t theta0 The starting angle (degrees) + /// \param Double_t z0 The value of z at theta0 + /// \param Double_t r0 The value of r at theta0 + /// \param Double_t theta1 The ending angle (degrees) + /// \param Double_t &z1 The value of z at theta1 + /// \param Double_t &r1 The value of r at theta1 + 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 content of the TGeoArb8 + /// \param TGeoArb8 *a + void PrintArb8(const TGeoArb8* a) const; + + /// Prints out the contents of the TGeoPcon + /// \param TGeoPcon *a + void PrintPcon(const TGeoPcon* a) const; + + /// Prints out the contents of the TGeoTube + /// \param TGeoTube *a + void PrintTube(const TGeoTube* a) const; + + /// Prints out the contents of the TGeoTubeSeg + /// \param TGeoTubeSeg *a + void PrintTubeSeg(const TGeoTubeSeg* a) const; + + /// Prints out the contents of the TGeoConeSeg + /// \param TGeoConeSeg *a + void PrintConeSeg(const TGeoConeSeg* a) const; + + /// Prints out the contents of the TGeoBBox + /// \param TGeoBBox *a + void PrintBBox(const TGeoBBox* a) const; + + /// Draws a cross sectional view of the TGeoPcon, Primarily for debugging. + /// A TCanvas should exist first. + /// \param TGeoPcon *p The TGeoPcon to be "drawn" + /// \param Int_t fillc The fill color to be used + /// \param Int_t fills The fill style to be used + /// \param Int_t linec The line color to be used + /// \param Int_t lines The line style to be used + /// \param Int_t linew The line width to be used + /// \param Int_t markc The markder color to be used + /// \param Int_t marks The markder style to be used + /// \param Float_t marksize The marker size + 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; + + /// 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. + /// Returns kTRUE if line intersects circle or kFALSE if line does not intersect circle + /// or the line is not properly defined point {x0,y0} and {x1,y1} are the same point. + /// \param Double_t x0 X of first point defining the line + /// \param Double_t y0 Y of first point defining the line + /// \param Double_t x1 X of Second point defining the line + /// \param Double_t y1 Y of Second point defining the line + /// \param Double_t xc X of Circle center point defining the line + /// \param Double_t yc Y of Circle center point defining the line + /// \param Double_t r radius of circle + /// \param Double_t &t0 First angle where line intersects circle + /// \param Double_t &t1 Second angle where line intersects 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; + + + /// 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 + /// \param Double_t x0 X Coordinate of arc 0 center. + /// \param Double_t y0 Y Coordinate of arc 0 center. + /// \param Double_t r0 Radius of curvature of arc 0. For signe see figure. + /// \param Double_t x1 X Coordinate of arc 1 center. + /// \param Double_t y1 Y Coordinate of arc 1 center. + /// \param Double_t r1 Radius of curvature of arc 1. For signe see figure. + /// \param Double_t t0 Ending angle of arch 0, with respect to x axis, Degrees. + /// \param Double_t t1 Starting angle of arch 1, with respect to x axis, Degrees. + 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. + /// Defined media here should correspond to the one defined in galice.cuts + /// File which is red in (AliMC*) fMCApp::Init() { ReadTransPar(); } + void CreateDefaultMaterials(); + + virtual void CreateMaterials() {}; + + /// Function to create the figure describing how the function + /// AnglesForRoundedCorners works. + /// \param Double_t x0 X Coordinate of arc 0 center. + /// \param Double_t y0 Y Coordinate of arc 0 center. + /// \param Double_t r0 Radius of curvature of arc 0. For signe see figure. + /// \param Double_t x1 X Coordinate of arc 1 center. + /// \param Double_t y1 Y Coordinate of arc 1 center. + /// \param Double_t r1 Radius of curvature of arc 1. For signe see figure. + 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 sMicron; ///< Convert micron to TGeom's cm. + static const Double_t sMm; ///< Convert mm to TGeom's cm. + static const Double_t sCm; ///< Convert cm to TGeom's cm. + static const Double_t sDegree; ///< Convert degrees to TGeom's degrees + static const Double_t sRadian; ///< To Radians + static const Double_t sGCm3; ///< Density in g/cm^3 + static const Double_t sKgm3; ///< Density in kg/m^3 + static const Double_t sKgdm3; ///< Density in kg/dm^3 + static const Double_t sCelsius; ///< Temperature in degrees Celcius + static const Double_t sPascal; ///< Preasure in Pascal + static const Double_t sKPascal; ///< Preasure in KPascal + static const Double_t sEV; ///< Energy in eV + static const Double_t sKEV; ///< Energy in KeV + static const Double_t sMEV; ///< Energy in MeV + static const Double_t sGEV; ///< Energy in GeV + +private: + /// 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. Returns the angle in Degrees + /// \param Double_t dx difference in x locations of the circle centers + /// \param Double_t dy difference in y locations of the circle centers + /// \param Double_t sdr difference or sum of the circle radii + Double_t 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. Returns the angle in Degrees + /// \param Double_t dx difference in x locations of the circle centers + /// \param Double_t dy difference in y locations of the circle centers + /// \param Double_t sdr difference or sum of the circle radii + Double_t AngleForRoundedCorners1(Double_t dx, Double_t dy, Double_t sdr) const; + + Int_t mDebug; ///< Debug flag/level + ClassDef(V11Geometry, 1) // Base class for ITS v11 geometry +}; +} +} + +#endif diff --git a/macro/run_sim.C b/macro/run_sim.C index d2ef62ebb19f4..5cd9107134d29 100644 --- a/macro/run_sim.C +++ b/macro/run_sim.C @@ -53,7 +53,7 @@ void run_sim(Int_t nEvents = 10, TString mcEngine = "TGeant3") run->AddModule(tpc); */ - O2Detector* its = new O2its("ITS", kTRUE, 7); + O2Detector* its = new AliceO2::ITS::Detector("ITS", kTRUE, 7); run->AddModule(its); // build ITS upgrade detector @@ -90,7 +90,7 @@ void run_sim(Int_t nEvents = 10, TString mcEngine = "TGeant3") gSystem->Exec(" rm itsSegmentations.root "); // create segmentations: - AliITSUSegmentationPix* seg0 = new AliITSUSegmentationPix(0, // segID (0:9) + AliceO2::ITS::UpgradeSegmentationPixel* seg0 = new AliceO2::ITS::UpgradeSegmentationPixel(0, // segID (0:9) 1, // chips per module kNCol, // ncols (total for module) kNRow, // nrows @@ -103,15 +103,15 @@ void run_sim(Int_t nEvents = 10, TString mcEngine = "TGeant3") kGuardRing, // right kGuardRing, // top kReadOutEdge // bottom - ); // see AliITSUSegmentationPix.h for extra options - seg0->Store(AliITSUGeomTGeo::GetITSsegmentationFileName()); + ); // see UpgradeSegmentationPixel.h for extra options + seg0->Store(AliceO2::ITS::UpgradeGeometryTGeo::GetITSsegmentationFileName()); seg0->Print(); double dzLr,rLr,phi0,turbo; int nStaveLr,nModPerStaveLr,idLr; - its->SetStaveModelIB(O2its::kIBModel22); - its->SetStaveModelOB(O2its::kOBModel1); + its->SetStaveModelIB(AliceO2::ITS::Detector::kIBModel22); + its->SetStaveModelOB(AliceO2::ITS::Detector::kOBModel1); const int kNWrapVol = 3; const double wrpRMin[kNWrapVol] = { 2.1, 15.0, 32.0};