From c67ff38c43d897a62cfa23e9824f8f72177b4554 Mon Sep 17 00:00:00 2001 From: David Emschermann <d.emschermann@gsi.de> Date: Tue, 26 Mar 2024 12:35:05 +0100 Subject: [PATCH] Add mTOF v24b geometry + macro, aligned to measurements in the cave, refs #3239 => Also add mTOF v24a creation macro (original from TOF experts) => Root file not added/removed as known not matching reality --- .../tof/mcbm/Create_TOF_Geometry_v24a_mcbm.C | 1312 ++++++++++++++++ .../tof/mcbm/Create_TOF_Geometry_v24b_mcbm.C | 1313 +++++++++++++++++ tof/tof_v24b_mcbm.geo.info | 15 + tof/tof_v24b_mcbm.geo.root | Bin 0 -> 12899 bytes 4 files changed, 2640 insertions(+) create mode 100644 macro/tof/mcbm/Create_TOF_Geometry_v24a_mcbm.C create mode 100644 macro/tof/mcbm/Create_TOF_Geometry_v24b_mcbm.C create mode 100644 tof/tof_v24b_mcbm.geo.info create mode 100644 tof/tof_v24b_mcbm.geo.root diff --git a/macro/tof/mcbm/Create_TOF_Geometry_v24a_mcbm.C b/macro/tof/mcbm/Create_TOF_Geometry_v24a_mcbm.C new file mode 100644 index 0000000..6033130 --- /dev/null +++ b/macro/tof/mcbm/Create_TOF_Geometry_v24a_mcbm.C @@ -0,0 +1,1312 @@ +/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Florian Uhlig, Shreya Roy [committer] */ + +/// +/// \file Create_TOF_Geometry_v24a_mcbm.C +/// \brief Generates TOF geometry in Root format. +/// + +// Changelog +// 2024-03-26 - v24a - DE - March 2024 setup by NH, script patched by DE in lines 1000 and 1004 to show only 2 STAR modules +// 2021-11-17 - v24a - QZ - Modified v20d to fit the logic of digibdf.par +// 2020-04-14 - v20b - NH - swapped double stack layer 2 with STAR2 moodule, buc kept as dummy +// 2020-04-01 - v20a - NH - move mTOF +20 cm in x direction for the Mar 2020 run +// 2019-11-28 - v19b - DE - move mTOF +12 cm in x direction for the Nov 2019 run +// 2019-07-31 - v19a - DE - this TOF March 2019 geometry is also known as v18m +// 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_v24a_mcbm"; // do not change +const TString geoVersionStand = geoVersion + "Stand"; +// +const TString fileTag = "tof_v24a"; +const TString FileNameSim = fileTag + "_mcbm.geo.root"; +const TString FileNameGeo = fileTag + "_mcbm_geo.root"; +const TString FileNameInfo = fileTag + "_mcbm.geo.info"; + +// TOF_Z_Front corresponds to front cover of outer super module towers +const Float_t TOF_Z_Front_Stand = 250.; // = 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., 32., 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., 32., 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, 16, 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, 34.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., 11., 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, 5, 5, 5, 1, 2, 1, 8, 2}; + +// Placement of the counter inside the module +const Float_t CounterXStartPosition[NofModuleTypes] = {-63.0, -66.0, -60.0, -60.0, -60.0, 0.0, 0., 0., -7., 0.}; +const Float_t CounterXDistance[NofModuleTypes] = {31.5, 32.0, 30.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, 10.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 + 36.; +const Float_t Star2_Delta_Z_Position = 16.; +const Float_t Star2_First_Y_Position = 0.; // +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] = {0.}; //{62.}; + +const Float_t Buc_First_Z_Position = TOF_Z_Front + 36.; +const Float_t Buc_Delta_Z_Position = 0.; +const Float_t Buc_First_Y_Position = 40; // +const Float_t Buc_Delta_Y_Position = 0.; // +const Float_t Buc_rotate_Z = 180.; +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] = {53.5}; + +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 = 3.; +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_v24a_mcbm() +{ + + // 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); + top->AddNode(tof, 1); + + TGeoVolume* tofstand = new TGeoVolumeAssembly(geoVersionStand); + // Mar 2020 run + TGeoTranslation* stand_trans = new TGeoTranslation("", 0., 0., TOF_Z_Front_Stand); + // Nov 2019 run + // TGeoTranslation* stand_trans = new TGeoTranslation("", 12., 0., TOF_Z_Front_Stand); + // TGeoTranslation* stand_trans = new TGeoTranslation("", 0., 0., TOF_Z_Front_Stand); + TGeoRotation* stand_rot = new TGeoRotation(); + stand_rot->RotateY(0.0); + TGeoCombiTrans* stand_combi_trans = new TGeoCombiTrans(*stand_trans, *stand_rot); + // tof->AddNode(tofstand, 1, stand_combi_trans); + tof->AddNode(tofstand, 1); + + 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(2); + // 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->CheckOverlaps(0.001, "s"); + gGeoMan->PrintOverlaps(); + gGeoMan->Test(); + + tof->Export(FileNameSim); + TFile* geoFile = new TFile(FileNameSim, "UPDATE"); + stand_combi_trans->Write(); + geoFile->Close(); + + /* + 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(kRed); // 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++; + + // Mar2019 setup + Int_t modNum[4] = {4 * 0}; + const Int_t NModules = 6; + xPos = 0.; + yPos = 0.; + zPos = TOF_Z_Front; + const Int_t ModType[NModules] = {0, 0, 0, 0, 0, 2}; + const Double_t ModDx[NModules] = {0., 0., 0., 0., 0., 0.}; + //const Double_t ModDx[NModules]= { 1.5, 0., -1.5, 49.8, 55.8}; + const Double_t ModDy[NModules] = {49.8, 0., -49.8, 28.5, -28.5, 37.5}; + const Double_t ModDz[NModules] = {0., 0, 0, 20., 20., 72.}; + const Double_t ModAng[NModules] = {0., 0., 0., 0., 0.0, 0.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); + if (iMod < 5) { gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[0], modNum, module_combi_trans); } + else { + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[2], modNum, module_combi_trans); + } + modNum++; + } +*/ + + 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[iMod]], modNum[ModType[iMod]], module_combi_trans); + cout << "Placed Module " << modNum[ModType[iMod]] << ", Type " << ModType[iMod] << endl; + modNum[ModType[iMod]]++; + } + + /* + 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++) { // DE + for (Int_t j = 0; j < 1; j++) { + Int_t modType = Star2_Types[j]; + Float_t xPos = Star2_X_Offset[j]; +// for (Int_t i = 0; i < Star2_Number[j]; i++) { // DE + for (Int_t i = 0; i < 2; 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); + cout << "Placed Module 1010 " << Star2_Number[j] << endl; // DE + 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); +} diff --git a/macro/tof/mcbm/Create_TOF_Geometry_v24b_mcbm.C b/macro/tof/mcbm/Create_TOF_Geometry_v24b_mcbm.C new file mode 100644 index 0000000..a97c25a --- /dev/null +++ b/macro/tof/mcbm/Create_TOF_Geometry_v24b_mcbm.C @@ -0,0 +1,1313 @@ +/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Florian Uhlig, Shreya Roy [committer] */ + +/// +/// \file Create_TOF_Geometry_v24b_mcbm.C +/// \brief Generates TOF geometry in Root format. +/// + +// Changelog +// 2024-03-26 - v24b - DE - Shifted in z to position measured in the cave +// 2024-03-26 - v24a - DE - March 2024 setup by NH, script patched by DE in lines 1000 and 1004 to show only 2 STAR modules +// 2021-11-17 - v24a - QZ - Modified v20d to fit the logic of digibdf.par +// 2020-04-14 - v20b - NH - swapped double stack layer 2 with STAR2 moodule, buc kept as dummy +// 2020-04-01 - v20a - NH - move mTOF +20 cm in x direction for the Mar 2020 run +// 2019-11-28 - v19b - DE - move mTOF +12 cm in x direction for the Nov 2019 run +// 2019-07-31 - v19a - DE - this TOF March 2019 geometry is also known as v18m +// 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_v24b_mcbm"; // do not change +const TString geoVersionStand = geoVersion + "Stand"; +// +const TString fileTag = "tof_v24b"; +const TString FileNameSim = fileTag + "_mcbm.geo.root"; +const TString FileNameGeo = fileTag + "_mcbm_geo.root"; +const TString FileNameInfo = fileTag + "_mcbm.geo.info"; + +// TOF_Z_Front corresponds to front cover of outer super module towers +const Float_t TOF_Z_Front_Stand = 232.5; // = 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., 32., 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., 32., 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, 16, 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, 34.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., 11., 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, 5, 5, 5, 1, 2, 1, 8, 2}; + +// Placement of the counter inside the module +const Float_t CounterXStartPosition[NofModuleTypes] = {-63.0, -66.0, -60.0, -60.0, -60.0, 0.0, 0., 0., -7., 0.}; +const Float_t CounterXDistance[NofModuleTypes] = {31.5, 32.0, 30.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, 10.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 + 36.; +const Float_t Star2_Delta_Z_Position = 16.; +const Float_t Star2_First_Y_Position = 0.; // +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] = {0.}; //{62.}; + +const Float_t Buc_First_Z_Position = TOF_Z_Front + 36.; +const Float_t Buc_Delta_Z_Position = 0.; +const Float_t Buc_First_Y_Position = 40; // +const Float_t Buc_Delta_Y_Position = 0.; // +const Float_t Buc_rotate_Z = 180.; +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] = {53.5}; + +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 = 3.; +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_v24b_mcbm() +{ + + // 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); + top->AddNode(tof, 1); + + TGeoVolume* tofstand = new TGeoVolumeAssembly(geoVersionStand); + // Mar 2020 run + TGeoTranslation* stand_trans = new TGeoTranslation("", 0., 0., TOF_Z_Front_Stand); + // Nov 2019 run + // TGeoTranslation* stand_trans = new TGeoTranslation("", 12., 0., TOF_Z_Front_Stand); + // TGeoTranslation* stand_trans = new TGeoTranslation("", 0., 0., TOF_Z_Front_Stand); + TGeoRotation* stand_rot = new TGeoRotation(); + stand_rot->RotateY(0.0); + TGeoCombiTrans* stand_combi_trans = new TGeoCombiTrans(*stand_trans, *stand_rot); + // tof->AddNode(tofstand, 1, stand_combi_trans); + tof->AddNode(tofstand, 1); + + 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(2); + // 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->CheckOverlaps(0.001, "s"); + gGeoMan->PrintOverlaps(); + gGeoMan->Test(); + + tof->Export(FileNameSim); + TFile* geoFile = new TFile(FileNameSim, "UPDATE"); + stand_combi_trans->Write(); + geoFile->Close(); + + /* + 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(kRed); // 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++; + + // Mar2019 setup + Int_t modNum[4] = {4 * 0}; + const Int_t NModules = 6; + xPos = 0.; + yPos = 0.; + zPos = TOF_Z_Front; + const Int_t ModType[NModules] = {0, 0, 0, 0, 0, 2}; + const Double_t ModDx[NModules] = {0., 0., 0., 0., 0., 0.}; + //const Double_t ModDx[NModules]= { 1.5, 0., -1.5, 49.8, 55.8}; + const Double_t ModDy[NModules] = {49.8, 0., -49.8, 28.5, -28.5, 37.5}; + const Double_t ModDz[NModules] = {0., 0, 0, 20., 20., 72.}; + const Double_t ModAng[NModules] = {0., 0., 0., 0., 0.0, 0.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); + if (iMod < 5) { gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[0], modNum, module_combi_trans); } + else { + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[2], modNum, module_combi_trans); + } + modNum++; + } +*/ + + 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[iMod]], modNum[ModType[iMod]], module_combi_trans); + cout << "Placed Module " << modNum[ModType[iMod]] << ", Type " << ModType[iMod] << endl; + modNum[ModType[iMod]]++; + } + + /* + 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++) { // DE + for (Int_t j = 0; j < 1; j++) { + Int_t modType = Star2_Types[j]; + Float_t xPos = Star2_X_Offset[j]; +// for (Int_t i = 0; i < Star2_Number[j]; i++) { // DE + for (Int_t i = 0; i < 2; 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); + cout << "Placed Module 1010 " << Star2_Number[j] << endl; // DE + 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); +} diff --git a/tof/tof_v24b_mcbm.geo.info b/tof/tof_v24b_mcbm.geo.info new file mode 100644 index 0000000..aa1f010 --- /dev/null +++ b/tof/tof_v24b_mcbm.geo.info @@ -0,0 +1,15 @@ +# +## tof_v24b_mcbm information file +# + +# created 20240326 + +# TOF setup + +# envelope + 0.00 cm start of TOF (z) + 416.50 cm end of TOF (z) + +# central tower position + 400.00 cm center of staggered, front RPC cell at x=0 + diff --git a/tof/tof_v24b_mcbm.geo.root b/tof/tof_v24b_mcbm.geo.root new file mode 100644 index 0000000000000000000000000000000000000000..ebfd0cbec4226394a48318c7ce3f4f1cc35b6467 GIT binary patch literal 12899 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 literal 0 HcmV?d00001 -- GitLab