From 362c8819841ac23c2726d435a655673ee392a20e Mon Sep 17 00:00:00 2001 From: Pierre-Alain Loizeau <p.-a.loizeau@gsi.de> Date: Mon, 4 Nov 2024 17:57:23 +0000 Subject: [PATCH] Provide mcbm2022 TOF v21k_mcbm geometry macro and update binary Corrects long standing issue. Adds creation macro to long-time in-use binary. Test module box shifted by 500 micron to remove overlap. Binary made reproducible. --- .../tof/mcbm/Create_TOF_Geometry_v21k_mcbm.C | 1305 +++++++++++++++++ setup/setup_mcbm_beam_2022_05_23_nickel.C | 2 +- tof/tof_v21k_mcbm.geo.info | 15 + tof/tof_v21k_mcbm.geo.root | Bin 0 -> 13997 bytes 4 files changed, 1321 insertions(+), 1 deletion(-) create mode 100644 macro/tof/mcbm/Create_TOF_Geometry_v21k_mcbm.C create mode 100644 tof/tof_v21k_mcbm.geo.info create mode 100644 tof/tof_v21k_mcbm.geo.root diff --git a/macro/tof/mcbm/Create_TOF_Geometry_v21k_mcbm.C b/macro/tof/mcbm/Create_TOF_Geometry_v21k_mcbm.C new file mode 100644 index 0000000..adda451 --- /dev/null +++ b/macro/tof/mcbm/Create_TOF_Geometry_v21k_mcbm.C @@ -0,0 +1,1305 @@ +/* Copyright (C) 2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Florian Uhlig [committer] */ +/// +/// \file Create_TOF_Geometry_v21k_mcbm.C +/// \brief Generates TOF geometry in Root format. +/// + +// clang-format off + +// Changelog +// +// 2023-10-01 - v21k - ID - adjust to fit data +// 2022-11-03 - v21j - ID - Setup for Nickel and Goald run 2022 +// 2022-05-07 - v21h - DE - shift v21g by x += 53.5 cm to align triple stack on z-axis +// 2022-04-10 - v21g - NH - setup for U-run, March 2022 +// 2022-03-23 - v21f - DE - apply global rotation of TOF around target _after_ z-shift +// 2022-03-19 - v21f - ID - Setup for Iron run of March 22nd +// 2021-05-24 - v21n - NH - add M6 module +// 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_v21k_mcbm"; // do not change +const TString geoVersionStand = geoVersion + "Stand"; +// +const TString fileTag = "tof_v21k"; +const TString FileNameSim = fileTag + "_mcbm.geo.root?reproducible"; +const TString FileNameGeo = fileTag + "_mcbm_geo.root?reproducible"; +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 = 233.1; // = z=298 mCBM@SIS18 +const Float_t TOF_X_Front_Stand = 0.33; // +const Float_t TOF_Y_Front_Stand = 0.1; // +const Float_t TOF_Z_Front = 0.; // +//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 USTC +// 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] = {27.0, 53., 26.8, 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] = {27.0, 53., 26.8, 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] = {32.0, 32.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; +// 0 M4 (TSHU) +// 1 M4 (USTC) +// 2 M6 (USTC) +// 5 Diamond +// 6 Buc +// 7 Testbox MRPC4 +// 8 Ceramic +// 9 Star2 +// Aluminum box for all module types +const Float_t Module_Size_X[NofModuleTypes] = {180., 180., 180., 180., 180., 5., 40., 100., 10., 100.}; +const Float_t Module_Size_Y[NofModuleTypes] = {49., 49., 74., 28., 18., 5., 15., 49., 10., 49.}; +const Float_t Module_Over_Y[NofModuleTypes] = {11.5, 11.5, 11., 4.5, 4.5, 0., 0., 0., 0., 0.}; +const Float_t Module_Size_Z[NofModuleTypes] = {11., 11., 13., 11., 11., 1., 12., 11., 1., 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, 1, 8, 2}; +const Int_t NCounterInModule[NofModuleTypes] = {5, 5, 5, 5, 5, 1, 2, 2, 1, 2}; + +// Placement of the counter inside the module +const Float_t CounterXStartPosition[NofModuleTypes] = {-60., -66.0, -61.1, -60.0, -60.0, 0.0, 0., 0., 0., 0.}; +const Float_t CounterXDistance[NofModuleTypes] = { 30., 32.0, 30.45, 30.0, 30.0, 0.0, 0., 0., 0., 0.}; +const Float_t CounterYStartPosition[NofModuleTypes] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0., 0., 0., 0., 0.}; +const Float_t CounterYDistance[NofModuleTypes] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0., 0., 0., 0., 0.}; +const Float_t CounterZDistance[NofModuleTypes] = { -2.5, 0.0, 0.0, 2.5, 2.5, 0., 6., 4., 0.1, 4.}; +const Float_t CounterZStartPosition[NofModuleTypes] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0., -3., -2., 0.0,-2.}; +const Float_t CounterRotationAngle[NofModuleTypes] = { 0., 8.7, -7.0, 0., 0., 0., 0., 0., 0., 0.}; +const Float_t CounterRotationAngleZ[NofModuleTypes] = { 0., 0., 0.0, 0., 0., 0., 0., 90., 0., 0.}; +// clang-format on + +// 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 + 15.9 + 16.1; +const Float_t Star2_Delta_Z_Position = 16.3; +const Float_t Star2_First_Y_Position = 30.34; // +const Float_t Star2_Delta_Y_Position = 0.; // +const Int_t Star2_NTypes = 1; +const Float_t Star2_rotate_Z[Star2_NTypes] = {-90.}; +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] = {49.75}; + +const Float_t Buc_First_Z_Position = TOF_Z_Front + 16.5 + 4.; //put 600 to position of 601 +const Float_t Buc_Delta_Z_Position = 0.; +const Float_t Buc_First_Y_Position = -29.1; // +const Float_t Buc_Delta_Y_Position = 0.; // +const Float_t Buc_rotate_Y = 180.; +const Float_t Buc_rotate_Z = 0.; +const Int_t Buc_NTypes = 1; +const Float_t Buc_Types[Buc_NTypes] = {6.}; +const Float_t Buc_Number[Buc_NTypes] = {1.}; //debugging, V16b +const Float_t Buc_X_Offset[Buc_NTypes] = {47.85}; + +const Int_t Cer_NTypes = 2; +const Float_t Cer_Z_Position[Cer_NTypes] = {(float) (TOF_Z_Front + 46.), (float) (TOF_Z_Front + 47.1)}; +const Float_t Cer_X_Position[Cer_NTypes] = {1., 1.}; +const Float_t Cer_Y_Position[Cer_NTypes] = {-29., -29.}; +const Float_t Cer_rotate_Z[Cer_NTypes] = {0., 0.}; +const Float_t Cer_Types[Cer_NTypes] = {8., 8.}; +const Float_t Cer_Number[Cer_NTypes] = {1., 1.}; + +const Float_t Testbox_MRPC4_Z_Position = TOF_Z_Front + 15.9; // +const Float_t Testbox_MRPC4_First_Y_Position = 32.70; +const Float_t Testbox_MRPC4_X_Offset = 50.17; //65.5; +const Float_t Testbox_MRPC4_rotate_Z = -90.; +const Int_t Testbox_MRPC4_NTypes = 1; +const Float_t Testbox_MRPC4_Types[Testbox_MRPC4_NTypes] = {7.}; // this is the SmType! +const Float_t Testbox_MRPC4_Number[Testbox_MRPC4_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.2 - TOF_Z_Front_Stand; +const Float_t Dia_First_Y_Position = 0.; //- TOF_Y_Front_Stand; +const Float_t Dia_X_Offset = 3.5; // - TOF_X_Front_Stand; +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_Testbox_MRPC4(Int_t); +void dump_info_file(); + + +void Create_TOF_Geometry_v21k_mcbm() +{ + // Load FairRunSim to ensure the correct unit system + FairRunSim* sim = new FairRunSim(); + + // 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, -2.); // ?? + + TGeoVolume* tofstand = new TGeoVolumeAssembly(geoVersionStand); + // Mar 2020 run + TGeoTranslation* stand_trans_local = new TGeoTranslation("", TOF_X_Front_Stand, TOF_Y_Front_Stand, 0.); + TGeoTranslation* stand_trans = new TGeoTranslation("", 0., 0., TOF_Z_Front_Stand); + TGeoCombiTrans* stand_combi_trans = new TGeoCombiTrans(*stand_trans, *tof_rotation); + + TGeoRotation* stand_rot = new TGeoRotation(); + //stand_rot->RotateY(0.); + stand_rot->RotateY(0.97); + TGeoCombiTrans* stand_combi_trans_local = new TGeoCombiTrans(*stand_trans_local, *stand_rot); + + //tof->AddNode(tofstand, 1, stand_combi_trans); + tof->AddNode(tofstand, 1, stand_combi_trans_local); + //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(1); + // position_cer_modules(2); + position_Testbox_MRPC4(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(); + + // create medialist for this geometry + TString createmedialist = gSystem->Getenv("VMCWORKDIR"); + createmedialist += "/macro/geometry/create_medialist.C"; + std::cout << "Loading macro " << createmedialist << std::endl; + gROOT->LoadMacro(createmedialist); + gROOT->ProcessLine("create_medialist(\"\", false)"); + + /* + TFile* outfile1 = new TFile(FileNameSim,"RECREATE"); + top->Write(); + //gGeoMan->Write(); + outfile1->Close(); +*/ + //tof->RemoveNode((TGeoNode*)tofstand); + //top->AddNode(tof, 1, tof_rotation); + //tof->ReplaceNode((TGeoNode*)tofstand, 0, stand_combi_trans); + /* + CbmTransport run; + run.SetGeoFileName(FileNameGeo); + run.LoadSetup("setup_mcbm_tof_2020"); + run.SetField(new CbmFieldConst()); +*/ + //top->Export(FileNameGeo); + + 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); + if ( CounterRotationAngleZ[modType] != 0. ) counter_rot->RotateZ(CounterRotationAngleZ[modType]); + 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; + + // for (Int_t j=0; j<modNType; j++){ + // for (Int_t j=1; j<modNType; j++){ + Int_t modType; + Int_t modNum[4] = {4 * 0}; + + // May2021 setup + const Int_t NModules = 6; + Double_t xPos = 0.; + Double_t yPos = 0.; + Double_t zPos = TOF_Z_Front; + const Int_t ModType[NModules] = {0, 0, 0, 0, 0, 2}; + //const Double_t ModDx[NModules] = {-53.5, -56.3, -66.8, 0., 0., -65.}; //Au, jun2022, run 2454 + //const Double_t ModDx[NModules] = { 0.3, -3.3, -13.5, 50.7, 50.7, -12.0}; //Ni, may2022, run 2391 + const Double_t ModDx[NModules] = { 0.2, -3.3, -13.8, 50.7, 49.5, -11.77}; //Ni, may2022, run 2391, data driven + //const Double_t ModDx[NModules] = {-53.5, -57., -72.7, 0., -21.5, -64.}; + //const Double_t ModDx[NModules] = {-53.5, -57., -57.7, 0., -21.5, -64.}; + //const Double_t ModDx[NModules] = {-53.5, -57., -75.7, 0., -21., -66.}; + //const Double_t ModDx[NModules] = { 1.5, 0., -1.5, 49.8, 55.8}; + const Double_t ModDy[NModules] = {0., 0., 0., 0., 0., -0.49}; + const Double_t ModDz[NModules] = {0., 15.9, 56., 0., 56., 32.}; // regular + const Double_t ModAng[NModules] = {-90., -90., -90., -90., -90.0, -90.}; + TGeoRotation* module_rot = NULL; + TGeoCombiTrans* module_combi_trans = NULL; + + for (Int_t iMod = 0; iMod < NModules; iMod++) { + module_trans = new TGeoTranslation("", xPos + ModDx[iMod], yPos + ModDy[iMod], zPos + ModDz[iMod]); + module_rot = new TGeoRotation(); + module_rot->RotateZ(ModAng[iMod]); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[ModType[iMod]], modNum[ModType[iMod]], module_combi_trans); + cout << "Placed Module " << modNum[ModType[iMod]] << ", Type " << ModType[iMod] << endl; + modNum[ModType[iMod]]++; + } + +} + +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); + //top->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + } + } +} + +void position_Star2(Int_t modNType) +{ + TGeoTranslation* module_trans = NULL; + TGeoCombiTrans* module_combi_trans = NULL; + TGeoRotation* module_rot = NULL; + Float_t yPos = Star2_First_Y_Position; + Float_t zPos = Star2_First_Z_Position; + Int_t ii = 0; + + Int_t modNum = 0; + for (Int_t j = 0; j < modNType; j++) { + Int_t modType = Star2_Types[j]; + Float_t xPos = Star2_X_Offset[j]; + module_rot = new TGeoRotation(); + module_rot->RotateZ(Star2_rotate_Z[j]); + for (Int_t i = 0; i < Star2_Number[j]; i++) { + ii++; + module_trans = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + yPos += Star2_Delta_Y_Position; + zPos += Star2_Delta_Z_Position; + } + } +} + +void position_Buc(Int_t modNType) +{ + TGeoTranslation* module_trans = NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(Buc_rotate_Z); + module_rot->RotateY(Buc_rotate_Y); + 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 = 0; 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_Testbox_MRPC4(Int_t modNType) +{ + TGeoTranslation* module_trans = NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(Testbox_MRPC4_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 = Testbox_MRPC4_First_Y_Position; + Int_t ii = 0; + Float_t xPos = Testbox_MRPC4_X_Offset; + Float_t zPos = Testbox_MRPC4_Z_Position; + + for (Int_t j = 0; j < modNType; j++) { + Int_t modType = Testbox_MRPC4_Types[j]; + Int_t modNum = 0; + for (Int_t i = 0; i < Testbox_MRPC4_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/setup/setup_mcbm_beam_2022_05_23_nickel.C b/setup/setup_mcbm_beam_2022_05_23_nickel.C index f4eb306..8c864d8 100644 --- a/setup/setup_mcbm_beam_2022_05_23_nickel.C +++ b/setup/setup_mcbm_beam_2022_05_23_nickel.C @@ -77,7 +77,7 @@ void setup_mcbm_beam_2022_05_23_nickel() { TString trdGeoTag = "v22h_mcbm"; // TRD-2D May 2022 + 2x TRD-1D modules // done - TString tofGeoTag = "v21j_mcbm"; // + TString tofGeoTag = "v21k_mcbm"; // // done TString richGeoTag = "v21c_mcbm"; // othogonal to z-axis diff --git a/tof/tof_v21k_mcbm.geo.info b/tof/tof_v21k_mcbm.geo.info new file mode 100644 index 0000000..f05c966 --- /dev/null +++ b/tof/tof_v21k_mcbm.geo.info @@ -0,0 +1,15 @@ +# +## tof_v21k_mcbm information file +# + +# created 20241001 + +# 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_v21k_mcbm.geo.root b/tof/tof_v21k_mcbm.geo.root new file mode 100644 index 0000000000000000000000000000000000000000..56845e03d85efd777982aad431b3088e553b8aeb GIT binary patch literal 13997 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 Rr`Z4bt}0-J|J`@`e*rPp4O;*J literal 0 HcmV?d00001 -- GitLab