Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • le.koch/cbmroot
  • patrick.pfistner_AT_kit.edu/cbmroot
  • lena.rossel_AT_stud.uni-frankfurt.de/cbmroot
  • i.deppner/cbmroot
  • fweig/cbmroot
  • karpushkin_AT_inr.ru/cbmroot
  • v.akishina/cbmroot
  • rishat.sultanov_AT_cern.ch/cbmroot
  • l_fabe01_AT_uni-muenster.de/cbmroot
  • pwg-c2f/cbmroot
  • j.decuveland/cbmroot
  • a.toia/cbmroot
  • i.vassiliev/cbmroot
  • n.herrmann/cbmroot
  • o.lubynets/cbmroot
  • se.gorbunov/cbmroot
  • cornelius.riesen_AT_physik.uni-giessen.de/cbmroot
  • zhangqn17_AT_mails.tsinghua.edu.cn/cbmroot
  • bartosz.sobol/cbmroot
  • ajit.kumar/cbmroot
  • computing/cbmroot
  • a.agarwal_AT_vecc.gov.in/cbmroot
  • osingh/cbmroot
  • wielanek_AT_if.pw.edu.pl/cbmroot
  • malgorzata.karabowicz.stud_AT_pw.edu.pl/cbmroot
  • m.shiroya/cbmroot
  • s.roy/cbmroot
  • p.-a.loizeau/cbmroot
  • a.weber/cbmroot
  • ma.beyer/cbmroot
  • d.klein/cbmroot
  • d.smith/cbmroot
  • mvdsoft/cbmroot
  • d.spicker/cbmroot
  • y.h.leung/cbmroot
  • aksharma/cbmroot
  • m.deveaux/cbmroot
  • mkunold/cbmroot
  • h.darwish/cbmroot
  • pk.sharma_AT_vecc.gov.in/cbmroot
  • f_fido01_AT_uni-muenster.de/cbmroot
  • g.kozlov/cbmroot
  • d.emschermann/cbmroot
  • evgeny.lavrik/cbmroot
  • v.friese/cbmroot
  • f.uhlig/cbmroot
  • ebechtel_AT_ikf.uni-frankfurt.de/cbmroot
  • a.senger/cbmroot
  • praisig/cbmroot
  • s.lebedev/cbmroot
  • redelbach_AT_compeng.uni-frankfurt.de/cbmroot
  • p.subramani/cbmroot
  • a_meye37_AT_uni-muenster.de/cbmroot
  • om/cbmroot
  • o.golosov/cbmroot
  • l.chlad/cbmroot
  • a.bercuci/cbmroot
  • d.ramirez/cbmroot
  • v.singhal/cbmroot
  • h.schiller/cbmroot
  • apuntke/cbmroot
  • f.zorn/cbmroot
  • rubio_AT_physi.uni-heidelberg.de/cbmroot
  • p.chudoba/cbmroot
  • apuntke/mcbmroot
  • r.karabowicz/cbmroot
