From ea4b73be6abff1462d96d3fa0a153ee1a94805db Mon Sep 17 00:00:00 2001 From: Ingo Deppner <deppner@physi.uni-heidelberg.de> Date: Thu, 30 Jan 2025 15:07:36 +0000 Subject: [PATCH] Provide TOF_v24a Macro, geometry, info, and ascii Module postion file. Updates the cfv setup file to include new geometry. --- .../fair/Create_TOF_Geometry_v24a_FullWall.C | 1042 +++++++++++++++++ macro/tof/fair/ModulePosition_10m_v24a.dat | 129 ++ setup/setup_sis100_cfv.C | 2 +- tof/tof_v24a.geo.info | 16 + tof/tof_v24a.geo.root | Bin 0 -> 20245 bytes 5 files changed, 1188 insertions(+), 1 deletion(-) create mode 100644 macro/tof/fair/Create_TOF_Geometry_v24a_FullWall.C create mode 100644 macro/tof/fair/ModulePosition_10m_v24a.dat create mode 100644 tof/tof_v24a.geo.info create mode 100644 tof/tof_v24a.geo.root diff --git a/macro/tof/fair/Create_TOF_Geometry_v24a_FullWall.C b/macro/tof/fair/Create_TOF_Geometry_v24a_FullWall.C new file mode 100644 index 00000000..24b6b82c --- /dev/null +++ b/macro/tof/fair/Create_TOF_Geometry_v24a_FullWall.C @@ -0,0 +1,1042 @@ +/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt, Germany + SPDX-License-Identifier: GPL-3.0-only + Authors: Ingo Deppner [commiter] */ +/// +/// \file Create_TOF_Geometry_v24a_FullWall.C +/// \brief Generates TOF geometry in Root format. +/// + +// Changelog +// 2024-11-14 - ID - make a CFV by removing outer modules. Not completely realistic. +// 2021-11-15 - ID - update design of inner wall (current design, 300 counters, 2 MRPC types) +// 2020-02-23 - ID - implementation of Bucharest wall (current design), possibility to choose between simple, single stack and double stack MRPCs +// 2017-10-18 - PAL- Fix the overlaps in the support structure => v17c +// 2016-07-18 - DE - patch double free or corruption with poleshort: same TGeoVolume name was used in pole +// 2015-11-09 - PAL- Change naming convention to follow the more meaningfull one used in trd: YYv_ss +// with YY = year, v = version (a, b, ...) and ss = setup (1h for SIS100 hadron, ...) +// => Prepare tof_v16a_1h to tof_v16a_3m +// 2015-11-09 - PAL- Modify to easily prepare tof_v14_0a to tof_v14_0e on model of 13_5a to 13_5e +// 2014-06-30 - NH - prepare tof_v14_0 geometry - SIS 300 hadron : TOF_Z_Front = 880 cm //Bucharest +// 2014-06-27 - NH - prepare tof_v13_6b geometry - SIS 300 hadron : TOF_Z_Front = 880 cm //external input +// 2013-10-16 - DE - prepare tof_v13_5a geometry - SIS 100 hadron : TOF_Z_Front = 450 cm +// 2013-10-16 - DE - prepare tof_v13_5b geometry - SIS 100 electron: TOF_Z_Front = 600 cm +// 2013-10-16 - DE - prepare tof_v13_5c geometry - SIS 100 muon : TOF_Z_Front = 650 cm +// 2013-10-16 - DE - prepare tof_v13_5d geometry - SIS 300 electron: TOF_Z_Front = 880 cm +// 2013-10-16 - DE - prepare tof_v13_5e geometry - SIS 300 muon : TOF_Z_Front = 1020 cm +// 2013-10-16 - DE - patch pole_alu bug - skip 0 thickness air volume in pole +// 2013-09-04 - DE - prepare tof_v13_4a geometry - SIS 100 hadron : TOF_Z_Front = 450 cm +// 2013-09-04 - DE - prepare tof_v13_4b geometry - SIS 100 electron: TOF_Z_Front = 600 cm +// 2013-09-04 - DE - prepare tof_v13_4c geometry - SIS 100 muon : TOF_Z_Front = 650 cm +// 2013-09-04 - DE - prepare tof_v13_4d geometry - SIS 300 electron: TOF_Z_Front = 880 cm +// 2013-09-04 - DE - prepare tof_v13_4e geometry - SIS 300 muon : TOF_Z_Front = 1020 cm +// 2013-09-04 - DE - dump z-positions to .geo.info file +// 2013-09-04 - DE - define front z-position of TOF wall (TOF_Z_Front) +// 2013-09-04 - DE - fix arrangement of glass plates in RPC cells + +// in root all sizes are given in cm +// read positions of modules from dat - file + +#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 "TROOT.h" +#include "TString.h" +#include "TSystem.h" + +#include <iostream> +#include <sstream> + +const Bool_t IncludeSupports = true; // false; // true, if support structure is included in geometry + +// Name of geometry version and output file +//const TString geoVersion = "tof_v24at_1h"; // SIS 100 hadron, 4.5 m +//const TString geoVersion = "tof_v24at_1e"; // SIS 100 electron, 6 m +//const TString geoVersion = "tof_v24at_1m"; // SIS 100 muon, 6.8 m +const TString geoVersion = "tof_v24a"; // SIS 300 electron, 8.8 m +//const TString geoVersion = "tof_v24at_3m"; // SIS 300 muon, 10 m +const TString FileNameSim = geoVersion + ".geo.root?reproducible"; +const TString FileNameGeo = geoVersion + "_geo.root?reproducible"; +const TString FileNameInfo = geoVersion + ".geo.info"; + +// TOF_Z_Front corresponds to front cover of outer super module towers +const Float_t TOF_Z_Front = ("tof_v24a_1h" == geoVersion ? 450 : // SIS 100 hadron + ("tof_v24a_1e" == geoVersion ? 600 : // SIS 100 electron + ("tof_v24a_1m" == geoVersion ? 680 : // SIS 100 muon + ("tof_v24a_3e" == geoVersion ? 880 : // SIS 300 electron + ("tof_v24a_3m" == geoVersion ? 1020 : // SIS 300 muon + 600 // Set default to SIS 100 electron + ))))); + +const TString GeometryType = "20b"; + +const TString KeepingVolumeMedium = "air"; +const TString BoxVolumeMedium = "aluminium"; +const TString PoleVolumeMedium = "tof_pole_aluminium"; +const TString NoActivGasMedium = "RPCgas_noact"; +const TString ActivGasMedium = "RPCgas"; +const TString GlasMedium = "RPCglass"; +const TString ElectronicsMedium = "carbon"; + +const Int_t NumberOfDifferentCounterTypes = 6; + +const Float_t PCB_X[NumberOfDifferentCounterTypes] = {32., 32., 32., 30., 30., 30.}; +const Float_t PCB_Y[NumberOfDifferentCounterTypes] = { + 52., 26.9, 26.9, 20., 10., 6, +}; +const Float_t PCB_Z[NumberOfDifferentCounterTypes] = {0.1, 0.1, 0.1, 0.1, 0.1, 0.1}; + +const Float_t Glass_X[NumberOfDifferentCounterTypes] = {32., 32., 32., 30., 30., 30.}; +const Float_t Glass_Y[NumberOfDifferentCounterTypes] = { + 52., 26.9, 26.9, 20., 10., 6, +}; +const Float_t Glass_Z[NumberOfDifferentCounterTypes] = {0.028, 0.028, 0.07, 0.07, 0.07, 0.07}; + +const Float_t GasGap_X[NumberOfDifferentCounterTypes] = {32., 32., 32., 30., 30., 30.}; +const Float_t GasGap_Y[NumberOfDifferentCounterTypes] = { + 52., 26.9, 26.9, 20., 10., 6, +}; +const Float_t GasGap_Z[NumberOfDifferentCounterTypes] = {0.023, 0.023, 0.025, 0.02, 0.02, 0.02}; + +const Int_t NumberOfGaps[NumberOfDifferentCounterTypes] = {10, 10, 8, 10, 10, 10}; +const Int_t NumberOfReadoutStrips[NumberOfDifferentCounterTypes] = {32, 32, 32, 32, 32, 32}; + +const Float_t Electronics_X[NumberOfDifferentCounterTypes] = {34.0, 34.0, 34.0, 32.0, 32.0, 32.0}; +const Float_t Electronics_Y[NumberOfDifferentCounterTypes] = {5.0, 5.0, 5.0, 0.5, 0.5, 0.5}; +const Float_t Electronics_Z[NumberOfDifferentCounterTypes] = {0.3, 0.3, 0.3, 0.3, 0.3, 0.3}; + +const Int_t NofModuleTypes = 15; +const Int_t MaxNofCounters = 60; +const Int_t MaxNofModules = 128; + +const Int_t NCounterInModule[NofModuleTypes] = {5, 5, 5, 5, 5, 30, 24, 27, 18, 24, 30, 24, 27, 18, 24}; +const Int_t NModulesOfModuleType[NofModuleTypes] = {62, 32, 8, 96, 16, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1}; +Int_t iMod[NofModuleTypes] = {0}; +//Int_t ActNofModuleTypes = 2; +//Int_t NModules[NofModuleTypes] = {0}; + +Float_t xPosCou[NofModuleTypes][MaxNofCounters]; +Float_t yPosCou[NofModuleTypes][MaxNofCounters]; +Float_t zPosCou[NofModuleTypes][MaxNofCounters]; +Int_t CouType[NofModuleTypes][MaxNofCounters]; + +Float_t xPosMod[MaxNofModules]; +Float_t yPosMod[MaxNofModules]; +Float_t zPosMod[MaxNofModules]; +Int_t ModType[MaxNofModules]; +//Float_t FlipMod[NofModuleTypes][MaxNofModules]; + +const Float_t Module_Size_X[NofModuleTypes] = {180.2, 180.2, 180.2, 180.2, 180.2, 210.5, 124.4, 98.3, + 69.3, 124.4, 210.5, 124.4, 98.3, 69.3, 124.4}; +const Float_t Module_Size_Y[NofModuleTypes] = {74., 49., 49., 49., 49., 73.8, 130.0, 128.7, + 128.7, 130.0, 73.8, 130.0, 128.7, 128.7, 130.0}; +const Float_t Module_Size_Z[NofModuleTypes] = {11.2, 11.2, 11.2, 11.2, 11.2, 19.6, 19.6, 19.6, + 19.6, 19.6, 19.6, 19.6, 19.6, 19.6, 19.6}; + +// Placement of the counter inside the module +const Float_t CounterRotationAngle[NofModuleTypes] = {10., 10., 0., 10., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}; + +const Float_t Module_Thick_Alu_X_left = 1.; +const Float_t Module_Thick_Alu_X_right = 0.1; +const Float_t Module_Thick_Alu_Y = 0.1; +const Float_t Module_Thick_Alu_Z_front = 0.1; +const Float_t Module_Thick_Alu_Z_back = 1.; + +const Float_t shift_gas_box_x = (Module_Thick_Alu_X_right - Module_Thick_Alu_X_left) / 2; +const Float_t shift_gas_box_z = (Module_Thick_Alu_Z_back - Module_Thick_Alu_Z_front) / 2; + +const Float_t Wall_Z_Position = + TOF_Z_Front + 1000. - 884.; // if you want to know where this numbers come from ask Ingo + +// Pole (support structure) +const Int_t MaxNumberOfPoles = 200; +Float_t Pole_ZPos[MaxNumberOfPoles]; +Float_t Pole_XPos[MaxNumberOfPoles]; +Float_t Pole_Col[MaxNumberOfPoles]; +Int_t NumberOfPoles = 0; + +const Float_t Pole_Size_X = 8.; +const Float_t Pole_Size_Y = 1000.; +const Float_t PoleShort_Size_Y = 370.; +const Float_t Pole_Size_Z = 2.; +const Float_t Pole_Thick_X = 0.4; +const Float_t Pole_Thick_Y = 0.4; +const Float_t Pole_Thick_Z = 0.4; +const Float_t XLimInner = 180.; + + +// Bars & frame (support structure) +const Float_t Frame_Size_X = 20.; +const Float_t Frame_Size_Y = 20.; +Float_t Bar_Size_Z = 176.; +const Float_t Frame_XLen = 1400; +const Float_t Frame_YLen = Pole_Size_Y + 2. * Frame_Size_Y; +Float_t Frame_Pos_Z = TOF_Z_Front + 88.; +const Float_t Bar_Size_X = 30; +const Float_t Bar_Size_Y = 20.; +Float_t Bar_Pos_Z; + +const Int_t MaxNumberOfBars = 200; +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.; + +// some global variables +TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance +TGeoVolume* gModules[NofModuleTypes]; // Global storage for module types +TGeoVolume* gCounter[NumberOfDifferentCounterTypes]; +TGeoVolume* gPole; +TGeoVolume* gPoleShort; +TGeoVolume* gBar[MaxNumberOfBars]; + +Float_t Last_Size_Y = 0.; +Float_t Last_Over_Y = 0.; + +// Forward declarations + +void create_materials_from_media_file(); +TGeoVolume* create_counter_simple(Int_t); +TGeoVolume* create_counter_doublestack(Int_t); +TGeoVolume* create_counter_singlestack(Int_t); +TGeoVolume* create_tof_module(Int_t); +TGeoVolume* create_tof_module_m(Int_t); +TGeoVolume* create_new_tof_module(Int_t); +TGeoVolume* create_new_tof_module_m(Int_t); +TGeoVolume* create_tof_pole(); +TGeoVolume* create_tof_poleshort(); +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_tof_modules(); +void position_tof_modules_m(Int_t, Int_t); +void dump_info_file(); +void read_module_positions(); +void read_counter_positions(); + +void Create_TOF_Geometry_v24a_FullWall() +{ + // Load the necessary FairRoot libraries + // gROOT->LoadMacro("$VMCWORKDIR/gconfig/basiclibs.C"); + // basiclibs(); + // gSystem->Load("libGeoBase"); + // gSystem->Load("libParBase"); + // gSystem->Load("libBase"); + + // Printout what we are generating + std::cout << "Generating geometry " << geoVersion << " at " << Wall_Z_Position << " cm from center of the magnet." << std::endl; + + // read input Data + read_counter_positions(); + read_module_positions(); + // 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(7); // 2 = super modules + gGeoMan->SetVisOption(1); + + // 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); + + TGeoVolume* tof = new TGeoVolumeAssembly(geoVersion); + top->AddNode(tof, 1); + + for (Int_t counterType = 0; counterType < NumberOfDifferentCounterTypes; counterType++) { + //gCounter[counterType] = create_counter_simple(counterType); + gCounter[counterType] = create_counter_doublestack(counterType); + //gCounter[counterType] = create_counter_singlestack(counterType); + } + + for (Int_t moduleType = 0; moduleType < NofModuleTypes; moduleType++) { + gModules[moduleType] = create_new_tof_module(moduleType); + gModules[moduleType]->SetVisContainers(1); + } + + gPole = create_tof_pole(); + gPoleShort = create_tof_poleshort(); + + position_tof_modules(); + + if (IncludeSupports) position_tof_poles(0); + if (IncludeSupports) position_tof_bars(0); + + gGeoMan->CloseGeometry(); + gGeoMan->CheckOverlaps(0.00001); + gGeoMan->CheckOverlaps(0.00001, "s"); + gGeoMan->PrintOverlaps(); + gGeoMan->GetListOfOverlaps()->Print(); + gGeoMan->Test(); + + tof->Export(FileNameSim); // an alternative way of writing the tof volume + + TFile* outfile = new TFile(FileNameSim, "UPDATE"); + TGeoTranslation* tof_placement = new TGeoTranslation("tof_trans", 0., 0., 0.); + tof_placement->Write(); + outfile->Close(); + + outfile = new TFile(FileNameGeo, "RECREATE"); + gGeoMan->Write(); + outfile->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(); + + // Printout what we are generating + std::cout << "Done generating geometry " << geoVersion << " at " << Wall_Z_Position << " cm from center of the magnet." << std::endl; +} + +void read_counter_positions() +{ + //TFile * fPosInput = new TFile( "TOF_10M.dat", "READ"); + for (Int_t modtype = 0; modtype < NofModuleTypes; modtype++) { + TString moduleTypeName = Form("ModuleType%d_v21a.dat", modtype); + cout << "load parameters from file " << moduleTypeName << endl; + ifstream inFile; + inFile.open(moduleTypeName); + if (!inFile.is_open()) { + cout << "<E> cannot open input file " << endl; + return; + } + + cout << "------------------------------" << endl; + cout << "Reading content of " << moduleTypeName << endl; + std::string strdummy; + std::getline(inFile, strdummy); + //cout<<strdummy<<endl; + Int_t iNum; + Int_t ictype; + Float_t iX; + Float_t iY; + Float_t iZ; + Int_t iCou = 0; + while (std::getline(inFile, strdummy)) { + // std::getline(inFile,strdummy); + //cout<<strdummy<<endl; + stringstream ss; + ss << strdummy; + ss >> iNum >> ictype >> iX >> iY >> iZ; + ss << strdummy; + //cout<<iCou<< " "<<iNum<<" "<<ictype<<" "<<iX<<" "<<iY<<" "<<iZ<<endl; + CouType[modtype][iCou] = ictype; + xPosCou[modtype][iCou] = iX; + yPosCou[modtype][iCou] = iY; + zPosCou[modtype][iCou] = iZ; + iCou++; + } + } +} + + +void read_module_positions() +{ + //TFile * fPosInput = new TFile( "TOF_10M.dat", "READ"); + ifstream inFile; + inFile.open("ModulePosition_10m_v24a.dat"); + if (!inFile.is_open()) { + cout << "<E> cannot open input file " << endl; + return; + } + + cout << "------------------------------" << endl; + cout << "Reading content of ModulePosition_10m_v24a.dat" << endl; + std::string strdummy; + std::getline(inFile, strdummy); + //cout<<strdummy<<endl; + Int_t iNum; + Int_t iModT; + Float_t iX; + Float_t iY; + Float_t iZ; + //Int_t iModType=0; + Int_t iMod = 0; + //while( !inFile.eof() ) + //for(Int_t iL=0; iL<2; iL++) + while (std::getline(inFile, strdummy)) { + // std::getline(inFile,strdummy); + //cout<<strdummy<<endl; + stringstream ss; + ss << strdummy; + ss >> iNum >> iModT >> iX >> iY >> iZ; + ss << strdummy; + // ss>>iNum>>iX>>iY>>iZ>>cType[0]>>cType[1]; + cout << iNum << " " << iModT << " " << iX << " " << iY << " " << iZ << endl; + + //cout<<" ModType "<<iModType<<endl; + //cout<<" ModType "<<iModType<<", # "<<iMod<<endl; + ModType[iMod] = iModT; + xPosMod[iMod] = iX; + yPosMod[iMod] = iY; + zPosMod[iMod] = iZ; + iMod++; + /* + if(cPos=='l'){ + FlipMod[iModType][iMod]=1.; + }else{ + FlipMod[iModType][iMod]=0.; + } + // if (iModType==1 && iMod==1) return; + + cout<<" ModType "<<iModType<<", Mod "<<iMod<<", x "<<xPosMod[iModType][iMod]<<", y " + <<yPosMod[iModType][iMod]<<", z "<<zPosMod[iModType][iMod]<<endl; + */ + } + cout << "Data reading finished for " << endl; +} + + +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* tof_pole_aluminium = geoMedia->getMedium("tof_pole_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(tof_pole_aluminium); + geoBuild->createMedium(RPCgas); + geoBuild->createMedium(RPCgas_noact); + geoBuild->createMedium(RPCglass); + geoBuild->createMedium(carbon); +} + + +TGeoVolume* create_counter_simple(Int_t countType) +{ + TGeoMedium* activeGasVolMed = gGeoMan->GetMedium(ActivGasMedium); + TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); + //TGeoMedium* glassPlateVolMed = gGeoMan->GetMedium(GlasMedium); + //gas gap + Int_t nstrips = NumberOfReadoutStrips[countType]; + + Float_t ggdx = GasGap_X[countType]; + Float_t ggdy = GasGap_Y[countType]; + //Float_t ggdz=GasGap_Z[countType]; + Float_t ggdz = 1.; + Float_t gsdx = ggdx / float(nstrips); + + + TGeoBBox* counter_box = new TGeoBBox("", (ggdx + 0.2) / 2., (ggdy + 0.2) / 2., (ggdz + 0.2) / 2.); + TGeoVolume* counter = new TGeoVolume("counter", counter_box, noActiveGasVolMed); + counter->SetLineColor(kCyan); // set line color for the counter + counter->SetTransparency(70); // set transparency for the TOF + // Single gas gap + 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(70); // set transparency for the TOF + TGeoTranslation* gas_gap_trans = new TGeoTranslation("", 0., 0., 0.); + + counter->AddNode(gas_gap_vol, 0, gas_gap_trans); + + return counter; +} + +TGeoVolume* create_counter_doublestack(Int_t countType) +{ + //glass + Float_t pdx = PCB_X[countType]; + Float_t pdy = PCB_Y[countType]; + Float_t pdz = PCB_Z[countType]; + + //glass + Float_t gdx = Glass_X[countType]; + Float_t gdy = Glass_Y[countType]; + Float_t gdz = Glass_Z[countType]; + + //gas gap + Int_t nstrips = NumberOfReadoutStrips[countType]; + Int_t ngaps = NumberOfGaps[countType]; + + + Float_t ggdx = GasGap_X[countType]; + Float_t ggdy = GasGap_Y[countType]; + Float_t ggdz = GasGap_Z[countType]; + 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[countType]; + Float_t dye = Electronics_Y[countType]; + Float_t dze = Electronics_Z[countType]; + 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 PCB + TGeoBBox* pcb = new TGeoBBox("", pdx / 2., pdy / 2., pdz / 2.); + TGeoVolume* pcb_vol = new TGeoVolume("tof_pcb", pcb, electronicsVolMed); + pcb_vol->SetLineColor(kGreen); // set line color for the pcb + pcb_vol->SetTransparency(20); // set transparency for the TOF + TGeoTranslation* pcb_trans0 = new TGeoTranslation("", 0., 0., 0.); + + // 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("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(70); // set transparency for the TOF + //TGeoTranslation* gas_gap_trans = new TGeoTranslation("", 0., 0., (gdz+ggdz)/2.); + + TGeoVolume* counter = new TGeoVolumeAssembly("counter"); + counter->AddNode(pcb_vol, 0, pcb_trans0); + Int_t l = 0; + for (l = 0; l < ngaps + 1; l++) { + if (l % 2 == 0) { + if (l == 0) { + TGeoTranslation* glass_plate_trans = new TGeoTranslation("", 0., 0., 0.5 * (pdz + gdz)); + counter->AddNode(glass_plate_vol, l, glass_plate_trans); + TGeoTranslation* glass_plate_trans1 = new TGeoTranslation("", 0., 0., -0.5 * (pdz + gdz)); + counter->AddNode(glass_plate_vol, l + ngaps + 1, glass_plate_trans1); + } + else { + TGeoTranslation* glass_plate_trans = + new TGeoTranslation("", 0., 0., 0.5 * (pdz + gdz) + l * (0.5 * (ggdz + gdz))); + counter->AddNode(glass_plate_vol, l, glass_plate_trans); + TGeoTranslation* glass_plate_trans1 = + new TGeoTranslation("", 0., 0., -0.5 * (pdz + gdz) - l * (0.5 * (ggdz + gdz))); + counter->AddNode(glass_plate_vol, l + ngaps + 1, glass_plate_trans1); + } + } + else { + TGeoTranslation* gas_gap_trans = new TGeoTranslation("", 0., 0., 0.5 * (pdz + gdz) + l * (0.5 * (ggdz + gdz))); + counter->AddNode(gas_gap_vol, l, gas_gap_trans); + TGeoTranslation* gas_gap_trans1 = new TGeoTranslation("", 0., 0., -0.5 * (pdz + gdz) - l * (0.5 * (ggdz + gdz))); + counter->AddNode(gas_gap_vol, l + ngaps + 1, gas_gap_trans1); + } + } + TGeoTranslation* pcb_trans1 = new TGeoTranslation("", 0., 0., (pdz + gdz) + (l - 1) * (0.5 * (ggdz + gdz))); + counter->AddNode(pcb_vol, l + ngaps + 1, pcb_trans1); + TGeoTranslation* pcb_trans2 = new TGeoTranslation("", 0., 0., -(pdz + gdz) - (l - 1) * (0.5 * (ggdz + gdz))); + counter->AddNode(pcb_vol, l + ngaps + 1, pcb_trans2); + + + TGeoBBox* epcb = new TGeoBBox("", dxe / 2., dye / 2., dze / 2.); + TGeoVolume* epcb_vol = new TGeoVolume("epcb", epcb, electronicsVolMed); + epcb_vol->SetLineColor(kCyan); // set line color for the electronic + epcb_vol->SetTransparency(10); // set transparency for the TOF + for (Int_t l = 0; l < 2; l++) { + yele *= -1.; + TGeoTranslation* epcb_trans = new TGeoTranslation("", 0., yele, 0.); + counter->AddNode(epcb_vol, l, epcb_trans); + } + + return counter; +} + +TGeoVolume* create_counter_singlestack(Int_t modType) +{ + + //glass + Float_t gdx = Glass_X[modType]; + Float_t gdy = Glass_Y[modType]; + Float_t gdz = Glass_Z[modType]; + + //gas gap + Int_t nstrips = NumberOfReadoutStrips[modType]; + Int_t ngaps = NumberOfGaps[modType]; + + + Float_t ggdx = GasGap_X[modType]; + Float_t ggdy = GasGap_Y[modType]; + Float_t ggdz = GasGap_Z[modType]; + Float_t gsdx = ggdx / (Float_t)(nstrips); + + // electronics + //pcb dimensions + Float_t dxe = Electronics_X[modType]; + Float_t dye = Electronics_Y[modType]; + Float_t dze = Electronics_Z[modType]; + Float_t yele = gdy / 2. + dye / 2.; + + // counter size (calculate from glas, gap and electronics sizes) + Float_t cdx = TMath::Max(gdx, ggdx); + cdx = TMath::Max(cdx, dxe) + 0.2; + Float_t cdy = TMath::Max(gdy, ggdy) + 2 * dye + 0.2; + Float_t cdz = ngaps * ggdz + (ngaps + 1) * gdz + 0.2; // ngaps * (gdz+ggdz) + gdz + 0.2; // ok + + //calculate thickness and first position in counter of single stack + Float_t dzpos = gdz + ggdz; + Float_t startzposglas = -ngaps * (gdz + ggdz) / 2.; // -cdz/2.+0.1+gdz/2.; // ok // (-cdz+gdz)/2.; // not ok + Float_t startzposgas = startzposglas + gdz / 2. + ggdz / 2.; // -cdz/2.+0.1+gdz +ggdz/2.; // ok + + + // needed materials + TGeoMedium* glassPlateVolMed = gGeoMan->GetMedium(GlasMedium); + TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); + TGeoMedium* activeGasVolMed = gGeoMan->GetMedium(ActivGasMedium); + TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsMedium); + + + // define counter volume + TGeoBBox* counter_box = new TGeoBBox("", cdx / 2., cdy / 2., cdz / 2.); + TGeoVolume* counter = new TGeoVolume("counter", counter_box, noActiveGasVolMed); + counter->SetLineColor(kCyan); // set line color for the counter + counter->SetTransparency(70); // set transparency for the TOF + + // define single glass plate volume + TGeoBBox* glass_plate = new TGeoBBox("", gdx / 2., gdy / 2., gdz / 2.); + TGeoVolume* glass_plate_vol = new TGeoVolume("tof_glass", glass_plate, glassPlateVolMed); + glass_plate_vol->SetLineColor(kMagenta); // set line color for the glass plate + glass_plate_vol->SetTransparency(20); // set transparency for the TOF + // define single gas gap volume + TGeoBBox* gas_gap = new TGeoBBox("", ggdx / 2., ggdy / 2., ggdz / 2.); + TGeoVolume* gas_gap_vol = new TGeoVolume("Gap", gas_gap, activeGasVolMed); + gas_gap_vol->Divide("Cell", 1, nstrips, -ggdx / 2., 0); + gas_gap_vol->SetLineColor(kRed); // set line color for the gas gap + gas_gap_vol->SetTransparency(99); // set transparency for the TOF + + // place 8 gas gaps and 9 glas plates in the counter + for (Int_t igap = 0; igap <= ngaps; igap++) { + // place (ngaps+1) glass plates + Float_t zpos_glas = startzposglas + igap * dzpos; + TGeoTranslation* glass_plate_trans = new TGeoTranslation("", 0., 0., zpos_glas); + counter->AddNode(glass_plate_vol, igap, glass_plate_trans); + // place ngaps gas gaps + if (igap < ngaps) { + Float_t zpos_gas = startzposgas + igap * dzpos; + TGeoTranslation* gas_gap_trans = new TGeoTranslation("", 0., 0., zpos_gas); + counter->AddNode(gas_gap_vol, igap, gas_gap_trans); + } + // cout <<"Zpos(Glas): "<< zpos_glas << endl; + // cout <<"Zpos(Gas): "<< zpos_gas << endl; + } + + // create and place the electronics above and below the glas stack + TGeoBBox* pcb = new TGeoBBox("", dxe / 2., dye / 2., dze / 2.); + TGeoVolume* pcb_vol = new TGeoVolume("pcb", pcb, electronicsVolMed); + pcb_vol->SetLineColor(kYellow); // kCyan); // set line color for electronics + pcb_vol->SetTransparency(10); // set transparency for the TOF + for (Int_t l = 0; l < 2; l++) { + yele *= -1.; + TGeoTranslation* pcb_trans = new TGeoTranslation("", 0., yele, 0.); + counter->AddNode(pcb_vol, l, pcb_trans); + } + + + return counter; +} + +TGeoVolume* create_new_tof_module(Int_t 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_aluzf = Module_Thick_Alu_Z_front; + Float_t width_aluzb = Module_Thick_Alu_Z_back; + 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 + + if (modType < 5) { + TGeoBBox* gas_box = new TGeoBBox("", (dx - (width_aluxl + width_aluxr)) / 2., (dy - 2 * width_aluy) / 2., + (dz - 2 * width_aluzf) / 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_x, 0., 0.); + module->AddNode(gas_box_vol, 0, gas_box_trans); + + for (Int_t j = 0; j < NCounterInModule[modType]; j++) { //loop over counters (modules) + cout << j << " " << modType << " xPos " << xPosCou[modType][j] << " yPos " << yPosCou[modType][j] << " zPos " + << zPosCou[modType][j] << endl; + TGeoTranslation* counter_trans = + new TGeoTranslation("", xPosCou[modType][j], yPosCou[modType][j], zPosCou[modType][j]); + TGeoRotation* counter_rot = new TGeoRotation(); + counter_rot->RotateY(rotangle); + TGeoCombiTrans* counter_combi_trans = new TGeoCombiTrans(*counter_trans, *counter_rot); + gas_box_vol->AddNode(gCounter[CouType[modType][j]], j, counter_combi_trans); + } + cout << "-------------------------------" << endl; + } + else { + TGeoBBox* gas_box = new TGeoBBox("", (dx - 2 * width_aluxr) / 2., (dy - 2 * width_aluy) / 2., + (dz + (width_aluzf - width_aluzb)) / 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("", 0., 0., -shift_gas_box_z); + module->AddNode(gas_box_vol, 0, gas_box_trans); + + for (Int_t j = 0; j < NCounterInModule[modType]; j++) { //loop over counters (modules) + cout << j << " " << modType << " xPos " << xPosCou[modType][j] << " yPos " << yPosCou[modType][j] << " zPos " + << zPosCou[modType][j] << endl; + TGeoTranslation* counter_trans = + new TGeoTranslation("", xPosCou[modType][j], yPosCou[modType][j], zPosCou[modType][j]); + TGeoRotation* counter_rot = new TGeoRotation(); + counter_rot->RotateY(rotangle); + TGeoCombiTrans* counter_combi_trans = new TGeoCombiTrans(*counter_trans, *counter_rot); + gas_box_vol->AddNode(gCounter[CouType[modType][j]], j, counter_combi_trans); + } + cout << "-------------------------------" << endl; + } + return module; +} + +TGeoVolume* create_tof_pole() +{ + // needed materials + TGeoMedium* boxVolMed = gGeoMan->GetMedium(PoleVolumeMedium); + 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_poleshort() +{ + // needed materials + TGeoMedium* boxVolMed = gGeoMan->GetMedium(PoleVolumeMedium); + TGeoMedium* airVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + + Float_t dx = Pole_Size_X; + Float_t dy = PoleShort_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("PoleShort"); + TGeoBBox* pole_alu_box = new TGeoBBox("", dx / 2., dy / 2., dz / 2.); + TGeoVolume* pole_alu_vol = new TGeoVolume("poleshort_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("poleshort_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(PoleVolumeMedium); + 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; + Int_t numPolesShort = 0; + for (Int_t i = 0; i < NumberOfPoles; i++) { + + Float_t xPos = Pole_XPos[i]; + Float_t zPos = Pole_ZPos[i]; + if (TMath::Abs(xPos) > XLimInner) { + pole_trans = new TGeoTranslation("", xPos, 0., zPos); + gGeoMan->GetVolume(geoVersion)->AddNode(gPole, numPoles, pole_trans); + numPoles++; + } + else { // position 2 short poles + + // upper short poles + pole_trans = new TGeoTranslation("", xPos, Pole_Size_Y / 2. - PoleShort_Size_Y / 2., zPos); + gGeoMan->GetVolume(geoVersion)->AddNode(gPoleShort, numPolesShort, pole_trans); + numPolesShort++; + + // lower short poles + pole_trans = new TGeoTranslation("", xPos, PoleShort_Size_Y / 2. - Pole_Size_Y / 2., zPos); + gGeoMan->GetVolume(geoVersion)->AddNode(gPoleShort, numPolesShort, pole_trans); + numPolesShort++; + } + // cout << " Position Pole "<< numPoles<<" at z="<< Pole_ZPos[i] <<", x "<<Pole_XPos[i]<< endl; + } +} + +void position_tof_bars(Int_t modType) +{ + + TGeoTranslation* bar_trans = NULL; + + Int_t numBars = 0; + Int_t i, j; + for (i = 0; i < NumberOfBars; i++) { + + Float_t xPos = Bar_XPos[i]; + Float_t zPos = Bar_ZPos[i]; + Float_t yPos = Pole_Size_Y / 2. + Bar_Size_Y / 2.; + + bar_trans = new TGeoTranslation("", xPos, yPos, zPos); + gGeoMan->GetVolume(geoVersion)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + bar_trans = new TGeoTranslation("", xPos, -yPos, zPos); + gGeoMan->GetVolume(geoVersion)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + bar_trans = new TGeoTranslation("", -xPos, yPos, zPos); + gGeoMan->GetVolume(geoVersion)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + bar_trans = new TGeoTranslation("", -xPos, -yPos, zPos); + gGeoMan->GetVolume(geoVersion)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + } + cout << " Position Bar " << numBars << " at z=" << Bar_ZPos[i] << endl; + + // outer horizontal and vertical frame bars + + NumberOfBars++; + i = NumberOfBars; + gBar[i] = create_tof_bar(Frame_XLen, Frame_Size_Y, Frame_Size_Y); // Outer frame big bar along X + j = i + 1; + gBar[j] = create_tof_bar(Frame_Size_X, Frame_YLen, Frame_Size_Y); // Outer frame big bar along Y + Float_t numBarY = 0; + numBars = 0; + + for (Float_t dZ = -1.; dZ < 2.; dZ += 2.) { + Float_t zPos = Frame_Pos_Z - dZ * (Bar_Size_Z / 2. - 10.); + Float_t yPos = Frame_YLen / 2. + Frame_Size_Y / 2; // Make outer frame independent of the inner poles!!!! + + // Outer Frame Top bar + bar_trans = new TGeoTranslation("", 0., yPos, zPos); + gGeoMan->GetVolume(geoVersion)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + // Outer Frame Bottom bar + bar_trans = new TGeoTranslation("", 0., -yPos, zPos); + gGeoMan->GetVolume(geoVersion)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + // Outer Frame Right bar + Float_t xPos = Frame_XLen / 2 - Frame_Size_Y / 2.; + bar_trans = new TGeoTranslation("", xPos, 0., zPos); + gGeoMan->GetVolume(geoVersion)->AddNode(gBar[j], numBarY, bar_trans); + numBarY++; + + // Outer Frame Left bar + bar_trans = new TGeoTranslation("", -xPos, 0., zPos); + gGeoMan->GetVolume(geoVersion)->AddNode(gBar[j], numBarY, bar_trans); + numBarY++; + } +} + +void position_tof_modules() +{ + TGeoTranslation* module_trans = NULL; + TGeoRotation* module_rot0 = new TGeoRotation(); + module_rot0->RotateZ(0.); + TGeoRotation* module_rot1 = new TGeoRotation(); + module_rot1->RotateZ(180.); + TGeoCombiTrans* module_combi_trans = NULL; + + // if(modType != 0) continue; // debugging + for (Int_t i = 0; i < MaxNofModules; i++) { + // for(Int_t i=0; i<5; i++) { + //if(i != 0) continue; // debugging + Float_t xPos = xPosMod[i]; + Float_t yPos = yPosMod[i]; + Float_t zPos = zPosMod[i] - 884.0 + TOF_Z_Front; + //cout<<"Place Mod Type "<<j<<" at x "<<xPos<<", y "<<yPos<<", z "<<zPos<<", Flip "<<FlipMod[j][i]<<endl; + + module_trans = new TGeoTranslation("", xPos, yPos, zPos); + if (ModType[i] < 5 && xPosMod[i] < 0.0) { module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot1); } + else { + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot0); + } + cout << i << " ModType " << ModType[i] << " iMod: " << iMod[ModType[i]] << endl; + gGeoMan->GetVolume(geoVersion)->AddNode(gModules[ModType[i]], iMod[ModType[i]], module_combi_trans); + iMod[ModType[i]]++; + } +} + +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 + 176.5; // back of TOF wall + + fprintf(ifile, "# envelope\n"); + // Show extension of TRD + fprintf(ifile, "%7.2f cm start of TOF (z)\n", Wall_Z_Position - 10.); + fprintf(ifile, "%7.2f cm end of TOF (z)\n", TOF_Z_Back + 10.); + 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/fair/ModulePosition_10m_v24a.dat b/macro/tof/fair/ModulePosition_10m_v24a.dat new file mode 100644 index 00000000..a40727f5 --- /dev/null +++ b/macro/tof/fair/ModulePosition_10m_v24a.dat @@ -0,0 +1,129 @@ +# ModType X Y Z +1 3 -408.2 75.0 944.7 +2 3 -423.2 51.0 957.7 +3 3 -408.2 25.0 944.7 +4 3 -423.2 0.0 957.7 +5 3 -408.2 -25.0 944.7 +6 3 -423.2 -51.0 957.7 +7 3 -408.2 -75.0 944.7 +8 3 -276.7 319.5 944.7 +9 3 -286.7 298.2 957.7 +10 3 -276.7 269.5 944.7 +11 3 -286.7 247.7 957.7 +12 3 -276.7 219.5 944.7 +13 3 -286.7 197.2 957.7 +14 3 -276.7 165.9 944.7 +15 3 -286.7 146.7 957.7 +16 3 -276.7 125.0 971.2 +17 3 -286.7 102.0 984.2 +18 3 -276.7 75.0 971.2 +19 3 -286.7 51.0 984.2 +20 3 -276.7 25.0 971.2 +21 3 -286.7 0.0 984.2 +22 3 -276.7 -25.0 971.2 +23 3 -286.7 -51.0 984.2 +24 3 -276.7 -75.0 971.2 +25 3 -286.7 -102.0 984.2 +26 3 -276.7 -125.0 971.2 +27 3 -286.7 -146.7 957.7 +28 3 -276.7 -165.9 944.7 +29 3 -286.7 -197.2 957.7 +30 3 -276.7 -219.5 944.7 +31 3 -286.7 -247.7 957.7 +32 3 -276.7 -269.5 944.7 +33 3 -286.7 -298.2 957.7 +34 3 -276.7 -319.5 944.7 +35 3 -141.7 325.0 971.2 +36 3 -146.7 303.8 984.2 +37 3 -141.7 275.0 971.2 +38 3 -146.7 253.3 984.2 +39 3 -141.7 225.0 971.2 +40 3 -146.7 202.8 984.2 +41 3 -141.7 175.0 971.2 +42 3 -146.7 152.3 984.2 +43 3 -146.7 -152.3 984.2 +44 3 -141.7 -175.0 971.2 +45 3 -146.7 -202.8 984.2 +46 3 -141.7 -225.0 971.2 +47 3 -146.7 -253.3 984.2 +48 3 -141.7 -275.0 971.2 +49 3 -146.7 -303.8 984.2 +50 3 -141.7 -325.0 971.2 +51 4 0 325.5 1000.0 +52 4 0 304.1 1013.0 +53 4 0 275.5 1000.0 +54 4 0 253.5 1013.0 +55 4 0 225.5 1000.0 +56 4 0 202.9 1013.0 +57 4 0 175.5 1000.0 +58 4 0 152.3 1013.0 +59 4 0 -152.3 1013.0 +60 4 0 -175.5 1000.0 +61 4 0 -202.9 1013.0 +62 4 0 -225.5 1000.0 +63 4 0 -253.5 1013.0 +64 4 0 -275.5 1000.0 +65 4 0 -304.1 1013.0 +66 4 0 -325.5 1000.0 +67 3 141.7 325.0 971.2 +68 3 146.7 303.8 984.2 +69 3 141.7 275.0 971.2 +70 3 146.7 253.3 984.2 +71 3 141.7 225.0 971.2 +72 3 146.7 202.8 984.2 +73 3 141.7 175.0 971.2 +74 3 146.7 152.3 984.2 +75 3 146.7 -152.3 984.2 +76 3 141.7 -175.0 971.2 +77 3 146.7 -202.8 984.2 +78 3 141.7 -225.0 971.2 +79 3 146.7 -253.3 984.2 +80 3 141.7 -275.0 971.2 +81 3 146.7 -303.8 984.2 +82 3 141.7 -325.0 971.2 +83 3 276.7 319.5 944.7 +84 3 286.7 298.2 957.7 +85 3 276.7 269.5 944.7 +86 3 286.7 247.7 957.7 +87 3 276.7 219.5 944.7 +88 3 286.7 197.2 957.7 +89 3 276.7 165.9 944.7 +90 3 286.7 146.7 957.7 +91 3 276.7 125.0 971.2 +92 3 286.7 102.0 984.2 +93 3 276.7 75.0 971.2 +94 3 286.7 51.0 984.2 +95 3 276.7 25.0 971.2 +96 3 286.7 0.0 984.2 +97 3 276.7 -25.0 971.2 +98 3 286.7 -51.0 984.2 +99 3 276.7 -75.0 971.2 +100 3 286.7 -102.0 984.2 +101 3 276.7 -125.0 971.2 +102 3 286.7 -146.7 957.7 +103 3 276.7 -165.9 944.7 +104 3 286.7 -197.2 957.7 +105 3 276.7 -219.5 944.7 +106 3 286.7 -247.7 957.7 +107 3 276.7 -269.5 944.7 +108 3 286.7 -298.2 957.7 +109 3 276.7 -319.5 944.7 +110 3 408.2 75.0 944.7 +111 3 423.2 51.0 957.7 +112 3 408.2 25.0 944.7 +113 3 423.2 0.0 957.7 +114 3 408.2 -25.0 944.7 +115 3 423.2 -51.0 957.7 +116 3 408.2 -75.0 944.7 +117 5 -109.05 0.0 1011 +118 6 -172.15 89.6 1050.4 +119 7 -71.7 89.4 1030.7 +120 8 0.0 89.4 1050.4 +121 7 71.7 89.4 1030.7 +122 9 172.15 89.6 1050.4 +123 10 149.05 0.0 1011 +124 11 172.15 -89.6 1050.4 +125 12 71.7 -89.6 1030.7 +126 13 0.0 -89.4 1050.4 +127 12 -71.15 -87.85 1030.7 +128 14 -172.15 -89.6 1050.4 diff --git a/setup/setup_sis100_cfv.C b/setup/setup_sis100_cfv.C index bb0b4be5..d58af2db 100644 --- a/setup/setup_sis100_cfv.C +++ b/setup/setup_sis100_cfv.C @@ -19,7 +19,7 @@ void setup_sis100_cfv() TString stsGeoTag = "v22d"; TString richGeoTag = "v23a"; TString trdGeoTag = "v23a_1e"; // CFV TRD 1D (reduced acceptance) - TString tofGeoTag = "v21a_1e"; + TString tofGeoTag = "v24a"; TString fsdGeoTag = "v25i"; TString psdGeoTag = "v23a"; TString platGeoTag = "v22b"; diff --git a/tof/tof_v24a.geo.info b/tof/tof_v24a.geo.info new file mode 100644 index 00000000..eb0259ba --- /dev/null +++ b/tof/tof_v24a.geo.info @@ -0,0 +1,16 @@ +# +## tof_v24a information file +# + +# created 20241216 + +# TOF setup +SIS 100 electron + +# envelope + 706.00 cm start of TOF (z) + 902.50 cm end of TOF (z) + +# central tower position + 716.00 cm center of staggered, front RPC cell at x=0 + diff --git a/tof/tof_v24a.geo.root b/tof/tof_v24a.geo.root new file mode 100644 index 0000000000000000000000000000000000000000..bc4080675322d9c83689ab9eefdee1eb51e3cbac GIT binary patch literal 20245 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 literal 0 HcmV?d00001 -- GitLab