66 results
Show changes
Showing
with 69 additions and 6024 deletions
......@@ -99,7 +99,7 @@ Double_t CbmMcbm2018RichPar::GetToTshift2(Int_t tdcIdx, Int_t ch) const
return fToTshiftMap[tdcIdx * 33 + ch];
}
void CbmMcbm2018RichPar::Print() const
void CbmMcbm2018RichPar::Print(Option_t*) const
{
LOG(info) << "Nb available TRB addresses: " << GetNaddresses();
......
......@@ -60,7 +60,7 @@ public:
*/
Double_t GetToTshift2(Int_t tdcIdx, Int_t ch) const;
void Print() const;
void Print(Option_t* option = "") const;
private: // Stored in the par file
/**
......
......@@ -8,4 +8,5 @@ flib_dpb/flib_dpb
ipc/ipc
jsroot
googletest
yaml-cpp/
xpu/
......@@ -35,6 +35,17 @@ if(DOWNLOAD_EXTERNALS)
set(KF_DEPENDS_ON "")
endif()
download_project_if_needed(PROJECT xpu
GIT_REPOSITORY "https://git.cbm.gsi.de/fweig/xpu.git"
GIT_TAG "v0.6.4"
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xpu
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
Add_Subdirectory(xpu)
Include(InstallKFParticle.cmake)
Include(InstallNicaFemto.cmake)
Include(InstallAnalysisTree.cmake)
......@@ -43,6 +54,8 @@ if(DOWNLOAD_EXTERNALS)
Include(InstallParameter.cmake)
Include(InstallInput.cmake)
Include(InstallGeometry.cmake)
Include(InstallYamlCpp.cmake)
else()
# Define targets which are needed by CbmRoot but are not available
# whithout the external packages
......
set(YAMLCPP_VERSION 0579ae3d976091d7d664aa9d2527e0d0cff25763) # version 0.7.0
set(YAMLCPP_SRC_URL "https://github.com/jbeder/yaml-cpp")
set(YAMLCPP_DESTDIR "${CMAKE_BINARY_DIR}/external/YAMLCPP-prefix")
#set(YAMLCPP_BYPRODUCT "${PROJECT_BINARY_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}yaml-cpp${CMAKE_SHARED_LIBRARY_SUFFIX}")
download_project_if_needed(PROJECT yaml-cpp
GIT_REPOSITORY ${YAMLCPP_SRC_URL}
GIT_TAG ${YAMLCPP_VERSION}
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/yaml-cpp
TEST_FILE CMakeLists.txt
)
If(ProjectUpdated)
File(REMOVE_RECURSE ${YAMLCPP_DESTDIR})
Message("yaml-cpp source directory was changed so build directory was deleted")
EndIf()
ExternalProject_Add(
yaml-cpp
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/yaml-cpp
GIT_CONFIG advice.detachedHead=false
BUILD_IN_SOURCE 0
LOG_DOWNLOAD 1 LOG_CONFIGURE 1 LOG_BUILD 1 LOG_INSTALL 1
CMAKE_ARGS -DYAML_CPP_BUILD_CONTRIB=OFF
-DYAML_CPP_BUILD_TOOLS=OFF
-DYAML_CPP_BUILD_TESTS=OFF
-DYAML_BUILD_SHARED_LIBS=OFF
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
BUILD_COMMAND ${CMAKE_COMMAND} --build . --target yaml-cpp --parallel 1
BUILD_BYPRODUCTS ${PROJECT_BINARY_DIR}/external/yaml-cpp-prefix/src/yaml-cpp-build/${CMAKE_STATIC_LIBRARY_PREFIX}yaml-cpp${CMAKE_STATIC_LIBRARY_SUFFIX}
INSTALL_COMMAND ""
)
# pre-create empty directory to make INTERFACE_INCLUDE_DIRECTORIES happy
file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/external/yaml-cpp/include)
add_library(external::yaml-cpp STATIC IMPORTED GLOBAL)
add_dependencies(external::yaml-cpp yaml-cpp)
set_target_properties(external::yaml-cpp PROPERTIES
IMPORTED_LOCATION ${PROJECT_BINARY_DIR}/external/yaml-cpp-prefix/src/yaml-cpp-build/${CMAKE_STATIC_LIBRARY_PREFIX}yaml-cpp${CMAKE_STATIC_LIBRARY_SUFFIX}
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/external/yaml-cpp/include
)
/* Copyright (C) 2019 PI-UHd, GSI
SPDX-License-Identifier: GPL-3.0-only
Authors: Norbert Herrmann [committer] */
///
/// \file Create_TOF_Geometry_v18k_mCbm.C
/// \brief Generates TOF geometry in Root format.
///
// Changelog
//
// 2017-11-03 - v18i - DE - shift mTOF to z=298 cm for acceptance matching with mSTS
// 2017-10-06 - v18h - DE - put v18f into vertical position to fit into the mCBM cave
// 2017-07-15 - v18g - DE - swap the z-position of TOF modules: 2 in the front, 3 in the back
// 2017-07-14 - v18f - DE - reduce vertical gap between TOF modules to fix the gap between modules 1-2 and 4-5
// 2017-05-17 - v18e - DE - rotate electronics away from beam, shift 16 cm away from beam along x-axis
// 2017-05-17 - v18d - DE - change geometry name to v18d
// in root all sizes are given in cm
#include "TFile.h"
#include "TGeoCompositeShape.h"
#include "TGeoManager.h"
#include "TGeoMaterial.h"
#include "TGeoMatrix.h"
#include "TGeoMedium.h"
#include "TGeoPgon.h"
#include "TGeoVolume.h"
#include "TList.h"
#include "TMath.h"
#include "TROOT.h"
#include "TString.h"
#include "TSystem.h"
#include <iostream>
// Name of geometry version and output file
const TString geoVersion = "tof_v18m"; // do not change
const TString geoVersionStand = geoVersion + "Stand";
//
const TString fileTag = "tof_v18m";
const TString FileNameSim = fileTag + "_mCbm.root";
const TString FileNameGeo = fileTag + "_mCbm.geo.root";
const TString FileNameInfo = fileTag + "_mCbm.info";
// TOF_Z_Front corresponds to front cover of outer super module towers
const Float_t TOF_Z_Front_Stand = 240; // = z=298 mCBM@SIS18
const Float_t TOF_Z_Front = 0; // = z=298 mCBM@SIS18
//const Float_t TOF_Z_Front = 130; // = z=225 mCBM@SIS18
//const Float_t TOF_Z_Front = 250; // SIS 100 hadron
//const Float_t TOF_Z_Front = 450; // SIS 100 hadron
//const Float_t TOF_Z_Front = 600; // SIS 100 electron
//const Float_t TOF_Z_Front = 650; // SIS 100 muon
//const Float_t TOF_Z_Front = 880; // SIS 300 electron
//const Float_t TOF_Z_Front = 1020; // SIS 300 muon
//
//const Float_t TOF_Z_Front = 951.5; // Wall_Z_Position = 1050 cm
// Names of the different used materials which are used to build the modules
// The materials are defined in the global media.geo file
const TString KeepingVolumeMedium = "air";
const TString BoxVolumeMedium = "aluminium";
const TString NoActivGasMedium = "RPCgas_noact";
const TString ActivGasMedium = "RPCgas";
const TString GlasMedium = "RPCglass";
const TString ElectronicsMedium = "carbon";
// Counters:
// 0 MRPC3a
// 1 MRPC3b
// 2
// 3
// 4 Diamond
//
// 6 Buc 2019
// 7 CERN 20gap
// 8 Ceramic Pad
const Int_t NumberOfDifferentCounterTypes = 9;
const Float_t Glass_X[NumberOfDifferentCounterTypes] = {32., 52., 32., 32., 0.2, 32., 28.8, 20., 2.4};
const Float_t Glass_Y[NumberOfDifferentCounterTypes] = {26.9, 53., 20., 10., 0.2, 10., 6., 20., 2.4};
const Float_t Glass_Z[NumberOfDifferentCounterTypes] = {0.1, 0.1, 0.1, 0.1, 0.01, 0.1, 0.1, 0.1, 0.1};
const Float_t GasGap_X[NumberOfDifferentCounterTypes] = {32., 52., 32., 32., 0.2, 32., 28.8, 20., 2.4};
const Float_t GasGap_Y[NumberOfDifferentCounterTypes] = {26.9, 53., 20., 10., 0.2, 10., 6., 20., 2.4};
const Float_t GasGap_Z[NumberOfDifferentCounterTypes] = {0.025, 0.025, 0.025, 0.025, 0.01, 0.02, 0.02, 0.02, 0.025};
const Int_t NumberOfGaps[NumberOfDifferentCounterTypes] = {8, 8, 8, 8, 1, 8, 10, 20, 4};
//const Int_t NumberOfGaps[NumberOfDifferentCounterTypes] = {1,1,1,1}; //deb
const Int_t NumberOfReadoutStrips[NumberOfDifferentCounterTypes] = {32, 32, 32, 32, 80, 32, 32, 20, 1};
//const Int_t NumberOfReadoutStrips[NumberOfDifferentCounterTypes] = {1,1,1,1}; //deb
const Float_t SingleStackStartPosition_Z[NumberOfDifferentCounterTypes] = {-0.6, -0.6, -0.6, -0.6, -0.1,
-0.6, -0.6, -0.6, -1.};
const Float_t Electronics_X[NumberOfDifferentCounterTypes] = {34.0, 53.0, 32.0, 32., 0.3, 0.1, 28.8, 20., 0.1};
const Float_t Electronics_Y[NumberOfDifferentCounterTypes] = {5.0, 5.0, 1.0, 1., 0.1, 0.1, 1.0, 1.0, 0.1};
const Float_t Electronics_Z[NumberOfDifferentCounterTypes] = {0.3, 0.3, 0.3, 0.3, 0.1, 0.1, 0.1, 0.1, 0.1};
const Int_t NofModuleTypes = 10;
// 5 Diamond
// 6 Buc
// 7 CERN 20 gap
// 8 Ceramic
// 9 Star2
// Aluminum box for all module types
const Float_t Module_Size_X[NofModuleTypes] = {180., 180., 180., 180., 180., 5., 40., 30., 22.5, 100.};
const Float_t Module_Size_Y[NofModuleTypes] = {49., 49., 74., 28., 18., 5., 12., 30., 11., 49.};
const Float_t Module_Over_Y[NofModuleTypes] = {11.5, 11.5, 11., 4.5, 4.5, 0., 0., 0., 0., 0.};
const Float_t Module_Size_Z[NofModuleTypes] = {11., 11., 13., 11., 11., 1., 12., 6., 6.2, 11.2};
const Float_t Module_Thick_Alu_X_left = 0.1;
const Float_t Module_Thick_Alu_X_right = 1.0;
const Float_t Module_Thick_Alu_Y = 0.1;
const Float_t Module_Thick_Alu_Z = 0.1;
// Distance to the center of the TOF wall [cm];
const Float_t Wall_Z_Position = 400.;
const Float_t MeanTheta = 0.;
//Type of Counter for module
const Int_t CounterTypeInModule[NofModuleTypes] = {0, 0, 1, 2, 3, 4, 6, 7, 8, 0};
const Int_t NCounterInModule[NofModuleTypes] = {5, 5, 3, 5, 5, 1, 2, 1, 8, 2};
// Placement of the counter inside the module
const Float_t CounterXStartPosition[NofModuleTypes] = {-60.0, -66.0, -56.0, -60.0, -60.0, 0.0, 0., 0., -7., 0.};
const Float_t CounterXDistance[NofModuleTypes] = {30.0, 32.0, 51.0, 30.0, 30.0, 0.0, 0., 0., 2., 0.};
const Float_t CounterYStartPosition[NofModuleTypes] = {0.0, 0.0, 0.0, 0.0, 0.0, 0., 0., -4., -1.3, 0.};
const Float_t CounterYDistance[NofModuleTypes] = {0.0, 0.0, 0.0, 0.0, 0.0, 0., 0., 8., 0., 0.};
const Float_t CounterZDistance[NofModuleTypes] = {-2.5, 0.0, 0.0, 2.5, 2.5, 0., 6., 0., 0.1, 4.};
const Float_t CounterZStartPosition[NofModuleTypes] = {0.0, 0.0, 0.0, 0.0, 0.0, 0., -3., 0., 0.0, -2.};
const Float_t CounterRotationAngle[NofModuleTypes] = {0., 8.7, 7.0, 0., 0., 0., 0., 0., 0., 0.};
// Pole (support structure)
const Int_t MaxNumberOfPoles = 20;
Float_t Pole_ZPos[MaxNumberOfPoles];
Float_t Pole_Col[MaxNumberOfPoles];
Int_t NumberOfPoles = 0;
const Float_t Pole_Size_X = 20.;
const Float_t Pole_Size_Y = 300.;
const Float_t Pole_Size_Z = 10.;
const Float_t Pole_Thick_X = 5.;
const Float_t Pole_Thick_Y = 5.;
const Float_t Pole_Thick_Z = 5.;
// Bars (support structure)
const Float_t Bar_Size_X = 20.;
const Float_t Bar_Size_Y = 20.;
Float_t Bar_Size_Z = 100.;
const Int_t MaxNumberOfBars = 20;
Float_t Bar_ZPos[MaxNumberOfBars];
Float_t Bar_XPos[MaxNumberOfBars];
Int_t NumberOfBars = 0;
const Float_t ChamberOverlap = 40;
const Float_t DxColl = 158.0; //Module_Size_X-ChamberOverlap;
//const Float_t Pole_Offset=Module_Size_X/2.+Pole_Size_X/2.;
const Float_t Pole_Offset = 90.0 + Pole_Size_X / 2.;
// Position for module placement
const Float_t Inner_Module_First_Y_Position = 16.;
const Float_t Inner_Module_Last_Y_Position = 480.;
const Float_t Inner_Module_X_Offset = 0.; // centered position in x/y
//const Float_t Inner_Module_X_Offset=18; // shift by 16 cm in x
const Int_t Inner_Module_NTypes = 3;
const Float_t Inner_Module_Types[Inner_Module_NTypes] = {4., 3., 0.};
//const Float_t Inner_Module_Number[Inner_Module_NTypes] = {2.,2.,6.}; //V13_3a
const Float_t Inner_Module_Number[Inner_Module_NTypes] = {2., 2., 1.}; //V13_3a
//const Float_t Inner_Module_Number[Inner_Module_NTypes] = {0.,0.,0.}; //debugging
const Float_t InnerSide_Module_X_Offset = 51.;
const Float_t InnerSide_Module_NTypes = 1;
const Float_t InnerSide_Module_Types[Inner_Module_NTypes] = {5.};
const Float_t InnerSide_Module_Number[Inner_Module_NTypes] = {2.}; //v13_3a
//const Float_t InnerSide_Module_Number[Inner_Module_NTypes] = {0.}; //debug
const Float_t Outer_Module_First_Y_Position = 0.;
const Float_t Outer_Module_Last_Y_Position = 480.;
const Float_t Outer_Module_X_Offset = 3.;
const Int_t Outer_Module_Col = 4;
const Int_t Outer_Module_NTypes = 2;
const Float_t Outer_Module_Types[Outer_Module_NTypes][Outer_Module_Col] = {1., 1., 1., 1., 2., 2., 2., 2.};
const Float_t Outer_Module_Number[Outer_Module_NTypes][Outer_Module_Col] = {9., 9., 2., 0., 0., 0., 3., 4.}; //V13_3a
//const Float_t Outer_Module_Number[Outer_Module_NTypes][Outer_Module_Col] = {1.,1.,0.,0., 0.,0.,0.,0.};//debug
const Float_t Star2_First_Z_Position = TOF_Z_Front + 34.;
const Float_t Star2_Delta_Z_Position = 0.;
const Float_t Star2_First_Y_Position = 32.; //
const Float_t Star2_Delta_Y_Position = 0.; //
const Float_t Star2_rotate_Z = -90.;
const Int_t Star2_NTypes = 1;
const Float_t Star2_Types[Star2_NTypes] = {9.};
const Float_t Star2_Number[Star2_NTypes] = {1.}; //debugging, V16b
const Float_t Star2_X_Offset[Star2_NTypes] = {51.}; //{62.};
const Float_t Buc_First_Z_Position = TOF_Z_Front + 34.;
const Float_t Buc_Delta_Z_Position = 0.;
const Float_t Buc_First_Y_Position = -35.; //
const Float_t Buc_Delta_Y_Position = 0.; //
const Float_t Buc_rotate_Z = 0.;
const Int_t Buc_NTypes = 1;
const Float_t Buc_Types[Buc_NTypes] = {6.};
const Float_t Buc_Number[Buc_NTypes] = {1.}; //debugging, V16b
const Float_t Buc_X_Offset[Buc_NTypes] = {50.};
const Int_t Cer_NTypes = 3;
const Float_t Cer_Z_Position[Cer_NTypes] = {(float) (TOF_Z_Front + 13.2), (float) (TOF_Z_Front + 45.),
(float) (TOF_Z_Front + 45.)};
const Float_t Cer_X_Position[Cer_NTypes] = {0., 49.8, 49.8};
const Float_t Cer_Y_Position[Cer_NTypes] = {-1., 5., 5.};
const Float_t Cer_rotate_Z[Cer_NTypes] = {0., 0., 0.};
const Float_t Cer_Types[Cer_NTypes] = {5., 8., 8.};
const Float_t Cer_Number[Cer_NTypes] = {1., 1., 1.}; //V16b
const Float_t CERN_Z_Position = TOF_Z_Front + 50; // 20 gap
const Float_t CERN_First_Y_Position = 36.;
const Float_t CERN_X_Offset = 46.; //65.5;
const Float_t CERN_rotate_Z = 90.;
const Int_t CERN_NTypes = 1;
const Float_t CERN_Types[CERN_NTypes] = {7.}; // this is the SmType!
const Float_t CERN_Number[CERN_NTypes] = {1.}; // evtl. double for split signals
// some global variables
TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance
TGeoVolume* gModules[NofModuleTypes]; // Global storage for module types
TGeoVolume* gCounter[NumberOfDifferentCounterTypes];
TGeoVolume* gPole;
TGeoVolume* gBar[MaxNumberOfBars];
const Float_t Dia_Z_Position = -0.5 - TOF_Z_Front_Stand;
const Float_t Dia_First_Y_Position = 0.;
const Float_t Dia_X_Offset = 0.;
const Float_t Dia_rotate_Z = 0.;
const Int_t Dia_NTypes = 1;
const Float_t Dia_Types[Dia_NTypes] = {5.};
const Float_t Dia_Number[Dia_NTypes] = {1.};
Float_t Last_Size_Y = 0.;
Float_t Last_Over_Y = 0.;
// Forward declarations
void create_materials_from_media_file();
TGeoVolume* create_counter(Int_t);
TGeoVolume* create_new_counter(Int_t);
TGeoVolume* create_tof_module(Int_t);
TGeoVolume* create_new_tof_module(Int_t);
TGeoVolume* create_tof_pole();
TGeoVolume* create_tof_bar();
void position_tof_poles(Int_t);
void position_tof_bars(Int_t);
void position_inner_tof_modules(Int_t);
void position_side_tof_modules(Int_t);
void position_outer_tof_modules(Int_t);
void position_Dia(Int_t);
void position_Star2(Int_t);
void position_Buc(Int_t);
void position_cer_modules(Int_t);
void position_CERN(Int_t);
void dump_info_file();
void Create_TOF_Geometry_v18m_mCbm()
{
// Load the necessary FairRoot libraries
// gROOT->LoadMacro("$VMCWORKDIR/gconfig/basiclibs.C");
// basiclibs();
// gSystem->Load("libGeoBase");
// gSystem->Load("libParBase");
// gSystem->Load("libBase");
// Load needed material definition from media.geo file
create_materials_from_media_file();
// Get the GeoManager for later usage
gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom");
gGeoMan->SetVisLevel(5); // 2 = super modules
gGeoMan->SetVisOption(0);
// Create the top volume
/*
TGeoBBox* topbox= new TGeoBBox("", 1000., 1000., 1000.);
TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air"));
gGeoMan->SetTopVolume(top);
*/
TGeoVolume* top = new TGeoVolumeAssembly("TOP");
gGeoMan->SetTopVolume(top);
TGeoRotation* tof_rotation = new TGeoRotation();
tof_rotation->RotateY(0.); // angle with respect to beam axis
//tof_rotation->RotateZ( 0 ); // electronics on 9 o'clock position = +x
// tof_rotation->RotateZ( 0 ); // electronics on 9 o'clock position = +x
// tof_rotation->RotateZ( 90 ); // electronics on 12 o'clock position (top)
// tof_rotation->RotateZ( 180 ); // electronics on 3 o'clock position = -x
// tof_rotation->RotateZ( 270 ); // electronics on 6 o'clock position (bottom)
TGeoVolume* tof = new TGeoVolumeAssembly(geoVersion);
top->AddNode(tof, 1, tof_rotation);
TGeoVolume* tofstand = new TGeoVolumeAssembly(geoVersionStand);
TGeoTranslation* stand_trans = new TGeoTranslation("", 0., 0., TOF_Z_Front_Stand);
TGeoRotation* stand_rot = new TGeoRotation();
stand_rot->RotateY(1.);
TGeoCombiTrans* stand_combi_trans = new TGeoCombiTrans(*stand_trans, *stand_rot);
tof->AddNode(tofstand, 1, stand_combi_trans);
for (Int_t counterType = 0; counterType < NumberOfDifferentCounterTypes; counterType++) {
gCounter[counterType] = create_new_counter(counterType);
}
for (Int_t moduleType = 0; moduleType < NofModuleTypes; moduleType++) {
gModules[moduleType] = create_new_tof_module(moduleType);
gModules[moduleType]->SetVisContainers(1);
}
// no pole
// gPole = create_tof_pole();
// position_side_tof_modules(1); // keep order !!
// position_inner_tof_modules(2);
position_inner_tof_modules(3);
position_Dia(1);
position_Star2(1);
position_cer_modules(3);
position_CERN(1);
position_Buc(1);
cout << "Outer Types " << Outer_Module_Types[0][0] << ", " << Outer_Module_Types[1][0]
<< ", col=1: " << Outer_Module_Types[0][1] << ", " << Outer_Module_Types[1][1] << endl;
cout << "Outer Number " << Outer_Module_Number[0][0] << ", " << Outer_Module_Number[1][0]
<< ", col=1: " << Outer_Module_Number[0][1] << ", " << Outer_Module_Number[1][1] << endl;
// position_outer_tof_modules(4);
// position_tof_poles(0);
// position_tof_bars(0);
gGeoMan->CloseGeometry();
gGeoMan->CheckOverlaps(0.001);
gGeoMan->PrintOverlaps();
gGeoMan->Test();
TFile* outfile1 = new TFile(FileNameSim, "RECREATE");
top->Write();
//gGeoMan->Write();
outfile1->Close();
TFile* outfile2 = new TFile(FileNameGeo, "RECREATE");
gGeoMan->Write();
outfile2->Close();
dump_info_file();
top->SetVisContainers(1);
gGeoMan->SetVisLevel(5);
top->Draw("ogl");
//top->Draw();
//gModules[0]->Draw("ogl");
// gModules[0]->Draw("");
gModules[0]->SetVisContainers(1);
// gModules[1]->Draw("");
gModules[1]->SetVisContainers(1);
//gModules[5]->Draw("");
// top->Raytrace();
}
void create_materials_from_media_file()
{
// Use the FairRoot geometry interface to load the media which are already defined
FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
TString geoPath = gSystem->Getenv("VMCWORKDIR");
TString geoFile = geoPath + "/geometry/media.geo";
geoFace->setMediaFile(geoFile);
geoFace->readMedia();
// Read the required media and create them in the GeoManager
FairGeoMedia* geoMedia = geoFace->getMedia();
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
FairGeoMedium* air = geoMedia->getMedium("air");
FairGeoMedium* aluminium = geoMedia->getMedium("aluminium");
FairGeoMedium* RPCgas = geoMedia->getMedium("RPCgas");
FairGeoMedium* RPCgas_noact = geoMedia->getMedium("RPCgas_noact");
FairGeoMedium* RPCglass = geoMedia->getMedium("RPCglass");
FairGeoMedium* carbon = geoMedia->getMedium("carbon");
// include check if all media are found
geoBuild->createMedium(air);
geoBuild->createMedium(aluminium);
geoBuild->createMedium(RPCgas);
geoBuild->createMedium(RPCgas_noact);
geoBuild->createMedium(RPCglass);
geoBuild->createMedium(carbon);
}
TGeoVolume* create_counter(Int_t modType)
{
//glass
Float_t gdx = Glass_X[modType];
Float_t gdy = Glass_Y[modType];
Float_t gdz = Glass_Z[modType];
//gas gap
Int_t nstrips = NumberOfReadoutStrips[modType];
Int_t ngaps = NumberOfGaps[modType];
Float_t ggdx = GasGap_X[modType];
Float_t ggdy = GasGap_Y[modType];
Float_t ggdz = GasGap_Z[modType];
Float_t gsdx = ggdx / float(nstrips);
//single stack
Float_t dzpos = gdz + ggdz;
Float_t startzpos = SingleStackStartPosition_Z[modType];
// electronics
//pcb dimensions
Float_t dxe = Electronics_X[modType];
Float_t dye = Electronics_Y[modType];
Float_t dze = Electronics_Z[modType];
Float_t yele = (gdy + 0.1) / 2. + dye / 2.;
// needed materials
TGeoMedium* glassPlateVolMed = gGeoMan->GetMedium(GlasMedium);
TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium);
TGeoMedium* activeGasVolMed = gGeoMan->GetMedium(ActivGasMedium);
TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsMedium);
// Single glass plate
TGeoBBox* glass_plate = new TGeoBBox("", gdx / 2., gdy / 2., gdz / 2.);
TGeoVolume* glass_plate_vol = new TGeoVolume("tof_glass", glass_plate, glassPlateVolMed);
glass_plate_vol->SetLineColor(kMagenta); // set line color for the glass plate
glass_plate_vol->SetTransparency(20); // set transparency for the TOF
TGeoTranslation* glass_plate_trans = new TGeoTranslation("", 0., 0., 0.);
// Single gas gap
TGeoBBox* gas_gap = new TGeoBBox("", ggdx / 2., ggdy / 2., ggdz / 2.);
//TGeoVolume* gas_gap_vol =
//new TGeoVolume("tof_gas_gap", gas_gap, noActiveGasVolMed);
TGeoVolume* gas_gap_vol = new TGeoVolume("tof_gas_active", gas_gap, activeGasVolMed);
gas_gap_vol->Divide("Strip", 1, nstrips, -ggdx / 2., 0);
gas_gap_vol->SetLineColor(kRed); // set line color for the gas gap
gas_gap_vol->SetTransparency(70); // set transparency for the TOF
TGeoTranslation* gas_gap_trans = new TGeoTranslation("", 0., 0., (gdz + ggdz) / 2.);
// Single subdivided active gas gap
/*
TGeoBBox* gas_active = new TGeoBBox("", gsdx/2., ggdy/2., ggdz/2.);
TGeoVolume* gas_active_vol =
new TGeoVolume("tof_gas_active", gas_active, activeGasVolMed);
gas_active_vol->SetLineColor(kBlack); // set line color for the gas gap
gas_active_vol->SetTransparency(70); // set transparency for the TOF
*/
// Add glass plate, inactive gas gap and active gas gaps to a single stack
TGeoVolume* single_stack = new TGeoVolumeAssembly("single_stack");
single_stack->AddNode(glass_plate_vol, 0, glass_plate_trans);
single_stack->AddNode(gas_gap_vol, 0, gas_gap_trans);
/*
for (Int_t l=0; l<nstrips; l++){
TGeoTranslation* gas_active_trans
= new TGeoTranslation("", -ggdx/2+(l+0.5)*gsdx, 0., 0.);
gas_gap_vol->AddNode(gas_active_vol, l, gas_active_trans);
// single_stack->AddNode(gas_active_vol, l, gas_active_trans);
}
*/
// Add 8 single stacks + one glass plate at the e09.750nd to a multi stack
TGeoVolume* multi_stack = new TGeoVolumeAssembly("multi_stack");
Int_t l;
for (l = 0; l < ngaps; l++) {
TGeoTranslation* single_stack_trans = new TGeoTranslation("", 0., 0., startzpos + l * dzpos);
multi_stack->AddNode(single_stack, l, single_stack_trans);
}
TGeoTranslation* single_glass_back_trans = new TGeoTranslation("", 0., 0., startzpos + ngaps * dzpos);
multi_stack->AddNode(glass_plate_vol, l, single_glass_back_trans);
// Add electronics above and below the glass stack to build a complete counter
TGeoVolume* counter = new TGeoVolumeAssembly("counter");
TGeoTranslation* multi_stack_trans = new TGeoTranslation("", 0., 0., 0.);
counter->AddNode(multi_stack, l, multi_stack_trans);
TGeoBBox* pcb = new TGeoBBox("", dxe / 2., dye / 2., dze / 2.);
TGeoVolume* pcb_vol = new TGeoVolume("pcb", pcb, electronicsVolMed);
pcb_vol->SetLineColor(kCyan); // set line color for the gas gap
pcb_vol->SetTransparency(10); // set transparency for the TOF
for (Int_t l = 0; l < 2; l++) {
yele *= -1.;
TGeoTranslation* pcb_trans = new TGeoTranslation("", 0., yele, 0.);
counter->AddNode(pcb_vol, l, pcb_trans);
}
return counter;
}
TGeoVolume* create_new_counter(Int_t modType)
{
//glass
Float_t gdx = Glass_X[modType];
Float_t gdy = Glass_Y[modType];
Float_t gdz = Glass_Z[modType];
//gas gap
Int_t nstrips = NumberOfReadoutStrips[modType];
Int_t ngaps = NumberOfGaps[modType];
Float_t ggdx = GasGap_X[modType];
Float_t ggdy = GasGap_Y[modType];
Float_t ggdz = GasGap_Z[modType];
Float_t gsdx = ggdx / (Float_t)(nstrips);
// electronics
//pcb dimensions
Float_t dxe = Electronics_X[modType];
Float_t dye = Electronics_Y[modType];
Float_t dze = Electronics_Z[modType];
Float_t yele = gdy / 2. + dye / 2.;
// counter size (calculate from glas, gap and electronics sizes)
Float_t cdx = TMath::Max(gdx, ggdx);
cdx = TMath::Max(cdx, dxe) + 0.2;
Float_t cdy = TMath::Max(gdy, ggdy) + 2 * dye + 0.2;
Float_t cdz = ngaps * ggdz + (ngaps + 1) * gdz + 0.2; // ngaps * (gdz+ggdz) + gdz + 0.2; // ok
//calculate thickness and first position in counter of single stack
Float_t dzpos = gdz + ggdz;
Float_t startzposglas = -ngaps * (gdz + ggdz) / 2.; // -cdz/2.+0.1+gdz/2.; // ok // (-cdz+gdz)/2.; // not ok
Float_t startzposgas = startzposglas + gdz / 2. + ggdz / 2.; // -cdz/2.+0.1+gdz +ggdz/2.; // ok
// needed materials
TGeoMedium* glassPlateVolMed = gGeoMan->GetMedium(GlasMedium);
TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium);
TGeoMedium* activeGasVolMed = gGeoMan->GetMedium(ActivGasMedium);
TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsMedium);
// define counter volume
TGeoBBox* counter_box = new TGeoBBox("", cdx / 2., cdy / 2., cdz / 2.);
TGeoVolume* counter = new TGeoVolume("counter", counter_box, noActiveGasVolMed);
counter->SetLineColor(kCyan); // set line color for the counter
counter->SetTransparency(70); // set transparency for the TOF
// define single glass plate volume
TGeoBBox* glass_plate = new TGeoBBox("", gdx / 2., gdy / 2., gdz / 2.);
TGeoVolume* glass_plate_vol = new TGeoVolume("tof_glass", glass_plate, glassPlateVolMed);
glass_plate_vol->SetLineColor(kMagenta); // set line color for the glass plate
glass_plate_vol->SetTransparency(20); // set transparency for the TOF
// define single gas gap volume
TGeoBBox* gas_gap = new TGeoBBox("", ggdx / 2., ggdy / 2., ggdz / 2.);
TGeoVolume* gas_gap_vol = new TGeoVolume("Gap", gas_gap, activeGasVolMed);
gas_gap_vol->Divide("Cell", 1, nstrips, -ggdx / 2., 0);
gas_gap_vol->SetLineColor(kRed); // set line color for the gas gap
gas_gap_vol->SetTransparency(99); // set transparency for the TOF
// place 8 gas gaps and 9 glas plates in the counter
for (Int_t igap = 0; igap <= ngaps; igap++) {
// place (ngaps+1) glass plates
Float_t zpos_glas = startzposglas + igap * dzpos;
TGeoTranslation* glass_plate_trans = new TGeoTranslation("", 0., 0., zpos_glas);
counter->AddNode(glass_plate_vol, igap, glass_plate_trans);
// place ngaps gas gaps
if (igap < ngaps) {
Float_t zpos_gas = startzposgas + igap * dzpos;
TGeoTranslation* gas_gap_trans = new TGeoTranslation("", 0., 0., zpos_gas);
counter->AddNode(gas_gap_vol, igap, gas_gap_trans);
}
// cout <<"Zpos(Glas): "<< zpos_glas << endl;
// cout <<"Zpos(Gas): "<< zpos_gas << endl;
}
// create and place the electronics above and below the glas stack
TGeoBBox* pcb = new TGeoBBox("", dxe / 2., dye / 2., dze / 2.);
TGeoVolume* pcb_vol = new TGeoVolume("pcb", pcb, electronicsVolMed);
pcb_vol->SetLineColor(kYellow); // kCyan); // set line color for electronics
pcb_vol->SetTransparency(10); // set transparency for the TOF
for (Int_t l = 0; l < 2; l++) {
yele *= -1.;
TGeoTranslation* pcb_trans = new TGeoTranslation("", 0., yele, 0.);
counter->AddNode(pcb_vol, l, pcb_trans);
}
return counter;
}
TGeoVolume* create_tof_module(Int_t modType)
{
Int_t cType = CounterTypeInModule[modType];
Float_t dx = Module_Size_X[modType];
Float_t dy = Module_Size_Y[modType];
Float_t dz = Module_Size_Z[modType];
Float_t width_aluxl = Module_Thick_Alu_X_left;
Float_t width_aluxr = Module_Thick_Alu_X_right;
Float_t width_aluy = Module_Thick_Alu_Y;
Float_t width_aluz = Module_Thick_Alu_Z;
Float_t shift_gas_box = (Module_Thick_Alu_X_right - Module_Thick_Alu_X_left) / 2;
Float_t dxpos = CounterXDistance[modType];
Float_t startxpos = CounterXStartPosition[modType];
Float_t dzoff = CounterZDistance[modType];
Float_t rotangle = CounterRotationAngle[modType];
TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium);
TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium);
TString moduleName = Form("module_%d", modType);
TGeoVolume* module = new TGeoVolumeAssembly(moduleName);
TGeoBBox* alu_box = new TGeoBBox("", dx / 2., dy / 2., dz / 2.);
TGeoVolume* alu_box_vol = new TGeoVolume("alu_box", alu_box, boxVolMed);
alu_box_vol->SetLineColor(kGreen); // set line color for the alu box
alu_box_vol->SetTransparency(20); // set transparency for the TOF
TGeoTranslation* alu_box_trans = new TGeoTranslation("", 0., 0., 0.);
module->AddNode(alu_box_vol, 0, alu_box_trans);
TGeoBBox* gas_box =
new TGeoBBox("", (dx - (width_aluxl + width_aluxr)) / 2., (dy - 2 * width_aluy) / 2., (dz - 2 * width_aluz) / 2.);
TGeoVolume* gas_box_vol = new TGeoVolume("gas_box", gas_box, noActiveGasVolMed);
gas_box_vol->SetLineColor(kYellow); // set line color for the gas box
gas_box_vol->SetTransparency(70); // set transparency for the TOF
TGeoTranslation* gas_box_trans = new TGeoTranslation("", shift_gas_box, 0., 0.);
alu_box_vol->AddNode(gas_box_vol, 0, gas_box_trans);
for (Int_t j = 0; j < 5; j++) { //loop over counters (modules)
Float_t zpos;
if (0 == modType) { zpos = dzoff *= -1; }
else {
zpos = 0.;
}
//cout << "counter z position " << zpos << endl;
TGeoTranslation* counter_trans = new TGeoTranslation("", startxpos + j * dxpos, 0.0, zpos);
TGeoRotation* counter_rot = new TGeoRotation();
counter_rot->RotateY(rotangle);
TGeoCombiTrans* counter_combi_trans = new TGeoCombiTrans(*counter_trans, *counter_rot);
gas_box_vol->AddNode(gCounter[cType], j, counter_combi_trans);
}
return module;
}
TGeoVolume* create_new_tof_module(Int_t modType)
{
Int_t cType = CounterTypeInModule[modType];
Float_t dx = Module_Size_X[modType];
Float_t dy = Module_Size_Y[modType];
Float_t dz = Module_Size_Z[modType];
Float_t width_aluxl = Module_Thick_Alu_X_left;
Float_t width_aluxr = Module_Thick_Alu_X_right;
Float_t width_aluy = Module_Thick_Alu_Y;
Float_t width_aluz = Module_Thick_Alu_Z;
Float_t shift_gas_box = (Module_Thick_Alu_X_right - Module_Thick_Alu_X_left) / 2;
Float_t dxpos = CounterXDistance[modType];
Float_t startxpos = CounterXStartPosition[modType];
Float_t dypos = CounterYDistance[modType];
Float_t startypos = CounterYStartPosition[modType];
Float_t dzoff = CounterZDistance[modType];
Float_t rotangle = CounterRotationAngle[modType];
TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium);
TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium);
TString moduleName = Form("module_%d", modType);
TGeoBBox* module_box = new TGeoBBox("", dx / 2., dy / 2., dz / 2.);
TGeoVolume* module = new TGeoVolume(moduleName, module_box, boxVolMed);
module->SetLineColor(kGreen); // set line color for the alu box
module->SetTransparency(20); // set transparency for the TOF
TGeoBBox* gas_box =
new TGeoBBox("", (dx - (width_aluxl + width_aluxr)) / 2., (dy - 2 * width_aluy) / 2., (dz - 2 * width_aluz) / 2.);
TGeoVolume* gas_box_vol = new TGeoVolume("gas_box", gas_box, noActiveGasVolMed);
gas_box_vol->SetLineColor(kBlue); // set line color for the alu box
gas_box_vol->SetTransparency(50); // set transparency for the TOF
TGeoTranslation* gas_box_trans = new TGeoTranslation("", shift_gas_box, 0., 0.);
module->AddNode(gas_box_vol, 0, gas_box_trans);
for (Int_t j = 0; j < NCounterInModule[modType]; j++) { //loop over counters (modules)
//for (Int_t j=0; j< 1; j++){ //loop over counters (modules)
Float_t xpos, ypos, zpos;
if (0 == modType || 3 == modType || 4 == modType || 5 == modType) { zpos = dzoff *= -1; }
else {
zpos = CounterZStartPosition[modType] + j * dzoff;
}
//cout << "counter z position " << zpos << endl;
xpos = startxpos + j * dxpos;
ypos = startypos + j * dypos;
TGeoTranslation* counter_trans = new TGeoTranslation("", xpos, ypos, zpos);
TGeoRotation* counter_rot = new TGeoRotation();
counter_rot->RotateY(rotangle);
TGeoCombiTrans* counter_combi_trans = new TGeoCombiTrans(*counter_trans, *counter_rot);
gas_box_vol->AddNode(gCounter[cType], j, counter_combi_trans);
}
return module;
}
TGeoVolume* create_tof_pole()
{
// needed materials
TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium);
TGeoMedium* airVolMed = gGeoMan->GetMedium(KeepingVolumeMedium);
Float_t dx = Pole_Size_X;
Float_t dy = Pole_Size_Y;
Float_t dz = Pole_Size_Z;
Float_t width_alux = Pole_Thick_X;
Float_t width_aluy = Pole_Thick_Y;
Float_t width_aluz = Pole_Thick_Z;
TGeoVolume* pole = new TGeoVolumeAssembly("Pole");
TGeoBBox* pole_alu_box = new TGeoBBox("", dx / 2., dy / 2., dz / 2.);
TGeoVolume* pole_alu_vol = new TGeoVolume("pole_alu", pole_alu_box, boxVolMed);
pole_alu_vol->SetLineColor(kGreen); // set line color for the alu box
pole_alu_vol->SetTransparency(20); // set transparency for the TOF
TGeoTranslation* pole_alu_trans = new TGeoTranslation("", 0., 0., 0.);
pole->AddNode(pole_alu_vol, 0, pole_alu_trans);
Float_t air_dx = dx / 2. - width_alux;
Float_t air_dy = dy / 2. - width_aluy;
Float_t air_dz = dz / 2. - width_aluz;
// cout << "My pole." << endl;
if (air_dx <= 0.) cout << "ERROR - No air volume in pole X, size: " << air_dx << endl;
if (air_dy <= 0.) cout << "ERROR - No air volume in pole Y, size: " << air_dy << endl;
if (air_dz <= 0.) cout << "ERROR - No air volume in pole Z, size: " << air_dz << endl;
if ((air_dx > 0.) && (air_dy > 0.) && (air_dz > 0.)) // crate air volume only, if larger than zero
{
TGeoBBox* pole_air_box = new TGeoBBox("", air_dx, air_dy, air_dz);
// TGeoBBox* pole_air_box = new TGeoBBox("", dx/2.-width_alux, dy/2.-width_aluy, dz/2.-width_aluz);
TGeoVolume* pole_air_vol = new TGeoVolume("pole_air", pole_air_box, airVolMed);
pole_air_vol->SetLineColor(kYellow); // set line color for the alu box
pole_air_vol->SetTransparency(70); // set transparency for the TOF
TGeoTranslation* pole_air_trans = new TGeoTranslation("", 0., 0., 0.);
pole_alu_vol->AddNode(pole_air_vol, 0, pole_air_trans);
}
else
cout << "Skipping pole_air_vol, no thickness: " << air_dx << " " << air_dy << " " << air_dz << endl;
return pole;
}
TGeoVolume* create_tof_bar(Float_t dx, Float_t dy, Float_t dz)
{
// needed materials
TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium);
TGeoMedium* airVolMed = gGeoMan->GetMedium(KeepingVolumeMedium);
Float_t width_alux = Pole_Thick_X;
Float_t width_aluy = Pole_Thick_Y;
Float_t width_aluz = Pole_Thick_Z;
TGeoVolume* bar = new TGeoVolumeAssembly("Bar");
TGeoBBox* bar_alu_box = new TGeoBBox("", dx / 2., dy / 2., dz / 2.);
TGeoVolume* bar_alu_vol = new TGeoVolume("bar_alu", bar_alu_box, boxVolMed);
bar_alu_vol->SetLineColor(kGreen); // set line color for the alu box
bar_alu_vol->SetTransparency(20); // set transparency for the TOF
TGeoTranslation* bar_alu_trans = new TGeoTranslation("", 0., 0., 0.);
bar->AddNode(bar_alu_vol, 0, bar_alu_trans);
TGeoBBox* bar_air_box = new TGeoBBox("", dx / 2. - width_alux, dy / 2. - width_aluy, dz / 2. - width_aluz);
TGeoVolume* bar_air_vol = new TGeoVolume("bar_air", bar_air_box, airVolMed);
bar_air_vol->SetLineColor(kYellow); // set line color for the alu box
bar_air_vol->SetTransparency(70); // set transparency for the TOF
TGeoTranslation* bar_air_trans = new TGeoTranslation("", 0., 0., 0.);
bar_alu_vol->AddNode(bar_air_vol, 0, bar_air_trans);
return bar;
}
void position_tof_poles(Int_t modType)
{
TGeoTranslation* pole_trans = NULL;
Int_t numPoles = 0;
for (Int_t i = 0; i < NumberOfPoles; i++) {
if (i < 2) {
pole_trans = new TGeoTranslation("", -Pole_Offset + 2.0, 0., Pole_ZPos[i]);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gPole, numPoles, pole_trans);
numPoles++;
}
else {
Float_t xPos = Pole_Offset + Pole_Size_X / 2. + Pole_Col[i] * DxColl;
Float_t zPos = Pole_ZPos[i];
pole_trans = new TGeoTranslation("", xPos, 0., zPos);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gPole, numPoles, pole_trans);
numPoles++;
pole_trans = new TGeoTranslation("", -xPos, 0., zPos);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gPole, numPoles, pole_trans);
numPoles++;
}
cout << " Position Pole " << numPoles << " at z=" << Pole_ZPos[i] << endl;
}
}
void position_tof_bars(Int_t modType)
{
TGeoTranslation* bar_trans = NULL;
Int_t numBars = 0;
Int_t i;
Float_t xPos;
Float_t yPos;
Float_t zPos;
for (i = 0; i < NumberOfBars; i++) {
xPos = Bar_XPos[i];
zPos = Bar_ZPos[i];
yPos = Pole_Size_Y / 2. + Bar_Size_Y / 2.;
bar_trans = new TGeoTranslation("", xPos, yPos, zPos);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans);
numBars++;
bar_trans = new TGeoTranslation("", xPos, -yPos, zPos);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans);
numBars++;
bar_trans = new TGeoTranslation("", -xPos, yPos, zPos);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans);
numBars++;
bar_trans = new TGeoTranslation("", -xPos, -yPos, zPos);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans);
numBars++;
}
cout << " Position Bar " << numBars << " at z=" << Bar_ZPos[i] << endl;
// horizontal frame bars
i = NumberOfBars;
NumberOfBars++;
// no bar
// gBar[i]=create_tof_bar(2.*xPos+Pole_Size_X,Bar_Size_Y,Bar_Size_Y);
zPos = Pole_ZPos[0] + Pole_Size_Z / 2.;
bar_trans = new TGeoTranslation("", 0., yPos, zPos);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans);
numBars++;
bar_trans = new TGeoTranslation("", 0., -yPos, zPos);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans);
numBars++;
}
void position_inner_tof_modules(Int_t modNType)
{
TGeoTranslation* module_trans = NULL;
// Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1;
Float_t yPos = Inner_Module_First_Y_Position;
Int_t ii = 0;
Float_t xPos = Inner_Module_X_Offset;
Float_t zPos = Wall_Z_Position;
Pole_ZPos[NumberOfPoles] = zPos;
Pole_Col[NumberOfPoles] = 0;
NumberOfPoles++;
Float_t DzPos = 0.;
for (Int_t j = 0; j < modNType; j++) {
if (Module_Size_Z[j] > DzPos) { DzPos = Module_Size_Z[j]; }
}
Pole_ZPos[NumberOfPoles] = zPos + DzPos;
Pole_Col[NumberOfPoles] = 0;
NumberOfPoles++;
// for (Int_t j=0; j<modNType; j++){
// for (Int_t j=1; j<modNType; j++){
Int_t modType;
Int_t modNum;
for (Int_t j = 2; j < modNType; j++) { // place only M4 type modules (modNType == 2)
//DEDE
modType = Inner_Module_Types[j];
modNum = 0;
// for(Int_t i=0; i<Inner_Module_Number[j]; i++) {
// for(Int_t i=0; i<1; i++) { // place 1x2 modules in the top and same in the bottom
for (Int_t i = 0; i < 2; i++) { // place 2x2 modules in the top and same in the bottom
ii++;
cout << "Inner ii " << ii << " Last " << Last_Size_Y << ", " << Last_Over_Y << endl;
Float_t DeltaY = Module_Size_Y[modType] + Last_Size_Y - 2. * (Module_Over_Y[modType] + Last_Over_Y);
// DeltaY = 1.5;
cout << "DeltaY " << DeltaY << endl;
yPos += DeltaY;
Last_Size_Y = Module_Size_Y[modType];
Last_Over_Y = Module_Over_Y[modType];
cout << "Position Inner Module " << i << " of " << Inner_Module_Number[j] << " Type " << modType
<< " at Y = " << yPos << " Ysize = " << Module_Size_Y[modType] << " DeltaY = " << DeltaY << endl;
/// module_trans = new TGeoTranslation("", xPos, yPos, zPos);
/// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans);
/// modNum++;
/// module_trans = new TGeoTranslation("", xPos, -yPos, zPos);
/// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans);
/// modNum++;
// // if (ii>0) {
// if (ii>1) {
// module_trans
// = new TGeoTranslation("", xPos, yPos-DeltaY/2, zPos+Module_Size_Z[modType]);
// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans);
// modNum++;
// module_trans
// = new TGeoTranslation("", xPos, -(yPos-DeltaY/2), zPos+Module_Size_Z[modType]);
// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans);
// modNum++;
// }
}
}
// module_trans = new TGeoTranslation("", xPos, -49-3, zPos);
// Mar2019 setup
const Int_t NModules = 5;
xPos = 0.;
yPos = 0.;
zPos = TOF_Z_Front;
const Double_t ModDx[NModules] = {0., 0., 1.5, 49.8, 49.8};
//const Double_t ModDx[NModules]= { 1.5, 0., -1.5, 49.8, 55.8};
const Double_t ModDy[NModules] = {0., 0., 0., 0., 0.};
const Double_t ModDz[NModules] = {0., 16.5, 34., 0., 16.5};
const Double_t ModAng[NModules] = {-90., -90., -90., -90., -90.0};
TGeoRotation* module_rot = NULL;
TGeoCombiTrans* module_combi_trans = NULL;
for (Int_t iMod = 0; iMod < NModules; iMod++) {
module_trans = new TGeoTranslation("", xPos + ModDx[iMod], yPos + ModDy[iMod], zPos + ModDz[iMod]);
module_rot = new TGeoRotation();
module_rot->RotateZ(ModAng[iMod]);
module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans);
modNum++;
}
/*
module_trans = new TGeoTranslation("", xPos, 0, zPos+16.5);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans);
modNum++;
// module_trans = new TGeoTranslation("", xPos, 49+3, zPos);
module_trans = new TGeoTranslation("", xPos, 0, zPos+16.5+17.5);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans);
modNum++;
// module_trans = new TGeoTranslation("", xPos,-26, zPos+Module_Size_Z[modType]);
module_trans = new TGeoTranslation("", xPos, -49.8, zPos);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans);
modNum++;
// module_trans = new TGeoTranslation("", xPos, 26, zPos+Module_Size_Z[modType]);
module_trans = new TGeoTranslation("", xPos, -49.8, zPos+16.5);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans);
modNum++;
*/
}
void position_Dia(Int_t modNType)
{
TGeoTranslation* module_trans = NULL;
TGeoRotation* module_rot = new TGeoRotation();
module_rot->RotateZ(Dia_rotate_Z);
TGeoCombiTrans* module_combi_trans = NULL;
// Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1;
Float_t yPos = Dia_First_Y_Position;
Int_t ii = 0;
Float_t xPos = Dia_X_Offset;
Float_t zPos = Dia_Z_Position;
Int_t modNum = 0;
for (Int_t j = 0; j < modNType; j++) {
Int_t modType = Dia_Types[j];
for (Int_t i = 0; i < Dia_Number[j]; i++) {
ii++;
module_trans = new TGeoTranslation("", xPos, yPos, zPos);
module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans);
modNum++;
}
}
}
void position_Star2(Int_t modNType)
{
TGeoTranslation* module_trans = NULL;
TGeoRotation* module_rot = new TGeoRotation();
module_rot->RotateZ(Star2_rotate_Z);
TGeoCombiTrans* module_combi_trans = NULL;
Float_t yPos = Star2_First_Y_Position;
Float_t zPos = Star2_First_Z_Position;
Int_t ii = 0;
Int_t modNum = 0;
for (Int_t j = 0; j < modNType; j++) {
Int_t modType = Star2_Types[j];
Float_t xPos = Star2_X_Offset[j];
for (Int_t i = 0; i < Star2_Number[j]; i++) {
ii++;
module_trans = new TGeoTranslation("", xPos, yPos, zPos);
module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans);
modNum++;
yPos += Star2_Delta_Y_Position;
zPos += Star2_Delta_Z_Position;
}
}
}
void position_Buc(Int_t modNType)
{
TGeoTranslation* module_trans = NULL;
TGeoRotation* module_rot = new TGeoRotation();
module_rot->RotateZ(Buc_rotate_Z);
TGeoCombiTrans* module_combi_trans = NULL;
Float_t yPos = Buc_First_Y_Position;
Float_t zPos = Buc_First_Z_Position;
Int_t ii = 0;
Int_t modNum = 0;
for (Int_t j = 0; j < modNType; j++) {
Int_t modType = Buc_Types[j];
Float_t xPos = Buc_X_Offset[j];
for (Int_t i = 0; i < Buc_Number[j]; i++) {
ii++;
module_trans = new TGeoTranslation("", xPos, yPos, zPos);
module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans);
modNum++;
yPos += Buc_Delta_Y_Position;
zPos += Buc_Delta_Z_Position;
}
}
}
void position_cer_modules(Int_t modNType)
{
Int_t ii = 0;
Int_t modNum = 0;
for (Int_t j = 1; j < modNType; j++) {
Int_t modType = Cer_Types[j];
Float_t xPos = Cer_X_Position[j];
Float_t yPos = Cer_Y_Position[j];
Float_t zPos = Cer_Z_Position[j];
TGeoTranslation* module_trans = NULL;
TGeoRotation* module_rot = new TGeoRotation(Form("Cer%d", j), Cer_rotate_Z[j], -MeanTheta, 0.);
// module_rot->RotateZ(Cer_rotate_Z[j]);
TGeoCombiTrans* module_combi_trans = NULL;
for (Int_t i = 0; i < Cer_Number[j]; i++) {
ii++;
cout << "Position Ceramic Module " << i << " of " << Cer_Number[j] << " Type " << modType << " at X = " << xPos
<< ", Y = " << yPos << ", Z = " << zPos << endl;
// Front staggered module (Top if pair), top
module_trans = new TGeoTranslation("", xPos, yPos, zPos);
module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans);
// modNum++;
}
}
}
void position_CERN(Int_t modNType)
{
TGeoTranslation* module_trans = NULL;
TGeoRotation* module_rot = new TGeoRotation();
module_rot->RotateZ(CERN_rotate_Z);
TGeoCombiTrans* module_combi_trans = NULL;
// Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1;
Float_t yPos = CERN_First_Y_Position;
Int_t ii = 0;
Float_t xPos = CERN_X_Offset;
Float_t zPos = CERN_Z_Position;
for (Int_t j = 0; j < modNType; j++) {
Int_t modType = CERN_Types[j];
Int_t modNum = 0;
for (Int_t i = 0; i < CERN_Number[j]; i++) {
ii++;
module_trans = new TGeoTranslation("", xPos, yPos, zPos);
module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans);
modNum++;
}
}
}
void position_side_tof_modules(Int_t modNType)
{
TGeoTranslation* module_trans = NULL;
TGeoRotation* module_rot = new TGeoRotation();
module_rot->RotateZ(180.);
TGeoCombiTrans* module_combi_trans = NULL;
// Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1;
Float_t yPos = 0.; //Inner_Module_First_Y_Position;
Int_t ii = 0;
for (Int_t j = 0; j < modNType; j++) {
Int_t modType = InnerSide_Module_Types[j];
Int_t modNum = 0;
for (Int_t i = 0; i < InnerSide_Module_Number[j]; i++) {
ii++;
cout << "InnerSide ii " << ii << " Last " << Last_Size_Y << "," << Last_Over_Y << endl;
Float_t DeltaY = Module_Size_Y[modType] + Last_Size_Y - 2. * (Module_Over_Y[modType] + Last_Over_Y);
if (ii > 1) { yPos += DeltaY; }
Last_Size_Y = Module_Size_Y[modType];
Last_Over_Y = Module_Over_Y[modType];
Float_t xPos = InnerSide_Module_X_Offset;
Float_t zPos = Wall_Z_Position;
cout << "Position InnerSide Module " << i << " of " << InnerSide_Module_Number[j] << " Type " << modType
<< " at Y = " << yPos << " Ysize = " << Module_Size_Y[modType] << " DeltaY = " << DeltaY << endl;
module_trans = new TGeoTranslation("", xPos, yPos, zPos);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans);
modNum++;
module_trans = new TGeoTranslation("", -xPos, yPos, zPos);
module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans);
modNum++;
if (ii > 1) {
module_trans = new TGeoTranslation("", xPos, -yPos, zPos);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans);
modNum++;
module_trans = new TGeoTranslation("", -xPos, -yPos, zPos);
module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans);
modNum++;
module_trans = new TGeoTranslation("", xPos, yPos - DeltaY / 2, zPos + Module_Size_Z[modType]);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans);
modNum++;
module_trans = new TGeoTranslation("", -xPos, yPos - DeltaY / 2, zPos + Module_Size_Z[modType]);
module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans);
modNum++;
module_trans = new TGeoTranslation("", xPos, -(yPos - DeltaY / 2), zPos + Module_Size_Z[modType]);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans);
modNum++;
module_trans = new TGeoTranslation("", -xPos, -(yPos - DeltaY / 2), zPos + Module_Size_Z[modType]);
module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans);
modNum++;
}
}
}
}
void position_outer_tof_modules(Int_t nCol) //modType, Int_t col1, Int_t col2)
{
TGeoTranslation* module_trans = NULL;
TGeoRotation* module_rot = new TGeoRotation();
module_rot->RotateZ(180.);
TGeoCombiTrans* module_combi_trans = NULL;
// Int_t numModules=(Int_t)( (Outer_Module_Last_Y_Position-Outer_Module_First_Y_Position)/Module_Size_Y[modType])+1;
Int_t modNum[NofModuleTypes];
for (Int_t k = 0; k < NofModuleTypes; k++) {
modNum[k] = 0;
}
Float_t zPos = Wall_Z_Position;
for (Int_t j = 0; j < nCol; j++) {
Float_t xPos = Outer_Module_X_Offset + ((j + 1) * DxColl);
Last_Size_Y = 0.;
Last_Over_Y = 0.;
Float_t yPos = 0.;
Int_t ii = 0;
Float_t DzPos = 0.;
for (Int_t k = 0; k < Outer_Module_NTypes; k++) {
Int_t modType = Outer_Module_Types[k][j];
if (Module_Size_Z[modType] > DzPos) {
if (Outer_Module_Number[k][j] > 0) { DzPos = Module_Size_Z[modType]; }
}
}
zPos -= 2. * DzPos; //((j+1)*2*Module_Size_Z[modType]);
Pole_ZPos[NumberOfPoles] = zPos;
Pole_Col[NumberOfPoles] = j + 1;
NumberOfPoles++;
Pole_ZPos[NumberOfPoles] = zPos + DzPos;
Pole_Col[NumberOfPoles] = j + 1;
NumberOfPoles++;
//if (j+1==nCol) {
if (1) {
Pole_ZPos[NumberOfPoles] = Pole_ZPos[0];
Pole_Col[NumberOfPoles] = j + 1;
NumberOfPoles++;
Bar_Size_Z = Pole_ZPos[0] - zPos;
gBar[NumberOfBars] = create_tof_bar(Bar_Size_X, Bar_Size_Y, Bar_Size_Z);
Bar_ZPos[NumberOfBars] = zPos + Bar_Size_Z / 2. - Pole_Size_Z / 2.;
Bar_XPos[NumberOfBars] = xPos + Pole_Offset;
NumberOfBars++;
}
for (Int_t k = 0; k < Outer_Module_NTypes; k++) {
Int_t modType = Outer_Module_Types[k][j];
Int_t numModules = Outer_Module_Number[k][j];
cout << " Outer: position " << numModules << " of type " << modType << " in col " << j << " at z = " << zPos
<< ", DzPos = " << DzPos << endl;
for (Int_t i = 0; i < numModules; i++) {
ii++;
cout << "Outer ii " << ii << " Last " << Last_Size_Y << "," << Last_Over_Y << endl;
Float_t DeltaY = Module_Size_Y[modType] + Last_Size_Y - 2. * (Module_Over_Y[modType] + Last_Over_Y);
if (ii > 1) { yPos += DeltaY; }
Last_Size_Y = Module_Size_Y[modType];
Last_Over_Y = Module_Over_Y[modType];
cout << "Position Outer Module " << i << " of " << Outer_Module_Number[k][j] << " Type " << modType << "(#"
<< modNum[modType] << ") "
<< " at Y = " << yPos << " Ysize = " << Module_Size_Y[modType] << " DeltaY = " << DeltaY << endl;
module_trans = new TGeoTranslation("", xPos, yPos, zPos);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans);
modNum[modType]++;
module_trans = new TGeoTranslation("", -xPos, yPos, zPos);
module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans);
modNum[modType]++;
if (ii > 1) {
module_trans = new TGeoTranslation("", xPos, -yPos, zPos);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans);
modNum[modType]++;
module_trans = new TGeoTranslation("", -xPos, -yPos, zPos);
module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans);
modNum[modType]++;
// second layer
module_trans = new TGeoTranslation("", xPos, yPos - DeltaY / 2., zPos + DzPos);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans);
modNum[modType]++;
module_trans = new TGeoTranslation("", -xPos, yPos - DeltaY / 2., zPos + DzPos);
module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans);
modNum[modType]++;
module_trans = new TGeoTranslation("", xPos, -(yPos - DeltaY / 2.), zPos + DzPos);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans);
modNum[modType]++;
module_trans = new TGeoTranslation("", -xPos, -(yPos - DeltaY / 2.), zPos + DzPos);
module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot);
gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans);
modNum[modType]++;
}
}
}
}
}
void dump_info_file()
{
TDatime datetime; // used to get timestamp
printf("writing info file: %s\n", FileNameInfo.Data());
FILE* ifile;
ifile = fopen(FileNameInfo.Data(), "w");
if (ifile == NULL) {
printf("error opening %s\n", FileNameInfo.Data());
exit(1);
}
fprintf(ifile, "#\n## %s information file\n#\n\n", geoVersion.Data());
fprintf(ifile, "# created %d\n\n", datetime.GetDate());
fprintf(ifile, "# TOF setup\n");
if (TOF_Z_Front == 450) fprintf(ifile, "SIS 100 hadron setup\n");
if (TOF_Z_Front == 600) fprintf(ifile, "SIS 100 electron\n");
if (TOF_Z_Front == 650) fprintf(ifile, "SIS 100 muon\n");
if (TOF_Z_Front == 880) fprintf(ifile, "SIS 300 electron\n");
if (TOF_Z_Front == 1020) fprintf(ifile, "SIS 300 muon\n");
fprintf(ifile, "\n");
const Float_t TOF_Z_Back = Wall_Z_Position + 1.5 * Module_Size_Z[0]; // back of TOF wall
fprintf(ifile, "# envelope\n");
// Show extension of TRD
fprintf(ifile, "%7.2f cm start of TOF (z)\n", TOF_Z_Front);
fprintf(ifile, "%7.2f cm end of TOF (z)\n", TOF_Z_Back);
fprintf(ifile, "\n");
// Layer thickness
fprintf(ifile, "# central tower position\n");
fprintf(ifile, "%7.2f cm center of staggered, front RPC cell at x=0\n", Wall_Z_Position);
fprintf(ifile, "\n");
fclose(ifile);
}
Geometries for mCBM
=========================================
# 1. Geometry macros
The geometry macros moved to the following folder:
geometry/<subsystem>/mcbm
/* Copyright (C) 2013-2017 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Volker Friese, David Emschermann [committer] */
/******************************************************************************
** Creation of beam pipe geometry in ROOT format (TGeo).
**
** @file create_pipegeo_v16.C
** @author Volker Friese <v.friese@gsi.de>
** @date 11.10.2013
**
** The beam pipe is composed of carbon with a thickness of 0.5 mm. It is
** placed directly into the cave as mother volume.
** The pipe consists of a number of parts. Each part has a PCON
** shape. The beam pipe inside the RICH is part of the RICH geometry;
** the beam pipe geometry thus excludes the z range of the RICH in case
** the latter is present in the setup.
*****************************************************************************/
#include "TGeoManager.h"
#include <iomanip>
#include <iostream>
using namespace std;
// ------------- Other global variables -----------------------------------
// ---> TGeoManager (too lazy to write out 'Manager' all the time
TGeoManager* gGeoMan = NULL; // will be set later
// ----------------------------------------------------------------------------
// ============================================================================
// ====== Main function =====
// ============================================================================
void create_platform_v18a()
{
// ----- Define platform parts ----------------------------------------------
/** For v18a (mCBM) **/
TString geoTag = "v18a_mcbm";
// Double_t platform_angle = 25.; // rotation angle around y-axis
Double_t platform_angle = 19.; // rotation angle around y-axis
Double_t platX_offset = -230.; // offset to the right side along x-axis
Double_t sizeX = 80.0; // symmetric in x
Double_t sizeY = 200.0; // without rails
Double_t sizeZ = 500.0; // short version
// Double_t endZ = 450.0; // ends at z = 450.0
// /** For v16b (SIS 300) **/
// TString geoTag = "v16b";
// Double_t sizeX = 725.0; // symmetric in x
// Double_t sizeY = 234.0; // without rails
// Double_t sizeZ = 455.0; // long version
// Double_t endZ = 540.0; // ends at z = 450.0
// Double_t beamY = 570.0; // nominal beam height
Double_t beamY = 100.0; // nominal beam height
Double_t posX = -sizeX / 2.;
Double_t posY = -beamY + sizeY / 2.; // rest on the floor at -beamY
Double_t posZ = +sizeZ / 2.;
// --------------------------------------------------------------------------
// ------- Geometry file name (output) ----------------------------------
TString geoFileName = "platform_";
geoFileName = geoFileName + geoTag + ".geo.root";
// --------------------------------------------------------------------------
// ------- Open info file -----------------------------------------------
TString infoFileName = geoFileName;
infoFileName.ReplaceAll("root", "info");
fstream infoFile;
infoFile.open(infoFileName.Data(), fstream::out);
infoFile << "Platform geometry created with create_platform_v16.C" << std::endl << std::endl;
// --------------------------------------------------------------------------
// ------- Load media from media file -----------------------------------
FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
TString geoPath = gSystem->Getenv("VMCWORKDIR");
TString medFile = geoPath + "/geometry/media.geo";
geoFace->setMediaFile(medFile);
geoFace->readMedia();
gGeoMan = gGeoManager;
// --------------------------------------------------------------------------
// ----------------- Get and create the required media -----------------
FairGeoMedia* geoMedia = geoFace->getMedia();
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
// ---> aluminium
FairGeoMedium* mAluminium = geoMedia->getMedium("aluminium");
if (!mAluminium) Fatal("Main", "FairMedium aluminium not found");
geoBuild->createMedium(mAluminium);
TGeoMedium* aluminium = gGeoMan->GetMedium("aluminium");
if (!aluminium) Fatal("Main", "Medium aluminium not found");
// // ---> air
// FairGeoMedium* mAir = geoMedia->getMedium("air");
// if ( ! mAir ) Fatal("Main", "FairMedium air not found");
// geoBuild->createMedium(mAir);
// TGeoMedium* air = gGeoMan->GetMedium("air");
// if ( ! air ) Fatal("Main", "Medium air not found");
// --------------------------------------------------------------------------
// -------------- Create geometry and top volume -------------------------
gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom");
gGeoMan->SetName("PLATFORMgeom");
TGeoVolume* top = new TGeoVolumeAssembly("top");
gGeoMan->SetTopVolume(top);
TString platformName = "platform_";
platformName += geoTag;
TGeoVolume* platform = new TGeoVolumeAssembly(platformName.Data());
// --------------------------------------------------------------------------
// ----- Create ---------------------------------------------------------
TGeoBBox* platform_base = new TGeoBBox("", sizeX / 2., sizeY / 2., sizeZ / 2.);
TGeoVolume* platform_vol = new TGeoVolume("platform", platform_base, aluminium);
platform_vol->SetLineColor(kBlue);
platform_vol->SetTransparency(70);
TGeoTranslation* platform_trans = new TGeoTranslation("", posX, posY, posZ);
platform->AddNode(platform_vol, 1, platform_trans);
infoFile << "sizeX: " << setprecision(2) << sizeX << "sizeY: " << setprecision(2) << sizeY
<< "sizeZ: " << setprecision(2) << sizeZ << endl;
infoFile << "posX : " << setprecision(2) << posX << "posY : " << setprecision(2) << posY
<< "posZ : " << setprecision(2) << posZ << endl;
// --------------- Finish -----------------------------------------------
top->AddNode(platform, 1);
cout << endl << endl;
gGeoMan->CloseGeometry();
gGeoMan->CheckOverlaps(0.001);
gGeoMan->PrintOverlaps();
gGeoMan->Test();
platform->Export(geoFileName); // an alternative way of writing the platform volume
TFile* geoFile = new TFile(geoFileName, "UPDATE");
// rotate the platform around y
TGeoRotation* platform_rotation = new TGeoRotation();
platform_rotation->RotateY(platform_angle);
// TGeoCombiTrans* platform_placement = new TGeoCombiTrans( sin( platform_angle/180.*acos(-1) ) * z1[1]/2., 0., 0., platform_rotation);
TGeoCombiTrans* platform_placement = new TGeoCombiTrans("platform_rot", platX_offset, 0., 0, platform_rotation);
// TGeoTranslation* platform_placement = new TGeoTranslation("platform_trans", 0., 0., 0.);
platform_placement->Write();
geoFile->Close();
cout << endl;
cout << "Geometry " << top->GetName() << " written to " << geoFileName << endl;
top->Draw("ogl");
infoFile.close();
}
// ============================================================================
// ====== End of main function =====
// ============================================================================
/* Copyright (C) 2013-2017 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Volker Friese, David Emschermann [committer] */
/******************************************************************************
** Creation of beam pipe geometry in ROOT format (TGeo).
**
** @file create_pipegeo_v16.C
** @author Volker Friese <v.friese@gsi.de>
** @date 11.10.2013
**
** The beam pipe is composed of carbon with a thickness of 0.5 mm. It is
** placed directly into the cave as mother volume.
** The pipe consists of a number of parts. Each part has a PCON
** shape. The beam pipe inside the RICH is part of the RICH geometry;
** the beam pipe geometry thus excludes the z range of the RICH in case
** the latter is present in the setup.
*****************************************************************************/
#include "TGeoManager.h"
#include <iomanip>
#include <iostream>
using namespace std;
// ------------- Other global variables -----------------------------------
// ---> TGeoManager (too lazy to write out 'Manager' all the time
TGeoManager* gGeoMan = NULL; // will be set later
// ----------------------------------------------------------------------------
// ============================================================================
// ====== Main function =====
// ============================================================================
void create_platform_v18c()
{
// ----- Define platform parts ----------------------------------------------
/** For v18c (mCBM) **/
TString geoTag = "v18c_mcbm";
// Double_t platform_angle = 25.; // rotation angle around y-axis
// Double_t platform_angle = 19.; // rotation angle around y-axis
Double_t platform_angle = 0.; // rotation angle around y-axis
// Double_t platX_offset = -230.; // offset to the right side along x-axis
Double_t platX_offset = 0.; // offset to the right side along x-axis
Double_t sizeX = 80.0; // table width
Double_t sizeY = 80.0; // table height
Double_t sizeZ = 400.0; // table length
// Double_t endZ = 450.0; // ends at z = 450.0
// /** For v16b (SIS 300) **/
// TString geoTag = "v16b";
// Double_t sizeX = 725.0; // symmetric in x
// Double_t sizeY = 234.0; // without rails
// Double_t sizeZ = 455.0; // long version
// Double_t endZ = 540.0; // ends at z = 450.0
// Double_t beamY = 570.0; // nominal beam height
Double_t beamY = 200.0; // nominal beam height
Double_t posX = 0;
Double_t posY = -beamY + sizeY / 2.; // rest on the floor at -beamY
Double_t posZ = +sizeZ / 2.;
// --------------------------------------------------------------------------
// ------- Geometry file name (output) ----------------------------------
TString geoFileName = "platform_";
geoFileName = geoFileName + geoTag + ".geo.root";
// --------------------------------------------------------------------------
// ------- Open info file -----------------------------------------------
TString infoFileName = geoFileName;
infoFileName.ReplaceAll("root", "info");
fstream infoFile;
infoFile.open(infoFileName.Data(), fstream::out);
infoFile << "Platform geometry created with create_platform_v16.C" << std::endl << std::endl;
// --------------------------------------------------------------------------
// ------- Load media from media file -----------------------------------
FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
TString geoPath = gSystem->Getenv("VMCWORKDIR");
TString medFile = geoPath + "/geometry/media.geo";
geoFace->setMediaFile(medFile);
geoFace->readMedia();
gGeoMan = gGeoManager;
// --------------------------------------------------------------------------
// ----------------- Get and create the required media -----------------
FairGeoMedia* geoMedia = geoFace->getMedia();
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
// // ---> aluminium
// FairGeoMedium* mAluminium = geoMedia->getMedium("aluminium");
// if ( ! mAluminium ) Fatal("Main", "FairMedium aluminium not found");
// geoBuild->createMedium(mAluminium);
// TGeoMedium* aluminium = gGeoMan->GetMedium("aluminium");
// if ( ! aluminium ) Fatal("Main", "Medium aluminium not found");
// ---> air
FairGeoMedium* mAir = geoMedia->getMedium("air");
if (!mAir) Fatal("Main", "FairMedium air not found");
geoBuild->createMedium(mAir);
TGeoMedium* air = gGeoMan->GetMedium("air");
if (!air) Fatal("Main", "Medium air not found");
// --------------------------------------------------------------------------
// -------------- Create geometry and top volume -------------------------
gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom");
gGeoMan->SetName("PLATFORMgeom");
TGeoVolume* top = new TGeoVolumeAssembly("top");
gGeoMan->SetTopVolume(top);
TString platformName = "platform_";
platformName += geoTag;
TGeoVolume* platform = new TGeoVolumeAssembly(platformName.Data());
// --------------------------------------------------------------------------
// ----- Create ---------------------------------------------------------
TGeoBBox* platform_base = new TGeoBBox("", sizeX / 2., sizeY / 2., sizeZ / 2.);
TGeoVolume* platform_vol = new TGeoVolume("platform", platform_base, air);
platform_vol->SetLineColor(kBlue);
platform_vol->SetTransparency(70);
TGeoTranslation* platform_trans = new TGeoTranslation("", posX, posY, posZ);
platform->AddNode(platform_vol, 1, platform_trans);
infoFile << "sizeX: " << setprecision(2) << sizeX << "sizeY: " << setprecision(2) << sizeY
<< "sizeZ: " << setprecision(2) << sizeZ << endl;
infoFile << "posX : " << setprecision(2) << posX << "posY : " << setprecision(2) << posY
<< "posZ : " << setprecision(2) << posZ << endl;
// --------------- Finish -----------------------------------------------
top->AddNode(platform, 1);
cout << endl << endl;
gGeoMan->CloseGeometry();
gGeoMan->CheckOverlaps(0.001);
gGeoMan->PrintOverlaps();
gGeoMan->Test();
platform->Export(geoFileName); // an alternative way of writing the platform volume
TFile* geoFile = new TFile(geoFileName, "UPDATE");
// rotate the platform around y
TGeoRotation* platform_rotation = new TGeoRotation();
platform_rotation->RotateY(platform_angle);
// TGeoCombiTrans* platform_placement = new TGeoCombiTrans( sin( platform_angle/180.*acos(-1) ) * z1[1]/2., 0., 0., platform_rotation);
TGeoCombiTrans* platform_placement = new TGeoCombiTrans("platform_rot", platX_offset, 0., 0, platform_rotation);
// TGeoTranslation* platform_placement = new TGeoTranslation("platform_trans", 0., 0., 0.);
platform_placement->Write();
geoFile->Close();
cout << endl;
cout << "Geometry " << top->GetName() << " written to " << geoFileName << endl;
top->Draw("ogl");
infoFile.close();
}
// ============================================================================
// ====== End of main function =====
// ============================================================================
/* Copyright (C) 2013-2018 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Volker Friese, David Emschermann [committer] */
/******************************************************************************
** Creation of beam pipe geometry in ROOT format (TGeo).
**
** @file create_pipegeo_v16.C
** @author Volker Friese <v.friese@gsi.de>
** @date 11.10.2013
**
** The beam pipe is composed of carbon with a thickness of 0.5 mm. It is
** placed directly into the cave as mother volume.
** The pipe consists of a number of parts. Each part has a PCON
** shape. The beam pipe inside the RICH is part of the RICH geometry;
** the beam pipe geometry thus excludes the z range of the RICH in case
** the latter is present in the setup.
*****************************************************************************/
// 2018.08.23 - DE - shorten the table length from 400 cm to 250 cm
#include "TGeoManager.h"
#include <iomanip>
#include <iostream>
using namespace std;
// ------------- Other global variables -----------------------------------
// ---> TGeoManager (too lazy to write out 'Manager' all the time
TGeoManager* gGeoMan = NULL; // will be set later
// ----------------------------------------------------------------------------
// ============================================================================
// ====== Main function =====
// ============================================================================
void create_platform_v18d()
{
// ----- Define platform parts ----------------------------------------------
/** For v18d (mCBM) **/
TString geoTag = "v18d_mcbm";
// Double_t platform_angle = 25.; // rotation angle around y-axis
// Double_t platform_angle = 19.; // rotation angle around y-axis
Double_t platform_angle = 0.; // rotation angle around y-axis
// Double_t platX_offset = -230.; // offset to the right side along x-axis
Double_t platX_offset = 0.; // offset to the right side along x-axis
Double_t sizeX = 80.0; // table width
Double_t sizeY = 80.0; // table height
Double_t sizeZ = 250.0; // table length
// Double_t endZ = 450.0; // ends at z = 450.0
// /** For v16b (SIS 300) **/
// TString geoTag = "v16b";
// Double_t sizeX = 725.0; // symmetric in x
// Double_t sizeY = 234.0; // without rails
// Double_t sizeZ = 455.0; // long version
// Double_t endZ = 540.0; // ends at z = 450.0
// Double_t beamY = 570.0; // nominal beam height
Double_t beamY = 200.0; // nominal beam height
Double_t posX = 0;
Double_t posY = -beamY + sizeY / 2.; // rest on the floor at -beamY
Double_t posZ = +sizeZ / 2.;
// --------------------------------------------------------------------------
// ------- Geometry file name (output) ----------------------------------
TString geoFileName = "platform_";
geoFileName = geoFileName + geoTag + ".geo.root";
// --------------------------------------------------------------------------
// ------- Open info file -----------------------------------------------
TString infoFileName = geoFileName;
infoFileName.ReplaceAll("root", "info");
fstream infoFile;
infoFile.open(infoFileName.Data(), fstream::out);
infoFile << "Platform geometry created with create_platform_v16.C" << std::endl << std::endl;
// --------------------------------------------------------------------------
// ------- Load media from media file -----------------------------------
FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
TString geoPath = gSystem->Getenv("VMCWORKDIR");
TString medFile = geoPath + "/geometry/media.geo";
geoFace->setMediaFile(medFile);
geoFace->readMedia();
gGeoMan = gGeoManager;
// --------------------------------------------------------------------------
// ----------------- Get and create the required media -----------------
FairGeoMedia* geoMedia = geoFace->getMedia();
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
// // ---> aluminium
// FairGeoMedium* mAluminium = geoMedia->getMedium("aluminium");
// if ( ! mAluminium ) Fatal("Main", "FairMedium aluminium not found");
// geoBuild->createMedium(mAluminium);
// TGeoMedium* aluminium = gGeoMan->GetMedium("aluminium");
// if ( ! aluminium ) Fatal("Main", "Medium aluminium not found");
// ---> air
FairGeoMedium* mAir = geoMedia->getMedium("air");
if (!mAir) Fatal("Main", "FairMedium air not found");
geoBuild->createMedium(mAir);
TGeoMedium* air = gGeoMan->GetMedium("air");
if (!air) Fatal("Main", "Medium air not found");
// --------------------------------------------------------------------------
// -------------- Create geometry and top volume -------------------------
gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom");
gGeoMan->SetName("PLATFORMgeom");
TGeoVolume* top = new TGeoVolumeAssembly("top");
gGeoMan->SetTopVolume(top);
TString platformName = "platform_";
platformName += geoTag;
TGeoVolume* platform = new TGeoVolumeAssembly(platformName.Data());
// --------------------------------------------------------------------------
// ----- Create ---------------------------------------------------------
TGeoBBox* platform_base = new TGeoBBox("", sizeX / 2., sizeY / 2., sizeZ / 2.);
TGeoVolume* platform_vol = new TGeoVolume("platform", platform_base, air);
platform_vol->SetLineColor(kBlue);
platform_vol->SetTransparency(70);
TGeoTranslation* platform_trans = new TGeoTranslation("", posX, posY, posZ);
platform->AddNode(platform_vol, 1, platform_trans);
infoFile << "sizeX: " << setprecision(2) << sizeX << "sizeY: " << setprecision(2) << sizeY
<< "sizeZ: " << setprecision(2) << sizeZ << endl;
infoFile << "posX : " << setprecision(2) << posX << "posY : " << setprecision(2) << posY
<< "posZ : " << setprecision(2) << posZ << endl;
// --------------- Finish -----------------------------------------------
top->AddNode(platform, 1);
cout << endl << endl;
gGeoMan->CloseGeometry();
gGeoMan->CheckOverlaps(0.001);
gGeoMan->PrintOverlaps();
gGeoMan->Test();
platform->Export(geoFileName); // an alternative way of writing the platform volume
TFile* geoFile = new TFile(geoFileName, "UPDATE");
// rotate the platform around y
TGeoRotation* platform_rotation = new TGeoRotation();
platform_rotation->RotateY(platform_angle);
// TGeoCombiTrans* platform_placement = new TGeoCombiTrans( sin( platform_angle/180.*acos(-1) ) * z1[1]/2., 0., 0., platform_rotation);
TGeoCombiTrans* platform_placement = new TGeoCombiTrans("platform_rot", platX_offset, 0., 0, platform_rotation);
// TGeoTranslation* platform_placement = new TGeoTranslation("platform_trans", 0., 0., 0.);
platform_placement->Write();
geoFile->Close();
cout << endl;
cout << "Geometry " << top->GetName() << " written to " << geoFileName << endl;
top->Draw("ogl");
infoFile.close();
}
// ============================================================================
// ====== End of main function =====
// ============================================================================
/* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: David Emschermann [committer] */
//
/// \file create_MUCH_geometry_v18b.C
/// \brief Generates MUCH geometry in Root format.
///
// 2017-09-04 - PPB - mcbm - preliminary version of mini much geometry
// 2017-05-16 - DE - v17b - position the modules in a way to split layers left-right along y axis
// 2017-05-16 - DE - v17b - attribute name to module frames
// 2017-05-16 - DE - v17b - remove rim from support CompositeShape
// 2017-05-02 - PPB - v17a - Change the shape of the first absorber according to latest design
// 2017-04-27 - DE - v17a - fix GEM module positions and angles
// 2017-04-22 - PPB - v17a - Define the absorber, shield and station shapes sizes ...
// 2016-04-19 - DE - v17a - initial version derived from TRD
// in root all sizes are given in cm
#include "TClonesArray.h"
#include "TDatime.h"
#include "TFile.h"
#include "TGeoBBox.h"
#include "TGeoCompositeShape.h"
#include "TGeoCone.h"
#include "TGeoManager.h"
#include "TGeoMaterial.h"
#include "TGeoMatrix.h"
#include "TGeoMedium.h"
#include "TGeoPgon.h"
#include "TGeoTube.h"
#include "TGeoVolume.h"
#include "TGeoXtru.h"
#include "TList.h"
#include "TMath.h"
#include "TObjArray.h"
#include "TRandom3.h"
#include "TString.h"
#include "TSystem.h"
#include <cassert>
#include <fstream>
#include <iostream>
#include <stdexcept>
// Name of output file with geometry
const TString tagVersion = "v18b";
const TString geoVersion = "much_" + tagVersion;
//const TString subVersion = "_3oclock";
//const TString geoVersion = "much_" + tagVersion + subVersion;
const TString FileNameSim = geoVersion + "_mcbm.geo.root";
const TString FileNameGeo = geoVersion + "_mcbm_geo.root";
const TString FileNameInfo = geoVersion + "_mcbm.geo.info";
// Names of the different used materials which are used to build the modules
// The materials are defined in the global media.geo file
const TString KeepingVolumeMedium = "air";
const TString L = "MUCHlead";
const TString W = "MUCHwolfram";
const TString C = "MUCHcarbon";
const TString I = "MUCHiron";
const TString activemedium = "MUCHargon";
const TString spacermedium = "MUCHnoryl";
const TString coolmedium = "aluminium"; //Al cooling plates
// Universal input parameters
// The inner angle is 11 degree (polar angle); We take z = 70 cm;
//Inner radius: R_in=z*tan(theta_min) cm
// Outer angle is decided from tan(theta_max)=R_out/z
// R_out=R_in+95 cm (transverse size of the M2 module)
Double_t fMuchZ1 = 0.0; // MuchCave Zin position [cm]
Double_t fAcceptanceTanMin = 0.19; // Acceptance tangent min (11 degree)
//************************************************************
// Input parameters for MUCH stations
//********************************************
const Int_t fNst = 1; // Number of stations
// Sector-type module parameters
// Number of sectors per layer (should be even for symmetry)
// Needs to be fixed with actual numbers
Double_t fActiveLzSector = 0.3; // Active volume thickness [cm]
Double_t fSpacerR = 2.5; // Spacer width in R [cm]
Double_t fSpacerPhi = 2.5; // Spacer width in Phi [cm]
Double_t fOverlapR = 0.0; // Overlap in R direction [cm]
// Station Zceneter [cm] in the cave reference frame
Double_t fStationZ0 = 80;
Int_t fNlayers = 3; // Number of layers
Double_t fLayersDz = 10; // distance between the layers
Double_t fCoolLz = 1.0; // thickness of the cooling plate also used as support
/*
1 - detailed design (modules at two sides)
* 0 - simple design (1 module per layer)
*/
//***********************************************************
// some global variables
TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance
TGeoVolume* gModules_station[fNst]; // Global storage for module types
// Forward declarations
void create_materials_from_media_file();
TGeoVolume* CreateStations(int ist);
TGeoVolume* CreateLayers(int istn, int ily);
void create_MUCH_geometry_v18b()
{
// Load needed material definition from media.geo file
create_materials_from_media_file();
// Get the GeoManager for later usage
gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom");
gGeoMan->SetVisLevel(10);
// Create the top volume
TGeoBBox* topbox = new TGeoBBox("", 1000., 1000., 2000.);
TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air"));
gGeoMan->SetTopVolume(top);
TGeoVolume* much = new TGeoVolumeAssembly(geoVersion);
top->AddNode(much, 1);
TGeoVolume* sttn = new TGeoVolumeAssembly("Station");
much->AddNode(sttn, 1);
for (Int_t istn = 0; istn < 1; istn++) { // 1 Station
gModules_station[istn] = CreateStations(istn);
sttn->AddNode(gModules_station[istn], istn);
}
gGeoMan->CloseGeometry();
gGeoMan->CheckOverlaps(0.000001);
gGeoMan->PrintOverlaps();
// gGeoMan->Test();
// const TString tagVersion = "mcbm";
// const TString subVersion = "_3oclock";
// const TString geoVersion = "much_" + tagVersion + subVersion;
// const TString FileNameSim = geoVersion + ".geo.root";
// const TString FileNameGeo = geoVersion + "_geo.root";
much->Export(FileNameSim); // an alternative way of writing the much
TFile* outfile = new TFile(FileNameSim, "UPDATE");
TGeoTranslation* much_placement = new TGeoTranslation("much_trans", 0., 0., 0.);
much_placement->Write();
outfile->Close();
outfile = new TFile(FileNameGeo, "RECREATE");
gGeoMan->Write(); // use this if you want GeoManager format in the output
outfile->Close();
top->Draw("ogl");
}
void create_materials_from_media_file()
{
// Use the FairRoot geometry interface to load the media which are already defined
FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
TString geoPath = gSystem->Getenv("VMCWORKDIR");
TString geoFile = geoPath + "/geometry/media.geo";
geoFace->setMediaFile(geoFile);
geoFace->readMedia();
// Read the required media and create them in the GeoManager
FairGeoMedia* geoMedia = geoFace->getMedia();
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
FairGeoMedium* air = geoMedia->getMedium(KeepingVolumeMedium);
geoBuild->createMedium(air);
FairGeoMedium* MUCHiron = geoMedia->getMedium(I);
geoBuild->createMedium(MUCHiron);
FairGeoMedium* MUCHlead = geoMedia->getMedium(L);
geoBuild->createMedium(MUCHlead);
FairGeoMedium* MUCHwolfram = geoMedia->getMedium(W);
geoBuild->createMedium(MUCHwolfram);
FairGeoMedium* MUCHcarbon = geoMedia->getMedium(C);
geoBuild->createMedium(MUCHcarbon);
FairGeoMedium* MUCHargon = geoMedia->getMedium(activemedium);
geoBuild->createMedium(MUCHargon);
FairGeoMedium* MUCHnoryl = geoMedia->getMedium(spacermedium);
geoBuild->createMedium(MUCHnoryl);
FairGeoMedium* aluminium = geoMedia->getMedium(coolmedium);
// geoBuild->createMedium(MUCHcool);
geoBuild->createMedium(aluminium);
}
TGeoVolume* CreateStations(int ist)
{
TString stationName = Form("muchstation%02i", ist + 1);
TGeoVolumeAssembly* station = new TGeoVolumeAssembly(stationName); //, shStation, air);
TGeoVolume* gLayer[4];
for (int ii = 0; ii < 3; ii++) { // 3 Layers
gLayer[ii] = CreateLayers(ist, ii);
station->AddNode(gLayer[ii], ii);
}
return station;
}
TGeoVolume* CreateLayers(int istn, int ily)
{
TString layerName = Form("muchstation%02ilayer%i", istn + 1, ily + 1);
TGeoVolumeAssembly* volayer = new TGeoVolumeAssembly(layerName);
Double_t DeltaR = 97.5; // transverse dimension of the module
Double_t stGlobalZ0 = fStationZ0 + fMuchZ1; //z position of station center (midplane) [cm]
Double_t stDz = ((fNlayers - 1) * fLayersDz + fCoolLz + 2 * fActiveLzSector) / 2.;
Double_t stGlobalZ2 = stGlobalZ0 + stDz;
Double_t stGlobalZ1 = stGlobalZ0 - stDz;
Double_t rmin = stGlobalZ1 * fAcceptanceTanMin;
Double_t rmax = rmin + fSpacerR + DeltaR;
Int_t Nsector = 16.0; // need to be hard coded to match with station 1 of SIS100
//cout<<" Nsector "<<Nsector<<endl;
Double_t layerZ0 = (ily - (fNlayers - 1) / 2.) * fLayersDz;
Double_t layerGlobalZ0 = layerZ0 + stGlobalZ0;
Double_t sideDz = fCoolLz / 2. + fActiveLzSector / 2.; // distance between side's and layer's centers
Double_t moduleZ = sideDz; // Z position of the module center in the layer cs
Double_t phi0 = TMath::Pi() / Nsector; // azimuthal half widh of each module
Double_t ymin = rmin + fSpacerR;
Double_t ymax = rmax;
//define the dimensions of the trapezoidal module
Double_t dy = (ymax - ymin) / 2.; //y (length)
Double_t dx1 = ymin * TMath::Tan(phi0) + fOverlapR / TMath::Cos(phi0); // large x
Double_t dx2 = ymax * TMath::Tan(phi0) + fOverlapR / TMath::Cos(phi0); // small x
Double_t dz = fActiveLzSector / 2.; // thickness
//define the spacer dimensions
Double_t tg = (dx2 - dx1) / 2 / dy;
Double_t dd1 = fSpacerPhi * tg;
Double_t dd2 = fSpacerPhi * sqrt(1 + tg * tg);
Double_t sdx1 = dx1 + dd2 - dd1;
Double_t sdx2 = dx2 + dd2 + dd1;
Double_t sdy = dy + fSpacerR; // frame width added
Double_t sdz = dz - 0.1;
// Define the (cooling plate) diemnsions
Double_t dy_s = dy + 2.0;
Double_t dx1_s = dx1 + 2.0; // large x
Double_t dx2_s = dx2 + 2.0; // x
Double_t dz_s = fCoolLz / 2.; //
TVector3 pos;
TVector3 size = TVector3(0.0, 0.0, fActiveLzSector);
// Now start adding the GEM modules
for (Int_t iModule = 0; iModule < 1; iModule++) {
// if (iModule!=0) continue;
// Double_t phi = 2 * phi0 * (iModule + 0.5); // add 0.5 to not overlap with y-axis for left-right layer separation
// Position oof the module will depend on Phi
// Set Phi=180 degree 6 o'clock position
// Set Phi=90 degree 3 o'clock position
Double_t phi = TMath::Pi() / 2.0;
Bool_t isBack = iModule % 2;
Char_t cside = (isBack == 1) ? 'b' : 'f';
// correct the x, y positions
pos[0] = -(ymin + dy) * sin(phi);
pos[1] = (ymin + dy) * cos(phi);
// different z positions for odd/even modules
// pos[2] = (isBack ? 1 : -1)*moduleZ + layerGlobalZ0;
pos[2] = layerGlobalZ0;
TGeoMedium* argon = gGeoMan->GetMedium(activemedium); // active medium
TGeoMedium* noryl = gGeoMan->GetMedium(spacermedium); // spacer medium
TGeoMedium* aluminium = gGeoMan->GetMedium(coolmedium); // cool medium
// Define and place the trapezoidal GEM module in X-Y plane
TGeoTrap* shape = new TGeoTrap(dz, 0, phi, dy, dx1, dx2, 0, dy, dx1, dx2, 0);
// TGeoTrap* shape = new TGeoTrap(dz,0,0,dy,dx1,dx2,0,dy,dx1,dx2,0);
shape->SetName(Form("shStation%02iLayer%i%cModule%03iActiveNoHole", istn, ily, cside, iModule));
TString activeName = Form("muchstation%02ilayer%i%cactive%03igasArgon", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voActive = new TGeoVolume(activeName, shape, argon);
voActive->SetLineColor(kGreen);
// Define the trapezoidal spacers
TGeoTrap* shapeFrame = new TGeoTrap(sdz, 0, phi, sdy, sdx1, sdx2, 0, sdy, sdx1, sdx2, 0);
//TGeoTrap* shapeFrame = new TGeoTrap(sdz,0,0,sdy,sdx1,sdx2,0,sdy,sdx1,sdx2,0);
shapeFrame->SetName(Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole", istn, ily, cside, iModule));
TString expression = Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole-"
"shStation%02iLayer%i%cModule%03iActiveNoHole",
istn, ily, cside, iModule, istn, ily, cside, iModule);
TGeoCompositeShape* shFrame = new TGeoCompositeShape(
Form("shStation%02iLayer%i%cModule%03iFrameNoHole", istn, ily, cside, iModule), expression);
TString frameName = Form("muchstation%02ilayer%i%csupport%03i", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voFrame = new TGeoVolume(frameName, shFrame, noryl); // add a name to the frame
voFrame->SetLineColor(kMagenta);
// Define the trapezoidal (cooling plates)
// TGeoTrap* cool = new TGeoTrap(dz_s,0,phi,dy_s,dx1_s,dx2_s,0,dy_s,dx1_s,dx2_s,0);
TGeoTrap* cool = new TGeoTrap(dz_s, 0, phi, dy_s, dx1_s, dx2_s, 0, dy_s, dx1_s, dx2_s, 0);
cool->SetName(Form("shStation%02iLayer%i%cModule%03icool", istn, ily, cside, iModule));
TString CoolName = Form("muchstation%02ilayer%i%ccool%03iAluminum", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voCool = new TGeoVolume(CoolName, cool, aluminium);
voCool->SetLineColor(kYellow);
// Calculate the phi angle of the sector where it has to be placed
Double_t angle = 180. / TMath::Pi() * phi; // convert angle phi from rad to deg
TGeoTranslation* trans2 = new TGeoTranslation("", pos[0], pos[1], pos[2]); //for module and frame
TGeoTranslation* trans3 = new TGeoTranslation("", pos[0], pos[1], pos[2] + 0.65); //for module and frame
TGeoRotation* r2 = new TGeoRotation("r2");
//rotate in the vertical plane (per to z axis) with angle
r2->RotateZ(angle);
// give rotation to set them in horizontal plane
//r2->RotateZ(90.0);//TMath::Pi());
TGeoHMatrix* incline_mod = new TGeoHMatrix("");
(*incline_mod) = (*trans2) * (*r2); // OK
volayer->AddNode(voFrame, iModule, incline_mod); // add frame
volayer->AddNode(voActive, iModule, incline_mod); // add active volume
TGeoHMatrix* incline_mod1 = new TGeoHMatrix("");
(*incline_mod1) = (*trans3) * (*r2); // for cooling
volayer->AddNode(voCool, iModule, incline_mod1); // cooling plate
// cout<<rmin<<" "<<rmax<<" "<<pos[1]<<" "<<phi<<" "<<fActiveLzSector<<" "<<stGlobalZ0<<" "<<istn<<" "<<ily<<pos[0]<<endl;
}
return volayer;
}
/* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: David Emschermann [committer] */
//
/// \file create_MUCH_geometry_v18c.C
/// \brief Generates MUCH geometry in Root format.
///
// 2017-10-23 - DE - mcbm - put mMUCH in 6 o'clock position on z axis, shift 15 cm up and to z = 60, 70 and 80 cm
// 2017-09-04 - PPB - mcbm - preliminary version of mini much geometry
// 2017-05-16 - DE - v17b - position the modules in a way to split layers left-right along y axis
// 2017-05-16 - DE - v17b - attribute name to module frames
// 2017-05-16 - DE - v17b - remove rim from support CompositeShape
// 2017-05-02 - PPB - v17a - Change the shape of the first absorber according to latest design
// 2017-04-27 - DE - v17a - fix GEM module positions and angles
// 2017-04-22 - PPB - v17a - Define the absorber, shield and station shapes sizes ...
// 2016-04-19 - DE - v17a - initial version derived from TRD
// in root all sizes are given in cm
#include "TClonesArray.h"
#include "TDatime.h"
#include "TFile.h"
#include "TGeoBBox.h"
#include "TGeoCompositeShape.h"
#include "TGeoCone.h"
#include "TGeoManager.h"
#include "TGeoMaterial.h"
#include "TGeoMatrix.h"
#include "TGeoMedium.h"
#include "TGeoPgon.h"
#include "TGeoTube.h"
#include "TGeoVolume.h"
#include "TGeoXtru.h"
#include "TList.h"
#include "TMath.h"
#include "TObjArray.h"
#include "TRandom3.h"
#include "TString.h"
#include "TSystem.h"
#include <cassert>
#include <fstream>
#include <iostream>
#include <stdexcept>
// Name of output file with geometry
const TString tagVersion = "v18c";
const TString geoVersion = "much_" + tagVersion;
//const TString subVersion = "_3oclock";
//const TString geoVersion = "much_" + tagVersion + subVersion;
const TString FileNameSim = geoVersion + "_mcbm.geo.root";
const TString FileNameGeo = geoVersion + "_mcbm_geo.root";
const TString FileNameInfo = geoVersion + "_mcbm.geo.info";
// Names of the different used materials which are used to build the modules
// The materials are defined in the global media.geo file
const TString KeepingVolumeMedium = "air";
const TString L = "MUCHlead";
const TString W = "MUCHwolfram";
const TString C = "MUCHcarbon";
const TString I = "MUCHiron";
const TString activemedium = "MUCHargon";
const TString spacermedium = "MUCHnoryl";
const TString coolmedium = "aluminium"; //Al cooling plates
// Universal input parameters
// The inner angle is 11 degree (polar angle); We take z = 70 cm;
//Inner radius: R_in=z*tan(theta_min) cm
// Outer angle is decided from tan(theta_max)=R_out/z
// R_out=R_in+95 cm (transverse size of the M2 module)
Double_t fMuchZ1 = 0.0; // MuchCave Zin position [cm]
Double_t fAcceptanceTanMin = 0.19; // Acceptance tangent min (11 degree)
//************************************************************
// Input parameters for MUCH stations
//********************************************
const Int_t fNst = 1; // Number of stations
// Sector-type module parameters
// Number of sectors per layer (should be even for symmetry)
// Needs to be fixed with actual numbers
Double_t fActiveLzSector = 0.3; // Active volume thickness [cm]
Double_t fSpacerR = 2.5; // Spacer width in R [cm]
Double_t fSpacerPhi = 2.5; // Spacer width in Phi [cm]
Double_t fOverlapR = 0.0; // Overlap in R direction [cm]
// Station Zceneter [cm] in the cave reference frame
//Double_t fStationZ0=80;
Double_t fStationZ0 = 70; // DE - move 10 cm upstream
Int_t fNlayers = 3; // Number of layers
Double_t fLayersDz = 10; // distance between the layers
Double_t fCoolLz = 1.0; // thickness of the cooling plate also used as support
/*
1 - detailed design (modules at two sides)
* 0 - simple design (1 module per layer)
*/
//***********************************************************
// some global variables
TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance
TGeoVolume* gModules_station[fNst]; // Global storage for module types
// Forward declarations
void create_materials_from_media_file();
TGeoVolume* CreateStations(int ist);
TGeoVolume* CreateLayers(int istn, int ily);
void create_MUCH_geometry_v18c()
{
// Load needed material definition from media.geo file
create_materials_from_media_file();
// Get the GeoManager for later usage
gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom");
gGeoMan->SetVisLevel(10);
// Create the top volume
TGeoBBox* topbox = new TGeoBBox("", 1000., 1000., 2000.);
TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air"));
gGeoMan->SetTopVolume(top);
TGeoVolume* much = new TGeoVolumeAssembly(geoVersion);
top->AddNode(much, 1);
TGeoVolume* sttn = new TGeoVolumeAssembly("Station");
much->AddNode(sttn, 1);
for (Int_t istn = 0; istn < 1; istn++) { // 1 Station
gModules_station[istn] = CreateStations(istn);
sttn->AddNode(gModules_station[istn], istn);
}
gGeoMan->CloseGeometry();
gGeoMan->CheckOverlaps(0.000001);
gGeoMan->PrintOverlaps();
// gGeoMan->Test();
// const TString tagVersion = "mcbm";
// const TString subVersion = "_3oclock";
// const TString geoVersion = "much_" + tagVersion + subVersion;
// const TString FileNameSim = geoVersion + ".geo.root";
// const TString FileNameGeo = geoVersion + "_geo.root";
much->Export(FileNameSim); // an alternative way of writing the much
TFile* outfile = new TFile(FileNameSim, "UPDATE");
TGeoTranslation* much_placement = new TGeoTranslation("much_trans", 0., 0., 0.);
much_placement->Write();
outfile->Close();
outfile = new TFile(FileNameGeo, "RECREATE");
gGeoMan->Write(); // use this if you want GeoManager format in the output
outfile->Close();
top->Draw("ogl");
}
void create_materials_from_media_file()
{
// Use the FairRoot geometry interface to load the media which are already defined
FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
TString geoPath = gSystem->Getenv("VMCWORKDIR");
TString geoFile = geoPath + "/geometry/media.geo";
geoFace->setMediaFile(geoFile);
geoFace->readMedia();
// Read the required media and create them in the GeoManager
FairGeoMedia* geoMedia = geoFace->getMedia();
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
FairGeoMedium* air = geoMedia->getMedium(KeepingVolumeMedium);
geoBuild->createMedium(air);
FairGeoMedium* MUCHiron = geoMedia->getMedium(I);
geoBuild->createMedium(MUCHiron);
FairGeoMedium* MUCHlead = geoMedia->getMedium(L);
geoBuild->createMedium(MUCHlead);
FairGeoMedium* MUCHwolfram = geoMedia->getMedium(W);
geoBuild->createMedium(MUCHwolfram);
FairGeoMedium* MUCHcarbon = geoMedia->getMedium(C);
geoBuild->createMedium(MUCHcarbon);
FairGeoMedium* MUCHargon = geoMedia->getMedium(activemedium);
geoBuild->createMedium(MUCHargon);
FairGeoMedium* MUCHnoryl = geoMedia->getMedium(spacermedium);
geoBuild->createMedium(MUCHnoryl);
FairGeoMedium* aluminium = geoMedia->getMedium(coolmedium);
// geoBuild->createMedium(MUCHcool);
geoBuild->createMedium(aluminium);
}
TGeoVolume* CreateStations(int ist)
{
TString stationName = Form("muchstation%02i", ist + 1);
TGeoVolumeAssembly* station = new TGeoVolumeAssembly(stationName); //, shStation, air);
TGeoVolume* gLayer[4];
for (int ii = 0; ii < 3; ii++) { // 3 Layers
gLayer[ii] = CreateLayers(ist, ii);
station->AddNode(gLayer[ii], ii);
}
return station;
}
TGeoVolume* CreateLayers(int istn, int ily)
{
TString layerName = Form("muchstation%02ilayer%i", istn + 1, ily + 1);
TGeoVolumeAssembly* volayer = new TGeoVolumeAssembly(layerName);
Double_t DeltaR = 97.5; // transverse dimension of the module
Double_t stGlobalZ0 = fStationZ0 + fMuchZ1; //z position of station center (midplane) [cm]
Double_t stDz = ((fNlayers - 1) * fLayersDz + fCoolLz + 2 * fActiveLzSector) / 2.;
Double_t stGlobalZ2 = stGlobalZ0 + stDz;
Double_t stGlobalZ1 = stGlobalZ0 - stDz;
Double_t rmin = stGlobalZ1 * fAcceptanceTanMin;
Double_t rmax = rmin + fSpacerR + DeltaR;
Int_t Nsector = 16.0; // need to be hard coded to match with station 1 of SIS100
//cout<<" Nsector "<<Nsector<<endl;
Double_t layerZ0 = (ily - (fNlayers - 1) / 2.) * fLayersDz;
Double_t layerGlobalZ0 = layerZ0 + stGlobalZ0;
Double_t sideDz = fCoolLz / 2. + fActiveLzSector / 2.; // distance between side's and layer's centers
Double_t moduleZ = sideDz; // Z position of the module center in the layer cs
Double_t phi0 = TMath::Pi() / Nsector; // azimuthal half widh of each module
Double_t ymin = rmin + fSpacerR;
Double_t ymax = rmax;
//define the dimensions of the trapezoidal module
Double_t dy = (ymax - ymin) / 2.; //y (length)
Double_t dx1 = ymin * TMath::Tan(phi0) + fOverlapR / TMath::Cos(phi0); // large x
Double_t dx2 = ymax * TMath::Tan(phi0) + fOverlapR / TMath::Cos(phi0); // small x
Double_t dz = fActiveLzSector / 2.; // thickness
//define the spacer dimensions
Double_t tg = (dx2 - dx1) / 2 / dy;
Double_t dd1 = fSpacerPhi * tg;
Double_t dd2 = fSpacerPhi * sqrt(1 + tg * tg);
Double_t sdx1 = dx1 + dd2 - dd1;
Double_t sdx2 = dx2 + dd2 + dd1;
Double_t sdy = dy + fSpacerR; // frame width added
Double_t sdz = dz - 0.1;
// Define the (cooling plate) diemnsions
Double_t dy_s = dy + 2.0;
Double_t dx1_s = dx1 + 2.0; // large x
Double_t dx2_s = dx2 + 2.0; // x
Double_t dz_s = fCoolLz / 2.; //
TVector3 pos;
TVector3 size = TVector3(0.0, 0.0, fActiveLzSector);
// Now start adding the GEM modules
for (Int_t iModule = 0; iModule < 1; iModule++) {
// if (iModule!=0) continue;
// Double_t phi = 2 * phi0 * (iModule + 0.5); // add 0.5 to not overlap with y-axis for left-right layer separation
// Position of the module will depend on Phi
// Set Phi=180 degree 6 o'clock position
// Set Phi=90 degree 3 o'clock position
Double_t phi = TMath::Pi() / 2.0;
Bool_t isBack = iModule % 2;
Char_t cside = (isBack == 1) ? 'b' : 'f';
// correct the x, y positions
// pos[0] = -(ymin+dy)*sin(phi);
// pos[1] = (ymin+dy)*cos(phi);
pos[0] = 0; // DE - do not displace mMUCH in x
pos[1] = 15; // DE - move upwards in y [cm]
// different z positions for odd/even modules
// pos[2] = (isBack ? 1 : -1)*moduleZ + layerGlobalZ0;
pos[2] = layerGlobalZ0;
TGeoMedium* argon = gGeoMan->GetMedium(activemedium); // active medium
TGeoMedium* noryl = gGeoMan->GetMedium(spacermedium); // spacer medium
TGeoMedium* aluminium = gGeoMan->GetMedium(coolmedium); // cool medium
// Define and place the trapezoidal GEM module in X-Y plane
TGeoTrap* shape = new TGeoTrap(dz, 0, phi, dy, dx1, dx2, 0, dy, dx1, dx2, 0);
// TGeoTrap* shape = new TGeoTrap(dz,0,0,dy,dx1,dx2,0,dy,dx1,dx2,0);
shape->SetName(Form("shStation%02iLayer%i%cModule%03iActiveNoHole", istn, ily, cside, iModule));
TString activeName = Form("muchstation%02ilayer%i%cactive%03igasArgon", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voActive = new TGeoVolume(activeName, shape, argon);
voActive->SetLineColor(kGreen);
// Define the trapezoidal spacers
TGeoTrap* shapeFrame = new TGeoTrap(sdz, 0, phi, sdy, sdx1, sdx2, 0, sdy, sdx1, sdx2, 0);
//TGeoTrap* shapeFrame = new TGeoTrap(sdz,0,0,sdy,sdx1,sdx2,0,sdy,sdx1,sdx2,0);
shapeFrame->SetName(Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole", istn, ily, cside, iModule));
TString expression = Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole-"
"shStation%02iLayer%i%cModule%03iActiveNoHole",
istn, ily, cside, iModule, istn, ily, cside, iModule);
TGeoCompositeShape* shFrame = new TGeoCompositeShape(
Form("shStation%02iLayer%i%cModule%03iFrameNoHole", istn, ily, cside, iModule), expression);
TString frameName = Form("muchstation%02ilayer%i%csupport%03i", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voFrame = new TGeoVolume(frameName, shFrame, noryl); // add a name to the frame
voFrame->SetLineColor(kMagenta);
// Define the trapezoidal (cooling plates)
// TGeoTrap* cool = new TGeoTrap(dz_s,0,phi,dy_s,dx1_s,dx2_s,0,dy_s,dx1_s,dx2_s,0);
TGeoTrap* cool = new TGeoTrap(dz_s, 0, phi, dy_s, dx1_s, dx2_s, 0, dy_s, dx1_s, dx2_s, 0);
cool->SetName(Form("shStation%02iLayer%i%cModule%03icool", istn, ily, cside, iModule));
TString CoolName = Form("muchstation%02ilayer%i%ccool%03iAluminum", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voCool = new TGeoVolume(CoolName, cool, aluminium);
voCool->SetLineColor(kYellow);
// Calculate the phi angle of the sector where it has to be placed
Double_t angle = 180. / TMath::Pi() * phi; // convert angle phi from rad to deg
TGeoTranslation* trans2 = new TGeoTranslation("", pos[0], pos[1], pos[2]); //for module and frame
TGeoTranslation* trans3 = new TGeoTranslation("", pos[0], pos[1], pos[2] + 0.65); //for module and frame
TGeoRotation* r2 = new TGeoRotation("r2");
//rotate in the vertical plane (per to z axis) with angle
// r2->RotateZ(angle);
// DE cout << "DE " << phi << endl;
// DE cout << "DE " << angle << endl;
// DE cout << "DE " << phi0 << endl;
// DE cout << "DE " << 180. / TMath::Pi() * phi0 << endl;
r2->RotateZ(180.0); // DE - 6 o'clock position
// r2->RotateZ(180.0-(180. / TMath::Pi() * phi0)); // DE - 6 o'clock position, left side vertical
// give rotation to set them in horizontal plane
//r2->RotateZ(90.0);//TMath::Pi());
TGeoHMatrix* incline_mod = new TGeoHMatrix("");
(*incline_mod) = (*trans2) * (*r2); // OK
volayer->AddNode(voFrame, iModule, incline_mod); // add frame
volayer->AddNode(voActive, iModule, incline_mod); // add active volume
TGeoHMatrix* incline_mod1 = new TGeoHMatrix("");
(*incline_mod1) = (*trans3) * (*r2); // for cooling
volayer->AddNode(voCool, iModule, incline_mod1); // cooling plate
// cout<<rmin<<" "<<rmax<<" "<<pos[1]<<" "<<phi<<" "<<fActiveLzSector<<" "<<stGlobalZ0<<" "<<istn<<" "<<ily<<pos[0]<<endl;
}
return volayer;
}
/* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: David Emschermann [committer] */
//
/// \file create_MUCH_geometry_v18d.C
/// \brief Generates MUCH geometry in Root format.
///
// 2017-10-23 - DE - mcbm - put mMUCH in 6 o'clock position on z axis, shift 15 cm up and to z = 60, 70 and 80 cm
// 2017-09-04 - PPB - mcbm - preliminary version of mini much geometry
// 2017-05-16 - DE - v17b - position the modules in a way to split layers left-right along y axis
// 2017-05-16 - DE - v17b - attribute name to module frames
// 2017-05-16 - DE - v17b - remove rim from support CompositeShape
// 2017-05-02 - PPB - v17a - Change the shape of the first absorber according to latest design
// 2017-04-27 - DE - v17a - fix GEM module positions and angles
// 2017-04-22 - PPB - v17a - Define the absorber, shield and station shapes sizes ...
// 2016-04-19 - DE - v17a - initial version derived from TRD
// in root all sizes are given in cm
#include "TClonesArray.h"
#include "TDatime.h"
#include "TFile.h"
#include "TGeoBBox.h"
#include "TGeoCompositeShape.h"
#include "TGeoCone.h"
#include "TGeoManager.h"
#include "TGeoMaterial.h"
#include "TGeoMatrix.h"
#include "TGeoMedium.h"
#include "TGeoPgon.h"
#include "TGeoTube.h"
#include "TGeoVolume.h"
#include "TGeoXtru.h"
#include "TList.h"
#include "TMath.h"
#include "TObjArray.h"
#include "TRandom3.h"
#include "TString.h"
#include "TSystem.h"
#include <cassert>
#include <fstream>
#include <iostream>
#include <stdexcept>
// Name of output file with geometry
const TString tagVersion = "v18d";
const TString geoVersion = "much_" + tagVersion;
//const TString subVersion = "_3oclock";
//const TString geoVersion = "much_" + tagVersion + subVersion;
const TString FileNameSim = geoVersion + "_mcbm.geo.root";
const TString FileNameGeo = geoVersion + "_mcbm_geo.root";
const TString FileNameInfo = geoVersion + "_mcbm.geo.info";
// Names of the different used materials which are used to build the modules
// The materials are defined in the global media.geo file
const TString KeepingVolumeMedium = "air";
const TString L = "MUCHlead";
const TString W = "MUCHwolfram";
const TString C = "MUCHcarbon";
const TString I = "MUCHiron";
const TString activemedium = "MUCHargon";
const TString spacermedium = "MUCHnoryl";
const TString coolmedium = "aluminium"; //Al cooling plates
// Universal input parameters
// The inner angle is 11 degree (polar angle); We take z = 70 cm;
//Inner radius: R_in=z*tan(theta_min) cm
// Outer angle is decided from tan(theta_max)=R_out/z
// R_out=R_in+95 cm (transverse size of the M2 module)
Double_t fMuchZ1 = 0.0; // MuchCave Zin position [cm]
Double_t fAcceptanceTanMin = 0.19; // Acceptance tangent min (11 degree)
//************************************************************
// Input parameters for MUCH stations
//********************************************
const Int_t fNst = 1; // Number of stations
// Sector-type module parameters
// Number of sectors per layer (should be even for symmetry)
// Needs to be fixed with actual numbers
Double_t fActiveLzSector = 0.3; // Active volume thickness [cm]
Double_t fSpacerR = 2.5; // Spacer width in R [cm]
Double_t fSpacerPhi = 2.5; // Spacer width in Phi [cm]
Double_t fOverlapR = 0.0; // Overlap in R direction [cm]
// Station Zceneter [cm] in the cave reference frame
//Double_t fStationZ0=80;
Double_t fStationZ0 = 70; // DE - move 10 cm upstream
Int_t fNlayers = 3; // Number of layers
Double_t fLayersDz = 10; // distance between the layers
Double_t fCoolLz = 1.0; // thickness of the cooling plate also used as support
/*
1 - detailed design (modules at two sides)
* 0 - simple design (1 module per layer)
*/
//***********************************************************
// some global variables
TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance
TGeoVolume* gModules_station[fNst]; // Global storage for module types
// Forward declarations
void create_materials_from_media_file();
TGeoVolume* CreateStations(int ist);
TGeoVolume* CreateLayers(int istn, int ily);
void create_MUCH_geometry_v18d()
{
// Load needed material definition from media.geo file
create_materials_from_media_file();
// Get the GeoManager for later usage
gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom");
gGeoMan->SetVisLevel(10);
// Create the top volume
TGeoBBox* topbox = new TGeoBBox("", 1000., 1000., 2000.);
TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air"));
gGeoMan->SetTopVolume(top);
TGeoVolume* much = new TGeoVolumeAssembly(geoVersion);
top->AddNode(much, 1);
TGeoVolume* sttn = new TGeoVolumeAssembly("Station");
much->AddNode(sttn, 1);
for (Int_t istn = 0; istn < 1; istn++) { // 1 Station
gModules_station[istn] = CreateStations(istn);
sttn->AddNode(gModules_station[istn], istn);
}
gGeoMan->CloseGeometry();
gGeoMan->CheckOverlaps(0.000001);
gGeoMan->PrintOverlaps();
// gGeoMan->Test();
// const TString tagVersion = "mcbm";
// const TString subVersion = "_3oclock";
// const TString geoVersion = "much_" + tagVersion + subVersion;
// const TString FileNameSim = geoVersion + ".geo.root";
// const TString FileNameGeo = geoVersion + "_geo.root";
much->Export(FileNameSim); // an alternative way of writing the much
TFile* outfile = new TFile(FileNameSim, "UPDATE");
TGeoTranslation* much_placement = new TGeoTranslation("much_trans", 0., 0., 0.);
much_placement->Write();
outfile->Close();
outfile = new TFile(FileNameGeo, "RECREATE");
gGeoMan->Write(); // use this if you want GeoManager format in the output
outfile->Close();
top->Draw("ogl");
}
void create_materials_from_media_file()
{
// Use the FairRoot geometry interface to load the media which are already defined
FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
TString geoPath = gSystem->Getenv("VMCWORKDIR");
TString geoFile = geoPath + "/geometry/media.geo";
geoFace->setMediaFile(geoFile);
geoFace->readMedia();
// Read the required media and create them in the GeoManager
FairGeoMedia* geoMedia = geoFace->getMedia();
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
FairGeoMedium* air = geoMedia->getMedium(KeepingVolumeMedium);
geoBuild->createMedium(air);
FairGeoMedium* MUCHiron = geoMedia->getMedium(I);
geoBuild->createMedium(MUCHiron);
FairGeoMedium* MUCHlead = geoMedia->getMedium(L);
geoBuild->createMedium(MUCHlead);
FairGeoMedium* MUCHwolfram = geoMedia->getMedium(W);
geoBuild->createMedium(MUCHwolfram);
FairGeoMedium* MUCHcarbon = geoMedia->getMedium(C);
geoBuild->createMedium(MUCHcarbon);
FairGeoMedium* MUCHargon = geoMedia->getMedium(activemedium);
geoBuild->createMedium(MUCHargon);
FairGeoMedium* MUCHnoryl = geoMedia->getMedium(spacermedium);
geoBuild->createMedium(MUCHnoryl);
FairGeoMedium* aluminium = geoMedia->getMedium(coolmedium);
// geoBuild->createMedium(MUCHcool);
geoBuild->createMedium(aluminium);
}
TGeoVolume* CreateStations(int ist)
{
TString stationName = Form("muchstation%02i", ist + 1);
TGeoVolumeAssembly* station = new TGeoVolumeAssembly(stationName); //, shStation, air);
TGeoVolume* gLayer[4];
for (int ii = 0; ii < 3; ii++) { // 3 Layers
gLayer[ii] = CreateLayers(ist, ii);
station->AddNode(gLayer[ii], ii);
}
return station;
}
TGeoVolume* CreateLayers(int istn, int ily)
{
TString layerName = Form("muchstation%02ilayer%i", istn + 1, ily + 1);
TGeoVolumeAssembly* volayer = new TGeoVolumeAssembly(layerName);
Double_t DeltaR = 97.5; // transverse dimension of the module
Double_t stGlobalZ0 = fStationZ0 + fMuchZ1; //z position of station center (midplane) [cm]
Double_t stDz = ((fNlayers - 1) * fLayersDz + fCoolLz + 2 * fActiveLzSector) / 2.;
Double_t stGlobalZ2 = stGlobalZ0 + stDz;
Double_t stGlobalZ1 = stGlobalZ0 - stDz;
Double_t rmin = stGlobalZ1 * fAcceptanceTanMin;
Double_t rmax = rmin + fSpacerR + DeltaR;
Int_t Nsector = 16.0; // need to be hard coded to match with station 1 of SIS100
//cout<<" Nsector "<<Nsector<<endl;
Double_t layerZ0 = (ily - (fNlayers - 1) / 2.) * fLayersDz;
Double_t layerGlobalZ0 = layerZ0 + stGlobalZ0;
Double_t sideDz = fCoolLz / 2. + fActiveLzSector / 2.; // distance between side's and layer's centers
Double_t moduleZ = sideDz; // Z position of the module center in the layer cs
Double_t phi0 = TMath::Pi() / Nsector; // azimuthal half widh of each module
Double_t ymin = rmin + fSpacerR;
Double_t ymax = rmax;
//define the dimensions of the trapezoidal module
Double_t dy = (ymax - ymin) / 2.; //y (length)
Double_t dx1 = ymin * TMath::Tan(phi0) + fOverlapR / TMath::Cos(phi0); // large x
Double_t dx2 = ymax * TMath::Tan(phi0) + fOverlapR / TMath::Cos(phi0); // small x
Double_t dz = fActiveLzSector / 2.; // thickness
//define the spacer dimensions
Double_t tg = (dx2 - dx1) / 2 / dy;
Double_t dd1 = fSpacerPhi * tg;
Double_t dd2 = fSpacerPhi * sqrt(1 + tg * tg);
Double_t sdx1 = dx1 + dd2 - dd1;
Double_t sdx2 = dx2 + dd2 + dd1;
Double_t sdy = dy + fSpacerR; // frame width added
Double_t sdz = dz - 0.1;
// Define the (cooling plate) diemnsions
Double_t dy_s = dy + 2.0;
Double_t dx1_s = dx1 + 2.0; // large x
Double_t dx2_s = dx2 + 2.0; // x
Double_t dz_s = fCoolLz / 2.; //
TVector3 pos;
TVector3 size = TVector3(0.0, 0.0, fActiveLzSector);
// Now start adding the GEM modules
for (Int_t iModule = 0; iModule < 1; iModule++) {
// if (iModule!=0) continue;
// Double_t phi = 2 * phi0 * (iModule + 0.5); // add 0.5 to not overlap with y-axis for left-right layer separation
// Position of the module will depend on Phi
// Set Phi=180 degree 6 o'clock position
// Set Phi=90 degree 3 o'clock position
Double_t phi = TMath::Pi() / 2.0;
Bool_t isBack = iModule % 2;
Char_t cside = (isBack == 1) ? 'b' : 'f';
// correct the x, y positions
// pos[0] = -(ymin+dy)*sin(phi);
// pos[1] = (ymin+dy)*cos(phi);
pos[0] = 0; // DE - do not displace mMUCH in x
pos[1] = 15; // DE - move upwards in y [cm]
// different z positions for odd/even modules
// pos[2] = (isBack ? 1 : -1)*moduleZ + layerGlobalZ0;
pos[2] = layerGlobalZ0;
TGeoMedium* argon = gGeoMan->GetMedium(activemedium); // active medium
TGeoMedium* noryl = gGeoMan->GetMedium(spacermedium); // spacer medium
TGeoMedium* aluminium = gGeoMan->GetMedium(coolmedium); // cool medium
// Define and place the trapezoidal GEM module in X-Y plane
TGeoTrap* shape = new TGeoTrap(dz, 0, phi, dy, dx1, dx2, 0, dy, dx1, dx2, 0);
// TGeoTrap* shape = new TGeoTrap(dz,0,0,dy,dx1,dx2,0,dy,dx1,dx2,0);
shape->SetName(Form("shStation%02iLayer%i%cModule%03iActiveNoHole", istn, ily, cside, iModule));
TString activeName = Form("muchstation%02ilayer%i%cactive%03igasArgon", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voActive = new TGeoVolume(activeName, shape, argon);
voActive->SetLineColor(kGreen);
// Define the trapezoidal spacers
TGeoTrap* shapeFrame = new TGeoTrap(sdz, 0, phi, sdy, sdx1, sdx2, 0, sdy, sdx1, sdx2, 0);
//TGeoTrap* shapeFrame = new TGeoTrap(sdz,0,0,sdy,sdx1,sdx2,0,sdy,sdx1,sdx2,0);
shapeFrame->SetName(Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole", istn, ily, cside, iModule));
TString expression = Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole-"
"shStation%02iLayer%i%cModule%03iActiveNoHole",
istn, ily, cside, iModule, istn, ily, cside, iModule);
TGeoCompositeShape* shFrame = new TGeoCompositeShape(
Form("shStation%02iLayer%i%cModule%03iFrameNoHole", istn, ily, cside, iModule), expression);
TString frameName = Form("muchstation%02ilayer%i%csupport%03i", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voFrame = new TGeoVolume(frameName, shFrame, noryl); // add a name to the frame
voFrame->SetLineColor(kMagenta);
// Define the trapezoidal (cooling plates)
// TGeoTrap* cool = new TGeoTrap(dz_s,0,phi,dy_s,dx1_s,dx2_s,0,dy_s,dx1_s,dx2_s,0);
TGeoTrap* cool = new TGeoTrap(dz_s, 0, phi, dy_s, dx1_s, dx2_s, 0, dy_s, dx1_s, dx2_s, 0);
cool->SetName(Form("shStation%02iLayer%i%cModule%03icool", istn, ily, cside, iModule));
TString CoolName = Form("muchstation%02ilayer%i%ccool%03iAluminum", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voCool = new TGeoVolume(CoolName, cool, aluminium);
voCool->SetLineColor(kYellow);
// Calculate the phi angle of the sector where it has to be placed
Double_t angle = 180. / TMath::Pi() * phi; // convert angle phi from rad to deg
TGeoTranslation* trans2 = new TGeoTranslation("", pos[0], pos[1], pos[2]); //for module and frame
TGeoTranslation* trans3 = new TGeoTranslation("", pos[0], pos[1], pos[2] + 0.65); //for module and frame
TGeoRotation* r2 = new TGeoRotation("r2");
//rotate in the vertical plane (per to z axis) with angle
// r2->RotateZ(angle);
// DE cout << "DE " << phi << endl;
// DE cout << "DE " << angle << endl;
// DE cout << "DE " << phi0 << endl;
// DE cout << "DE " << 180. / TMath::Pi() * phi0 << endl;
// r2->RotateZ(180.0); // DE - 6 o'clock position
r2->RotateZ(180.0 - (180. / TMath::Pi() * phi0)); // DE - 6 o'clock position, left side vertical
// give rotation to set them in horizontal plane
//r2->RotateZ(90.0);//TMath::Pi());
TGeoHMatrix* incline_mod = new TGeoHMatrix("");
(*incline_mod) = (*trans2) * (*r2); // OK
volayer->AddNode(voFrame, iModule, incline_mod); // add frame
volayer->AddNode(voActive, iModule, incline_mod); // add active volume
TGeoHMatrix* incline_mod1 = new TGeoHMatrix("");
(*incline_mod1) = (*trans3) * (*r2); // for cooling
volayer->AddNode(voCool, iModule, incline_mod1); // cooling plate
// cout<<rmin<<" "<<rmax<<" "<<pos[1]<<" "<<phi<<" "<<fActiveLzSector<<" "<<stGlobalZ0<<" "<<istn<<" "<<ily<<pos[0]<<endl;
}
return volayer;
}
/* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: David Emschermann [committer] */
//
/// \file create_MUCH_geometry_v18e.C
/// \brief Generates MUCH geometry in Root format.
///
//2017-11-10 -- PPB -- corerct the y position of the moduels to genertae much points
//2017-11-07 - PPB - change the shape of cooling plates from rectangular to sector
//2017-11-06 - PPB, VS and AM - mcbm version with actual Mv2 dimesions of the module
// 2017-10-23 - DE - mcbm - put mMUCH in 6 o'clock position on z axis, shift 15 cm up and to z = 60, 70 and 80 cm
// 2017-09-04 - PPB - mcbm - preliminary version of mini much geometry
// 2017-05-16 - DE - v17b - position the modules in a way to split layers left-right along y axis
// 2017-05-16 - DE - v17b - attribute name to module frames
// 2017-05-16 - DE - v17b - remove rim from support CompositeShape
// 2017-05-02 - PPB - v17a - Change the shape of the first absorber according to latest design
// 2017-04-27 - DE - v17a - fix GEM module positions and angles
// 2017-04-22 - PPB - v17a - Define the absorber, shield and station shapes sizes ...
// 2016-04-19 - DE - v17a - initial version derived from TRD
// in root all sizes are given in cm
#include "TClonesArray.h"
#include "TDatime.h"
#include "TFile.h"
#include "TGeoBBox.h"
#include "TGeoCompositeShape.h"
#include "TGeoCone.h"
#include "TGeoManager.h"
#include "TGeoMaterial.h"
#include "TGeoMatrix.h"
#include "TGeoMedium.h"
#include "TGeoPgon.h"
#include "TGeoTube.h"
#include "TGeoVolume.h"
#include "TGeoXtru.h"
#include "TList.h"
#include "TMath.h"
#include "TObjArray.h"
#include "TRandom3.h"
#include "TString.h"
#include "TSystem.h"
#include <cassert>
#include <fstream>
#include <iostream>
#include <stdexcept>
// Name of output file with geometry
const TString tagVersion = "_v18e";
const TString geoVersion = "much";
const TString FileNameSim = geoVersion + tagVersion + "_mcbm.geo.root";
const TString FileNameGeo = geoVersion + tagVersion + "_mcbm_geo.root";
const TString FileNameInfo = geoVersion + tagVersion + "_mcbm.geo.info";
// Names of the different used materials which are used to build the modules
// The materials are defined in the global media.geo file
const TString KeepingVolumeMedium = "air";
const TString L = "MUCHlead";
const TString W = "MUCHwolfram";
const TString C = "MUCHcarbon";
const TString I = "MUCHiron";
const TString activemedium = "MUCHargon";
const TString spacermedium = "MUCHnoryl";
const TString coolmedium = "aluminium"; //Al cooling plates
// Universal input parameters
// The inner angle is 11 degree (polar angle); We take z = 70 cm;
//Inner radius: R_in=z*tan(theta_min) cm
// Outer angle is decided from tan(theta_max)=R_out/z
// R_out=R_in+95 cm (transverse size of the M2 module)
Double_t fMuchZ1 = 0.0; // MuchCave Zin position [cm]
Double_t fAcceptanceTanMin = 0.19; // Acceptance tangent min (11 degree)
//************************************************************
// Input parameters for MUCH stations
//********************************************
const Int_t fNst = 1; // Number of stations
// Sector-type module parameters
// Number of sectors per layer (should be even for symmetry)
// Needs to be fixed with actual numbers
Double_t fActiveLzSector = 0.3; // Active volume thickness [cm]
Double_t fSpacerR1 = 2.8; // Spacer width in R at low Z[cm]
Double_t fSpacerR2 = 3.5; // Spacer width in R at high Z[cm]
Double_t fSpacerPhi = 2.8; // Spacer width in Phi [cm]
Double_t fOverlapR = 0.0; // Overlap in R direction [cm]
// Station Zceneter [cm] in the cave reference frame
//Double_t fStationZ0=80;
Double_t fStationZ0 = 70; // DE - move 10 cm upstream
Int_t fNlayers = 3; // Number of layers
Double_t fLayersDz = 10; // distance between the layers
Double_t fCoolLz = 1.0; // thickness of the cooling plate also used as support
/*
1 - detailed design (modules at two sides)
* 0 - simple design (1 module per layer)
*/
//***********************************************************
// some global variables
TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance
TGeoVolume* gModules_station[fNst]; // Global storage for module types
// Forward declarations
void create_materials_from_media_file();
TGeoVolume* CreateStations(int ist);
TGeoVolume* CreateLayers(int istn, int ily);
void create_MUCH_geometry_v18e()
{
// Load needed material definition from media.geo file
create_materials_from_media_file();
// Get the GeoManager for later usage
gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom");
gGeoMan->SetVisLevel(10);
// Create the top volume
TGeoBBox* topbox = new TGeoBBox("", 1000., 1000., 2000.);
TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air"));
gGeoMan->SetTopVolume(top);
TGeoVolume* much = new TGeoVolumeAssembly(geoVersion);
top->AddNode(much, 1);
TGeoVolume* sttn = new TGeoVolumeAssembly("station"); //change name from Station ->station
much->AddNode(sttn, 1);
for (Int_t istn = 0; istn < 1; istn++) { // 1 Station
gModules_station[istn] = CreateStations(istn);
sttn->AddNode(gModules_station[istn], istn);
}
gGeoMan->CloseGeometry();
gGeoMan->CheckOverlaps(0.000001);
gGeoMan->PrintOverlaps();
// gGeoMan->Test();
much->Export(FileNameSim); // an alternative way of writing the much
TFile* outfile = new TFile(FileNameSim, "UPDATE");
TGeoTranslation* much_placement = new TGeoTranslation("much_trans", 0., 0., 0.);
much_placement->Write();
outfile->Close();
outfile = new TFile(FileNameGeo, "RECREATE");
gGeoMan->Write(); // use this if you want GeoManager format in the output
outfile->Close();
top->Draw("ogl");
}
void create_materials_from_media_file()
{
// Use the FairRoot geometry interface to load the media which are already defined
FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
TString geoPath = gSystem->Getenv("VMCWORKDIR");
TString geoFile = geoPath + "/geometry/media.geo";
geoFace->setMediaFile(geoFile);
geoFace->readMedia();
// Read the required media and create them in the GeoManager
FairGeoMedia* geoMedia = geoFace->getMedia();
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
FairGeoMedium* air = geoMedia->getMedium(KeepingVolumeMedium);
geoBuild->createMedium(air);
FairGeoMedium* MUCHiron = geoMedia->getMedium(I);
geoBuild->createMedium(MUCHiron);
FairGeoMedium* MUCHlead = geoMedia->getMedium(L);
geoBuild->createMedium(MUCHlead);
FairGeoMedium* MUCHwolfram = geoMedia->getMedium(W);
geoBuild->createMedium(MUCHwolfram);
FairGeoMedium* MUCHcarbon = geoMedia->getMedium(C);
geoBuild->createMedium(MUCHcarbon);
FairGeoMedium* MUCHargon = geoMedia->getMedium(activemedium);
geoBuild->createMedium(MUCHargon);
FairGeoMedium* MUCHnoryl = geoMedia->getMedium(spacermedium);
geoBuild->createMedium(MUCHnoryl);
FairGeoMedium* aluminium = geoMedia->getMedium(coolmedium);
// geoBuild->createMedium(MUCHcool);
geoBuild->createMedium(aluminium);
}
TGeoVolume* CreateStations(int ist)
{
TString stationName = Form("muchstation%02i", ist + 1);
TGeoVolumeAssembly* station = new TGeoVolumeAssembly(stationName); //, shStation, air);
TGeoVolume* gLayer[4];
for (int ii = 0; ii < 3; ii++) { // 3 Layers
gLayer[ii] = CreateLayers(ist, ii);
station->AddNode(gLayer[ii], ii);
}
return station;
}
TGeoVolume* CreateLayers(int istn, int ily)
{
TString layerName = Form("muchstation%02ilayer%i", istn + 1, ily + 1);
TGeoVolumeAssembly* volayer = new TGeoVolumeAssembly(layerName);
//Double_t DeltaR=80.0; // transverse dimension of the module
Double_t stGlobalZ0 = fStationZ0 + fMuchZ1; //z position of station center (midplane) [cm]
Double_t stDz = ((fNlayers - 1) * fLayersDz + fCoolLz + 2 * fActiveLzSector) / 2.;
Double_t stGlobalZ2 = stGlobalZ0 + stDz;
Double_t stGlobalZ1 = stGlobalZ0 - stDz;
//Double_t rmin = stGlobalZ1 * fAcceptanceTanMin;
// Double_t rmax = rmin+ fSpacerR + DeltaR;
Int_t Nsector = 16.0; // need to be hard coded to match with station 1 of SIS100
//cout<<" Nsector "<<Nsector<<endl;
Double_t layerZ0 = (ily - (fNlayers - 1) / 2.) * fLayersDz;
Double_t layerGlobalZ0 = layerZ0 + stGlobalZ0;
Double_t sideDz = fCoolLz / 2. + fActiveLzSector / 2.; // distance between side's and layer's centers
Double_t moduleZ = sideDz; // Z position of the module center in the layer cs
Double_t phi0 = TMath::Pi() / Nsector; // azimuthal half widh of each module
//Double_t ymin = rmin+fSpacerR;
// Double_t ymax = rmax;
//define the dimensions of the trapezoidal module
//Use hard coded values for mini-cbm
Double_t dy = 40.0; //(ymax-ymin)/2.; //y (length)
Double_t dx1 = 3.75; //ymin*TMath::Tan(phi0)+fOverlapR/TMath::Cos(phi0); // large x
Double_t dx2 = 20; //ymax*TMath::Tan(phi0)+fOverlapR/TMath::Cos(phi0); // small x
Double_t dz = fActiveLzSector / 2.; // thickness
//define the spacer dimensions
Double_t tg = (dx2 - dx1) / 2 / dy;
Double_t dd1 = fSpacerPhi * tg;
Double_t dd2 = fSpacerPhi * sqrt(1 + tg * tg);
Double_t sdx1 = dx1 + dd2 - dd1;
Double_t sdx2 = dx2 + dd2 + dd1;
Double_t sdy1 = dy + fSpacerR1; // frame width added
Double_t sdy2 = dy + fSpacerR2; // frame width added
Double_t sdz = dz - 0.1;
// Define the (cooling plate) diemnsions (hardcoded for mcbm)
Double_t dy_s = sdy2; //46.5;//dy+2.0;
Double_t dx1_s = sdx1; //27.0; //dx1+2.0 ;// large x
Double_t dx2_s = sdx2; //27.0; //dx2+2.0;// x
Double_t dz_s = fCoolLz / 2.; //
TVector3 pos;
TVector3 size = TVector3(0.0, 0.0, fActiveLzSector);
// Now start adding the GEM modules
for (Int_t iModule = 0; iModule < 1; iModule++) {
// if (iModule!=0) continue;
// Double_t phi = 2 * phi0 * (iModule + 0.5); // add 0.5 to not overlap with y-axis for left-right layer separation
// Position of the module will depend on Phi
// Set Phi=180 degree 6 o'clock position
// Set Phi=90 degree 3 o'clock position
Double_t phi = TMath::Pi() / 2.0;
Bool_t isBack = iModule % 2;
Char_t cside = (isBack == 1) ? 'b' : 'f';
// correct the x, y positions
// pos[0] = -(ymin+dy)*sin(phi);
// pos[1] = (ymin+dy)*cos(phi);
pos[0] = 0; // DE - do not displace mMUCH in x
pos[1] = 0; //15; // DE - move upwards in y [cm]
// different z positions for odd/even modules
// pos[2] = (isBack ? 1 : -1)*moduleZ + layerGlobalZ0;
pos[2] = layerGlobalZ0;
TGeoMedium* argon = gGeoMan->GetMedium(activemedium); // active medium
TGeoMedium* noryl = gGeoMan->GetMedium(spacermedium); // spacer medium
TGeoMedium* aluminium = gGeoMan->GetMedium(coolmedium); // cool medium
// Define and place the trapezoidal GEM module in X-Y plane
TGeoTrap* shape = new TGeoTrap(dz, 0, phi, dy, dx1, dx2, 0, dy, dx1, dx2, 0);
// TGeoTrap* shape = new TGeoTrap(dz,0,0,dy,dx1,dx2,0,dy,dx1,dx2,0);
shape->SetName(Form("shStation%02iLayer%i%cModule%03iActiveNoHole", istn, ily, cside, iModule));
TString activeName = Form("muchstation%02ilayer%i%cactive%03igasArgon", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voActive = new TGeoVolume(activeName, shape, argon);
voActive->SetLineColor(kGreen);
// Define the trapezoidal spacers
TGeoTrap* shapeFrame = new TGeoTrap(sdz, 0, phi, sdy1, sdx1, sdx2, 0, sdy2, sdx1, sdx2, 0);
//TGeoTrap* shapeFrame = new TGeoTrap(sdz,0,0,sdy,sdx1,sdx2,0,sdy,sdx1,sdx2,0);
shapeFrame->SetName(Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole", istn, ily, cside, iModule));
TString expression = Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole-"
"shStation%02iLayer%i%cModule%03iActiveNoHole",
istn, ily, cside, iModule, istn, ily, cside, iModule);
TGeoCompositeShape* shFrame = new TGeoCompositeShape(
Form("shStation%02iLayer%i%cModule%03iFrameNoHole", istn, ily, cside, iModule), expression);
TString frameName = Form("muchstation%02ilayer%i%csupport%03i", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voFrame = new TGeoVolume(frameName, shFrame, noryl); // add a name to the frame
voFrame->SetLineColor(kMagenta);
// Define the trapezoidal (cooling plates)
// TGeoTrap* cool = new TGeoTrap(dz_s,0,phi,dy_s,dx1_s,dx2_s,0,dy_s,dx1_s,dx2_s,0);
TGeoTrap* cool = new TGeoTrap(dz_s, 0, phi, dy_s, dx1_s, dx2_s, 0, dy_s, dx1_s, dx2_s, 0);
cool->SetName(Form("shStation%02iLayer%i%cModule%03icool", istn, ily, cside, iModule));
TString CoolName = Form("muchstation%02ilayer%i%ccool%03iAluminum", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voCool = new TGeoVolume(CoolName, cool, aluminium);
voCool->SetLineColor(kYellow);
// Calculate the phi angle of the sector where it has to be placed
Double_t angle = 180. / TMath::Pi() * phi; // convert angle phi from rad to deg
TGeoTranslation* trans2 = new TGeoTranslation("", pos[0], pos[1], pos[2]); //for module and frame
TGeoTranslation* trans3 = new TGeoTranslation("", pos[0], pos[1], pos[2] + 0.65); //for module and frame
TGeoRotation* r2 = new TGeoRotation("r2");
//rotate in the vertical plane (per to z axis) with angle
// r2->RotateZ(angle);
// DE cout << "DE " << phi << endl;
// DE cout << "DE " << angle << endl;
// DE cout << "DE " << phi0 << endl;
// DE cout << "DE " << 180. / TMath::Pi() * phi0 << endl;
// r2->RotateZ(180.0); // DE - 6 o'clock position
r2->RotateZ(180.0 - (180. / TMath::Pi() * phi0)); // DE - 6 o'clock position, left side vertical
// r2->RotateZ(180.0-11.25); // DE - 6 o'clock position, left side vertical
// give rotation to set them in horizontal plane
//r2->RotateZ(90.0);//TMath::Pi());
TGeoHMatrix* incline_mod = new TGeoHMatrix("");
(*incline_mod) = (*trans2) * (*r2); // OK
volayer->AddNode(voFrame, iModule, incline_mod); // add frame
volayer->AddNode(voActive, iModule, incline_mod); // add active volume
TGeoHMatrix* incline_mod1 = new TGeoHMatrix("");
(*incline_mod1) = (*trans3) * (*r2); // for cooling
volayer->AddNode(voCool, iModule, incline_mod1); // cooling plate
}
return volayer;
}
/* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: David Emschermann [committer] */
//
/// \file create_MUCH_geometry_v18e.C
/// \brief Generates MUCH geometry in Root format.
///
// 2017-11-06 - PPB, VS and AM - v18e - mMUCH version with actual Mv2 dimesions of the module
// 2017-10-23 - DE - mcbm - put mMUCH in 6 o'clock position on z axis, shift 15 cm up and to z = 60, 70 and 80 cm
// 2017-09-04 - PPB - mcbm - preliminary version of mini much geometry
// 2017-05-16 - DE - v17b - position the modules in a way to split layers left-right along y axis
// 2017-05-16 - DE - v17b - attribute name to module frames
// 2017-05-16 - DE - v17b - remove rim from support CompositeShape
// 2017-05-02 - PPB - v17a - Change the shape of the first absorber according to latest design
// 2017-04-27 - DE - v17a - fix GEM module positions and angles
// 2017-04-22 - PPB - v17a - Define the absorber, shield and station shapes sizes ...
// 2016-04-19 - DE - v17a - initial version derived from TRD
// in root all sizes are given in cm
#include "TClonesArray.h"
#include "TDatime.h"
#include "TFile.h"
#include "TGeoBBox.h"
#include "TGeoCompositeShape.h"
#include "TGeoCone.h"
#include "TGeoManager.h"
#include "TGeoMaterial.h"
#include "TGeoMatrix.h"
#include "TGeoMedium.h"
#include "TGeoPgon.h"
#include "TGeoTube.h"
#include "TGeoVolume.h"
#include "TGeoXtru.h"
#include "TList.h"
#include "TMath.h"
#include "TObjArray.h"
#include "TRandom3.h"
#include "TString.h"
#include "TSystem.h"
#include <cassert>
#include <fstream>
#include <iostream>
#include <stdexcept>
// Name of output file with geometry
const TString tagVersion = "_v18e";
const TString geoVersion = "much";
//const TString subVersion = "_3oclock";
//const TString geoVersion = "much_" + tagVersion + subVersion;
const TString FileNameSim = geoVersion + tagVersion + "_mcbm.geo.root";
const TString FileNameGeo = geoVersion + tagVersion + "_mcbm_geo.root";
const TString FileNameInfo = geoVersion + tagVersion + "_mcbm.geo.info";
// Names of the different used materials which are used to build the modules
// The materials are defined in the global media.geo file
const TString KeepingVolumeMedium = "air";
const TString L = "MUCHlead";
const TString W = "MUCHwolfram";
const TString C = "MUCHcarbon";
const TString I = "MUCHiron";
const TString activemedium = "MUCHargon";
const TString spacermedium = "MUCHnoryl";
const TString coolmedium = "aluminium"; //Al cooling plates
// Universal input parameters
// The inner angle is 11 degree (polar angle); We take z = 70 cm;
//Inner radius: R_in=z*tan(theta_min) cm
// Outer angle is decided from tan(theta_max)=R_out/z
// R_out=R_in+95 cm (transverse size of the M2 module)
Double_t fMuchZ1 = 0.0; // MuchCave Zin position [cm]
Double_t fAcceptanceTanMin = 0.19; // Acceptance tangent min (11 degree)
//************************************************************
// Input parameters for MUCH stations
//********************************************
const Int_t fNst = 1; // Number of stations
// Sector-type module parameters
// Number of sectors per layer (should be even for symmetry)
// Needs to be fixed with actual numbers
Double_t fActiveLzSector = 0.3; // Active volume thickness [cm]
Double_t fSpacerR1 = 2.8; // Spacer width in R at low Z[cm]
Double_t fSpacerR2 = 3.5; // Spacer width in R at high Z[cm]
Double_t fSpacerPhi = 2.8; // Spacer width in Phi [cm]
Double_t fOverlapR = 0.0; // Overlap in R direction [cm]
// Station Zceneter [cm] in the cave reference frame
//Double_t fStationZ0=80;
Double_t fStationZ0 = 70; // DE - move 10 cm upstream
Int_t fNlayers = 3; // Number of layers
Double_t fLayersDz = 10; // distance between the layers
Double_t fCoolLz = 1.0; // thickness of the cooling plate also used as support
/*
1 - detailed design (modules at two sides)
* 0 - simple design (1 module per layer)
*/
//***********************************************************
// some global variables
TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance
TGeoVolume* gModules_station[fNst]; // Global storage for module types
// Forward declarations
void create_materials_from_media_file();
TGeoVolume* CreateStations(int ist);
TGeoVolume* CreateLayers(int istn, int ily);
void create_MUCH_geometry_v18e()
{
// Load needed material definition from media.geo file
create_materials_from_media_file();
// Get the GeoManager for later usage
gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom");
gGeoMan->SetVisLevel(10);
// Create the top volume
TGeoBBox* topbox = new TGeoBBox("", 1000., 1000., 2000.);
TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air"));
gGeoMan->SetTopVolume(top);
TGeoVolume* much = new TGeoVolumeAssembly(geoVersion);
top->AddNode(much, 1);
TGeoVolume* sttn = new TGeoVolumeAssembly("station"); //change name from Station ->station
much->AddNode(sttn, 1);
for (Int_t istn = 0; istn < 1; istn++) { // 1 Station
gModules_station[istn] = CreateStations(istn);
sttn->AddNode(gModules_station[istn], istn);
}
gGeoMan->CloseGeometry();
gGeoMan->CheckOverlaps(0.000001);
gGeoMan->PrintOverlaps();
// gGeoMan->Test();
// const TString tagVersion = "mcbm";
// const TString subVersion = "_3oclock";
// const TString geoVersion = "much_" + tagVersion + subVersion;
// const TString FileNameSim = geoVersion + ".geo.root";
// const TString FileNameGeo = geoVersion + "_geo.root";
much->Export(FileNameSim); // an alternative way of writing the much
TFile* outfile = new TFile(FileNameSim, "UPDATE");
TGeoTranslation* much_placement = new TGeoTranslation("much_trans", 0., 0., 0.);
much_placement->Write();
outfile->Close();
outfile = new TFile(FileNameGeo, "RECREATE");
gGeoMan->Write(); // use this if you want GeoManager format in the output
outfile->Close();
top->Draw("ogl");
}
void create_materials_from_media_file()
{
// Use the FairRoot geometry interface to load the media which are already defined
FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
TString geoPath = gSystem->Getenv("VMCWORKDIR");
TString geoFile = geoPath + "/geometry/media.geo";
geoFace->setMediaFile(geoFile);
geoFace->readMedia();
// Read the required media and create them in the GeoManager
FairGeoMedia* geoMedia = geoFace->getMedia();
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
FairGeoMedium* air = geoMedia->getMedium(KeepingVolumeMedium);
geoBuild->createMedium(air);
FairGeoMedium* MUCHiron = geoMedia->getMedium(I);
geoBuild->createMedium(MUCHiron);
FairGeoMedium* MUCHlead = geoMedia->getMedium(L);
geoBuild->createMedium(MUCHlead);
FairGeoMedium* MUCHwolfram = geoMedia->getMedium(W);
geoBuild->createMedium(MUCHwolfram);
FairGeoMedium* MUCHcarbon = geoMedia->getMedium(C);
geoBuild->createMedium(MUCHcarbon);
FairGeoMedium* MUCHargon = geoMedia->getMedium(activemedium);
geoBuild->createMedium(MUCHargon);
FairGeoMedium* MUCHnoryl = geoMedia->getMedium(spacermedium);
geoBuild->createMedium(MUCHnoryl);
FairGeoMedium* aluminium = geoMedia->getMedium(coolmedium);
// geoBuild->createMedium(MUCHcool);
geoBuild->createMedium(aluminium);
}
TGeoVolume* CreateStations(int ist)
{
TString stationName = Form("muchstation%02i", ist + 1);
TGeoVolumeAssembly* station = new TGeoVolumeAssembly(stationName); //, shStation, air);
TGeoVolume* gLayer[4];
for (int ii = 0; ii < 3; ii++) { // 3 Layers
gLayer[ii] = CreateLayers(ist, ii);
station->AddNode(gLayer[ii], ii);
}
return station;
}
TGeoVolume* CreateLayers(int istn, int ily)
{
TString layerName = Form("muchstation%02ilayer%i", istn + 1, ily + 1);
TGeoVolumeAssembly* volayer = new TGeoVolumeAssembly(layerName);
//Double_t DeltaR=80.0; // transverse dimension of the module
Double_t stGlobalZ0 = fStationZ0 + fMuchZ1; //z position of station center (midplane) [cm]
Double_t stDz = ((fNlayers - 1) * fLayersDz + fCoolLz + 2 * fActiveLzSector) / 2.;
Double_t stGlobalZ2 = stGlobalZ0 + stDz;
Double_t stGlobalZ1 = stGlobalZ0 - stDz;
//Double_t rmin = stGlobalZ1 * fAcceptanceTanMin;
// Double_t rmax = rmin+ fSpacerR + DeltaR;
Int_t Nsector = 16.0; // need to be hard coded to match with station 1 of SIS100
//cout<<" Nsector "<<Nsector<<endl;
Double_t layerZ0 = (ily - (fNlayers - 1) / 2.) * fLayersDz;
Double_t layerGlobalZ0 = layerZ0 + stGlobalZ0;
Double_t sideDz = fCoolLz / 2. + fActiveLzSector / 2.; // distance between side's and layer's centers
Double_t moduleZ = sideDz; // Z position of the module center in the layer cs
Double_t phi0 = TMath::Pi() / Nsector; // azimuthal half widh of each module
//Double_t ymin = rmin+fSpacerR;
// Double_t ymax = rmax;
//define the dimensions of the trapezoidal module
//Use hard coded values for mini-cbm
Double_t dy = 40.0; //(ymax-ymin)/2.; //y (length)
Double_t dx1 = 3.75; //ymin*TMath::Tan(phi0)+fOverlapR/TMath::Cos(phi0); // large x
Double_t dx2 = 20; //ymax*TMath::Tan(phi0)+fOverlapR/TMath::Cos(phi0); // small x
Double_t dz = fActiveLzSector / 2.; // thickness
//define the spacer dimensions
Double_t tg = (dx2 - dx1) / 2 / dy;
Double_t dd1 = fSpacerPhi * tg;
Double_t dd2 = fSpacerPhi * sqrt(1 + tg * tg);
Double_t sdx1 = dx1 + dd2 - dd1;
Double_t sdx2 = dx2 + dd2 + dd1;
Double_t sdy1 = dy + fSpacerR1; // frame width added
Double_t sdy2 = dy + fSpacerR2; // frame width added
Double_t sdz = dz - 0.1;
// Define the (cooling plate) diemnsions (hardcoded for mcbm)
Double_t dy_s = 46.5; //dy+2.0;
Double_t dx1_s = 27.0; //dx1+2.0 ;// large x
Double_t dx2_s = 27.0; //dx2+2.0;// x
Double_t dz_s = fCoolLz / 2.; //
TVector3 pos;
TVector3 size = TVector3(0.0, 0.0, fActiveLzSector);
// Now start adding the GEM modules
for (Int_t iModule = 0; iModule < 1; iModule++) {
// if (iModule!=0) continue;
// Double_t phi = 2 * phi0 * (iModule + 0.5); // add 0.5 to not overlap with y-axis for left-right layer separation
// Position of the module will depend on Phi
// Set Phi=180 degree 6 o'clock position
// Set Phi=90 degree 3 o'clock position
Double_t phi = TMath::Pi() / 2.0;
Bool_t isBack = iModule % 2;
Char_t cside = (isBack == 1) ? 'b' : 'f';
// correct the x, y positions
// pos[0] = -(ymin+dy)*sin(phi);
// pos[1] = (ymin+dy)*cos(phi);
pos[0] = 0; // DE - do not displace mMUCH in x
pos[1] = 15; // DE - move upwards in y [cm]
// different z positions for odd/even modules
// pos[2] = (isBack ? 1 : -1)*moduleZ + layerGlobalZ0;
pos[2] = layerGlobalZ0;
TGeoMedium* argon = gGeoMan->GetMedium(activemedium); // active medium
TGeoMedium* noryl = gGeoMan->GetMedium(spacermedium); // spacer medium
TGeoMedium* aluminium = gGeoMan->GetMedium(coolmedium); // cool medium
// Define and place the trapezoidal GEM module in X-Y plane
TGeoTrap* shape = new TGeoTrap(dz, 0, phi, dy, dx1, dx2, 0, dy, dx1, dx2, 0);
// TGeoTrap* shape = new TGeoTrap(dz,0,0,dy,dx1,dx2,0,dy,dx1,dx2,0);
shape->SetName(Form("shStation%02iLayer%i%cModule%03iActiveNoHole", istn, ily, cside, iModule));
TString activeName = Form("muchstation%02ilayer%i%cactive%03igasArgon", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voActive = new TGeoVolume(activeName, shape, argon);
voActive->SetLineColor(kGreen);
// Define the trapezoidal spacers
TGeoTrap* shapeFrame = new TGeoTrap(sdz, 0, phi, sdy1, sdx1, sdx2, 0, sdy2, sdx1, sdx2, 0);
//TGeoTrap* shapeFrame = new TGeoTrap(sdz,0,0,sdy,sdx1,sdx2,0,sdy,sdx1,sdx2,0);
shapeFrame->SetName(Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole", istn, ily, cside, iModule));
TString expression = Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole-"
"shStation%02iLayer%i%cModule%03iActiveNoHole",
istn, ily, cside, iModule, istn, ily, cside, iModule);
TGeoCompositeShape* shFrame = new TGeoCompositeShape(
Form("shStation%02iLayer%i%cModule%03iFrameNoHole", istn, ily, cside, iModule), expression);
TString frameName = Form("muchstation%02ilayer%i%csupport%03i", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voFrame = new TGeoVolume(frameName, shFrame, noryl); // add a name to the frame
voFrame->SetLineColor(kMagenta);
// Define the trapezoidal (cooling plates)
// TGeoTrap* cool = new TGeoTrap(dz_s,0,phi,dy_s,dx1_s,dx2_s,0,dy_s,dx1_s,dx2_s,0);
TGeoTrap* cool = new TGeoTrap(dz_s, 0, phi, dy_s, dx1_s, dx2_s, 0, dy_s, dx1_s, dx2_s, 0);
cool->SetName(Form("shStation%02iLayer%i%cModule%03icool", istn, ily, cside, iModule));
TString CoolName = Form("muchstation%02ilayer%i%ccool%03iAluminum", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voCool = new TGeoVolume(CoolName, cool, aluminium);
voCool->SetLineColor(kYellow);
// Calculate the phi angle of the sector where it has to be placed
Double_t angle = 180. / TMath::Pi() * phi; // convert angle phi from rad to deg
TGeoTranslation* trans2 = new TGeoTranslation("", pos[0], pos[1], pos[2]); //for module and frame
TGeoTranslation* trans3 = new TGeoTranslation("", pos[0], pos[1], pos[2] + 0.65); //for module and frame
TGeoRotation* r2 = new TGeoRotation("r2");
//rotate in the vertical plane (per to z axis) with angle
// r2->RotateZ(angle);
// DE cout << "DE " << phi << endl;
// DE cout << "DE " << angle << endl;
// DE cout << "DE " << phi0 << endl;
// DE cout << "DE " << 180. / TMath::Pi() * phi0 << endl;
// r2->RotateZ(180.0); // DE - 6 o'clock position
r2->RotateZ(180.0 - (180. / TMath::Pi() * phi0)); // DE - 6 o'clock position, left side vertical
// give rotation to set them in horizontal plane
//r2->RotateZ(90.0);//TMath::Pi());
TGeoHMatrix* incline_mod = new TGeoHMatrix("");
(*incline_mod) = (*trans2) * (*r2); // OK
volayer->AddNode(voFrame, iModule, incline_mod); // add frame
volayer->AddNode(voActive, iModule, incline_mod); // add active volume
TGeoHMatrix* incline_mod1 = new TGeoHMatrix("");
(*incline_mod1) = (*trans3) * (*r2); // for cooling
volayer->AddNode(voCool, iModule, incline_mod1); // cooling plate
}
return volayer;
}
/* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: David Emschermann [committer] */
//
/// \file create_MUCH_geometry_v18f.C
/// \brief Generates MUCH geometry in Root format.
///
// 2017-11-15 - DE - v18f - shift mMUCH back to z = 70, 80 and 90 cm to avoid clash with mSTS box
// 2017-11-06 - PPB, VS and AM - v18e - mMUCH version with actual Mv2 dimesions of the module
// 2017-10-23 - DE - v18e - put mMUCH in 6 o'clock position on z axis, shift 15 cm up and to z = 60, 70 and 80 cm
// 2017-09-04 - PPB - mcbm - preliminary version of mini much geometry
// 2017-05-16 - DE - v17b - position the modules in a way to split layers left-right along y axis
// 2017-05-16 - DE - v17b - attribute name to module frames
// 2017-05-16 - DE - v17b - remove rim from support CompositeShape
// 2017-05-02 - PPB - v17a - Change the shape of the first absorber according to latest design
// 2017-04-27 - DE - v17a - fix GEM module positions and angles
// 2017-04-22 - PPB - v17a - Define the absorber, shield and station shapes sizes ...
// 2016-04-19 - DE - v17a - initial version derived from TRD
// in root all sizes are given in cm
#include "TClonesArray.h"
#include "TDatime.h"
#include "TFile.h"
#include "TGeoBBox.h"
#include "TGeoCompositeShape.h"
#include "TGeoCone.h"
#include "TGeoManager.h"
#include "TGeoMaterial.h"
#include "TGeoMatrix.h"
#include "TGeoMedium.h"
#include "TGeoPgon.h"
#include "TGeoTube.h"
#include "TGeoVolume.h"
#include "TGeoXtru.h"
#include "TList.h"
#include "TMath.h"
#include "TObjArray.h"
#include "TRandom3.h"
#include "TString.h"
#include "TSystem.h"
#include <cassert>
#include <fstream>
#include <iostream>
#include <stdexcept>
// Name of output file with geometry
const TString tagVersion = "_v18f";
const TString geoVersion = "much";
//const TString subVersion = "_3oclock";
//const TString geoVersion = "much_" + tagVersion + subVersion;
const TString FileNameSim = geoVersion + tagVersion + "_mcbm.geo.root";
const TString FileNameGeo = geoVersion + tagVersion + "_mcbm_geo.root";
const TString FileNameInfo = geoVersion + tagVersion + "_mcbm.geo.info";
// Names of the different used materials which are used to build the modules
// The materials are defined in the global media.geo file
const TString KeepingVolumeMedium = "air";
const TString L = "MUCHlead";
const TString W = "MUCHwolfram";
const TString C = "MUCHcarbon";
const TString I = "MUCHiron";
const TString activemedium = "MUCHargon";
const TString spacermedium = "MUCHnoryl";
const TString coolmedium = "aluminium"; //Al cooling plates
// Universal input parameters
// The inner angle is 11 degree (polar angle); We take z = 70 cm;
//Inner radius: R_in=z*tan(theta_min) cm
// Outer angle is decided from tan(theta_max)=R_out/z
// R_out=R_in+95 cm (transverse size of the M2 module)
Double_t fMuchZ1 = 0.0; // MuchCave Zin position [cm]
Double_t fAcceptanceTanMin = 0.19; // Acceptance tangent min (11 degree)
//************************************************************
// Input parameters for MUCH stations
//********************************************
const Int_t fNst = 1; // Number of stations
// Sector-type module parameters
// Number of sectors per layer (should be even for symmetry)
// Needs to be fixed with actual numbers
Double_t fActiveLzSector = 0.3; // Active volume thickness [cm]
Double_t fSpacerR1 = 2.8; // Spacer width in R at low Z[cm]
Double_t fSpacerR2 = 3.5; // Spacer width in R at high Z[cm]
Double_t fSpacerPhi = 2.8; // Spacer width in Phi [cm]
Double_t fOverlapR = 0.0; // Overlap in R direction [cm]
// Station Zceneter [cm] in the cave reference frame
Double_t fStationZ0 = 80;
//Double_t fStationZ0=70; // DE - move 10 cm upstream
Int_t fNlayers = 3; // Number of layers
Double_t fLayersDz = 10; // distance between the layers
Double_t fCoolLz = 1.0; // thickness of the cooling plate also used as support
/*
1 - detailed design (modules at two sides)
* 0 - simple design (1 module per layer)
*/
//***********************************************************
// some global variables
TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance
TGeoVolume* gModules_station[fNst]; // Global storage for module types
// Forward declarations
void create_materials_from_media_file();
TGeoVolume* CreateStations(int ist);
TGeoVolume* CreateLayers(int istn, int ily);
void create_MUCH_geometry_v18f()
{
// Load needed material definition from media.geo file
create_materials_from_media_file();
// Get the GeoManager for later usage
gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom");
gGeoMan->SetVisLevel(10);
// Create the top volume
TGeoBBox* topbox = new TGeoBBox("", 1000., 1000., 2000.);
TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air"));
gGeoMan->SetTopVolume(top);
TGeoVolume* much = new TGeoVolumeAssembly(geoVersion);
top->AddNode(much, 1);
TGeoVolume* sttn = new TGeoVolumeAssembly("station"); //change name from Station ->station
much->AddNode(sttn, 1);
for (Int_t istn = 0; istn < 1; istn++) { // 1 Station
gModules_station[istn] = CreateStations(istn);
sttn->AddNode(gModules_station[istn], istn);
}
gGeoMan->CloseGeometry();
gGeoMan->CheckOverlaps(0.000001);
gGeoMan->PrintOverlaps();
// gGeoMan->Test();
// const TString tagVersion = "mcbm";
// const TString subVersion = "_3oclock";
// const TString geoVersion = "much_" + tagVersion + subVersion;
// const TString FileNameSim = geoVersion + ".geo.root";
// const TString FileNameGeo = geoVersion + "_geo.root";
much->Export(FileNameSim); // an alternative way of writing the much
TFile* outfile = new TFile(FileNameSim, "UPDATE");
TGeoTranslation* much_placement = new TGeoTranslation("much_trans", 0., 0., 0.);
much_placement->Write();
outfile->Close();
outfile = new TFile(FileNameGeo, "RECREATE");
gGeoMan->Write(); // use this if you want GeoManager format in the output
outfile->Close();
top->Draw("ogl");
}
void create_materials_from_media_file()
{
// Use the FairRoot geometry interface to load the media which are already defined
FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
TString geoPath = gSystem->Getenv("VMCWORKDIR");
TString geoFile = geoPath + "/geometry/media.geo";
geoFace->setMediaFile(geoFile);
geoFace->readMedia();
// Read the required media and create them in the GeoManager
FairGeoMedia* geoMedia = geoFace->getMedia();
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
FairGeoMedium* air = geoMedia->getMedium(KeepingVolumeMedium);
geoBuild->createMedium(air);
FairGeoMedium* MUCHiron = geoMedia->getMedium(I);
geoBuild->createMedium(MUCHiron);
FairGeoMedium* MUCHlead = geoMedia->getMedium(L);
geoBuild->createMedium(MUCHlead);
FairGeoMedium* MUCHwolfram = geoMedia->getMedium(W);
geoBuild->createMedium(MUCHwolfram);
FairGeoMedium* MUCHcarbon = geoMedia->getMedium(C);
geoBuild->createMedium(MUCHcarbon);
FairGeoMedium* MUCHargon = geoMedia->getMedium(activemedium);
geoBuild->createMedium(MUCHargon);
FairGeoMedium* MUCHnoryl = geoMedia->getMedium(spacermedium);
geoBuild->createMedium(MUCHnoryl);
FairGeoMedium* aluminium = geoMedia->getMedium(coolmedium);
// geoBuild->createMedium(MUCHcool);
geoBuild->createMedium(aluminium);
}
TGeoVolume* CreateStations(int ist)
{
TString stationName = Form("muchstation%02i", ist + 1);
TGeoVolumeAssembly* station = new TGeoVolumeAssembly(stationName); //, shStation, air);
TGeoVolume* gLayer[4];
for (int ii = 0; ii < 3; ii++) { // 3 Layers
gLayer[ii] = CreateLayers(ist, ii);
station->AddNode(gLayer[ii], ii);
}
return station;
}
TGeoVolume* CreateLayers(int istn, int ily)
{
TString layerName = Form("muchstation%02ilayer%i", istn + 1, ily + 1);
TGeoVolumeAssembly* volayer = new TGeoVolumeAssembly(layerName);
//Double_t DeltaR=80.0; // transverse dimension of the module
Double_t stGlobalZ0 = fStationZ0 + fMuchZ1; //z position of station center (midplane) [cm]
Double_t stDz = ((fNlayers - 1) * fLayersDz + fCoolLz + 2 * fActiveLzSector) / 2.;
Double_t stGlobalZ2 = stGlobalZ0 + stDz;
Double_t stGlobalZ1 = stGlobalZ0 - stDz;
//Double_t rmin = stGlobalZ1 * fAcceptanceTanMin;
// Double_t rmax = rmin+ fSpacerR + DeltaR;
Int_t Nsector = 16.0; // need to be hard coded to match with station 1 of SIS100
//cout<<" Nsector "<<Nsector<<endl;
Double_t layerZ0 = (ily - (fNlayers - 1) / 2.) * fLayersDz;
Double_t layerGlobalZ0 = layerZ0 + stGlobalZ0;
Double_t sideDz = fCoolLz / 2. + fActiveLzSector / 2.; // distance between side's and layer's centers
Double_t moduleZ = sideDz; // Z position of the module center in the layer cs
Double_t phi0 = TMath::Pi() / Nsector; // azimuthal half widh of each module
//Double_t ymin = rmin+fSpacerR;
// Double_t ymax = rmax;
//define the dimensions of the trapezoidal module
//Use hard coded values for mini-cbm
Double_t dy = 40.0; //(ymax-ymin)/2.; //y (length)
Double_t dx1 = 3.75; //ymin*TMath::Tan(phi0)+fOverlapR/TMath::Cos(phi0); // large x
Double_t dx2 = 20; //ymax*TMath::Tan(phi0)+fOverlapR/TMath::Cos(phi0); // small x
Double_t dz = fActiveLzSector / 2.; // thickness
//define the spacer dimensions
Double_t tg = (dx2 - dx1) / 2 / dy;
Double_t dd1 = fSpacerPhi * tg;
Double_t dd2 = fSpacerPhi * sqrt(1 + tg * tg);
Double_t sdx1 = dx1 + dd2 - dd1;
Double_t sdx2 = dx2 + dd2 + dd1;
Double_t sdy1 = dy + fSpacerR1; // frame width added
Double_t sdy2 = dy + fSpacerR2; // frame width added
Double_t sdz = dz - 0.1;
// Define the (cooling plate) diemnsions (hardcoded for mcbm)
Double_t dy_s = 46.5; //dy+2.0;
Double_t dx1_s = 27.0; //dx1+2.0 ;// large x
Double_t dx2_s = 27.0; //dx2+2.0;// x
Double_t dz_s = fCoolLz / 2.; //
TVector3 pos;
TVector3 size = TVector3(0.0, 0.0, fActiveLzSector);
// Now start adding the GEM modules
for (Int_t iModule = 0; iModule < 1; iModule++) {
// if (iModule!=0) continue;
// Double_t phi = 2 * phi0 * (iModule + 0.5); // add 0.5 to not overlap with y-axis for left-right layer separation
// Position of the module will depend on Phi
// Set Phi=180 degree 6 o'clock position
// Set Phi=90 degree 3 o'clock position
Double_t phi = TMath::Pi() / 2.0;
Bool_t isBack = iModule % 2;
Char_t cside = (isBack == 1) ? 'b' : 'f';
// correct the x, y positions
// pos[0] = -(ymin+dy)*sin(phi);
// pos[1] = (ymin+dy)*cos(phi);
pos[0] = 0; // DE - do not displace mMUCH in x
pos[1] = 15; // DE - move upwards in y [cm]
// different z positions for odd/even modules
// pos[2] = (isBack ? 1 : -1)*moduleZ + layerGlobalZ0;
pos[2] = layerGlobalZ0;
TGeoMedium* argon = gGeoMan->GetMedium(activemedium); // active medium
TGeoMedium* noryl = gGeoMan->GetMedium(spacermedium); // spacer medium
TGeoMedium* aluminium = gGeoMan->GetMedium(coolmedium); // cool medium
// Define and place the trapezoidal GEM module in X-Y plane
TGeoTrap* shape = new TGeoTrap(dz, 0, phi, dy, dx1, dx2, 0, dy, dx1, dx2, 0);
// TGeoTrap* shape = new TGeoTrap(dz,0,0,dy,dx1,dx2,0,dy,dx1,dx2,0);
shape->SetName(Form("shStation%02iLayer%i%cModule%03iActiveNoHole", istn, ily, cside, iModule));
TString activeName = Form("muchstation%02ilayer%i%cactive%03igasArgon", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voActive = new TGeoVolume(activeName, shape, argon);
voActive->SetLineColor(kGreen);
// Define the trapezoidal spacers
TGeoTrap* shapeFrame = new TGeoTrap(sdz, 0, phi, sdy1, sdx1, sdx2, 0, sdy2, sdx1, sdx2, 0);
//TGeoTrap* shapeFrame = new TGeoTrap(sdz,0,0,sdy,sdx1,sdx2,0,sdy,sdx1,sdx2,0);
shapeFrame->SetName(Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole", istn, ily, cside, iModule));
TString expression = Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole-"
"shStation%02iLayer%i%cModule%03iActiveNoHole",
istn, ily, cside, iModule, istn, ily, cside, iModule);
TGeoCompositeShape* shFrame = new TGeoCompositeShape(
Form("shStation%02iLayer%i%cModule%03iFrameNoHole", istn, ily, cside, iModule), expression);
TString frameName = Form("muchstation%02ilayer%i%csupport%03i", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voFrame = new TGeoVolume(frameName, shFrame, noryl); // add a name to the frame
voFrame->SetLineColor(kMagenta);
// Define the trapezoidal (cooling plates)
// TGeoTrap* cool = new TGeoTrap(dz_s,0,phi,dy_s,dx1_s,dx2_s,0,dy_s,dx1_s,dx2_s,0);
TGeoTrap* cool = new TGeoTrap(dz_s, 0, phi, dy_s, dx1_s, dx2_s, 0, dy_s, dx1_s, dx2_s, 0);
cool->SetName(Form("shStation%02iLayer%i%cModule%03icool", istn, ily, cside, iModule));
TString CoolName = Form("muchstation%02ilayer%i%ccool%03iAluminum", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voCool = new TGeoVolume(CoolName, cool, aluminium);
voCool->SetLineColor(kYellow);
// Calculate the phi angle of the sector where it has to be placed
Double_t angle = 180. / TMath::Pi() * phi; // convert angle phi from rad to deg
TGeoTranslation* trans2 = new TGeoTranslation("", pos[0], pos[1], pos[2]); //for module and frame
TGeoTranslation* trans3 = new TGeoTranslation("", pos[0], pos[1], pos[2] + 0.65); //for module and frame
TGeoRotation* r2 = new TGeoRotation("r2");
//rotate in the vertical plane (per to z axis) with angle
// r2->RotateZ(angle);
// DE cout << "DE " << phi << endl;
// DE cout << "DE " << angle << endl;
// DE cout << "DE " << phi0 << endl;
// DE cout << "DE " << 180. / TMath::Pi() * phi0 << endl;
// r2->RotateZ(180.0); // DE - 6 o'clock position
r2->RotateZ(180.0 - (180. / TMath::Pi() * phi0)); // DE - 6 o'clock position, left side vertical
// give rotation to set them in horizontal plane
//r2->RotateZ(90.0);//TMath::Pi());
TGeoHMatrix* incline_mod = new TGeoHMatrix("");
(*incline_mod) = (*trans2) * (*r2); // OK
volayer->AddNode(voFrame, iModule, incline_mod); // add frame
volayer->AddNode(voActive, iModule, incline_mod); // add active volume
TGeoHMatrix* incline_mod1 = new TGeoHMatrix("");
(*incline_mod1) = (*trans3) * (*r2); // for cooling
volayer->AddNode(voCool, iModule, incline_mod1); // cooling plate
}
return volayer;
}
/* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: David Emschermann [committer] */
//
/// \file create_MUCH_geometry_v18g.C
/// \brief Generates MUCH geometry in Root format.
///
// 2017-11-20 - DE - v18g - shift back to z = 70, 80 and 90 cm to avoid mSTS box
// 2017-11-10 - PPB - - correct the y position of the modules to generate much points
// 2017-11-07 - PPB - - change the shape of cooling plates from rectangular to sector
// 2017-11-06 - PPB, VS and AM - mcbm version with actual Mv2 dimesions of the module
// 2017-10-23 - DE - mcbm - put mMUCH in 6 o'clock position on z axis, shift 15 cm up and to z = 60, 70 and 80 cm
// 2017-09-04 - PPB - mcbm - preliminary version of mini much geometry
// 2017-05-16 - DE - v17b - position the modules in a way to split layers left-right along y axis
// 2017-05-16 - DE - v17b - attribute name to module frames
// 2017-05-16 - DE - v17b - remove rim from support CompositeShape
// 2017-05-02 - PPB - v17a - Change the shape of the first absorber according to latest design
// 2017-04-27 - DE - v17a - fix GEM module positions and angles
// 2017-04-22 - PPB - v17a - Define the absorber, shield and station shapes sizes ...
// 2016-04-19 - DE - v17a - initial version derived from TRD
// in root all sizes are given in cm
#include "TClonesArray.h"
#include "TDatime.h"
#include "TFile.h"
#include "TGeoBBox.h"
#include "TGeoCompositeShape.h"
#include "TGeoCone.h"
#include "TGeoManager.h"
#include "TGeoMaterial.h"
#include "TGeoMatrix.h"
#include "TGeoMedium.h"
#include "TGeoPgon.h"
#include "TGeoTube.h"
#include "TGeoVolume.h"
#include "TGeoXtru.h"
#include "TList.h"
#include "TMath.h"
#include "TObjArray.h"
#include "TRandom3.h"
#include "TString.h"
#include "TSystem.h"
#include <cassert>
#include <fstream>
#include <iostream>
#include <stdexcept>
// Name of output file with geometry
const TString tagVersion = "_v18g";
const TString geoVersion = "much";
const TString FileNameSim = geoVersion + tagVersion + "_mcbm.geo.root";
const TString FileNameGeo = geoVersion + tagVersion + "_mcbm_geo.root";
const TString FileNameInfo = geoVersion + tagVersion + "_mcbm.geo.info";
// Names of the different used materials which are used to build the modules
// The materials are defined in the global media.geo file
const TString KeepingVolumeMedium = "air";
const TString L = "MUCHlead";
const TString W = "MUCHwolfram";
const TString C = "MUCHcarbon";
const TString I = "MUCHiron";
const TString activemedium = "MUCHargon";
const TString spacermedium = "MUCHnoryl";
const TString coolmedium = "aluminium"; //Al cooling plates
// Universal input parameters
// The inner angle is 11 degree (polar angle); We take z = 70 cm;
//Inner radius: R_in=z*tan(theta_min) cm
// Outer angle is decided from tan(theta_max)=R_out/z
// R_out=R_in+95 cm (transverse size of the M2 module)
Double_t fMuchZ1 = 0.0; // MuchCave Zin position [cm]
Double_t fAcceptanceTanMin = 0.19; // Acceptance tangent min (11 degree)
//************************************************************
// Input parameters for MUCH stations
//********************************************
const Int_t fNst = 1; // Number of stations
// Sector-type module parameters
// Number of sectors per layer (should be even for symmetry)
// Needs to be fixed with actual numbers
Double_t fActiveLzSector = 0.3; // Active volume thickness [cm]
Double_t fSpacerR1 = 2.8; // Spacer width in R at low Z[cm]
Double_t fSpacerR2 = 3.5; // Spacer width in R at high Z[cm]
Double_t fSpacerPhi = 2.8; // Spacer width in Phi [cm]
Double_t fOverlapR = 0.0; // Overlap in R direction [cm]
// Station Zceneter [cm] in the cave reference frame
Double_t fStationZ0 = 80;
//Double_t fStationZ0=70; // DE - move 10 cm upstream
Int_t fNlayers = 3; // Number of layers
Double_t fLayersDz = 10; // distance between the layers
Double_t fCoolLz = 1.0; // thickness of the cooling plate also used as support
/*
1 - detailed design (modules at two sides)
* 0 - simple design (1 module per layer)
*/
//***********************************************************
// some global variables
TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance
TGeoVolume* gModules_station[fNst]; // Global storage for module types
// Forward declarations
void create_materials_from_media_file();
TGeoVolume* CreateStations(int ist);
TGeoVolume* CreateLayers(int istn, int ily);
void create_MUCH_geometry_v18g()
{
// Load needed material definition from media.geo file
create_materials_from_media_file();
// Get the GeoManager for later usage
gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom");
gGeoMan->SetVisLevel(10);
// Create the top volume
TGeoBBox* topbox = new TGeoBBox("", 1000., 1000., 2000.);
TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air"));
gGeoMan->SetTopVolume(top);
TGeoVolume* much = new TGeoVolumeAssembly(geoVersion);
top->AddNode(much, 1);
TGeoVolume* sttn = new TGeoVolumeAssembly("station"); //change name from Station ->station
much->AddNode(sttn, 1);
for (Int_t istn = 0; istn < 1; istn++) { // 1 Station
gModules_station[istn] = CreateStations(istn);
sttn->AddNode(gModules_station[istn], istn);
}
gGeoMan->CloseGeometry();
gGeoMan->CheckOverlaps(0.000001);
gGeoMan->PrintOverlaps();
// gGeoMan->Test();
much->Export(FileNameSim); // an alternative way of writing the much
TFile* outfile = new TFile(FileNameSim, "UPDATE");
TGeoTranslation* much_placement = new TGeoTranslation("much_trans", 0., 0., 0.);
much_placement->Write();
outfile->Close();
outfile = new TFile(FileNameGeo, "RECREATE");
gGeoMan->Write(); // use this if you want GeoManager format in the output
outfile->Close();
top->Draw("ogl");
}
void create_materials_from_media_file()
{
// Use the FairRoot geometry interface to load the media which are already defined
FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
TString geoPath = gSystem->Getenv("VMCWORKDIR");
TString geoFile = geoPath + "/geometry/media.geo";
geoFace->setMediaFile(geoFile);
geoFace->readMedia();
// Read the required media and create them in the GeoManager
FairGeoMedia* geoMedia = geoFace->getMedia();
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
FairGeoMedium* air = geoMedia->getMedium(KeepingVolumeMedium);
geoBuild->createMedium(air);
FairGeoMedium* MUCHiron = geoMedia->getMedium(I);
geoBuild->createMedium(MUCHiron);
FairGeoMedium* MUCHlead = geoMedia->getMedium(L);
geoBuild->createMedium(MUCHlead);
FairGeoMedium* MUCHwolfram = geoMedia->getMedium(W);
geoBuild->createMedium(MUCHwolfram);
FairGeoMedium* MUCHcarbon = geoMedia->getMedium(C);
geoBuild->createMedium(MUCHcarbon);
FairGeoMedium* MUCHargon = geoMedia->getMedium(activemedium);
geoBuild->createMedium(MUCHargon);
FairGeoMedium* MUCHnoryl = geoMedia->getMedium(spacermedium);
geoBuild->createMedium(MUCHnoryl);
FairGeoMedium* aluminium = geoMedia->getMedium(coolmedium);
// geoBuild->createMedium(MUCHcool);
geoBuild->createMedium(aluminium);
}
TGeoVolume* CreateStations(int ist)
{
TString stationName = Form("muchstation%02i", ist + 1);
TGeoVolumeAssembly* station = new TGeoVolumeAssembly(stationName); //, shStation, air);
TGeoVolume* gLayer[4];
for (int ii = 0; ii < 3; ii++) { // 3 Layers
gLayer[ii] = CreateLayers(ist, ii);
station->AddNode(gLayer[ii], ii);
}
return station;
}
TGeoVolume* CreateLayers(int istn, int ily)
{
TString layerName = Form("muchstation%02ilayer%i", istn + 1, ily + 1);
TGeoVolumeAssembly* volayer = new TGeoVolumeAssembly(layerName);
//Double_t DeltaR=80.0; // transverse dimension of the module
Double_t stGlobalZ0 = fStationZ0 + fMuchZ1; //z position of station center (midplane) [cm]
Double_t stDz = ((fNlayers - 1) * fLayersDz + fCoolLz + 2 * fActiveLzSector) / 2.;
Double_t stGlobalZ2 = stGlobalZ0 + stDz;
Double_t stGlobalZ1 = stGlobalZ0 - stDz;
//Double_t rmin = stGlobalZ1 * fAcceptanceTanMin;
// Double_t rmax = rmin+ fSpacerR + DeltaR;
Int_t Nsector = 16.0; // need to be hard coded to match with station 1 of SIS100
//cout<<" Nsector "<<Nsector<<endl;
Double_t layerZ0 = (ily - (fNlayers - 1) / 2.) * fLayersDz;
Double_t layerGlobalZ0 = layerZ0 + stGlobalZ0;
Double_t sideDz = fCoolLz / 2. + fActiveLzSector / 2.; // distance between side's and layer's centers
Double_t moduleZ = sideDz; // Z position of the module center in the layer cs
Double_t phi0 = TMath::Pi() / Nsector; // azimuthal half widh of each module
//Double_t ymin = rmin+fSpacerR;
// Double_t ymax = rmax;
//define the dimensions of the trapezoidal module
//Use hard coded values for mini-cbm
Double_t dy = 40.0; //(ymax-ymin)/2.; //y (length)
Double_t dx1 = 3.75; //ymin*TMath::Tan(phi0)+fOverlapR/TMath::Cos(phi0); // large x
Double_t dx2 = 20; //ymax*TMath::Tan(phi0)+fOverlapR/TMath::Cos(phi0); // small x
Double_t dz = fActiveLzSector / 2.; // thickness
//define the spacer dimensions
Double_t tg = (dx2 - dx1) / 2 / dy;
Double_t dd1 = fSpacerPhi * tg;
Double_t dd2 = fSpacerPhi * sqrt(1 + tg * tg);
Double_t sdx1 = dx1 + dd2 - dd1;
Double_t sdx2 = dx2 + dd2 + dd1;
Double_t sdy1 = dy + fSpacerR1; // frame width added
Double_t sdy2 = dy + fSpacerR2; // frame width added
Double_t sdz = dz - 0.1;
// Define the (cooling plate) diemnsions (hardcoded for mcbm)
Double_t dy_s = sdy2; //46.5;//dy+2.0;
Double_t dx1_s = sdx1; //27.0; //dx1+2.0 ;// large x
Double_t dx2_s = sdx2; //27.0; //dx2+2.0;// x
Double_t dz_s = fCoolLz / 2.; //
TVector3 pos;
TVector3 size = TVector3(0.0, 0.0, fActiveLzSector);
// Now start adding the GEM modules
for (Int_t iModule = 0; iModule < 1; iModule++) {
// if (iModule!=0) continue;
// Double_t phi = 2 * phi0 * (iModule + 0.5); // add 0.5 to not overlap with y-axis for left-right layer separation
// Position of the module will depend on Phi
// Set Phi=180 degree 6 o'clock position
// Set Phi=90 degree 3 o'clock position
// Double_t phi=TMath::Pi()/2.0;
Double_t phi = 0; // do not blow up yMin in CbmMuchGeoScheme to see points
Bool_t isBack = iModule % 2;
Char_t cside = (isBack == 1) ? 'b' : 'f';
// correct the x, y positions
// pos[0] = -(ymin+dy)*sin(phi);
// pos[1] = (ymin+dy)*cos(phi);
pos[0] = 0; // DE - do not displace mMUCH in x
pos[1] = 15; // DE - move upwards in y [cm]
// different z positions for odd/even modules
// pos[2] = (isBack ? 1 : -1)*moduleZ + layerGlobalZ0;
pos[2] = layerGlobalZ0;
TGeoMedium* argon = gGeoMan->GetMedium(activemedium); // active medium
TGeoMedium* noryl = gGeoMan->GetMedium(spacermedium); // spacer medium
TGeoMedium* aluminium = gGeoMan->GetMedium(coolmedium); // cool medium
// Define and place the trapezoidal GEM module in X-Y plane
TGeoTrap* shape = new TGeoTrap(dz, 0, phi, dy, dx1, dx2, 0, dy, dx1, dx2, 0);
// TGeoTrap* shape = new TGeoTrap(dz,0,0,dy,dx1,dx2,0,dy,dx1,dx2,0);
shape->SetName(Form("shStation%02iLayer%i%cModule%03iActiveNoHole", istn, ily, cside, iModule));
TString activeName = Form("muchstation%02ilayer%i%cactive%03igasArgon", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voActive = new TGeoVolume(activeName, shape, argon);
voActive->SetLineColor(kGreen);
// Define the trapezoidal spacers
TGeoTrap* shapeFrame = new TGeoTrap(sdz, 0, phi, sdy1, sdx1, sdx2, 0, sdy2, sdx1, sdx2, 0);
//TGeoTrap* shapeFrame = new TGeoTrap(sdz,0,0,sdy,sdx1,sdx2,0,sdy,sdx1,sdx2,0);
shapeFrame->SetName(Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole", istn, ily, cside, iModule));
TString expression = Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole-"
"shStation%02iLayer%i%cModule%03iActiveNoHole",
istn, ily, cside, iModule, istn, ily, cside, iModule);
TGeoCompositeShape* shFrame = new TGeoCompositeShape(
Form("shStation%02iLayer%i%cModule%03iFrameNoHole", istn, ily, cside, iModule), expression);
TString frameName = Form("muchstation%02ilayer%i%csupport%03i", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voFrame = new TGeoVolume(frameName, shFrame, noryl); // add a name to the frame
voFrame->SetLineColor(kMagenta);
// Define the trapezoidal (cooling plates)
// TGeoTrap* cool = new TGeoTrap(dz_s,0,phi,dy_s,dx1_s,dx2_s,0,dy_s,dx1_s,dx2_s,0);
TGeoTrap* cool = new TGeoTrap(dz_s, 0, phi, dy_s, dx1_s, dx2_s, 0, dy_s, dx1_s, dx2_s, 0);
cool->SetName(Form("shStation%02iLayer%i%cModule%03icool", istn, ily, cside, iModule));
TString CoolName = Form("muchstation%02ilayer%i%ccool%03iAluminum", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voCool = new TGeoVolume(CoolName, cool, aluminium);
voCool->SetLineColor(kYellow);
// Calculate the phi angle of the sector where it has to be placed
Double_t angle = 180. / TMath::Pi() * phi; // convert angle phi from rad to deg
TGeoTranslation* trans2 = new TGeoTranslation("", pos[0], pos[1], pos[2]); //for module and frame
TGeoTranslation* trans3 = new TGeoTranslation("", pos[0], pos[1], pos[2] + 0.65); //for module and frame
TGeoRotation* r2 = new TGeoRotation("r2");
//rotate in the vertical plane (per to z axis) with angle
// r2->RotateZ(angle);
// DE cout << "DE " << phi << endl;
// DE cout << "DE " << angle << endl;
// DE cout << "DE " << phi0 << endl;
// DE cout << "DE " << 180. / TMath::Pi() * phi0 << endl;
// r2->RotateZ(180.0); // DE - 6 o'clock position
r2->RotateZ(180.0 - (180. / TMath::Pi() * phi0)); // DE - 6 o'clock position, left side vertical
// r2->RotateZ(180.0-11.25); // DE - 6 o'clock position, left side vertical
// give rotation to set them in horizontal plane
//r2->RotateZ(90.0);//TMath::Pi());
TGeoHMatrix* incline_mod = new TGeoHMatrix("");
(*incline_mod) = (*trans2) * (*r2); // OK
volayer->AddNode(voFrame, iModule, incline_mod); // add frame
volayer->AddNode(voActive, iModule, incline_mod); // add active volume
TGeoHMatrix* incline_mod1 = new TGeoHMatrix("");
(*incline_mod1) = (*trans3) * (*r2); // for cooling
volayer->AddNode(voCool, iModule, incline_mod1); // cooling plate
}
return volayer;
}
/* Copyright (C) 2018 Department of Physics, Aligarh Muslim University, Aligarh
SPDX-License-Identifier: GPL-3.0-only
Authors: Omveer Singh [committer] */
//
/// \file create_MUCH_geometry_v18h.C
/// \brief Generates MUCH geometry in Root format.
///
// 2018-05-11 - OS & PPB & AJ- v18h - Add additional material(Drift and G10)
// 2017-11-20 - DE - v18g - shift back to z = 70, 80 and 90 cm to avoid mSTS box
// 2017-11-10 - PPB - - correct the y position of the modules to generate much points
// 2017-11-07 - PPB - - change the shape of cooling plates from rectangular to sector
// 2017-11-06 - PPB, VS and AM - mcbm version with actual Mv2 dimesions of the module
// 2017-10-23 - DE - mcbm - put mMUCH in 6 o'clock position on z axis, shift 15 cm up and to z = 60, 70 and 80 cm
// 2017-09-04 - PPB - mcbm - preliminary version of mini much geometry
// 2017-05-16 - DE - v17b - position the modules in a way to split layers left-right along y axis
// 2017-05-16 - DE - v17b - attribute name to module frames
// 2017-05-16 - DE - v17b - remove rim from support CompositeShape
// 2017-05-02 - PPB - v17a - Change the shape of the first absorber according to latest design
// 2017-04-27 - DE - v17a - fix GEM module positions and angles
// 2017-04-22 - PPB - v17a - Define the absorber, shield and station shapes sizes ...
// 2016-04-19 - DE - v17a - initial version derived from TRD
// in root all sizes are given in cm
#include "TClonesArray.h"
#include "TDatime.h"
#include "TFile.h"
#include "TGeoBBox.h"
#include "TGeoCompositeShape.h"
#include "TGeoCone.h"
#include "TGeoManager.h"
#include "TGeoMaterial.h"
#include "TGeoMatrix.h"
#include "TGeoMedium.h"
#include "TGeoPgon.h"
#include "TGeoTube.h"
#include "TGeoVolume.h"
#include "TGeoXtru.h"
#include "TList.h"
#include "TMath.h"
#include "TObjArray.h"
#include "TRandom3.h"
#include "TString.h"
#include "TSystem.h"
#include <cassert>
#include <fstream>
#include <iostream>
#include <stdexcept>
// Name of output file with geometry
const TString tagVersion = "_v18h";
const TString geoVersion = "much";
const TString FileNameSim = geoVersion + tagVersion + "_mcbm.geo.root";
const TString FileNameGeo = geoVersion + tagVersion + "_mcbm_geo.root";
const TString FileNameInfo = geoVersion + tagVersion + "_mcbm.geo.info";
// Names of the different used materials which are used to build the modules
// The materials are defined in the global media.geo file
const TString KeepingVolumeMedium = "air";
const TString L = "MUCHlead";
const TString W = "MUCHwolfram";
const TString C = "MUCHcarbon";
const TString I = "MUCHiron";
const TString activemedium = "MUCHargon";
const TString spacermedium = "MUCHnoryl";
const TString coolmedium = "aluminium"; //Al cooling plates
const TString g10 = "G10"; //G10 Plate
const TString copper = "copper"; //Drift
// Universal input parameters
// The inner angle is 11 degree (polar angle); We take z = 70 cm;
//Inner radius: R_in=z*tan(theta_min) cm
// Outer angle is decided from tan(theta_max)=R_out/z
// R_out=R_in+95 cm (transverse size of the M2 module)
Double_t fMuchZ1 = 0.0; // MuchCave Zin position [cm]
Double_t fAcceptanceTanMin = 0.19; // Acceptance tangent min (11 degree)
//************************************************************
// Input parameters for MUCH stations
//********************************************
const Int_t fNst = 1; // Number of stations
// Sector-type module parameters
// Number of sectors per layer (should be even for symmetry)
// Needs to be fixed with actual numbers
Double_t fActiveLzSector = 0.3; // Active volume thickness [cm]
Double_t fSpacerR1 = 2.8; // Spacer width in R at low Z[cm]
Double_t fSpacerR2 = 3.5; // Spacer width in R at high Z[cm]
Double_t fSpacerPhi = 2.8; // Spacer width in Phi [cm]
Double_t fOverlapR = 0.0; // Overlap in R direction [cm]
// Station Zceneter [cm] in the cave reference frame
Double_t fStationZ0 = 80;
//Double_t fStationZ0=70; // DE - move 10 cm upstream
Int_t fNlayers = 3; // Number of layers
Double_t fLayersDz = 10; // distance between the layers
Double_t fCoolLz = 1.0; // thickness of the cooling plate also used as support
Double_t fDriftDz = 0.0035; //35 micron copper Drift & Readout
Double_t fG10Dz = 0.3; // 3 mm G10
/*
1 - detailed design (modules at two sides)
* 0 - simple design (1 module per layer)
*/
//***********************************************************
// some global variables
TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance
TGeoVolume* gModules_station[fNst]; // Global storage for module types
// Forward declarations
void create_materials_from_media_file();
TGeoVolume* CreateStations(int ist);
TGeoVolume* CreateLayers(int istn, int ily);
void create_MUCH_geometry_v18h()
{
// Load needed material definition from media.geo file
create_materials_from_media_file();
// Get the GeoManager for later usage
gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom");
gGeoMan->SetVisLevel(10);
// Create the top volume
TGeoBBox* topbox = new TGeoBBox("", 1000., 1000., 2000.);
TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air"));
gGeoMan->SetTopVolume(top);
TString topName = geoVersion + tagVersion;
TGeoVolume* much = new TGeoVolumeAssembly(topName);
top->AddNode(much, 1);
TGeoVolume* sttn = new TGeoVolumeAssembly("station"); //change name from Station ->station
much->AddNode(sttn, 1);
for (Int_t istn = 0; istn < 1; istn++) { // 1 Station
gModules_station[istn] = CreateStations(istn);
sttn->AddNode(gModules_station[istn], istn);
}
gGeoMan->CloseGeometry();
gGeoMan->CheckOverlaps(0.000001);
gGeoMan->PrintOverlaps();
// gGeoMan->Test();
much->Export(FileNameSim); // an alternative way of writing the much
TFile* outfile = new TFile(FileNameSim, "UPDATE");
TGeoTranslation* much_placement = new TGeoTranslation("much_trans", 0., 0., 0.);
much_placement->Write();
outfile->Close();
outfile = new TFile(FileNameGeo, "RECREATE");
gGeoMan->Write(); // use this if you want GeoManager format in the output
outfile->Close();
top->Draw("ogl");
}
void create_materials_from_media_file()
{
// Use the FairRoot geometry interface to load the media which are already defined
FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
TString geoPath = gSystem->Getenv("VMCWORKDIR");
TString geoFile = geoPath + "/geometry/media.geo";
geoFace->setMediaFile(geoFile);
geoFace->readMedia();
// Read the required media and create them in the GeoManager
FairGeoMedia* geoMedia = geoFace->getMedia();
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
FairGeoMedium* air = geoMedia->getMedium(KeepingVolumeMedium);
geoBuild->createMedium(air);
FairGeoMedium* MUCHiron = geoMedia->getMedium(I);
geoBuild->createMedium(MUCHiron);
FairGeoMedium* MUCHlead = geoMedia->getMedium(L);
geoBuild->createMedium(MUCHlead);
FairGeoMedium* MUCHwolfram = geoMedia->getMedium(W);
geoBuild->createMedium(MUCHwolfram);
FairGeoMedium* MUCHcarbon = geoMedia->getMedium(C);
geoBuild->createMedium(MUCHcarbon);
FairGeoMedium* MUCHargon = geoMedia->getMedium(activemedium);
geoBuild->createMedium(MUCHargon);
FairGeoMedium* MUCHnoryl = geoMedia->getMedium(spacermedium);
geoBuild->createMedium(MUCHnoryl);
FairGeoMedium* aluminium = geoMedia->getMedium(coolmedium);
// geoBuild->createMedium(MUCHcool);
geoBuild->createMedium(aluminium);
FairGeoMedium* g10plate = geoMedia->getMedium(g10); //G10
geoBuild->createMedium(g10plate);
FairGeoMedium* copperplate = geoMedia->getMedium(copper); //Copper for Drift
geoBuild->createMedium(copperplate);
}
TGeoVolume* CreateStations(int ist)
{
TString stationName = Form("muchstation%02i", ist + 1);
TGeoVolumeAssembly* station = new TGeoVolumeAssembly(stationName); //, shStation, air);
TGeoVolume* gLayer[4];
for (int ii = 0; ii < 3; ii++) { // 3 Layers
gLayer[ii] = CreateLayers(ist, ii);
station->AddNode(gLayer[ii], ii);
}
return station;
}
TGeoVolume* CreateLayers(int istn, int ily)
{
TString layerName = Form("muchstation%02ilayer%i", istn + 1, ily + 1);
TGeoVolumeAssembly* volayer = new TGeoVolumeAssembly(layerName);
//Double_t DeltaR=80.0; // transverse dimension of the module
Double_t stGlobalZ0 = fStationZ0 + fMuchZ1; //z position of station center (midplane) [cm]
Double_t stDz = ((fNlayers - 1) * fLayersDz + fCoolLz + 2 * fActiveLzSector) / 2.;
Double_t stGlobalZ2 = stGlobalZ0 + stDz;
Double_t stGlobalZ1 = stGlobalZ0 - stDz;
//Double_t rmin = stGlobalZ1 * fAcceptanceTanMin;
// Double_t rmax = rmin+ fSpacerR + DeltaR;
Int_t Nsector = 16.0; // need to be hard coded to match with station 1 of SIS100
//cout<<" Nsector "<<Nsector<<endl;
Double_t layerZ0 = (ily - (fNlayers - 1) / 2.) * fLayersDz;
Double_t layerGlobalZ0 = layerZ0 + stGlobalZ0;
Double_t sideDz = fCoolLz / 2. + fActiveLzSector / 2.; // distance between side's and layer's centers
Double_t moduleZ = sideDz; // Z position of the module center in the layer cs
Double_t phi0 = TMath::Pi() / Nsector; // azimuthal half widh of each module
//Double_t ymin = rmin+fSpacerR;
// Double_t ymax = rmax;
//define the dimensions of the trapezoidal module
//Use hard coded values for mini-cbm
Double_t dy = 40.0; //(ymax-ymin)/2.; //y (length)
Double_t dx1 = 3.75; //ymin*TMath::Tan(phi0)+fOverlapR/TMath::Cos(phi0); // large x
Double_t dx2 = 20; //ymax*TMath::Tan(phi0)+fOverlapR/TMath::Cos(phi0); // small x
Double_t dz = fActiveLzSector / 2.; // thickness
//define the spacer dimensions
Double_t tg = (dx2 - dx1) / 2 / dy;
Double_t dd1 = fSpacerPhi * tg;
Double_t dd2 = fSpacerPhi * sqrt(1 + tg * tg);
Double_t sdx1 = dx1 + dd2 - dd1;
Double_t sdx2 = dx2 + dd2 + dd1;
Double_t sdy1 = dy + fSpacerR1; // frame width added
Double_t sdy2 = dy + fSpacerR2; // frame width added
Double_t sdz = dz - 0.1;
// Define the (cooling plate) diemnsions (hardcoded for mcbm) + Drift and G10
Double_t dy_s = sdy2; //46.5;//dy+2.0;
Double_t dx1_s = sdx1; //27.0; //dx1+2.0 ;// large x
Double_t dx2_s = sdx2; //27.0; //dx2+2.0;// x
Double_t dz_s = fCoolLz / 2.; //
Double_t dz_sD = fDriftDz / 2.; //35 micron copper Drift & Readout
Double_t dz_sG = fG10Dz / 2.; // 3 mm G10
TVector3 pos;
TVector3 size = TVector3(0.0, 0.0, fActiveLzSector);
// Now start adding the GEM modules
for (Int_t iModule = 0; iModule < 1; iModule++) {
// if (iModule!=0) continue;
// Double_t phi = 2 * phi0 * (iModule + 0.5); // add 0.5 to not overlap with y-axis for left-right layer separation
// Position of the module will depend on Phi
// Set Phi=180 degree 6 o'clock position
// Set Phi=90 degree 3 o'clock position
// Double_t phi=TMath::Pi()/2.0;
Double_t phi = 0; // do not blow up yMin in CbmMuchGeoScheme to see points
Bool_t isBack = iModule % 2;
Char_t cside = (isBack == 1) ? 'b' : 'f';
// correct the x, y positions
// pos[0] = -(ymin+dy)*sin(phi);
// pos[1] = (ymin+dy)*cos(phi);
pos[0] = 0; // DE - do not displace mMUCH in x
pos[1] = 15; // DE - move upwards in y [cm]
// different z positions for odd/even modules
// pos[2] = (isBack ? 1 : -1)*moduleZ + layerGlobalZ0;
pos[2] = layerGlobalZ0;
TGeoMedium* argon = gGeoMan->GetMedium(activemedium); // active medium
TGeoMedium* noryl = gGeoMan->GetMedium(spacermedium); // spacer medium
TGeoMedium* aluminium = gGeoMan->GetMedium(coolmedium); // cool medium
TGeoMedium* g10plate = gGeoMan->GetMedium(g10); // G10 medium
TGeoMedium* copperplate = gGeoMan->GetMedium(copper); // copper Drift medium
//Front G10 and copper Drift
TGeoTrap* frontG10 = new TGeoTrap(dz_sG, 0, phi, dy_s, dx1_s, dx2_s, 0, dy_s, dx1_s, dx2_s, 0);
frontG10->SetName(Form("shStation%02iLayer%i%cModule%03ifront", istn, ily, cside, iModule));
TString fG10Name = Form("muchstation%02ilayer%i%cfront%03iG10", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* vofG10 = new TGeoVolume(fG10Name, frontG10, g10plate);
vofG10->SetLineColor(28);
TGeoTrap* frontDrift = new TGeoTrap(dz_sD, 0, phi, dy_s, dx1_s, dx2_s, 0, dy_s, dx1_s, dx2_s, 0);
frontDrift->SetName(Form("shStation%02iLayer%i%cModule%03ifront", istn, ily, cside, iModule));
TString fDriftName = Form("muchstation%02ilayer%i%ccopper%03iDrift", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* vofDrift = new TGeoVolume(fDriftName, frontDrift, copperplate);
vofDrift->SetLineColor(kRed);
//Back G10 and copper Readout
TGeoTrap* backG10 = new TGeoTrap(dz_sG, 0, phi, dy_s, dx1_s, dx2_s, 0, dy_s, dx1_s, dx2_s, 0);
backG10->SetName(Form("shStation%02iLayer%i%cModule%03iback", istn, ily, cside, iModule));
TString bG10Name = Form("muchstation%02ilayer%i%cback%03iG10", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* vobG10 = new TGeoVolume(bG10Name, backG10, g10plate);
vobG10->SetLineColor(28);
TGeoTrap* backDrift = new TGeoTrap(dz_sD, 0, phi, dy_s, dx1_s, dx2_s, 0, dy_s, dx1_s, dx2_s, 0);
backDrift->SetName(Form("shStation%02iLayer%i%cModule%03iback", istn, ily, cside, iModule));
TString bDriftName = Form("muchstation%02ilayer%i%ccooper%03iReadout", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* vobDrift = new TGeoVolume(bDriftName, backDrift, copperplate);
vobDrift->SetLineColor(kRed);
// Define and place the trapezoidal GEM module in X-Y plane
TGeoTrap* shape = new TGeoTrap(dz, 0, phi, dy, dx1, dx2, 0, dy, dx1, dx2, 0);
// TGeoTrap* shape = new TGeoTrap(dz,0,0,dy,dx1,dx2,0,dy,dx1,dx2,0);
shape->SetName(Form("shStation%02iLayer%i%cModule%03iActiveNoHole", istn, ily, cside, iModule));
TString activeName = Form("muchstation%02ilayer%i%cactive%03igasArgon", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voActive = new TGeoVolume(activeName, shape, argon);
voActive->SetLineColor(kGreen);
// Define the trapezoidal spacers
TGeoTrap* shapeFrame = new TGeoTrap(sdz, 0, phi, sdy1, sdx1, sdx2, 0, sdy2, sdx1, sdx2, 0);
//TGeoTrap* shapeFrame = new TGeoTrap(sdz,0,0,sdy,sdx1,sdx2,0,sdy,sdx1,sdx2,0);
shapeFrame->SetName(Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole", istn, ily, cside, iModule));
TString expression = Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole-"
"shStation%02iLayer%i%cModule%03iActiveNoHole",
istn, ily, cside, iModule, istn, ily, cside, iModule);
TGeoCompositeShape* shFrame = new TGeoCompositeShape(
Form("shStation%02iLayer%i%cModule%03iFrameNoHole", istn, ily, cside, iModule), expression);
TString frameName = Form("muchstation%02ilayer%i%csupport%03i", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voFrame = new TGeoVolume(frameName, shFrame, noryl); // add a name to the frame
voFrame->SetLineColor(kMagenta);
// Define the trapezoidal (cooling plates)
// TGeoTrap* cool = new TGeoTrap(dz_s,0,phi,dy_s,dx1_s,dx2_s,0,dy_s,dx1_s,dx2_s,0);
TGeoTrap* cool = new TGeoTrap(dz_s, 0, phi, dy_s, dx1_s, dx2_s, 0, dy_s, dx1_s, dx2_s, 0);
cool->SetName(Form("shStation%02iLayer%i%cModule%03icool", istn, ily, cside, iModule));
TString CoolName = Form("muchstation%02ilayer%i%ccool%03iAluminum", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voCool = new TGeoVolume(CoolName, cool, aluminium);
voCool->SetLineColor(kYellow);
Double_t RMin = (pos[1] / TMath::Cos(phi)) - dy;
Double_t RMax = 2 * dy + RMin;
// cout<<"posY "<<pos[1]<<endl;
// cout<<"RMin "<<RMin<<" RMax "<<RMax<<endl;
// Calculate the phi angle of the sector where it has to be placed
Double_t angle = 180. / TMath::Pi() * phi; // convert angle phi from rad to deg
TGeoTranslation* trans2 = new TGeoTranslation("", pos[0], pos[1], pos[2]); //for module and frame
TGeoTranslation* trans3 = new TGeoTranslation("", pos[0], pos[1],
pos[2] + dz + 2 * dz_sD + 2 * dz_sG + dz_s); //Aluminum plate
TGeoTranslation* transfG10 = new TGeoTranslation("", pos[0], pos[1], pos[2] - dz - 2 * dz_sD - dz_sG); //Front G10
TGeoTranslation* transfDrift = new TGeoTranslation("", pos[0], pos[1], pos[2] - dz - dz_sD); //Front copper Drift
TGeoTranslation* transbG10 = new TGeoTranslation("", pos[0], pos[1], pos[2] + dz + 2 * dz_sD + dz_sG); //Back G10
TGeoTranslation* transbDrift = new TGeoTranslation("", pos[0], pos[1], pos[2] + dz + dz_sD); //Back copper Readout
//cout<<"FrontG10: "<<pos[2]-dz-2*dz_sD-dz_sG<<" FrontCopper: "<<pos[2]-dz-dz_sD<<" Active: "<<pos[2]<<" BackCopper: "<<pos[2]+dz+dz_sD<<" BackG10: "<<pos[2]+dz+2*dz_sD+dz_sG<<" Alumi: "<<pos[2]+dz+2*dz_sD+2*dz_sG+dz_s<<endl;
TGeoRotation* r2 = new TGeoRotation("r2");
//rotate in the vertical plane (per to z axis) with angle
// r2->RotateZ(angle);
// r2->RotateZ(180.0); // DE - 6 o'clock position
r2->RotateZ(180.0 - (180. / TMath::Pi() * phi0)); // DE - 6 o'clock position, left side vertical
// r2->RotateZ(180.0-11.25); // DE - 6 o'clock position, left side vertical
// give rotation to set them in horizontal plane
//r2->RotateZ(90.0);//TMath::Pi());
TGeoHMatrix* incline_mod = new TGeoHMatrix("");
(*incline_mod) = (*trans2) * (*r2); // OK
volayer->AddNode(voFrame, iModule, incline_mod); // add frame
volayer->AddNode(voActive, iModule, incline_mod); // add active volume
TGeoHMatrix* incline_mod1 = new TGeoHMatrix(""); // for cooling
(*incline_mod1) = (*trans3) * (*r2);
volayer->AddNode(voCool, iModule, incline_mod1);
TGeoHMatrix* incline_mod2 = new TGeoHMatrix(""); // front G10
(*incline_mod2) = (*transfG10) * (*r2);
volayer->AddNode(vofG10, iModule, incline_mod2);
TGeoHMatrix* incline_mod3 = new TGeoHMatrix(""); // front copper Drift
(*incline_mod3) = (*transfDrift) * (*r2);
volayer->AddNode(vofDrift, iModule, incline_mod3);
TGeoHMatrix* incline_mod4 = new TGeoHMatrix(""); // Back G10
(*incline_mod4) = (*transbG10) * (*r2);
volayer->AddNode(vobG10, iModule, incline_mod4);
TGeoHMatrix* incline_mod5 = new TGeoHMatrix(""); // Back copper Readout
(*incline_mod5) = (*transbDrift) * (*r2);
volayer->AddNode(vobDrift, iModule, incline_mod5);
}
return volayer;
}
/* Copyright (C) 2018 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: David Emschermann [committer] */
//
/// \file create_MUCH_geometry_v18i.C
/// \brief Generates MUCH geometry in Root format.
///
// 2018-08-28 - DE - v18i - build a mMUCH with 2 GEM modules at z = 70 and 95 cm
// 2017-11-20 - DE - v18g - shift back to z = 70, 80 and 90 cm to avoid mSTS box
// 2017-11-10 - PPB - - correct the y position of the modules to generate much points
// 2017-11-07 - PPB - - change the shape of cooling plates from rectangular to sector
// 2017-11-06 - PPB, VS and AM - mcbm version with actual Mv2 dimesions of the module
// 2017-10-23 - DE - mcbm - put mMUCH in 6 o'clock position on z axis, shift 15 cm up and to z = 60, 70 and 80 cm
// 2017-09-04 - PPB - mcbm - preliminary version of mini much geometry
// 2017-05-16 - DE - v17b - position the modules in a way to split layers left-right along y axis
// 2017-05-16 - DE - v17b - attribute name to module frames
// 2017-05-16 - DE - v17b - remove rim from support CompositeShape
// 2017-05-02 - PPB - v17a - Change the shape of the first absorber according to latest design
// 2017-04-27 - DE - v17a - fix GEM module positions and angles
// 2017-04-22 - PPB - v17a - Define the absorber, shield and station shapes sizes ...
// 2016-04-19 - DE - v17a - initial version derived from TRD
// in root all sizes are given in cm
#include "TClonesArray.h"
#include "TDatime.h"
#include "TFile.h"
#include "TGeoBBox.h"
#include "TGeoCompositeShape.h"
#include "TGeoCone.h"
#include "TGeoManager.h"
#include "TGeoMaterial.h"
#include "TGeoMatrix.h"
#include "TGeoMedium.h"
#include "TGeoPgon.h"
#include "TGeoTube.h"
#include "TGeoVolume.h"
#include "TGeoXtru.h"
#include "TList.h"
#include "TMath.h"
#include "TObjArray.h"
#include "TRandom3.h"
#include "TString.h"
#include "TSystem.h"
#include <cassert>
#include <fstream>
#include <iostream>
#include <stdexcept>
// Name of output file with geometry
const TString tagVersion = "_v18i";
const TString geoVersion = "much";
const TString FileNameSim = geoVersion + tagVersion + "_mcbm.geo.root";
const TString FileNameGeo = geoVersion + tagVersion + "_mcbm_geo.root";
const TString FileNameInfo = geoVersion + tagVersion + "_mcbm.geo.info";
// Names of the different used materials which are used to build the modules
// The materials are defined in the global media.geo file
const TString KeepingVolumeMedium = "air";
const TString L = "MUCHlead";
const TString W = "MUCHwolfram";
const TString C = "MUCHcarbon";
const TString I = "MUCHiron";
const TString activemedium = "MUCHargon";
const TString spacermedium = "MUCHnoryl";
const TString coolmedium = "aluminium"; //Al cooling plates
// Universal input parameters
// The inner angle is 11 degree (polar angle); We take z = 70 cm;
//Inner radius: R_in=z*tan(theta_min) cm
// Outer angle is decided from tan(theta_max)=R_out/z
// R_out=R_in+95 cm (transverse size of the M2 module)
Double_t fMuchZ1 = 0.0; // MuchCave Zin position [cm]
Double_t fAcceptanceTanMin = 0.19; // Acceptance tangent min (11 degree)
//************************************************************
// Input parameters for MUCH stations
//********************************************
const Int_t fNst = 1; // Number of stations
// Sector-type module parameters
// Number of sectors per layer (should be even for symmetry)
// Needs to be fixed with actual numbers
Double_t fActiveLzSector = 0.3; // Active volume thickness [cm]
Double_t fSpacerR1 = 2.8; // Spacer width in R at low Z[cm]
Double_t fSpacerR2 = 3.5; // Spacer width in R at high Z[cm]
Double_t fSpacerPhi = 2.8; // Spacer width in Phi [cm]
Double_t fOverlapR = 0.0; // Overlap in R direction [cm]
// Station Zceneter [cm] in the cave reference frame
Double_t fStationZ0 = 95;
//Double_t fStationZ0=70; // DE - move 10 cm upstream
Int_t fNlayers = 3; // Number of layers
Double_t fLayersDz = 25; // distance between the layers
Double_t fCoolLz = 1.0; // thickness of the cooling plate also used as support
/*
1 - detailed design (modules at two sides)
* 0 - simple design (1 module per layer)
*/
//***********************************************************
// some global variables
TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance
TGeoVolume* gModules_station[fNst]; // Global storage for module types
// Forward declarations
void create_materials_from_media_file();
TGeoVolume* CreateStations(int ist);
TGeoVolume* CreateLayers(int istn, int ily);
void create_MUCH_geometry_v18i()
{
// Load needed material definition from media.geo file
create_materials_from_media_file();
// Get the GeoManager for later usage
gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom");
gGeoMan->SetVisLevel(10);
// Create the top volume
TGeoBBox* topbox = new TGeoBBox("", 1000., 1000., 2000.);
TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air"));
gGeoMan->SetTopVolume(top);
TGeoVolume* much = new TGeoVolumeAssembly(geoVersion);
top->AddNode(much, 1);
TGeoVolume* sttn = new TGeoVolumeAssembly("station"); //change name from Station ->station
much->AddNode(sttn, 1);
for (Int_t istn = 0; istn < 1; istn++) { // 1 Station
gModules_station[istn] = CreateStations(istn);
sttn->AddNode(gModules_station[istn], istn);
}
gGeoMan->CloseGeometry();
gGeoMan->CheckOverlaps(0.000001);
gGeoMan->PrintOverlaps();
// gGeoMan->Test();
much->Export(FileNameSim); // an alternative way of writing the much
TFile* outfile = new TFile(FileNameSim, "UPDATE");
TGeoTranslation* much_placement = new TGeoTranslation("much_trans", 0., 0., 0.);
much_placement->Write();
outfile->Close();
outfile = new TFile(FileNameGeo, "RECREATE");
gGeoMan->Write(); // use this if you want GeoManager format in the output
outfile->Close();
top->Draw("ogl");
}
void create_materials_from_media_file()
{
// Use the FairRoot geometry interface to load the media which are already defined
FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
TString geoPath = gSystem->Getenv("VMCWORKDIR");
TString geoFile = geoPath + "/geometry/media.geo";
geoFace->setMediaFile(geoFile);
geoFace->readMedia();
// Read the required media and create them in the GeoManager
FairGeoMedia* geoMedia = geoFace->getMedia();
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
FairGeoMedium* air = geoMedia->getMedium(KeepingVolumeMedium);
geoBuild->createMedium(air);
FairGeoMedium* MUCHiron = geoMedia->getMedium(I);
geoBuild->createMedium(MUCHiron);
FairGeoMedium* MUCHlead = geoMedia->getMedium(L);
geoBuild->createMedium(MUCHlead);
FairGeoMedium* MUCHwolfram = geoMedia->getMedium(W);
geoBuild->createMedium(MUCHwolfram);
FairGeoMedium* MUCHcarbon = geoMedia->getMedium(C);
geoBuild->createMedium(MUCHcarbon);
FairGeoMedium* MUCHargon = geoMedia->getMedium(activemedium);
geoBuild->createMedium(MUCHargon);
FairGeoMedium* MUCHnoryl = geoMedia->getMedium(spacermedium);
geoBuild->createMedium(MUCHnoryl);
FairGeoMedium* aluminium = geoMedia->getMedium(coolmedium);
// geoBuild->createMedium(MUCHcool);
geoBuild->createMedium(aluminium);
}
TGeoVolume* CreateStations(int ist)
{
TString stationName = Form("muchstation%02i", ist + 1);
TGeoVolumeAssembly* station = new TGeoVolumeAssembly(stationName); //, shStation, air);
TGeoVolume* gLayer[4];
for (int ii = 0; ii < 3; ii++) { // 3 Layers
gLayer[ii] = CreateLayers(ist, ii);
if (ii != 2) // DE - skip 3rd=last GEM module for 2018
station->AddNode(gLayer[ii], ii);
}
return station;
}
TGeoVolume* CreateLayers(int istn, int ily)
{
TString layerName = Form("muchstation%02ilayer%i", istn + 1, ily + 1);
TGeoVolumeAssembly* volayer = new TGeoVolumeAssembly(layerName);
//Double_t DeltaR=80.0; // transverse dimension of the module
Double_t stGlobalZ0 = fStationZ0 + fMuchZ1; //z position of station center (midplane) [cm]
Double_t stDz = ((fNlayers - 1) * fLayersDz + fCoolLz + 2 * fActiveLzSector) / 2.;
Double_t stGlobalZ2 = stGlobalZ0 + stDz;
Double_t stGlobalZ1 = stGlobalZ0 - stDz;
//Double_t rmin = stGlobalZ1 * fAcceptanceTanMin;
// Double_t rmax = rmin+ fSpacerR + DeltaR;
Int_t Nsector = 16.0; // need to be hard coded to match with station 1 of SIS100
//cout<<" Nsector "<<Nsector<<endl;
Double_t layerZ0 = (ily - (fNlayers - 1) / 2.) * fLayersDz;
Double_t layerGlobalZ0 = layerZ0 + stGlobalZ0;
Double_t sideDz = fCoolLz / 2. + fActiveLzSector / 2.; // distance between side's and layer's centers
Double_t moduleZ = sideDz; // Z position of the module center in the layer cs
Double_t phi0 = TMath::Pi() / Nsector; // azimuthal half widh of each module
//Double_t ymin = rmin+fSpacerR;
// Double_t ymax = rmax;
//define the dimensions of the trapezoidal module
//Use hard coded values for mini-cbm
Double_t dy = 40.0; //(ymax-ymin)/2.; //y (length)
Double_t dx1 = 3.75; //ymin*TMath::Tan(phi0)+fOverlapR/TMath::Cos(phi0); // large x
Double_t dx2 = 20; //ymax*TMath::Tan(phi0)+fOverlapR/TMath::Cos(phi0); // small x
Double_t dz = fActiveLzSector / 2.; // thickness
//define the spacer dimensions
Double_t tg = (dx2 - dx1) / 2 / dy;
Double_t dd1 = fSpacerPhi * tg;
Double_t dd2 = fSpacerPhi * sqrt(1 + tg * tg);
Double_t sdx1 = dx1 + dd2 - dd1;
Double_t sdx2 = dx2 + dd2 + dd1;
Double_t sdy1 = dy + fSpacerR1; // frame width added
Double_t sdy2 = dy + fSpacerR2; // frame width added
Double_t sdz = dz - 0.1;
// Define the (cooling plate) diemnsions (hardcoded for mcbm)
Double_t dy_s = sdy2; //46.5;//dy+2.0;
Double_t dx1_s = sdx1; //27.0; //dx1+2.0 ;// large x
Double_t dx2_s = sdx2; //27.0; //dx2+2.0;// x
Double_t dz_s = fCoolLz / 2.; //
TVector3 pos;
TVector3 size = TVector3(0.0, 0.0, fActiveLzSector);
// Now start adding the GEM modules
for (Int_t iModule = 0; iModule < 1; iModule++) {
// if (iModule!=0) continue;
// Double_t phi = 2 * phi0 * (iModule + 0.5); // add 0.5 to not overlap with y-axis for left-right layer separation
// Position of the module will depend on Phi
// Set Phi=180 degree 6 o'clock position
// Set Phi=90 degree 3 o'clock position
// Double_t phi=TMath::Pi()/2.0;
Double_t phi = 0; // do not blow up yMin in CbmMuchGeoScheme to see points
Bool_t isBack = iModule % 2;
Char_t cside = (isBack == 1) ? 'b' : 'f';
// correct the x, y positions
// pos[0] = -(ymin+dy)*sin(phi);
// pos[1] = (ymin+dy)*cos(phi);
pos[0] = 0; // DE - do not displace mMUCH in x
pos[1] = 15; // DE - move upwards in y [cm]
// different z positions for odd/even modules
// pos[2] = (isBack ? 1 : -1)*moduleZ + layerGlobalZ0;
pos[2] = layerGlobalZ0;
TGeoMedium* argon = gGeoMan->GetMedium(activemedium); // active medium
TGeoMedium* noryl = gGeoMan->GetMedium(spacermedium); // spacer medium
TGeoMedium* aluminium = gGeoMan->GetMedium(coolmedium); // cool medium
// Define and place the trapezoidal GEM module in X-Y plane
TGeoTrap* shape = new TGeoTrap(dz, 0, phi, dy, dx1, dx2, 0, dy, dx1, dx2, 0);
// TGeoTrap* shape = new TGeoTrap(dz,0,0,dy,dx1,dx2,0,dy,dx1,dx2,0);
shape->SetName(Form("shStation%02iLayer%i%cModule%03iActiveNoHole", istn, ily, cside, iModule));
TString activeName = Form("muchstation%02ilayer%i%cactive%03igasArgon", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voActive = new TGeoVolume(activeName, shape, argon);
voActive->SetLineColor(kGreen);
// Define the trapezoidal spacers
TGeoTrap* shapeFrame = new TGeoTrap(sdz, 0, phi, sdy1, sdx1, sdx2, 0, sdy2, sdx1, sdx2, 0);
//TGeoTrap* shapeFrame = new TGeoTrap(sdz,0,0,sdy,sdx1,sdx2,0,sdy,sdx1,sdx2,0);
shapeFrame->SetName(Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole", istn, ily, cside, iModule));
TString expression = Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole-"
"shStation%02iLayer%i%cModule%03iActiveNoHole",
istn, ily, cside, iModule, istn, ily, cside, iModule);
TGeoCompositeShape* shFrame = new TGeoCompositeShape(
Form("shStation%02iLayer%i%cModule%03iFrameNoHole", istn, ily, cside, iModule), expression);
TString frameName = Form("muchstation%02ilayer%i%csupport%03i", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voFrame = new TGeoVolume(frameName, shFrame, noryl); // add a name to the frame
voFrame->SetLineColor(kMagenta);
// Define the trapezoidal (cooling plates)
// TGeoTrap* cool = new TGeoTrap(dz_s,0,phi,dy_s,dx1_s,dx2_s,0,dy_s,dx1_s,dx2_s,0);
TGeoTrap* cool = new TGeoTrap(dz_s, 0, phi, dy_s, dx1_s, dx2_s, 0, dy_s, dx1_s, dx2_s, 0);
cool->SetName(Form("shStation%02iLayer%i%cModule%03icool", istn, ily, cside, iModule));
TString CoolName = Form("muchstation%02ilayer%i%ccool%03iAluminum", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voCool = new TGeoVolume(CoolName, cool, aluminium);
voCool->SetLineColor(kYellow);
// Calculate the phi angle of the sector where it has to be placed
Double_t angle = 180. / TMath::Pi() * phi; // convert angle phi from rad to deg
TGeoTranslation* trans2 = new TGeoTranslation("", pos[0], pos[1], pos[2]); //for module and frame
TGeoTranslation* trans3 = new TGeoTranslation("", pos[0], pos[1], pos[2] + 0.65); //for module and frame
TGeoRotation* r2 = new TGeoRotation("r2");
//rotate in the vertical plane (per to z axis) with angle
// r2->RotateZ(angle);
// DE cout << "DE " << phi << endl;
// DE cout << "DE " << angle << endl;
// DE cout << "DE " << phi0 << endl;
// DE cout << "DE " << 180. / TMath::Pi() * phi0 << endl;
// r2->RotateZ(180.0); // DE - 6 o'clock position
r2->RotateZ(180.0 - (180. / TMath::Pi() * phi0)); // DE - 6 o'clock position, left side vertical
// r2->RotateZ(180.0-11.25); // DE - 6 o'clock position, left side vertical
// give rotation to set them in horizontal plane
//r2->RotateZ(90.0);//TMath::Pi());
TGeoHMatrix* incline_mod = new TGeoHMatrix("");
(*incline_mod) = (*trans2) * (*r2); // OK
volayer->AddNode(voFrame, iModule, incline_mod); // add frame
volayer->AddNode(voActive, iModule, incline_mod); // add active volume
TGeoHMatrix* incline_mod1 = new TGeoHMatrix("");
(*incline_mod1) = (*trans3) * (*r2); // for cooling
volayer->AddNode(voCool, iModule, incline_mod1); // cooling plate
}
return volayer;
}
/* Copyright (C) 2018 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: David Emschermann [committer] */
//
/// \file create_MUCH_geometry_v18j.C
/// \brief Generates MUCH geometry in Root format.
///
// 2018-09-06 - DE - v18j - reposition mMUCH at z=199 cm for cosmic setup 2018
// 2018-08-28 - DE - v18i - build a mMUCH with 2 GEM modules at z = 70 and 95 cm
// 2017-11-20 - DE - v18g - shift back to z = 70, 80 and 90 cm to avoid mSTS box
// 2017-11-10 - PPB - - correct the y position of the modules to generate much points
// 2017-11-07 - PPB - - change the shape of cooling plates from rectangular to sector
// 2017-11-06 - PPB, VS and AM - mcbm version with actual Mv2 dimesions of the module
// 2017-10-23 - DE - mcbm - put mMUCH in 6 o'clock position on z axis, shift 15 cm up and to z = 60, 70 and 80 cm
// 2017-09-04 - PPB - mcbm - preliminary version of mini much geometry
// 2017-05-16 - DE - v17b - position the modules in a way to split layers left-right along y axis
// 2017-05-16 - DE - v17b - attribute name to module frames
// 2017-05-16 - DE - v17b - remove rim from support CompositeShape
// 2017-05-02 - PPB - v17a - Change the shape of the first absorber according to latest design
// 2017-04-27 - DE - v17a - fix GEM module positions and angles
// 2017-04-22 - PPB - v17a - Define the absorber, shield and station shapes sizes ...
// 2016-04-19 - DE - v17a - initial version derived from TRD
// in root all sizes are given in cm
#include "TClonesArray.h"
#include "TDatime.h"
#include "TFile.h"
#include "TGeoBBox.h"
#include "TGeoCompositeShape.h"
#include "TGeoCone.h"
#include "TGeoManager.h"
#include "TGeoMaterial.h"
#include "TGeoMatrix.h"
#include "TGeoMedium.h"
#include "TGeoPgon.h"
#include "TGeoTube.h"
#include "TGeoVolume.h"
#include "TGeoXtru.h"
#include "TList.h"
#include "TMath.h"
#include "TObjArray.h"
#include "TRandom3.h"
#include "TString.h"
#include "TSystem.h"
#include <cassert>
#include <fstream>
#include <iostream>
#include <stdexcept>
// Name of output file with geometry
const TString tagVersion = "_v18j";
const TString geoVersion = "much";
const TString FileNameSim = geoVersion + tagVersion + "_mcbm.geo.root";
const TString FileNameGeo = geoVersion + tagVersion + "_mcbm_geo.root";
const TString FileNameInfo = geoVersion + tagVersion + "_mcbm.geo.info";
// Names of the different used materials which are used to build the modules
// The materials are defined in the global media.geo file
const TString KeepingVolumeMedium = "air";
const TString L = "MUCHlead";
const TString W = "MUCHwolfram";
const TString C = "MUCHcarbon";
const TString I = "MUCHiron";
const TString activemedium = "MUCHargon";
const TString spacermedium = "MUCHnoryl";
const TString coolmedium = "aluminium"; //Al cooling plates
// Universal input parameters
// The inner angle is 11 degree (polar angle); We take z = 70 cm;
//Inner radius: R_in=z*tan(theta_min) cm
// Outer angle is decided from tan(theta_max)=R_out/z
// R_out=R_in+95 cm (transverse size of the M2 module)
Double_t fMuchZ1 = 0.0; // MuchCave Zin position [cm]
Double_t fAcceptanceTanMin = 0.19; // Acceptance tangent min (11 degree)
//************************************************************
// Input parameters for MUCH stations
//********************************************
const Int_t fNst = 1; // Number of stations
// Sector-type module parameters
// Number of sectors per layer (should be even for symmetry)
// Needs to be fixed with actual numbers
Double_t fActiveLzSector = 0.3; // Active volume thickness [cm]
Double_t fSpacerR1 = 2.8; // Spacer width in R at low Z[cm]
Double_t fSpacerR2 = 3.5; // Spacer width in R at high Z[cm]
Double_t fSpacerPhi = 2.8; // Spacer width in Phi [cm]
Double_t fOverlapR = 0.0; // Overlap in R direction [cm]
// Station Zceneter [cm] in the cave reference frame
Double_t fStationZ0 = 234;
//Double_t fStationZ0=70; // DE - move 10 cm upstream
Int_t fNlayers = 3; // Number of layers
Double_t fLayersDz = 25; // distance between the layers
Double_t fCoolLz = 1.0; // thickness of the cooling plate also used as support
/*
1 - detailed design (modules at two sides)
* 0 - simple design (1 module per layer)
*/
//***********************************************************
// some global variables
TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance
TGeoVolume* gModules_station[fNst]; // Global storage for module types
// Forward declarations
void create_materials_from_media_file();
TGeoVolume* CreateStations(int ist);
TGeoVolume* CreateLayers(int istn, int ily);
void create_MUCH_geometry_v18j()
{
// Load needed material definition from media.geo file
create_materials_from_media_file();
// Get the GeoManager for later usage
gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom");
gGeoMan->SetVisLevel(10);
// Create the top volume
TGeoBBox* topbox = new TGeoBBox("", 1000., 1000., 2000.);
TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air"));
gGeoMan->SetTopVolume(top);
TGeoVolume* much = new TGeoVolumeAssembly(geoVersion);
top->AddNode(much, 1);
TGeoVolume* sttn = new TGeoVolumeAssembly("station"); //change name from Station ->station
much->AddNode(sttn, 1);
for (Int_t istn = 0; istn < 1; istn++) { // 1 Station
gModules_station[istn] = CreateStations(istn);
sttn->AddNode(gModules_station[istn], istn);
}
gGeoMan->CloseGeometry();
gGeoMan->CheckOverlaps(0.000001);
gGeoMan->PrintOverlaps();
// gGeoMan->Test();
much->Export(FileNameSim); // an alternative way of writing the much
TFile* outfile = new TFile(FileNameSim, "UPDATE");
TGeoTranslation* much_placement = new TGeoTranslation("much_trans", 0., 0., 0.);
much_placement->Write();
outfile->Close();
outfile = new TFile(FileNameGeo, "RECREATE");
gGeoMan->Write(); // use this if you want GeoManager format in the output
outfile->Close();
top->Draw("ogl");
}
void create_materials_from_media_file()
{
// Use the FairRoot geometry interface to load the media which are already defined
FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
TString geoPath = gSystem->Getenv("VMCWORKDIR");
TString geoFile = geoPath + "/geometry/media.geo";
geoFace->setMediaFile(geoFile);
geoFace->readMedia();
// Read the required media and create them in the GeoManager
FairGeoMedia* geoMedia = geoFace->getMedia();
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
FairGeoMedium* air = geoMedia->getMedium(KeepingVolumeMedium);
geoBuild->createMedium(air);
FairGeoMedium* MUCHiron = geoMedia->getMedium(I);
geoBuild->createMedium(MUCHiron);
FairGeoMedium* MUCHlead = geoMedia->getMedium(L);
geoBuild->createMedium(MUCHlead);
FairGeoMedium* MUCHwolfram = geoMedia->getMedium(W);
geoBuild->createMedium(MUCHwolfram);
FairGeoMedium* MUCHcarbon = geoMedia->getMedium(C);
geoBuild->createMedium(MUCHcarbon);
FairGeoMedium* MUCHargon = geoMedia->getMedium(activemedium);
geoBuild->createMedium(MUCHargon);
FairGeoMedium* MUCHnoryl = geoMedia->getMedium(spacermedium);
geoBuild->createMedium(MUCHnoryl);
FairGeoMedium* aluminium = geoMedia->getMedium(coolmedium);
// geoBuild->createMedium(MUCHcool);
geoBuild->createMedium(aluminium);
}
TGeoVolume* CreateStations(int ist)
{
TString stationName = Form("muchstation%02i", ist + 1);
TGeoVolumeAssembly* station = new TGeoVolumeAssembly(stationName); //, shStation, air);
TGeoVolume* gLayer[4];
for (int ii = 0; ii < 3; ii++) { // 3 Layers
gLayer[ii] = CreateLayers(ist, ii);
if (ii != 2) // DE - skip 3rd=last GEM module for 2018
station->AddNode(gLayer[ii], ii);
}
return station;
}
TGeoVolume* CreateLayers(int istn, int ily)
{
TString layerName = Form("muchstation%02ilayer%i", istn + 1, ily + 1);
TGeoVolumeAssembly* volayer = new TGeoVolumeAssembly(layerName);
//Double_t DeltaR=80.0; // transverse dimension of the module
Double_t stGlobalZ0 = fStationZ0 + fMuchZ1; //z position of station center (midplane) [cm]
Double_t stDz = ((fNlayers - 1) * fLayersDz + fCoolLz + 2 * fActiveLzSector) / 2.;
Double_t stGlobalZ2 = stGlobalZ0 + stDz;
Double_t stGlobalZ1 = stGlobalZ0 - stDz;
//Double_t rmin = stGlobalZ1 * fAcceptanceTanMin;
// Double_t rmax = rmin+ fSpacerR + DeltaR;
Int_t Nsector = 16.0; // need to be hard coded to match with station 1 of SIS100
//cout<<" Nsector "<<Nsector<<endl;
Double_t layerZ0 = (ily - (fNlayers - 1) / 2.) * fLayersDz;
Double_t layerGlobalZ0 = layerZ0 + stGlobalZ0;
Double_t sideDz = fCoolLz / 2. + fActiveLzSector / 2.; // distance between side's and layer's centers
Double_t moduleZ = sideDz; // Z position of the module center in the layer cs
Double_t phi0 = TMath::Pi() / Nsector; // azimuthal half widh of each module
//Double_t ymin = rmin+fSpacerR;
// Double_t ymax = rmax;
//define the dimensions of the trapezoidal module
//Use hard coded values for mini-cbm
Double_t dy = 40.0; //(ymax-ymin)/2.; //y (length)
Double_t dx1 = 3.75; //ymin*TMath::Tan(phi0)+fOverlapR/TMath::Cos(phi0); // large x
Double_t dx2 = 20; //ymax*TMath::Tan(phi0)+fOverlapR/TMath::Cos(phi0); // small x
Double_t dz = fActiveLzSector / 2.; // thickness
//define the spacer dimensions
Double_t tg = (dx2 - dx1) / 2 / dy;
Double_t dd1 = fSpacerPhi * tg;
Double_t dd2 = fSpacerPhi * sqrt(1 + tg * tg);
Double_t sdx1 = dx1 + dd2 - dd1;
Double_t sdx2 = dx2 + dd2 + dd1;
Double_t sdy1 = dy + fSpacerR1; // frame width added
Double_t sdy2 = dy + fSpacerR2; // frame width added
Double_t sdz = dz - 0.1;
// Define the (cooling plate) diemnsions (hardcoded for mcbm)
Double_t dy_s = sdy2; //46.5;//dy+2.0;
Double_t dx1_s = sdx1; //27.0; //dx1+2.0 ;// large x
Double_t dx2_s = sdx2; //27.0; //dx2+2.0;// x
Double_t dz_s = fCoolLz / 2.; //
TVector3 pos;
TVector3 size = TVector3(0.0, 0.0, fActiveLzSector);
// Now start adding the GEM modules
for (Int_t iModule = 0; iModule < 1; iModule++) {
// if (iModule!=0) continue;
// Double_t phi = 2 * phi0 * (iModule + 0.5); // add 0.5 to not overlap with y-axis for left-right layer separation
// Position of the module will depend on Phi
// Set Phi=180 degree 6 o'clock position
// Set Phi=90 degree 3 o'clock position
// Double_t phi=TMath::Pi()/2.0;
Double_t phi = 0; // do not blow up yMin in CbmMuchGeoScheme to see points
Bool_t isBack = iModule % 2;
Char_t cside = (isBack == 1) ? 'b' : 'f';
// correct the x, y positions
// pos[0] = -(ymin+dy)*sin(phi);
// pos[1] = (ymin+dy)*cos(phi);
pos[0] = 0; // DE - do not displace mMUCH in x
pos[1] = 15; // DE - move upwards in y [cm]
// different z positions for odd/even modules
// pos[2] = (isBack ? 1 : -1)*moduleZ + layerGlobalZ0;
pos[2] = layerGlobalZ0;
TGeoMedium* argon = gGeoMan->GetMedium(activemedium); // active medium
TGeoMedium* noryl = gGeoMan->GetMedium(spacermedium); // spacer medium
TGeoMedium* aluminium = gGeoMan->GetMedium(coolmedium); // cool medium
// Define and place the trapezoidal GEM module in X-Y plane
TGeoTrap* shape = new TGeoTrap(dz, 0, phi, dy, dx1, dx2, 0, dy, dx1, dx2, 0);
// TGeoTrap* shape = new TGeoTrap(dz,0,0,dy,dx1,dx2,0,dy,dx1,dx2,0);
shape->SetName(Form("shStation%02iLayer%i%cModule%03iActiveNoHole", istn, ily, cside, iModule));
TString activeName = Form("muchstation%02ilayer%i%cactive%03igasArgon", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voActive = new TGeoVolume(activeName, shape, argon);
voActive->SetLineColor(kGreen);
// Define the trapezoidal spacers
TGeoTrap* shapeFrame = new TGeoTrap(sdz, 0, phi, sdy1, sdx1, sdx2, 0, sdy2, sdx1, sdx2, 0);
//TGeoTrap* shapeFrame = new TGeoTrap(sdz,0,0,sdy,sdx1,sdx2,0,sdy,sdx1,sdx2,0);
shapeFrame->SetName(Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole", istn, ily, cside, iModule));
TString expression = Form("shStation%02iLayer%i%cModule%03iFullFrameNoHole-"
"shStation%02iLayer%i%cModule%03iActiveNoHole",
istn, ily, cside, iModule, istn, ily, cside, iModule);
TGeoCompositeShape* shFrame = new TGeoCompositeShape(
Form("shStation%02iLayer%i%cModule%03iFrameNoHole", istn, ily, cside, iModule), expression);
TString frameName = Form("muchstation%02ilayer%i%csupport%03i", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voFrame = new TGeoVolume(frameName, shFrame, noryl); // add a name to the frame
voFrame->SetLineColor(kMagenta);
// Define the trapezoidal (cooling plates)
// TGeoTrap* cool = new TGeoTrap(dz_s,0,phi,dy_s,dx1_s,dx2_s,0,dy_s,dx1_s,dx2_s,0);
TGeoTrap* cool = new TGeoTrap(dz_s, 0, phi, dy_s, dx1_s, dx2_s, 0, dy_s, dx1_s, dx2_s, 0);
cool->SetName(Form("shStation%02iLayer%i%cModule%03icool", istn, ily, cside, iModule));
TString CoolName = Form("muchstation%02ilayer%i%ccool%03iAluminum", istn + 1, ily + 1, cside, iModule + 1);
TGeoVolume* voCool = new TGeoVolume(CoolName, cool, aluminium);
voCool->SetLineColor(kYellow);
// Calculate the phi angle of the sector where it has to be placed
Double_t angle = 180. / TMath::Pi() * phi; // convert angle phi from rad to deg
TGeoTranslation* trans2 = new TGeoTranslation("", pos[0], pos[1], pos[2]); //for module and frame
TGeoTranslation* trans3 = new TGeoTranslation("", pos[0], pos[1], pos[2] + 0.65); //for module and frame
TGeoRotation* r2 = new TGeoRotation("r2");
//rotate in the vertical plane (per to z axis) with angle
// r2->RotateZ(angle);
// DE cout << "DE " << phi << endl;
// DE cout << "DE " << angle << endl;
// DE cout << "DE " << phi0 << endl;
// DE cout << "DE " << 180. / TMath::Pi() * phi0 << endl;
// r2->RotateZ(180.0); // DE - 6 o'clock position
r2->RotateZ(180.0 - (180. / TMath::Pi() * phi0)); // DE - 6 o'clock position, left side vertical
// r2->RotateZ(180.0-11.25); // DE - 6 o'clock position, left side vertical
// give rotation to set them in horizontal plane
//r2->RotateZ(90.0);//TMath::Pi());
TGeoHMatrix* incline_mod = new TGeoHMatrix("");
(*incline_mod) = (*trans2) * (*r2); // OK
volayer->AddNode(voFrame, iModule, incline_mod); // add frame
volayer->AddNode(voActive, iModule, incline_mod); // add active volume
TGeoHMatrix* incline_mod1 = new TGeoHMatrix("");
(*incline_mod1) = (*trans3) * (*r2); // for cooling
volayer->AddNode(voCool, iModule, incline_mod1); // cooling plate
}
return volayer;
}