From 4d9bfb87b3b8bf0adc298fa424976f8fbe9827db Mon Sep 17 00:00:00 2001 From: Axel Puntke <axel.puntke@uni-muenster.de> Date: Fri, 12 Apr 2024 12:59:02 +0000 Subject: [PATCH] Add TRD v24c_mcbm geometry (module rotation correction) --- macro/trd/mcbm/Create_TRD_Geometry_v24c.C | 4737 +++++++++++++++++++++ setup/setup_mcbm_beam_2024_03_22_gold.C | 3 +- trd/trd_v24c_mcbm.geo.info | 85 + trd/trd_v24c_mcbm.geo.root | Bin 0 -> 17393 bytes 4 files changed, 4824 insertions(+), 1 deletion(-) create mode 100644 macro/trd/mcbm/Create_TRD_Geometry_v24c.C create mode 100644 trd/trd_v24c_mcbm.geo.info create mode 100644 trd/trd_v24c_mcbm.geo.root diff --git a/macro/trd/mcbm/Create_TRD_Geometry_v24c.C b/macro/trd/mcbm/Create_TRD_Geometry_v24c.C new file mode 100644 index 0000000..4e22a09 --- /dev/null +++ b/macro/trd/mcbm/Create_TRD_Geometry_v24c.C @@ -0,0 +1,4737 @@ +/* Copyright (C) 2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: David Emschermann [committer], Alexandru Bercuci */ + +// clang-format off + +/// +/// \file Create_TRD_Geometry_v24c.C +/// \brief Generates TRD geometry in Root format. +/// + +// 2024-04-08 - AP - v24c - based on v24b - rotated teh y-sensitive TRD1D module by 180° +// 2024-03-26 - DE - v24b - based on v24a - adapted to positions measured in the cave +// 2024-02-08 - AP - v24a - based on v22h - change TRD1D modules to type 5 +// 2022-05-05 - AB - v22h - based on v22e - update for the actual FEE setup installed on the TRD2D (18 FEBs) +// 2022-03-10 - DE - v22e - based on v21a - correct gibbet material and z-positions +// 2021-10-28 - SR - v22b - based on v22a the TRD-2D is removed +// 2021-10-07 - SR - v22a - based on v20b the TRD-2D is inserted +// 2021-09-28 - SR - v21b - based on v21a the position is corrected +// 2021-07-25 - AB - v21a - based on v20b, add 2 TRD2D modules and their support structure for the 2021 setup +// 2020-05-25 - DE - v20b - based on v20a, use 2 TRD modules for 2021 setup +// 2020-05-23 - DE - v20a - add support structure to TRD v18q, realign module in x +// 2018-08-24 - DE - v18q - use only 1st 2 layers of TRD in 2018 setup +// 2017-11-22 - DE - v18n - do not generate mBUCH at z=125 cm, only mTRD +// 2017-11-22 - DE - v18m - mBUCH at z=125 cm, mTRD at z=149, 171, 193 and 215 cm - layer pitch 22 cm from CAD +// 2017-11-03 - DE - v18l - shift mTRD to z=140 cm for acceptance matching with mSTS (= same result as v18g) +// 2017-11-03 - DE - v18k - plot 4 mTRD modules first, then mBUCH to simplyfy the realignment in x (= same result as v18j) +// 2017-11-02 - DE - v18j - move Muenster TRD modules back to original positions in x (fix bug in v18i) +// 2017-10-17 - DE - v18i - add Bucharest 60x60 cm2 Bucharest TRD module with FASP ASICs +// 2017-05-16 - DE - v18e - re-align all TRD modules to same theta angle using left side of 4th TRD module as reference +// 2017-05-02 - DE - v18a - re-base miniTRD v18e on CBM TRD v17a +// 2017-04-28 - DE - v17 - implement power bus bars as defined in the TDR +// 2017-04-26 - DE - v17 - add aluminium ledge around backpanel +// 2017-01-10 - DE - v17a_3e - replace 6 ultimate density by 9 super density FEBs for TRD type 1 modules +// 2016-07-05 - FU - v16a_3e - identical to v15a, change the way the trd volume is exported to resolve a bug with TGeoShape destructor +// 2015-01-08 - DE - v15a_3e - reduce frame thickness in large modules to 15 mm instead of 20 mm +// 2014-06-25 - DE - v14a_3e - consists of only 3 small and 3 large modules types (was 4+4 before) +// 2014-06-25 - DE - v14a_3e - inner part of all 3 stations is now identical +// 2014-05-02 - DE - v14a_3e - redesign inner part of station 3, now with 5x5-1 small modules, like in station 1 and station 2 +// 2014-05-02 - DE - v14a_3e - include optional GBTX readout boards on each module +// 2014-05-02 - DE - v14a_3e - introduce 3x5=15 Spadic FEBs for ultimate density on module type 1 +// 2013-11-14 - DE - v13q_3e - generate information about pad plane layout (CbmTrdPads_v14a.h) for all module types in this macro +// 2013-11-04 - DE - v13p4 - adapt the number of front-end boards to the pad layout of the 540 mm modules +// 2013-11-04 - DE - v13p4 - use 8 module types (4x S + 4x L) to better match the occupancy +// 2013-10-31 - DE - v13p4 - modify the support structure of station 1 to match with the MUCH/RICH platform +// 2013-10-29 - DE - v13p4 - build lattice grid as TGeoBBox instead of VolumeAssembly - in run_sim.C save 9% of time compared to v13p7 +// 2013-10-29 - DE - v13p4 - build lattice grid as TGeoBBox instead of CompositeShape - in run_sim.C save 18% of time compared to v13p6 +// 2013-10-28 - DE - introduce new geometry naming scheme: v13p1 - SIS 100 hadron +// 2013-10-28 - DE - introduce new geometry naming scheme: v13p2 - SIS 100 electron +// 2013-10-28 - DE - introduce new geometry naming scheme: v13p3 - SIS 100 muon +// 2013-10-28 - DE - introduce new geometry naming scheme: v13p4 - SIS 300 electron +// 2013-10-28 - DE - introduce new geometry naming scheme: v13p5 - SIS 300 muon +// 2013-10-28 - DE - add option to draw the magnetic field vector in the magnet +// 2013-09-27 - DE - do not use TGeoXtru to build the supports, use TGeoBBox instead +// 2013-06-25 - DE - v13g trd300_rich (10 layers, z = 4100 ) - TRD right behind SIS300 RICH +// 2013-06-25 - DE - v13h trd100_sts ( 4 layers, z = 2600 ) - TRD completely on RICH/MUCH platform to allow TOF to move upstream +// 2013-06-25 - DE - v13i trd100_rich ( 2 layers, z = 4100 ) - TRD right behind RICH +// 2013-06-25 - DE - v13j trd100_rich ( 3 layers, z = 4100 ) - TRD right behind RICH +// 2013-06-25 - DE - v13k trd100_rich ( 4 layers, z = 4100 ) - TRD right behind RICH +// 2013-06-25 - DE - --- trd100_much_2_absorbers ( 4 layers, z = 4300 ) - same as version at z = 4600 +// 2013-06-25 - DE - v13l trd100_much_3_absorbers ( 4 layers, z = 4600 ) - TRD right behind SIS100 MUCH +// 2013-06-25 - DE - v13m trd300_much_6_absorbers (10 layers, z = 5500 ) - TRD right behind SIS300 MUCH +// 2013-06-25 - DE - v13n trd300_rich_stretched (10 layers, z = 4600 ) - TRD stretched behind SIS300 RICH +// 2013-06-19 - DE - add TRD (I, II, III) labels on support structure +// 2013-05-29 - DE - allow for flexible TRD z-positions defined by position of layer01 +// 2013-05-23 - DE - remove "trd_" prefix from node names (except top node) +// 2013-05-22 - DE - radiators G30 (z=240 mm) +// 2013-05-22 - DE - radiators H (z=275 mm - 125 * 2.2mm), (H++ z=335 mm) +// 2013-05-22 - DE - radiators B++ (z=254 mm - 350 * 0.724 mm), K++ (z=254 mm - 350 * 0.724 mm) +// 2013-04-17 - DE - introduce volume assembly for layers, e.g. trd_layer03 +// 2013-03-26 - DE - use Air as ASIC material +// 2013-03-26 - DE - put support structure into its own assembly +// 2013-03-26 - DE - move TRD upstream to z=400m +// 2013-03-26 - DE - RICH will probably end at z=380 cm, TRD can move to 400 cm +// 2013-03-25 - DE - shrink active area from 570 to 540 mm and 960 to 910 mm +// 2013-03-06 - DE - add ASICs on FEBs +// 2013-03-05 - DE - introduce supports for SIS100 and SIS300 +// 2013-03-05 - DE - replace all Float_t by Double_t +// 2013-01-21 - DE - introduce TRD media, use TRDG10 as material for pad plane and FEBs +// 2013-01-21 - DE - put backpanel into the geometry +// 2013-01-11 - DE - allow for misalignment of TRD modules +// 2012-11-04 - DE - add kapton foil, add FR4 padplane +// 2012-11-03 - DE - add lattice grid on entrance window as CompositeShape + +// TODO: +// - use Silicon as ASIC material + +// in root all sizes are given in cm + +#include "TDatime.h" +#include "TFile.h" +#include "TGeoArb8.h" +#include "TGeoCompositeShape.h" +#include "TGeoCone.h" +#include "TGeoManager.h" +#include "TGeoMaterial.h" +#include "TGeoMatrix.h" +#include "TGeoMedium.h" +#include "TGeoPgon.h" +#include "TGeoTube.h" +#include "TGeoVolume.h" +#include "TGeoXtru.h" +#include "TList.h" +#include "TRandom3.h" +#include "TString.h" +#include "TSystem.h" + +#include <iostream> + +// Name of output file with geometry +const TString tagVersion = "v24c_mcbm"; +// const TString subVersion = "_1h"; +// const TString subVersion = "_1e"; +// const TString subVersion = "_1m"; +// const TString subVersion = "_3e"; +// const TString subVersion = "_3m"; + +const Int_t setupid = 1; // 1e is the default +// const Double_t zfront[5] = {260., 410., 360., 410., 550.}; +const Double_t zfront[5] = {260., 149.0-40.2, 360., 410., 550.}; // move 1st TRD-1D z=99 cm // mCBM 2022_02 +const TString setupVer[5] = {"_1h", "_1e", "_1m", "_3e", "_3m"}; +const TString subVersion = setupVer[setupid]; + +const TString geoVersion = "trd_" + tagVersion; // + subVersion; +const TString FileNameSim = geoVersion + ".geo.root"; +const TString FileNameGeo = geoVersion + "_geo.root"; +const TString FileNameInfo = geoVersion + ".geo.info"; +const TString FileNamePads = "CbmTrdPads_" + tagVersion + ".h"; + +// display switches +const Bool_t IncludeRadiator = false; // false; // true, if radiator is included in geometry +const Bool_t IncludeLattice = true; // false; // true, if lattice grid is included in geometry + +const Bool_t IncludeKaptonFoil = true; // false; // true, if entrance window is included in geometry +const Bool_t IncludeGasFrame = true; // false; // true, if frame around gas volume is included in geometry +const Bool_t IncludePadplane = true; // false; // true, if padplane is included in geometry +const Bool_t IncludeBackpanel = true; // false; // true, if backpanel is included in geometry +const Bool_t IncludeAluLedge = true; // false; // true, if Al-ledge around the + // backpanel is included in geometry +const Bool_t IncludeGibbet = true; // false; // true, if mTRD gibbet support to be drawn +const Bool_t IncludePowerbars = false; // false; // true, if LV copper bus bars to be drawn + +const Bool_t IncludeFebs = true; // false; // true, if FEBs are included in geometry +const Bool_t IncludeRobs1D = false; // true, if ROBs are included in geometry +const Bool_t IncludeRobs2D = true; // true, if ROBs are included in geometry +const Bool_t IncludeAsics = true; // true, if ASICs are included in geometry +const Bool_t IncludeSupports = false; // false; // true, if support structure is included in geometry +const Bool_t IncludeLabels = false; // false; // true, if TRD (I, II, III) + // labels are plotted in (VisLevel 5) +const Bool_t IncludeFieldVector = false; // true, if magnetic field vector to be shown (in the magnet) + +// positioning switches +const Bool_t DisplaceRandom = false; // true; // false; // add random + // displacement of modules for alignment + // study +const Bool_t RotateRandom = false; // true; // false; // add random rotation of + // modules for alignment study +const Bool_t DoExplode = false; // true, // false; // add random displacement + // of modules for alignment study + +// positioning parameters +const Double_t maxdx = 0.2; // max +- 0.1 cm shift in x +const Double_t maxdy = 0.2; // max +- 0.1 cm shift in y +const Double_t maxdz = 1.0; // max +- 1.0 cm shift in z + +const Double_t maxdrotx = 2.0; // 20.0; // max rotation around x +const Double_t maxdroty = 2.0; // 20.0; // max rotation around y +const Double_t maxdrotz = 2.0; // 20.0; // max rotation around z + +const Double_t ExplodeFactor = 1.02; // 1.02; // Factor by which modules are exploded in the x/y plane + +// initialise random numbers +TRandom3 r3(0); + +// Parameters defining the layout of the complete detector build out of +// different detector layers. +const Int_t MaxLayers = 10; // max layers + +// select layers to display +// +// const Int_t ShowLayer[MaxLayers] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // +// 1st layer only +// const Int_t ShowLayer[MaxLayers] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // +// 2nd layer only +// const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }; // +// 5th layer only +// const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }; // +// 6th layer only +// const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }; // +// 9th layer only +// const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; // +// 10th layer only +// +// const Int_t ShowLayer[MaxLayers] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // +// Station 1, layer 1, 2 +// const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 }; // +// Station 2, layer 5, 6 +// const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; // +// Station 3, layer 9,10 +// const Int_t ShowLayer[MaxLayers] = { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0 }; // +// Station 1 and 2 +// const Int_t ShowLayer[MaxLayers] = { 1, 1, 0, 0, 1, 1, 1, 0, 1, 1 }; // +// Station 1, 2 and 3 +// +// const Int_t ShowLayer[MaxLayers] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // +// SIS100-2l // 1: plot, 0: hide +// const Int_t ShowLayer[MaxLayers] = { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; // +// SIS100-3l // 1: plot, 0: hide +// +// const Int_t ShowLayer[MaxLayers] = { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 }; // +// SIS100-4l // 1: plot, 0: hide +// const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 }; // +// SIS300-mu // 1: plot, 0: hide +// const Int_t ShowLayer[MaxLayers] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; // +// SIS300-e // 1: plot, 0: hide +Int_t ShowLayer[MaxLayers] = {1, 1, 1, 0, 0, 0, 0, 0, 0, 0}; // SIS100-4l is default + +Int_t BusBarOrientation[MaxLayers] = {0, 1, 1, 0, 1, 0, 0, 0, 0, 0}; // 1 = vertical + +Int_t PlaneId[MaxLayers]; // automatically filled with layer ID + +const Int_t LayerType[MaxLayers] = {20, 10, 11, 20, 20, 21, 20, 21, 30, 31}; // ab: a [1-4] - layer + // type, b [0,1] - + // vertical/horizontal pads +// ### Layer Type 20 is mCBM Layer Type 2 with Buch prototype module (type 4) +// with vertical pads +// ### Layer Type 11 is Layer Type 1 with detector modules rotated by 90?? +// ### Layer Type 21 is Layer Type 2 with detector modules rotated by 90?? +// ### Layer Type 31 is Layer Type 3 with detector modules rotated by 90?? +// In the subroutine creating the layers this is recognized automatically + +const Int_t LayerNrInStation[MaxLayers] = {1, 2, 3, 4, 1, 2, 3, 4, 1, 2}; + +Double_t LayerPosition[MaxLayers] = {0.}; // start position = 0 - 2016-07-12 - DE + +// 5x z-positions from 260 till 550 cm +// Double_t LayerPosition[MaxLayers] = { 260. }; // start position - 2013-10-28 +// - DE - v14_1h - SIS 100 hadron ( 4 layers, z = 2600 ) +// Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-10-28 +// - DE - v14_1e - SIS 100 electron ( 4 layers, z = 4100 ) +// Double_t LayerPosition[MaxLayers] = { 360. }; // start position - 2014-06-16 +// - DE - v14_1m - SIS 100 muon ( 4 layers, z = 3600 ) was 460. +// Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-10-28 +// - DE - v14_3e - SIS 300 electron (10 layers, z = 4100 ) +// Double_t LayerPosition[MaxLayers] = { 550. }; // start position - 2013-10-28 +// - DE - v14_3m - SIS 300 muon 6_abs (10 layers, z = 5500 ) +// +// obsolete variants +// Double_t LayerPosition[MaxLayers] = { 460. }; // start position - 2013-10-28 +// - DE - v13x3 - SIS 100 muon ( 4 layers, z = 4600 ) +// Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-06-25 +// - DE - v13i trd100_rich ( 2 layers, z = 4100 ) +// Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-06-25 +// - DE - v13j trd100_rich ( 3 layers, z = 4100 ) +// Double_t LayerPosition[MaxLayers] = { 430. }; // start position - 2013-06-25 +// - DE - --- trd100_much_2_absorbers ( 4 layers, z = 4300 ) +// Double_t LayerPosition[MaxLayers] = { 460. }; // start position - 2013-06-25 +// - DE - v13n trd300_rich_stretched (10 layers, z = 4600 ) + +// const Double_t LayerThickness = 22.0; // miniCBM - Thickness of one TRD +// layer in cm +const Double_t LayerThickness = 40.2; // miniCBM - Thickness of one TRD layer in cm in 2024 +// const Double_t LayerThickness = 25.0; // miniCBM - Thickness of one TRD layer +// in cm +// const Double_t LayerThickness = 45.0; // Thickness of one TRD layer in cm + +const Double_t LayerOffset[MaxLayers] = {0., 0., 0., 0., -112., + 0., 0., 0., 5., 0.}; // v13x[4,5] - z offset in addition to LayerThickness +// const Double_t LayerOffset[MaxLayers] = { 0., 0., 0., 0., -115., +// 0., 0., 0., 5., 0. }; // v13x[4,5] - z offset in addition to +// LayerThickness +// 140 / 165 / 190 / 215 / 240 - 115 = 125 +// const Double_t LayerOffset[MaxLayers] = { 0., 0., 0., 0., -115., +// 0., 0., 0., 5., 0. }; // v13x[4,5] - z offset in addition to +// LayerThickness +// 115 / 140 / 165 / 190 / 215 - 125 = 100 + +// const Double_t LayerOffset[MaxLayers] = { 0., -10., 0., 0., 0., +// 0., 0., 0., 5., 0. }; // v13x[4,5] - z offset in addition to +// LayerThickness +// 100 / 125 - 10 = 115 / 140 / 165 / 190 + +// const Double_t LayerOffset[MaxLayers] = { 0., 0., 0., 0., 0., 0., +// 0., 0., 0., 0. }; // SIS100 - z offset in addition to LayerThickness +// const Double_t LayerOffset[MaxLayers] = { 0., 0., 0., 0., 95., 0., +// 0., 0., 5., 0. }; // v13n - z offset in addition to +// LayerThickness + +const Int_t LayerArraySize[3][4] = {{5, 5, 9, 11}, // for layer[1-3][i,o] below + {5, 5, 9, 11}, + {5, 5, 9, 11}}; + +// ### Layer Type 1 +// v14x - module types in the inner sector of layer type 1 - looking upstream +const Int_t layer1i[5][5] = {{0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + // { 0, 0, 101, 0, 0 }, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}}; + +// const Int_t layer1i[5][5] = { { 323, 323, 321, 321, 321 }, // abc: a +// module type - b orientation (x90 deg) in odd - c even layers +// { 223, 123, 121, 121, 221 }, +// { 203, 103, 0, 101, 201 }, +// { 203, 103, 101, 101, 201 }, +// { 303, 303, 301, 301, 301 } }; +// number of modules: 24 + +// v14x - module types in the outer sector of layer type 1 - looking upstream +const Int_t layer1o[9][11] = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 501, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; +//// v14x - module types in the outer sector of layer type 1 - looking upstream +// const Int_t layer1o[9][11]= { { 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0 }, +// { 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0 }, +// { 0, 0, 823, 823, 723, 721, 721, 821, +// 821, 0, 0 }, +// { 0, 0, 823, 623, 0, 0, 0, 621, +// 821, 0, 0 }, +// { 0, 0, 703, 603, 0, 0, 0, 601, +// 701, 0, 0 }, +// { 0, 0, 803, 603, 0, 0, 0, 601, +// 801, 0, 0 }, +// { 0, 0, 803, 803, 703, 701, 701, 801, +// 801, 0, 0 }, +// { 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0 }, +// { 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0 } }; +// number of modules: 26 +// Layer1 = 24 + 26; // v14a + +// ### Layer Type 2 -> remapped for Buch prototype +// v14x - module types in the inner sector of layer type 2 - looking upstream +// const Int_t layer2i[5][5] = { { 323, 323, 321, 321, 321 }, // abc: a +// module type - b orientation (x90 deg) in odd - c even layers +// { 223, 123, 121, 121, 221 }, +// { 203, 103, 0, 101, 201 }, +// { 203, 103, 101, 101, 201 }, +// { 303, 303, 301, 301, 301 } }; +const Int_t layer2i[5][5] = {{0}, // abc: a module type - b orientation (x90 deg) in odd - c even layers + {0}, + {0, 0, 900, 0, 0}, + {0}, + {0}}; + +// number of modules: 24 + +// v14x - module types in the outer sector of layer type 2 - looking upstream +// const Int_t layer2o[9][11]= { { 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0 }, +// { 0, 823, 823, 823, 823, 821, 821, +// 821, 821, 821, 0 }, +// { 0, 823, 823, 823, 723, 721, 721, +// 821, 821, 821, 0 }, +// { 0, 823, 723, 623, 0, 0, 0, +// 621, 721, 821, 0 }, +// { 0, 803, 703, 603, 0, 0, 0, +// 601, 701, 801, 0 }, +// { 0, 803, 703, 603, 0, 0, 0, +// 601, 701, 801, 0 }, +// { 0, 803, 803, 803, 703, 701, 701, +// 801, 801, 801, 0 }, +// { 0, 803, 803, 803, 803, 801, 801, +// 801, 801, 801, 0 }, +// { 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0 } }; +const Int_t layer2o[9][11] = {{0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}; +// number of modules: 54 +// Layer2 = 24 + 54; // v14a + +// ### Layer Type 3 +// v14x - module types in the inner sector of layer type 3 - looking upstream +const Int_t layer3i[5][5] = {{323, 323, 321, 321, 321}, // abc: a module type - b orientation (x90 deg) + // in odd - c even layers + {223, 123, 121, 121, 221}, + {203, 103, 0, 101, 201}, + {203, 103, 101, 101, 201}, + {303, 303, 301, 301, 301}}; +// number of modules: 24 + +// v14x - module types in the outer sector of layer type 3 - looking upstream +const Int_t layer3o[9][11] = { + {823, 823, 823, 823, 823, 821, 821, 821, 821, 821, 821}, {823, 823, 823, 823, 823, 821, 821, 821, 821, 821, 821}, + {823, 823, 823, 723, 623, 621, 621, 721, 821, 821, 821}, {823, 823, 723, 623, 0, 0, 0, 621, 721, 821, 821}, + {803, 803, 703, 603, 0, 0, 0, 601, 701, 801, 801}, {803, 803, 703, 603, 0, 0, 0, 601, 701, 801, 801}, + {803, 803, 803, 703, 603, 601, 601, 701, 801, 801, 801}, {803, 803, 803, 803, 803, 801, 801, 801, 801, 801, 801}, + {803, 803, 803, 803, 803, 801, 801, 801, 801, 801, 801}}; +// number of modules: 90 +// Layer2 = 24 + 90; // v14a + +// Parameters defining the layout of the different detector modules +const Int_t NofModuleTypes = 10; +const Int_t ModuleType[NofModuleTypes] = {0, 0, 0, 2, 1, 1, 1, 1, 2, 3}; // 0 = small module, 1 = + // large module, 2 = mCBM + // Bucharest prototype, 3 + // = mCBM Bucharest + // TRD-2Dh prototype + +// FEB inclination angle +const Double_t feb_rotation_angle[NofModuleTypes] = { + 70, 90, 90, 0, 80, 90, 90, 90, 0, 0}; // rotation around x-axis, 0 = vertical, 90 = horizontal +// const Double_t feb_rotation_angle[NofModuleTypes] = { 45, 45, 45, 45, 45, +// 45, 45, 45 }; // rotation around x-axis, 0 = vertical, 90 = horizontal + +// GBTx ROB definitions +const Int_t RobsPerModule[NofModuleTypes] = {3, 2, 1, 6, 2, 2, 1, 1, 30, 1}; // number of GBTx ROBs on module +const Int_t GbtxPerRob[NofModuleTypes] = {105, 105, 105, 103, 107, + 105, 105, 103, 103, 103}; // number of GBTx ASICs on ROB + +const Int_t GbtxPerModule[NofModuleTypes] = {15, 10, 5, 18, 0, + 10, 5, 3, 18, 18}; // for .geo.info - TODO: merge with above GbtxPerRob +const Int_t RobTypeOnModule[NofModuleTypes] = {555, 55, 5, 333333, 0, + 55, 5, 3, 333333, 333333}; // for .geo.info - TODO: merge with above + // GbtxPerRob + +// const Int_t RobsPerModule[NofModuleTypes] = { 2, 2, 1, 1, 2, 2, 1, 1 +// }; // number of GBTx ROBs on module +// const Int_t GbtxPerRob[NofModuleTypes] = {107,105,105,103,107,105,105,103 +// }; // number of GBTx ASICs on ROB +// const Int_t GbtxPerModule[NofModuleTypes] = { 14, 8, 5, 0, 0, 10, 5, 3 +// }; // for .geo.info - TODO: merge with above GbtxPerRob +// const Int_t RobTypeOnModule[NofModuleTypes] = { 77, 53, 5, 0, 0, 55, 5, +// 3 }; // for .geo.info - TODO: merge with above GbtxPerRob + +// super density for type 1 modules - 2017 - 540 mm +const Int_t FebsPerModule[NofModuleTypes] = {9, 5, 6, 18, 12, 8, 4, 3, 18, 18}; // number of FEBs on backside +// const Int_t FebsPerModule[NofModuleTypes] = { 9, 6, 3, 4, 12, 8, 4, 2 +// }; // number of FEBs on backside +const Int_t AsicsPerFeb[NofModuleTypes] = {210, 210, 210, 410, 109, 108, 108, 108, 410, 410}; // %100 gives + // number of + // ASICs on FEB, + // /100 gives + // grouping +//// ultimate density - 540 mm +// const Int_t FebsPerModule[NofModuleTypes] = { 6, 5, 6, 4, 12, 8, 4, 3 +// }; // number of FEBs on backside - reduced FEBs (64 ch ASICs) +// const Int_t AsicsPerFeb[NofModuleTypes] = {315,210,105,105,108,108,108,108 +// }; // %100 gives number of ASICs on FEB, /100 gives grouping +////const Int_t FebsPerModule[NofModuleTypes] = { 6, 5, 3, 2, 6, 3, 4, 3 +///}; // min number of FEBs // number of FEBs on backside - reduced FEBs (64 ch +/// ASICs) +////const Int_t AsicsPerFeb[NofModuleTypes] = {315,210,210,210,216,216,108,108 +///}; // %100 gives number of ASICs on FEB, /100 gives grouping +////const Int_t AsicsPerFeb[NofModuleTypes] = {216,210,210,210,216,216,108,108 +///}; // %100 gives number of ASICs on FEB, /100 gives grouping +// +////// super density - 540 mm +// const Int_t FebsPerModule[NofModuleTypes] = { 9, 5, 6, 4, 12, 6, 4, 3 +// }; // light // number of FEBs on backside - reduced FEBs (64 ch ASICs) +// const Int_t AsicsPerFeb[NofModuleTypes] = {210,210,105,105,108,108,108,108 +// }; // %100 gives number of ASICs on FEB, /100 gives grouping +// +//// normal density - 540 mm +// const Int_t FebsPerModule[NofModuleTypes] = { 18, 10, 6, 4, 12, 6, 4, 3 +// }; // number of FEBs on backside (linked to pad layout) - mod4 = mod3, +// therefore same +// const Int_t AsicsPerFeb[NofModuleTypes] = {105,105,105,105,108,108,108,108 +// }; // %100 gives number of ASICs on FEB, /100 gives grouping + +// ultimate density - 570 mm +// const Int_t FebsPerModule[NofModuleTypes] = { 6, 5, 3, 2, 5, 3, 2, 1 +// }; // min number of FEBs // number of FEBs on backside - reduced FEBs (64 ch +// ASICs) +// const Int_t AsicsPerFeb[NofModuleTypes] = {216,210,210,210,216,216,216,216 +// }; // %100 gives number of ASICs on FEB, /100 gives grouping +// +// const Int_t FebsPerModule[NofModuleTypes] = { 6, 5, 3, 3, 10, 5, 3, 3 +// }; // min (6) module types // number of FEBs on backside - reduced FEBs (64 +// ch ASICs) +// const Int_t AsicsPerFeb[NofModuleTypes] = {216,210,210,210,108,108,108,108 +// }; // %100 gives number of ASICs on FEB, /100 gives grouping +//// super density - 570 mm +// const Int_t FebsPerModule[NofModuleTypes] = { 10, 5, 5, 5, 12, 6, 4, 3 +// }; // light // number of FEBs on backside - reduced FEBs (64 ch ASICs) +// const Int_t AsicsPerFeb[NofModuleTypes] = {210,210,105,105,108,108,108,108 +// }; // %100 gives number of ASICs on FEB, /100 gives grouping +// +//// normal density - 570 mm +// const Int_t FebsPerModule[NofModuleTypes] = { 19, 10, 5, 5, 12, 6, 4, 3 +// }; // number of FEBs on backside (linked to pad layout) - mod4 = mod3, +// therefore same +// const Int_t AsicsPerFeb[NofModuleTypes] = {105,105,105,105,108,108,108,108 +// }; // %100 gives number of ASICs on FEB, /100 gives grouping + +/* TODO: activate connector grouping info below +// ultimate - grouping of pads to connectors +const Int_t RowsPerConnector[NofModuleTypes] = { 6, 4, 2, 2, 2, 2, 2, 2 +}; +const Int_t ColsPerConnector[NofModuleTypes] = { 16, 16, 16, 16, 16, 16, 16, 16 +}; +// super - grouping of pads to connectors +const Int_t RowsPerConnector[NofModuleTypes] = { 4, 4, 2, 2, 2, 2, 2, 2 +}; +const Int_t ColsPerConnector[NofModuleTypes] = { 16, 16, 16, 16, 16, 16, 16, 16 +}; +// normal - grouping of pads to connectors +const Int_t RowsPerConnector[NofModuleTypes] = { 2, 2, 2, 2, 2, 2, 2, 2 +}; +const Int_t ColsPerConnector[NofModuleTypes] = { 16, 16, 16, 16, 16, 16, 16, 16 +}; +*/ + +const Double_t feb_z_offset = 0.1; // 1 mm - offset in z of FEBs to backpanel +const Double_t asic_offset = 0.1; // 1 mm - offset of ASICs to FEBs to avoid overlaps + +// ASIC parameters +Double_t asic_distance; + +// const Double_t FrameWidth[2] = { 1.5, 2.0 }; // Width of detector frames +// in cm +const Double_t FrameWidth[4] = {1.5, 1.5, 2.5, 1.5}; // Width of detector frames in cm +// mini - production +const Double_t DetectorSizeX[4] = {57., 99., 59.0, 23.04 + 3.}; // => 54 x 54 cm2 & 96 x 96 cm2 active area +const Double_t DetectorSizeY[4] = {57., 99., 60.8, 8.16 + 3.}; // quadratic modules +//// default +// const Double_t DetectorSizeX[2] = { 60., 100.}; // => 57 x 57 cm2 & 96 x 96 +// cm2 active area +// const Double_t DetectorSizeY[2] = { 60., 100.}; // quadratic modules + +// Parameters tor the lattice grid reinforcing the entrance window +// const Double_t lattice_o_width[2] = { 1.5, 2.0 }; // Width of outer lattice +// frame in cm +const Double_t lattice_o_width[2] = {1.5, 1.5}; // Width of outer lattice frame in cm +const Double_t lattice_i_width[2] = {0.2, 0.2}; // { 0.4, 0.4 }; // Width of inner lattice frame in cm +// Thickness (in z) of lattice frames in cm - see below + +// statistics +Int_t ModuleStats[MaxLayers][NofModuleTypes] = {0}; + +// z - geometry of TRD modules +const Double_t radiator_thickness = 0.0; // 35 cm thickness of radiator +// const Double_t radiator_thickness = 30.0; // 30 cm thickness of +// radiator + shift pad plane to integer multiple of 1 mm +const Double_t radiator_position = -LayerThickness / 2. + radiator_thickness / 2.; + +// const Double_t lattice_thickness = 1.0; // 1.0; // 10 mm thick +// lattice frames +const Double_t lattice_thickness = 1.0 - 0.0025; // 0.9975; // 1.0; // 10 mm thick lattice frames +const Double_t lattice_position = radiator_position + radiator_thickness / 2. + lattice_thickness / 2.; + +const Double_t kapton_thickness = 0.0025; // 25 micron thickness of kapton +const Double_t kapton_position = lattice_position + lattice_thickness / 2. + kapton_thickness / 2.; + +const Double_t gas_thickness = 1.2; // 12 mm thickness of gas +const Double_t gas_position = kapton_position + kapton_thickness / 2. + gas_thickness / 2.; + +// frame thickness +const Double_t frame_thickness = gas_thickness; // frame covers gas volume: from kapton foil to pad plane +const Double_t frame_position = + -LayerThickness / 2. + radiator_thickness + lattice_thickness + kapton_thickness + frame_thickness / 2.; + +// pad plane +const Double_t padcopper_thickness = 0.0025; // 25 micron thickness of copper pads +const Double_t padcopper_position = gas_position + gas_thickness / 2. + padcopper_thickness / 2.; + +const Double_t padplane_thickness = 0.0360; // 360 micron thickness of padplane +const Double_t padplane_position = padcopper_position + padcopper_thickness / 2. + padplane_thickness / 2.; + +// backpanel components +const Double_t carbon_thickness = 0.0190 * 2; // use 2 layers!! // 190 micron thickness for 1 layer of carbon fibers +const Double_t honeycomb_thickness = 2.3 - kapton_thickness - padcopper_thickness - padplane_thickness + - carbon_thickness; // ~ 2.3 mm thickness of honeycomb +const Double_t honeycomb_position = padplane_position + padplane_thickness / 2. + honeycomb_thickness / 2.; +const Double_t carbon_position = honeycomb_position + honeycomb_thickness / 2. + carbon_thickness / 2.; + +// aluminium thickness +const Double_t aluminium_thickness = 0.4; // crossbar of 1 x 1 cm at every module edge +const Double_t aluminium_width = 1.0; // crossbar of 1 x 1 cm at every module edge +const Double_t aluminium_position = carbon_position + carbon_thickness / 2. + aluminium_thickness / 2.; + +// power bus bars +const Double_t powerbar_thickness = 1.0; // 1 cm in z direction +const Double_t powerbar_width = 2.0; // 2 cm in x/y direction +const Double_t powerbar_position = aluminium_position + aluminium_thickness / 2. + powerbar_thickness / 2.; + +// gibbet support +const Double_t gibbet_thickness = 10.0; // 10 cm in z direction +const Double_t gibbet_width = 10.0; // 10 cm in x/y direction +const Double_t gibbet_position = aluminium_position + aluminium_thickness / 2. + gibbet_thickness / 2.; + +// module rails +const Double_t rail_thickness = 5.0; // 5 cm in z direction +const Double_t rail_width = 3.0; // 3 cm in x/y direction +const Double_t rail_position = aluminium_position + aluminium_thickness / 2. + rail_thickness / 2.; + +// readout boards +// const Double_t feb_width = 10.0; // width of FEBs in cm +const Double_t feb_width = 8.5; // width of FEBs in cm +const Double_t feb_thickness = 0.25; // light // 2.5 mm thickness of FEBs +const Double_t febvolume_position = aluminium_position + aluminium_thickness / 2. + feb_width / 2.; + +// ASIC parameters +const Double_t asic_thickness = 0.25; // 2.5 mm asic_thickness +const Double_t asic_width = 3.0; // 2.0; 1.0; // 1 cm + +// -------------- BUCHAREST PROTOTYPE SPECIFICS +// ---------------------------------- +// Frontpanel components +const Double_t carbonBu_thickness = 0.03; // 300 micron thickness for 1 layer of carbon fibers +const Double_t honeycombBu_thickness = 0.94; // 9 mm thickness of honeycomb +const Double_t WIN_Frame_thickness = 0.6; // entrance window framing 6x12 mm2 +// const Double_t carbonBu0_position = radiator_position + radiator_thickness +// / 2. + carbonBu_thickness / 2.; +const Double_t honeycombBu0_position = radiator_position + radiator_thickness / 2. + honeycombBu_thickness / 2.; +const Double_t carbonBu1_position = honeycombBu0_position + honeycombBu_thickness / 2. + carbonBu_thickness / 2.; +// Active volume +const Double_t gasBu_position = carbonBu1_position + carbonBu_thickness / 2. + gas_thickness / 2.; +// Pad plane +const Double_t padcopperBu_position = gasBu_position + gas_thickness / 2. + padcopper_thickness / 2.; +const Double_t padplaneBu_position = padcopperBu_position + padcopper_thickness / 2. + padplane_thickness / 2.; +// Backpanel components +const Double_t honeycombBu1_position = padplaneBu_position + padplane_thickness / 2. + honeycombBu_thickness / 2.; +// PCB +const Double_t glassFibre_thickness = 0.0270; // 300 microns overall PCB thickness +const Double_t cuCoating_thickness = 0.0030; +const Double_t glassFibre_position = honeycombBu1_position + honeycombBu_thickness / 2. + glassFibre_thickness / 2.; +const Double_t cuCoating_position = glassFibre_position + glassFibre_thickness / 2. + cuCoating_thickness / 2.; +// Frame around entrance window, active volume and exit window +const Double_t frameBu_thickness = 2 * carbonBu_thickness + honeycombBu_thickness + gas_thickness + padcopper_thickness + + padplane_thickness + honeycombBu_thickness + glassFibre_thickness + + cuCoating_thickness; +const Double_t frameBu_position = radiator_position + radiator_thickness / 2. + frameBu_thickness / 2.; +// ROB FASP +const Double_t febFASP_zspace = 1.5; // gap size between boards +const Double_t febFASP_width = 5.5; // width of FASP FEBs in cm +const Double_t febFASP_position = cuCoating_position + febFASP_width / 2. + 1.5; +const Double_t febFASP_thickness = feb_thickness; + +// FASP-ASIC parameters +const Double_t fasp_size[2] = {2, 2.5}; // FASP package size 2x3 cm2 +const Double_t fasp_xoffset = 1.35; // ASIC offset from ROC middle (horizontally) +const Double_t fasp_yoffset = 0.6; // ASIC offset from DET connector (vertical) +// GETS2C-ROB3 connector boord parameters +const Double_t robConn_size_x = 15.0; +const Double_t robConn_size_y = 6.0; +const Double_t robConn_xoffset = 6.0; +const Double_t robConn_FMCwidth = 1.5; // width of a MF FMC connector +const Double_t robConn_FMClength = 6.5; // length of a MF FMC connector +const Double_t robConn_FMCheight = 1.5; // height of a MF FMC connector + +// C-ROB3 parameters : GBTx ROBs +const Double_t rob_size_x = 20.0; // 13.0; // 130 mm +const Double_t rob_size_y = 9.0; // 4.5; // 45 mm +const Double_t rob_yoffset = 0.3; // offset wrt detector frame (on the detector plane) +const Double_t rob_zoffset = -7.5; // offset wrt entrace plane - center board +const Double_t rob_thickness = feb_thickness; +// GBTX parameters +const Double_t gbtx_thickness = 0.25; // 2.5 mm +const Double_t gbtx_width = 3.0; // 2.0; 1.0; // 1 cm +const Double_t gbtx_distance = 0.4; + +// 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 RadiatorVolumeMedium = "TRDpefoam20"; +const TString LatticeVolumeMedium = "TRDG10"; +const TString KaptonVolumeMedium = "TRDkapton"; +const TString GasVolumeMedium = "TRDgas"; +const TString PadCopperVolumeMedium = "TRDcopper"; +const TString PadPcbVolumeMedium = "TRDG10"; // todo - put correct FEB material here +const TString HoneycombVolumeMedium = "TRDaramide"; +const TString CarbonVolumeMedium = "TRDcarbon"; +const TString FebVolumeMedium = "TRDG10"; // todo - put correct FEB material here +const TString AsicVolumeMedium = "air"; // todo - put correct ASIC material here +const TString TextVolumeMedium = "air"; // leave as air +const TString FrameVolumeMedium = "TRDG10"; +const TString PowerBusVolumeMedium = "TRDcopper"; // power bus bars +const TString AluLegdeVolumeMedium = "aluminium"; // aluminium frame around backpanel +const TString AluminiumVolumeMedium = "aluminium"; +const TString Kanya10x10sVolumeMedium = "KANYAProfile10x10Strong"; +const TString Kanya10x10nVolumeMedium = "KANYAProfile10x10Normal"; +const TString Kanya03x05nVolumeMedium = "KANYAProfile3x5Normal"; +// const TString MylarVolumeMedium = "mylar"; +// const TString RadiatorVolumeMedium = "polypropylene"; +// const TString ElectronicsVolumeMedium = "goldcoatedcopper"; + +// some global variables +TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance +TGeoVolume* gModules[NofModuleTypes]; // Global storage for module types + +// Forward declarations +void create_materials_from_media_file(); +TGeoVolume* create_trd_module_type(Int_t moduleType); +TGeoVolume* create_trd2d_module_type(Int_t moduleType); +void create_detector_layers(Int_t layer); +void create_gibbet_support(); +void create_power_bars_vertical(); +void create_power_bars_horizontal(); +void create_xtru_supports(); +void create_box_supports(); +void add_trd_labels(TGeoVolume*, TGeoVolume*, TGeoVolume*); +void create_mag_field_vector(); +void dump_info_file(); +void dump_digi_file(); + +void Create_TRD_Geometry_v24c() +{ + // Load FairRunSim to ensure the correct unit system + FairRunSim* sim = new FairRunSim(); + + // declare TRD layer layout + if (setupid > 2) + for (Int_t i = 0; i < MaxLayers; i++) + ShowLayer[i] = 1; // show all layers + + // Load needed material definition from media.geo file + create_materials_from_media_file(); + + // Position the layers in z + for (Int_t iLayer = 1; iLayer < MaxLayers; iLayer++) + LayerPosition[iLayer] = + LayerPosition[iLayer - 1] + LayerThickness + LayerOffset[iLayer]; // add offset for extra gaps + + // Get the GeoManager for later usage + gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom"); + gGeoMan->SetVisLevel(10); + + // Create the top volume + TGeoBBox* topbox = new TGeoBBox("", 1000., 1000., 2000.); + TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air")); + gGeoMan->SetTopVolume(top); + + TGeoVolume* trd = new TGeoVolumeAssembly(geoVersion); + top->AddNode(trd, 1); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + Int_t moduleType = iModule + 1; + gModules[iModule] = (iModule >= 8 ? create_trd2d_module_type(moduleType) : create_trd_module_type(moduleType)); + } + + Int_t nLayer = 0; // active layer counter + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) { + // if ((iLayer != 0) && (iLayer != 3)) continue; // first layer only - + // comment later on + // if (iLayer != 0) continue; // first layer only - comment later on + if (ShowLayer[iLayer]) { + PlaneId[iLayer] = ++nLayer; + create_detector_layers(iLayer); + // printf("calling layer %2d\n",iLayer); + } + } + + // TODO: remove or comment out + // test PlaneId + printf("generated TRD layers: "); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) printf(" %2d", PlaneId[iLayer]); + printf("\n"); + + if (IncludeSupports) { create_box_supports(); } + + if (IncludeGibbet) { create_gibbet_support(); } + + if (IncludePowerbars) { + create_power_bars_vertical(); + create_power_bars_horizontal(); + } + + if (IncludeFieldVector) create_mag_field_vector(); + + gGeoMan->CloseGeometry(); + gGeoMan->CheckOverlaps(0.001); + gGeoMan->PrintOverlaps(); + gGeoMan->Test(); + + trd->Export(FileNameSim); // an alternative way of writing the trd volume + + TFile* outfile = new TFile(FileNameSim, "UPDATE"); + TGeoTranslation* trd_placement = new TGeoTranslation("trd_trans", 0., 0., zfront[setupid]); + trd_placement->Write(); + outfile->Close(); + + outfile = new TFile(FileNameGeo, "RECREATE"); + gGeoMan->Write(); // use this is you want GeoManager format in the output + outfile->Close(); + + dump_info_file(); + dump_digi_file(); + + top->Draw("ogl"); + + // top->Raytrace(); + + // cout << "Press Return to exit" << endl; + // cin.get(); + // exit(); + + // 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)"); +} + +//============================================================== +void dump_digi_file() +{ + TDatime datetime; // used to get timestamp + + const Double_t ActiveAreaX[4] = {DetectorSizeX[0] - 2 * FrameWidth[0], DetectorSizeX[1] - 2 * FrameWidth[1], + DetectorSizeX[2] - 2 * FrameWidth[2], DetectorSizeX[3] - 2 * FrameWidth[3]}; + const Double_t ActiveAreaY[4] = {DetectorSizeY[0] - 2 * FrameWidth[0], DetectorSizeY[1] - 2 * FrameWidth[1], + DetectorSizeY[2] - 2 * FrameWidth[2], DetectorSizeY[3] - 2 * FrameWidth[3]}; + const Int_t NofSectors = 3; + const Int_t NofPadsInRow[4] = {80, 144, 72, 32}; // number of pads in rows + Int_t nrow = 0; // number of rows in module + + const Double_t PadHeightInSector[NofModuleTypes][NofSectors] = // pad height + {{1.50, 1.50, 1.50}, // module type 1 - 1.01 mm2 + {2.25, 2.25, 2.25}, // module type 2 - 1.52 mm2 + // { 2.75, 2.50, 2.75 }, // module type 2 - 1.86 mm2 + {4.50, 4.50, 4.50}, // module type 3 - 3.04 mm2 + // { 2.75, 6.75, 6.75 }, // module type 4 - 4.56 mm2 + {2.79, 2.79, 2.79}, // module type 4 - triangular pads H=27.7+0.2 mm, W=7.3+0.2 mm + + {4.00, 4.00, 4.00}, // module type 5 - 2.67 cm2 + {6.00, 6.00, 6.00}, // module type 6 - 4.00 cm2 + {12.00, 12.00, 12.00}, // module type 7 - 8.00 cm2 + {24.00, 24.00, 24.00}, // module type 8 - 16.00 cm2 + // TRD2D with triangular pads + {2.79, 2.79, 2.79}, // module type 9 - H=27.7+0.2 mm, W=7.3+0.2 mm + {2.72, 2.72, 2.72}}; // module type 10 - H=27.7+0.2 mm, W=7.3+0.2 mm + // { 23.00, 23.00, 23.00 } }; // module type 8 - 16.52 mm2 + // { 7.50, 7.75, 7.50 }, // module type 6 - 5.51 mm2 + // { 5.50, 5.75, 5.50 }, // module type 6 - 4.09 mm2 + // { 11.25, 11.50, 11.25 }, // module type 7 - 8.18 mm2 + + const Int_t NofRowsInSector[NofModuleTypes][NofSectors] = // number of rows per sector + {{12, 12, 12}, // module type 1 + {8, 8, 8}, // module type 2 + // { 8, 4, 8 }, // module type 2 + {4, 4, 4}, // module type 3 + // { 2, 4, 2 }, // module type 4 + {2, 16, 2}, // module type 4 + + {8, 8, 8}, // module type 5 + {6, 4, 6}, // module type 6 + {2, 4, 2}, // module type 7 + {1, 2, 1}, // module type 8 + // { 1, 2, 1 } }; // module type 8 + // { 10, 4, 10 }, // module type 5 + // { 4, 4, 4 }, // module type 6 + // { 2, 12, 2 }, // module type 6 + // { 2, 4, 2 }, // module type 7 + // { 2, 2, 2 } }; // module type 8 + {1, 18, 1}, // module type 9 + {1, 1, 1}}; // module type 10 + + Double_t HeightOfSector[NofModuleTypes][NofSectors]; + Double_t PadWidth[NofModuleTypes]; + + // calculate pad width + for (Int_t im = 0; im < NofModuleTypes; im++) + PadWidth[im] = ActiveAreaX[ModuleType[im]] / NofPadsInRow[ModuleType[im]]; + + // calculate height of sectors + for (Int_t im = 0; im < NofModuleTypes; im++) + for (Int_t is = 0; is < NofSectors; is++) + HeightOfSector[im][is] = NofRowsInSector[im][is] * PadHeightInSector[im][is]; + + // check, if the entire module size is covered by pads + for (Int_t im = 0; im < NofModuleTypes; im++) { + if (im != 3 + && ActiveAreaY[ModuleType[im]] - (HeightOfSector[im][0] + HeightOfSector[im][1] + HeightOfSector[im][2]) != 0) { + printf("WARNING: sector size does not add up to module size for module " + "type %d\n", + im + 1); + printf("%.2f = %.2f + %.2f + %.2f\n", ActiveAreaY[ModuleType[im]], HeightOfSector[im][0], HeightOfSector[im][1], + HeightOfSector[im][2]); + // exit(1); + } + } + //============================================================== + + printf("writing trd pad information file: %s\n", FileNamePads.Data()); + + FILE* ifile; + ifile = fopen(FileNamePads.Data(), "w"); + + if (ifile == NULL) { + printf("error opening %s\n", FileNamePads.Data()); + exit(1); + } + + fprintf(ifile, "//\n"); + fprintf(ifile, "// TRD pad layout for geometry %s\n", tagVersion.Data()); + fprintf(ifile, "//\n"); + fprintf(ifile, "// automatically generated by Create_TRD_Geometry_%s%s.C\n", tagVersion.Data(), subVersion.Data()); + fprintf(ifile, "// created %d\n", datetime.GetDate()); + fprintf(ifile, "//\n"); + + fprintf(ifile, "\n"); + fprintf(ifile, "#ifndef CBMTRDPADS_H\n"); + fprintf(ifile, "#define CBMTRDPADS_H\n"); + fprintf(ifile, "\n"); + fprintf(ifile, "Int_t fst1_sect_count = 3;\n"); + fprintf(ifile, "// array of pad geometries in the TRD (trd1mod[1-%d])\n", NofModuleTypes); + fprintf(ifile, "// %d modules // 3 sectors // 4 values \n", NofModuleTypes); + fprintf(ifile, "Float_t fst1_pad_type[%d][3][4] = \n", NofModuleTypes); + // fprintf(ifile,"Double_t fst1_pad_type[8][3][4] = \n"); + fprintf(ifile, " \n"); + + for (Int_t im = 0; im < NofModuleTypes; im++) { + if (im + 1 == 5) fprintf(ifile, "//---\n\n"); + fprintf(ifile, "// module type %d\n", im + 1); + + // number of pads + nrow = 0; // reset number of pad rows to 0 + for (Int_t is = 0; is < NofSectors; is++) + nrow += HeightOfSector[im][is] / PadHeightInSector[im][is]; // add number of rows in this sector + fprintf(ifile, "// number of pads: %3d x %2d = %4d\n", NofPadsInRow[ModuleType[im]], nrow, + NofPadsInRow[ModuleType[im]] * nrow); + + // pad size + fprintf(ifile, "// pad size sector 1: %5.2f cm x %5.2f cm = %5.2f cm2\n", PadWidth[im], PadHeightInSector[im][1], + PadWidth[im] * PadHeightInSector[im][1]); + fprintf(ifile, "// pad size sector 0: %5.2f cm x %5.2f cm = %5.2f cm2\n", PadWidth[im], PadHeightInSector[im][0], + PadWidth[im] * PadHeightInSector[im][0]); + + for (Int_t is = 0; is < NofSectors; is++) { + if ((im == 0) && (is == 0)) fprintf(ifile, " { { "); + else if (is == 0) + fprintf(ifile, " { "); + else + fprintf(ifile, " "); + + fprintf(ifile, "{ %.2f, %5.2f, %.2f/%3d, %5.2f }", ActiveAreaX[ModuleType[im]], HeightOfSector[im][is], + ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][is]); + + if ((im == NofModuleTypes - 1) && (is == 2)) fprintf(ifile, " } };"); + else if (is == 2) + fprintf(ifile, " },"); + else + fprintf(ifile, ","); + + fprintf(ifile, "\n"); + } + + fprintf(ifile, "\n"); + } + + fprintf(ifile, "#endif\n"); + + // Int_t im = 0; + // fprintf(ifile,"// module type %d \n", im+1); + // fprintf(ifile," { { { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", + // ActiveAreaX[ModuleType[im]], HeightOfSector[im][0], + // ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], + // PadHeightInSector[im][0]); + // fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", + // ActiveAreaX[ModuleType[im]], HeightOfSector[im][1], + // ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], + // PadHeightInSector[im][1]); + // fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f } }, \n", + // ActiveAreaX[ModuleType[im]], HeightOfSector[im][2], + // ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], + // PadHeightInSector[im][2]); + // fprintf(ifile,"\n"); + // + // for (Int_t im = 1; im < NofModuleTypes-1; im++) + // { + // fprintf(ifile,"// module type %d \n", im+1); + // fprintf(ifile," { { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", + // ActiveAreaX[ModuleType[im]], HeightOfSector[im][0], + // ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], + // PadHeightInSector[im][0]); + // fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", + // ActiveAreaX[ModuleType[im]], HeightOfSector[im][1], + // ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], + // PadHeightInSector[im][1]); + // fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f } }, \n", + // ActiveAreaX[ModuleType[im]], HeightOfSector[im][2], + // ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], + // PadHeightInSector[im][2]); + // fprintf(ifile,"\n"); + // } + // + // Int_t im = 7; + // fprintf(ifile,"// module type %d \n", im+1); + // fprintf(ifile," { { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", + // ActiveAreaX[ModuleType[im]], HeightOfSector[im][0], + // ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], + // PadHeightInSector[im][0]); + // fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", + // ActiveAreaX[ModuleType[im]], HeightOfSector[im][1], + // ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], + // PadHeightInSector[im][1]); + // fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f } } };\n", + // ActiveAreaX[ModuleType[im]], HeightOfSector[im][2], + // ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], + // PadHeightInSector[im][2]); + // fprintf(ifile,"\n"); + + fclose(ifile); +} + +void dump_info_file() +{ + TDatime datetime; // used to get timestamp + + Double_t z_first_layer = 2000; // z position of first layer (front) + Double_t z_last_layer = 0; // z position of last layer (front) + + Double_t xangle; // horizontal angle + Double_t yangle; // vertical angle + + Double_t total_surface = 0; // total surface + Double_t total_actarea = 0; // total active area + + Int_t channels_per_module[NofModuleTypes + 1] = {0}; // number of channels per module + Int_t channels_per_feb[NofModuleTypes + 1] = {0}; // number of channels per feb + Int_t asics_per_module[NofModuleTypes + 1] = {0}; // number of asics per module + + Int_t total_modules[NofModuleTypes + 1] = {0}; // total number of modules + Int_t total_febs[NofModuleTypes + 1] = {0}; // total number of febs + Int_t total_asics[NofModuleTypes + 1] = {0}; // total number of asics + Int_t total_gbtx[NofModuleTypes + 1] = {0}; // total number of gbtx + Int_t total_rob3[NofModuleTypes + 1] = {0}; // total number of gbtx rob3 + Int_t total_rob5[NofModuleTypes + 1] = {0}; // total number of gbtx rob5 + Int_t total_rob7[NofModuleTypes + 1] = {0}; // total number of gbtx rob7 + Int_t total_channels[NofModuleTypes + 1] = {0}; // total number of channels + + Int_t total_channels_u = 0; // total number of ultimate channels + Int_t total_channels_s = 0; // total number of super channels + Int_t total_channels_r = 0; // total number of regular channels + + printf("writing summary information 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()); + + // determine first and last TRD layer + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) { + if (ShowLayer[iLayer]) { + if (z_first_layer > LayerPosition[iLayer]) z_first_layer = LayerPosition[iLayer]; + if (z_last_layer < LayerPosition[iLayer]) z_last_layer = LayerPosition[iLayer]; + } + } + + fprintf(ifile, "# envelope, in TRD local system\n"); + // Show extension of TRD + fprintf(ifile, "%4f cm start of TRD (z)\n", z_first_layer); + fprintf(ifile, "%4f cm end of TRD (z)\n", z_last_layer + LayerThickness); + fprintf(ifile, "\n"); + + // Show layer flags + fprintf(ifile, "# generated TRD layers\n "); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) fprintf(ifile, "%2d ", PlaneId[iLayer]); + fprintf(ifile, " planeID\n"); + fprintf(ifile, "\n"); + + // Show layer positions + fprintf(ifile, "# z-positions of layer front, in TRD local system\n"); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) { + if (ShowLayer[iLayer]) fprintf(ifile, "%5f cm z-position of layer %2d\n", LayerPosition[iLayer], PlaneId[iLayer]); + } + fprintf(ifile, "\n"); + + // flags + fprintf(ifile, "# flags\n"); + + fprintf(ifile, "support structure is : "); + if (!IncludeSupports) fprintf(ifile, "NOT "); + fprintf(ifile, "included\n"); + + fprintf(ifile, "radiator is : "); + if (!IncludeRadiator) fprintf(ifile, "NOT "); + fprintf(ifile, "included\n"); + + fprintf(ifile, "lattice grid is : "); + if (!IncludeLattice) fprintf(ifile, "NOT "); + fprintf(ifile, "included\n"); + + fprintf(ifile, "kapton window is : "); + if (!IncludeKaptonFoil) fprintf(ifile, "NOT "); + fprintf(ifile, "included\n"); + + fprintf(ifile, "gas frame is : "); + if (!IncludeGasFrame) fprintf(ifile, "NOT "); + fprintf(ifile, "included\n"); + + fprintf(ifile, "padplane is : "); + if (!IncludePadplane) fprintf(ifile, "NOT "); + fprintf(ifile, "included\n"); + + fprintf(ifile, "backpanel is : "); + if (!IncludeBackpanel) fprintf(ifile, "NOT "); + fprintf(ifile, "included\n"); + + fprintf(ifile, "Aluminium ledge is : "); + if (!IncludeAluLedge) fprintf(ifile, "NOT "); + fprintf(ifile, "included\n"); + + fprintf(ifile, "Gibbet support is : "); + if (!IncludeGibbet) fprintf(ifile, "NOT "); + fprintf(ifile, "included\n"); + + fprintf(ifile, "Power bus bars are : "); + if (!IncludePowerbars) fprintf(ifile, "NOT "); + fprintf(ifile, "included\n"); + + fprintf(ifile, "asics are : "); + if (!IncludeAsics) fprintf(ifile, "NOT "); + fprintf(ifile, "included\n"); + + fprintf(ifile, "front-end boards are : "); + if (!IncludeFebs) fprintf(ifile, "NOT "); + fprintf(ifile, "included\n"); + + fprintf(ifile, "1D GBTX readout boards are : "); + if (!IncludeRobs1D) fprintf(ifile, "NOT "); + fprintf(ifile, "included\n"); + + fprintf(ifile, "2D GBTX readout boards are : "); + if (!IncludeRobs2D) fprintf(ifile, "NOT "); + fprintf(ifile, "included\n"); + + fprintf(ifile, "\n"); + + // module statistics + // fprintf(ifile,"#\n## modules\n#\n\n"); + // fprintf(ifile,"number of modules per type and layer:\n"); + fprintf(ifile, "# modules\n"); + + for (Int_t iModule = 1; iModule <= NofModuleTypes; iModule++) + fprintf(ifile, " mod%1d", iModule); + fprintf(ifile, " total"); + + fprintf(ifile, "\n------------------------------------------------------------------" + "---------------\n"); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) { + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + fprintf(ifile, " %8d", ModuleStats[iLayer][iModule]); + total_modules[iModule] += ModuleStats[iLayer][iModule]; // sum up modules across layers + } + fprintf(ifile, " layer %2d\n", PlaneId[iLayer]); + } + fprintf(ifile, "\n------------------------------------------------------------------" + "---------------\n"); + + // total statistics + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + fprintf(ifile, " %8d", total_modules[iModule]); + total_modules[NofModuleTypes] += total_modules[iModule]; + } + fprintf(ifile, " %8d", total_modules[NofModuleTypes]); + fprintf(ifile, " number of modules\n"); + + //------------------------------------------------------------------------------ + + // number of FEBs + // fprintf(ifile,"\n#\n## febs\n#\n\n"); + fprintf(ifile, "# febs\n"); + + fprintf(ifile, " "); + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + if ((AsicsPerFeb[iModule] / 100) == 3) fprintf(ifile, "%8du", FebsPerModule[iModule]); + else if ((AsicsPerFeb[iModule] / 100) == 2) + fprintf(ifile, "%8ds", FebsPerModule[iModule]); + else + fprintf(ifile, "%8d ", FebsPerModule[iModule]); + } + fprintf(ifile, " FEBs per module\n"); + + // FEB total per type + total_febs[NofModuleTypes] = 0; // reset sum to 0 + fprintf(ifile, " "); + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + if ((AsicsPerFeb[iModule] / 100) == 3) { + total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule]; + fprintf(ifile, "%8du", total_febs[iModule]); + total_febs[NofModuleTypes] += total_febs[iModule]; + } + else + fprintf(ifile, " "); + } + fprintf(ifile, "%8d", total_febs[NofModuleTypes]); + fprintf(ifile, " ultimate FEBs\n"); + + // FEB total per type + total_febs[NofModuleTypes] = 0; // reset sum to 0 + fprintf(ifile, " "); + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + if ((AsicsPerFeb[iModule] / 100) == 2) { + total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule]; + fprintf(ifile, "%8ds", total_febs[iModule]); + total_febs[NofModuleTypes] += total_febs[iModule]; + } + else + fprintf(ifile, " "); + } + fprintf(ifile, "%8d", total_febs[NofModuleTypes]); + fprintf(ifile, " super FEBs\n"); + + // FEB total per type + total_febs[NofModuleTypes] = 0; // reset sum to 0 + fprintf(ifile, " "); + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + if ((AsicsPerFeb[iModule] / 100) == 1) { + total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule]; + fprintf(ifile, "%8d ", total_febs[iModule]); + total_febs[NofModuleTypes] += total_febs[iModule]; + } + else + fprintf(ifile, " "); + } + fprintf(ifile, "%8d", total_febs[NofModuleTypes]); + fprintf(ifile, " regular FEBs\n"); + + // FEB total over all types + total_febs[NofModuleTypes] = 0; // reset sum to 0 + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule]; + fprintf(ifile, " %8d", total_febs[iModule]); + total_febs[NofModuleTypes] += total_febs[iModule]; + } + fprintf(ifile, " %8d", total_febs[NofModuleTypes]); + fprintf(ifile, " number of FEBs\n"); + + //------------------------------------------------------------------------------ + + // number of ASICs + // fprintf(ifile,"\n#\n## asics\n#\n\n"); + fprintf(ifile, "# asics\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + fprintf(ifile, " %8d", AsicsPerFeb[iModule] % 100); + } + fprintf(ifile, " ASICs per FEB\n"); + + // ASICs per module + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + asics_per_module[iModule] = FebsPerModule[iModule] * (AsicsPerFeb[iModule] % 100); + fprintf(ifile, " %8d", asics_per_module[iModule]); + } + fprintf(ifile, " ASICs per module\n"); + + // ASICs per module type + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + total_asics[iModule] = total_febs[iModule] * (AsicsPerFeb[iModule] % 100); + fprintf(ifile, " %8d", total_asics[iModule]); + total_asics[NofModuleTypes] += total_asics[iModule]; + } + fprintf(ifile, " %8d", total_asics[NofModuleTypes]); + fprintf(ifile, " number of ASICs\n"); + + //------------------------------------------------------------------------------ + + // number of GBTXs + // fprintf(ifile,"\n#\n## asics\n#\n\n"); + fprintf(ifile, "# gbtx\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + fprintf(ifile, " %8d", GbtxPerModule[iModule]); + } + fprintf(ifile, " GBTXs per module\n"); + + // GBTXs per module type + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + total_gbtx[iModule] = total_modules[iModule] * GbtxPerModule[iModule]; + fprintf(ifile, " %8d", total_gbtx[iModule]); + total_gbtx[NofModuleTypes] += total_gbtx[iModule]; + } + fprintf(ifile, " %8d", total_gbtx[NofModuleTypes]); + fprintf(ifile, " number of GBTXs\n"); + + // GBTX ROB types per module type + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + fprintf(ifile, " %8d", RobTypeOnModule[iModule]); + } + fprintf(ifile, " GBTX ROB types on module\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + if ((RobTypeOnModule[iModule] % 10) == 7) total_rob7[iModule]++; + if ((RobTypeOnModule[iModule] / 10 % 10) == 7) total_rob7[iModule]++; + if ((RobTypeOnModule[iModule] / 100) == 7) total_rob7[iModule]++; + + if ((RobTypeOnModule[iModule] % 10) == 5) total_rob5[iModule]++; + if ((RobTypeOnModule[iModule] / 10 % 10) == 5) total_rob5[iModule]++; + if ((RobTypeOnModule[iModule] / 100) == 5) total_rob5[iModule]++; + + if ((RobTypeOnModule[iModule] % 10) == 3) total_rob3[iModule]++; + if ((RobTypeOnModule[iModule] / 10 % 10) == 3) total_rob3[iModule]++; + if ((RobTypeOnModule[iModule] / 100 % 10) == 3) total_rob3[iModule]++; + if ((RobTypeOnModule[iModule] / 1000 % 10) == 3) total_rob3[iModule]++; + if ((RobTypeOnModule[iModule] / 10000 % 10) == 3) total_rob3[iModule]++; + if ((RobTypeOnModule[iModule] / 100000) == 3) total_rob3[iModule]++; + } + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + total_rob7[iModule] *= total_modules[iModule]; + fprintf(ifile, " %8d", total_rob7[iModule]); + total_rob7[NofModuleTypes] += total_rob7[iModule]; + } + fprintf(ifile, " %8d", total_rob7[NofModuleTypes]); + fprintf(ifile, " number of GBTX ROB7\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + total_rob5[iModule] *= total_modules[iModule]; + fprintf(ifile, " %8d", total_rob5[iModule]); + total_rob5[NofModuleTypes] += total_rob5[iModule]; + } + fprintf(ifile, " %8d", total_rob5[NofModuleTypes]); + fprintf(ifile, " number of GBTX ROB5\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + total_rob3[iModule] *= total_modules[iModule]; + fprintf(ifile, " %8d", total_rob3[iModule]); + total_rob3[NofModuleTypes] += total_rob3[iModule]; + } + fprintf(ifile, " %8d", total_rob3[NofModuleTypes]); + fprintf(ifile, " number of GBTX ROB3\n"); + + //------------------------------------------------------------------------------ + fprintf(ifile, "# e-links\n"); + + // e-links used + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + fprintf(ifile, " %8d", asics_per_module[iModule] * 2); + fprintf(ifile, " %8d", total_asics[NofModuleTypes] * 2); + fprintf(ifile, " e-links used\n"); + + // e-links available + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + fprintf(ifile, " %8d", GbtxPerModule[iModule] * 14); + fprintf(ifile, " %8d", total_gbtx[NofModuleTypes] * 14); + fprintf(ifile, " e-links available\n"); + + // e-link efficiency + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + if (total_gbtx[iModule] != 0) + fprintf(ifile, " %7.1f%%", (float) total_asics[iModule] * 2 / (total_gbtx[iModule] * 14) * 100); + else + fprintf(ifile, " -"); + } + if (total_gbtx[NofModuleTypes] != 0) + fprintf(ifile, " %7.1f%%", (float) total_asics[NofModuleTypes] * 2 / (total_gbtx[NofModuleTypes] * 14) * 100); + fprintf(ifile, " e-link efficiency\n\n"); + + //------------------------------------------------------------------------------ + + // number of channels + fprintf(ifile, "# channels\n"); + + // channels per module + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + if ((AsicsPerFeb[iModule] % 100) == 16) { + channels_per_feb[iModule] = 80 * 6; // rows // 84, if 63 of 64 ch used + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + if ((AsicsPerFeb[iModule] % 100) == 15) { + channels_per_feb[iModule] = 80 * 6; // rows + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + if ((AsicsPerFeb[iModule] % 100) == 10) { + // channels_per_feb[iModule] = 80 * 4; // rows + channels_per_feb[iModule] = (AsicsPerFeb[iModule] % 100) * 16; // electronic channels + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + if ((AsicsPerFeb[iModule] % 100) == 5) { + channels_per_feb[iModule] = 80 * 2; // rows + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + if ((AsicsPerFeb[iModule] % 100) == 9) { + channels_per_feb[iModule] = 144 * 2; // rows + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + if ((AsicsPerFeb[iModule] % 100) == 8) { + channels_per_feb[iModule] = 128 * 2; // rows + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + } + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + fprintf(ifile, " %8d", channels_per_module[iModule]); + fprintf(ifile, " channels per module\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + fprintf(ifile, " %8d", channels_per_feb[iModule]); + fprintf(ifile, " channels per feb\n"); + + // channels used + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + total_channels[iModule] = channels_per_module[iModule] * total_modules[iModule]; + fprintf(ifile, " %8d", total_channels[iModule]); + total_channels[NofModuleTypes] += total_channels[iModule]; + } + fprintf(ifile, " %8d", total_channels[NofModuleTypes]); + fprintf(ifile, " channels used\n"); + + // channels available + fprintf(ifile, " "); + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + if ((AsicsPerFeb[iModule] / 100) == 4) // FASP case + { + fprintf(ifile, "%8dF", total_asics[iModule] * 16); + total_channels_u += total_asics[iModule] * 16; + } + else if ((AsicsPerFeb[iModule] / 100) == 3) { + fprintf(ifile, "%8du", total_asics[iModule] * 32); + total_channels_u += total_asics[iModule] * 32; + } + else if ((AsicsPerFeb[iModule] / 100) == 2) { + fprintf(ifile, "%8ds", total_asics[iModule] * 32); + total_channels_s += total_asics[iModule] * 32; + } + else { + fprintf(ifile, "%8d ", total_asics[iModule] * 32); + total_channels_r += total_asics[iModule] * 32; + } + } + fprintf(ifile, "%8d", total_asics[NofModuleTypes] * 32); + fprintf(ifile, " channels available\n"); + + // channel ratio for u,s,r density + fprintf(ifile, " "); + fprintf(ifile, "%7.1f%%u", (float) total_channels_u / (total_asics[NofModuleTypes] * 32) * 100); + fprintf(ifile, "%7.1f%%s", (float) total_channels_s / (total_asics[NofModuleTypes] * 32) * 100); + fprintf(ifile, "%7.1f%%r", (float) total_channels_r / (total_asics[NofModuleTypes] * 32) * 100); + fprintf(ifile, " " + "channel ratio\n"); + + fprintf(ifile, "\n"); + fprintf(ifile, "%8.1f%% channel efficiency\n", + 1. * total_channels[NofModuleTypes] / (total_asics[NofModuleTypes] * 32) * 100); + + //------------------------------------------------------------------------------ + + // total surface of TRD + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + if (iModule <= 3) { + total_surface += total_modules[iModule] * DetectorSizeX[0] / 100 * DetectorSizeY[0] / 100; + total_actarea += total_modules[iModule] * (DetectorSizeX[0] - 2 * FrameWidth[0]) / 100 + * (DetectorSizeY[0] - 2 * FrameWidth[0]) / 100; + } + else { + total_surface += total_modules[iModule] * DetectorSizeX[1] / 100 * DetectorSizeY[1] / 100; + total_actarea += total_modules[iModule] * (DetectorSizeX[1] - 2 * FrameWidth[1]) / 100 + * (DetectorSizeY[1] - 2 * FrameWidth[1]) / 100; + } + fprintf(ifile, "\n"); + + // summary + fprintf(ifile, "%7.2f m2 total surface \n", total_surface); + fprintf(ifile, "%7.2f m2 total active area\n", total_actarea); + fprintf(ifile, "%7.2f m3 total gas volume \n", + total_actarea * gas_thickness / 100); // convert cm to m for thickness + + fprintf(ifile, "%7.2f cm2/ch average channel size\n", 100. * 100 * total_actarea / total_channels[NofModuleTypes]); + fprintf(ifile, "%7.2f ch/m2 channels per m2 active area\n", 1. * total_channels[NofModuleTypes] / total_actarea); + fprintf(ifile, "\n"); + + // gas volume position + fprintf(ifile, "# gas volume position, in TRD local system\n"); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + fprintf(ifile, "%10.4f cm position of gas volume - layer %2d\n", + LayerPosition[iLayer] + LayerThickness / 2. + gas_position, PlaneId[iLayer]); + fprintf(ifile, "\n"); + + fclose(ifile); +} + +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 medFile = geoPath + "/geometry/media.geo"; + geoFace->setMediaFile(medFile); + geoFace->readMedia(); + + // Read the required media and create them in the GeoManager + FairGeoMedia* geoMedia = geoFace->getMedia(); + FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder(); + + FairGeoMedium* air = geoMedia->getMedium(KeepingVolumeMedium); + FairGeoMedium* pefoam20 = geoMedia->getMedium(RadiatorVolumeMedium); + FairGeoMedium* G10 = geoMedia->getMedium(LatticeVolumeMedium); + FairGeoMedium* kapton = geoMedia->getMedium(KaptonVolumeMedium); + FairGeoMedium* trdGas = geoMedia->getMedium(GasVolumeMedium); + FairGeoMedium* copper = geoMedia->getMedium(PadCopperVolumeMedium); + FairGeoMedium* carbon = geoMedia->getMedium(CarbonVolumeMedium); + FairGeoMedium* honeycomb = geoMedia->getMedium(HoneycombVolumeMedium); + FairGeoMedium* aluminium = geoMedia->getMedium(AluminiumVolumeMedium); + + FairGeoMedium* KANYAProfile10x10Strong = geoMedia->getMedium(Kanya10x10sVolumeMedium); + FairGeoMedium* KANYAProfile10x10Normal = geoMedia->getMedium(Kanya10x10nVolumeMedium); + FairGeoMedium* KANYAProfile3x5Normal = geoMedia->getMedium(Kanya03x05nVolumeMedium); + + // FairGeoMedium* goldCoatedCopper = geoMedia->getMedium("goldcoatedcopper"); + // FairGeoMedium* polypropylene = geoMedia->getMedium("polypropylene"); + // FairGeoMedium* mylar = geoMedia->getMedium("mylar"); + + geoBuild->createMedium(air); + geoBuild->createMedium(pefoam20); + geoBuild->createMedium(trdGas); + geoBuild->createMedium(honeycomb); + geoBuild->createMedium(carbon); + geoBuild->createMedium(G10); + geoBuild->createMedium(copper); + geoBuild->createMedium(kapton); + geoBuild->createMedium(aluminium); + + geoBuild->createMedium(KANYAProfile10x10Strong); + geoBuild->createMedium(KANYAProfile10x10Normal); + geoBuild->createMedium(KANYAProfile3x5Normal); + + // geoBuild->createMedium(goldCoatedCopper); + // geoBuild->createMedium(polypropylene); + // geoBuild->createMedium(mylar); +} + +TGeoVolume* create_trd_module_type(Int_t moduleType) +{ + Int_t type = ModuleType[moduleType - 1]; + Double_t sizeX = DetectorSizeX[type]; + Double_t sizeY = DetectorSizeY[type]; + Double_t frameWidth = FrameWidth[type]; + Double_t activeAreaX = sizeX - 2 * frameWidth; + Double_t activeAreaY = sizeY - 2 * frameWidth; + + TGeoMedium* keepVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + TGeoMedium* radVolMed = gGeoMan->GetMedium(RadiatorVolumeMedium); + TGeoMedium* latticeVolMed = gGeoMan->GetMedium(LatticeVolumeMedium); + TGeoMedium* kaptonVolMed = gGeoMan->GetMedium(KaptonVolumeMedium); + TGeoMedium* gasVolMed = gGeoMan->GetMedium(GasVolumeMedium); + TGeoMedium* padcopperVolMed = gGeoMan->GetMedium(PadCopperVolumeMedium); + TGeoMedium* padpcbVolMed = gGeoMan->GetMedium(PadPcbVolumeMedium); + TGeoMedium* honeycombVolMed = gGeoMan->GetMedium(HoneycombVolumeMedium); + TGeoMedium* carbonVolMed = gGeoMan->GetMedium(CarbonVolumeMedium); + // TGeoMedium* mylarVolMed = gGeoMan->GetMedium(MylarVolumeMedium); + // TGeoMedium* electronicsVolMed = + // gGeoMan->GetMedium(ElectronicsVolumeMedium); + TGeoMedium* frameVolMed = gGeoMan->GetMedium(FrameVolumeMedium); + TGeoMedium* aluledgeVolMed = gGeoMan->GetMedium(AluLegdeVolumeMedium); + TGeoMedium* febVolMed = gGeoMan->GetMedium(FebVolumeMedium); + TGeoMedium* asicVolMed = gGeoMan->GetMedium(AsicVolumeMedium); + // TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium); + + TString name = Form("module%d", moduleType); + TGeoVolume* module = new TGeoVolumeAssembly(name); + + if (IncludeRadiator) { + // Radiator + // TGeoBBox* trd_radiator = new TGeoBBox("", activeAreaX /2., activeAreaY + // /2., radiator_thickness /2.); + TGeoBBox* trd_radiator = new TGeoBBox("trd_radiator", sizeX / 2., sizeY / 2., radiator_thickness / 2.); + TGeoVolume* trdmod1_radvol = new TGeoVolume("radiator", trd_radiator, radVolMed); + // TGeoVolume* trdmod1_radvol = new TGeoVolume(Form("module%d_radiator", + // moduleType), trd_radiator, radVolMed); + // TGeoVolume* trdmod1_radvol = new TGeoVolume(Form("trd1mod%dradiator", + // moduleType), trd_radiator, radVolMed); + trdmod1_radvol->SetLineColor(kBlue); + trdmod1_radvol->SetTransparency(70); // (60); // (70); // set transparency for the TRD radiator + TGeoTranslation* trd_radiator_trans = new TGeoTranslation("", 0., 0., radiator_position); + module->AddNode(trdmod1_radvol, 1, trd_radiator_trans); + } + + // Lattice grid + if (IncludeLattice) { + + if (type == 0) // inner modules + { + // printf("lattice type %d\n", type); + // drift window - lattice grid - sprossenfenster + TGeoBBox* trd_lattice_mod0_ho = new TGeoBBox("trd_lattice_mod0_ho", sizeX / 2., lattice_o_width[type] / 2., + lattice_thickness / 2.); // horizontal outer + TGeoBBox* trd_lattice_mod0_hi = + new TGeoBBox("trd_lattice_mod0_hi", sizeX / 2. - lattice_o_width[type], lattice_i_width[type] / 2., + lattice_thickness / 2.); // horizontal inner + TGeoBBox* trd_lattice_mod0_vo = + new TGeoBBox("trd_lattice_mod0_vo", lattice_o_width[type] / 2., sizeX / 2. - lattice_o_width[type], + lattice_thickness / 2.); // vertical outer + TGeoBBox* trd_lattice_mod0_vi = new TGeoBBox("trd_lattice_mod0_vi", lattice_i_width[type] / 2., + 0.20 * activeAreaY / 2. - lattice_i_width[type] / 2., + lattice_thickness / 2.); // vertical inner + TGeoBBox* trd_lattice_mod0_vb = new TGeoBBox("trd_lattice_mod0_vb", lattice_i_width[type] / 2., + 0.20 * activeAreaY / 2. - lattice_i_width[type] / 4., + lattice_thickness / 2.); // vertical border + + TGeoVolume* trd_lattice_mod0_vol_ho = new TGeoVolume("lattice0ho", trd_lattice_mod0_ho, latticeVolMed); + TGeoVolume* trd_lattice_mod0_vol_hi = new TGeoVolume("lattice0hi", trd_lattice_mod0_hi, latticeVolMed); + TGeoVolume* trd_lattice_mod0_vol_vo = new TGeoVolume("lattice0vo", trd_lattice_mod0_vo, latticeVolMed); + TGeoVolume* trd_lattice_mod0_vol_vi = new TGeoVolume("lattice0vi", trd_lattice_mod0_vi, latticeVolMed); + TGeoVolume* trd_lattice_mod0_vol_vb = new TGeoVolume("lattice0vb", trd_lattice_mod0_vb, latticeVolMed); + + trd_lattice_mod0_vol_ho->SetLineColor(kYellow); // kBlue); + trd_lattice_mod0_vol_vo->SetLineColor(kYellow); // kOrange); + trd_lattice_mod0_vol_hi->SetLineColor(kYellow); // kRed); + trd_lattice_mod0_vol_vi->SetLineColor(kYellow); // kWhite); + trd_lattice_mod0_vol_vb->SetLineColor(kYellow); + + TGeoTranslation* tv010 = + new TGeoTranslation("tv010", 0., (1.00 * activeAreaY / 2. + lattice_o_width[type] / 2.), 0); + TGeoTranslation* tv015 = + new TGeoTranslation("tv015", 0., -(1.00 * activeAreaY / 2. + lattice_o_width[type] / 2.), 0); + + TGeoTranslation* th020 = + new TGeoTranslation("th020", (1.00 * activeAreaX / 2. + lattice_o_width[type] / 2.), 0., 0); + TGeoTranslation* th025 = + new TGeoTranslation("th025", -(1.00 * activeAreaX / 2. + lattice_o_width[type] / 2.), 0., 0); + + Double_t hypos0[4] = {(0.60 * activeAreaY / 2.), (0.20 * activeAreaY / 2.), -(0.20 * activeAreaY / 2.), + -(0.60 * activeAreaY / 2.)}; + + Double_t vxpos0[4] = {(0.60 * activeAreaX / 2.), (0.20 * activeAreaX / 2.), -(0.20 * activeAreaX / 2.), + -(0.60 * activeAreaX / 2.)}; + + Double_t vypos0[5] = {(0.80 * activeAreaY / 2. + lattice_i_width[type] / 4.), (0.40 * activeAreaY / 2.), + (0.00 * activeAreaY / 2.), -(0.40 * activeAreaY / 2.), + -(0.80 * activeAreaY / 2. + lattice_i_width[type] / 4.)}; + + // TGeoVolumeAssembly* trdmod0_lattice = new + // TGeoVolumeAssembly("mod0lattice"); // volume for lattice grid + + TGeoBBox* trd_lattice_mod0 = new TGeoBBox("trd_lattice_mod0", sizeX / 2., sizeY / 2., lattice_thickness / 2.); + TGeoVolume* trdmod0_lattice = new TGeoVolume("lat_grid_mod0", trd_lattice_mod0, keepVolMed); + + // trdmod0_lattice->SetLineColor(kGreen); // set color for keeping + // volume + + // outer frame + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_ho, 1, tv010); + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_ho, 2, tv015); + + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vo, 3, th020); + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vo, 4, th025); + + // lattice piece number + Int_t lat0_no = 5; + + // horizontal bars + for (Int_t y = 0; y < 4; y++) { + TGeoTranslation* t0xy = new TGeoTranslation("", 0, hypos0[y], 0); + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_hi, lat0_no, t0xy); + lat0_no++; + } + + // vertical bars + for (Int_t x = 0; x < 4; x++) + for (Int_t y = 0; y < 5; y++) { + TGeoTranslation* t0xy = new TGeoTranslation("", vxpos0[x], vypos0[y], 0); + if ((y == 0) || (y == 4)) trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vb, lat0_no, + t0xy); // border piece + else + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vi, lat0_no, + t0xy); // middle piece + lat0_no++; + } + + // add lattice to module + TGeoTranslation* trd_lattice_trans = new TGeoTranslation("", 0., 0., lattice_position); + module->AddNode(trdmod0_lattice, 1, trd_lattice_trans); + } + + else if (type == 1) // outer modules + { + // printf("lattice type %d\n", type); + // drift window - lattice grid - sprossenfenster + TGeoBBox* trd_lattice_mod1_ho = new TGeoBBox("trd_lattice_mod1_ho", sizeX / 2., lattice_o_width[type] / 2., + lattice_thickness / 2.); // horizontal outer + TGeoBBox* trd_lattice_mod1_hi = + new TGeoBBox("trd_lattice_mod1_hi", sizeX / 2. - lattice_o_width[type], lattice_i_width[type] / 2., + lattice_thickness / 2.); // horizontal inner + TGeoBBox* trd_lattice_mod1_vo = + new TGeoBBox("trd_lattice_mod1_vo", lattice_o_width[type] / 2., sizeX / 2. - lattice_o_width[type], + lattice_thickness / 2.); // vertical outer + TGeoBBox* trd_lattice_mod1_vi = new TGeoBBox("trd_lattice_mod1_vi", lattice_i_width[type] / 2., + 0.125 * activeAreaY / 2. - lattice_i_width[type] / 2., + lattice_thickness / 2.); // vertical inner + TGeoBBox* trd_lattice_mod1_vb = new TGeoBBox("trd_lattice_mod1_vb", lattice_i_width[type] / 2., + 0.125 * activeAreaY / 2. - lattice_i_width[type] / 4., + lattice_thickness / 2.); // vertical border + + TGeoVolume* trd_lattice_mod1_vol_ho = new TGeoVolume("lattice1ho", trd_lattice_mod1_ho, latticeVolMed); + TGeoVolume* trd_lattice_mod1_vol_hi = new TGeoVolume("lattice1hi", trd_lattice_mod1_hi, latticeVolMed); + TGeoVolume* trd_lattice_mod1_vol_vo = new TGeoVolume("lattice1vo", trd_lattice_mod1_vo, latticeVolMed); + TGeoVolume* trd_lattice_mod1_vol_vi = new TGeoVolume("lattice1vi", trd_lattice_mod1_vi, latticeVolMed); + TGeoVolume* trd_lattice_mod1_vol_vb = new TGeoVolume("lattice1vb", trd_lattice_mod1_vb, latticeVolMed); + + trd_lattice_mod1_vol_ho->SetLineColor(kYellow); // kBlue); + trd_lattice_mod1_vol_vo->SetLineColor(kYellow); // kOrange); + trd_lattice_mod1_vol_hi->SetLineColor(kYellow); // kRed); + trd_lattice_mod1_vol_vi->SetLineColor(kYellow); // kWhite); + trd_lattice_mod1_vol_vb->SetLineColor(kYellow); + + TGeoTranslation* tv110 = + new TGeoTranslation("tv110", 0., (1.00 * activeAreaY / 2. + lattice_o_width[type] / 2.), 0); + TGeoTranslation* tv118 = + new TGeoTranslation("tv118", 0., -(1.00 * activeAreaY / 2. + lattice_o_width[type] / 2.), 0); + + TGeoTranslation* th120 = + new TGeoTranslation("th120", (1.00 * activeAreaX / 2. + lattice_o_width[type] / 2.), 0., 0); + TGeoTranslation* th128 = + new TGeoTranslation("th128", -(1.00 * activeAreaX / 2. + lattice_o_width[type] / 2.), 0., 0); + + Double_t hypos1[7] = {(0.75 * activeAreaY / 2.), (0.50 * activeAreaY / 2.), (0.25 * activeAreaY / 2.), + (0.00 * activeAreaY / 2.), -(0.25 * activeAreaY / 2.), -(0.50 * activeAreaY / 2.), + -(0.75 * activeAreaY / 2.)}; + + Double_t vxpos1[7] = {(0.75 * activeAreaX / 2.), (0.50 * activeAreaX / 2.), (0.25 * activeAreaX / 2.), + (0.00 * activeAreaX / 2.), -(0.25 * activeAreaX / 2.), -(0.50 * activeAreaX / 2.), + -(0.75 * activeAreaX / 2.)}; + + Double_t vypos1[8] = {(0.875 * activeAreaY / 2. + lattice_i_width[type] / 4.), + (0.625 * activeAreaY / 2.), + (0.375 * activeAreaY / 2.), + (0.125 * activeAreaY / 2.), + -(0.125 * activeAreaY / 2.), + -(0.375 * activeAreaY / 2.), + -(0.625 * activeAreaY / 2.), + -(0.875 * activeAreaY / 2. + lattice_i_width[type] / 4.)}; + + // TGeoVolumeAssembly* trdmod1_lattice = new + // TGeoVolumeAssembly("mod1lattice"); // volume for lattice grid + + TGeoBBox* trd_lattice_mod1 = new TGeoBBox("trd_lattice_mod1", sizeX / 2., sizeY / 2., lattice_thickness / 2.); + TGeoVolume* trdmod1_lattice = new TGeoVolume("lat_grid_mod1", trd_lattice_mod1, keepVolMed); + + // trdmod1_lattice->SetLineColor(kGreen); // set color for keeping + // volume + + // outer frame + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_ho, 1, tv110); + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_ho, 2, tv118); + + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vo, 3, th120); + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vo, 4, th128); + + // lattice piece number + Int_t lat1_no = 5; + + // horizontal bars + for (Int_t y = 0; y < 7; y++) { + TGeoTranslation* t1xy = new TGeoTranslation("", 0, hypos1[y], 0); + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_hi, lat1_no, t1xy); + lat1_no++; + } + + // vertical bars + for (Int_t x = 0; x < 7; x++) + for (Int_t y = 0; y < 8; y++) { + TGeoTranslation* t1xy = new TGeoTranslation("", vxpos1[x], vypos1[y], 0); + if ((y == 0) || (y == 7)) trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vb, lat1_no, + t1xy); // border piece + else + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vi, lat1_no, + t1xy); // middle piece + lat1_no++; + } + + // add lattice to module + TGeoTranslation* trd_lattice_trans = new TGeoTranslation("", 0., 0., lattice_position); + module->AddNode(trdmod1_lattice, 1, trd_lattice_trans); + } + + } // with lattice grid + + if (IncludeKaptonFoil) { + // Kapton Foil + TGeoBBox* trd_kapton = new TGeoBBox("trd_kapton", sizeX / 2., sizeY / 2., kapton_thickness / 2.); + TGeoVolume* trdmod1_kaptonvol = new TGeoVolume("kaptonfoil", trd_kapton, kaptonVolMed); + // TGeoVolume* trdmod1_kaptonvol = new + // TGeoVolume(Form("module%d_kaptonfoil", moduleType), trd_kapton, + // kaptonVolMed); + // TGeoVolume* trdmod1_kaptonvol = new TGeoVolume(Form("trd1mod%dkapton", + // moduleType), trd_kapton, kaptonVolMed); + trdmod1_kaptonvol->SetLineColor(kGreen); + TGeoTranslation* trd_kapton_trans = new TGeoTranslation("", 0., 0., kapton_position); + module->AddNode(trdmod1_kaptonvol, 1, trd_kapton_trans); + } + + // start of Frame in z + // Gas + TGeoBBox* trd_gas = new TGeoBBox("trd_gas", activeAreaX / 2., activeAreaY / 2., gas_thickness / 2.); + TGeoVolume* trdmod1_gasvol = new TGeoVolume("gas", trd_gas, gasVolMed); + // TGeoVolume* trdmod1_gasvol = new TGeoVolume(Form("module%d_gas", + // moduleType), trd_gas, gasVolMed); + // TGeoVolume* trdmod1_gasvol = new TGeoVolume(Form("trd1mod%dgas", + // moduleType), trd_gas, gasVolMed); + // trdmod1_gasvol->SetLineColor(kBlue); + trdmod1_gasvol->SetLineColor(kGreen); // to avoid blue overlaps in the screenshots + trdmod1_gasvol->SetTransparency(40); // set transparency for the TRD gas + TGeoTranslation* trd_gas_trans = new TGeoTranslation("", 0., 0., gas_position); + module->AddNode(trdmod1_gasvol, 1, trd_gas_trans); + // end of Frame in z + + if (IncludeGasFrame) { + // frame1 + TGeoBBox* trd_frame1 = new TGeoBBox("trd_frame1", sizeX / 2., frameWidth / 2., frame_thickness / 2.); + TGeoVolume* trdmod1_frame1vol = new TGeoVolume("frame1", trd_frame1, frameVolMed); + trdmod1_frame1vol->SetLineColor(kRed); + + // translations + TGeoTranslation* trd_frame1_trans = new TGeoTranslation("", 0., activeAreaY / 2. + frameWidth / 2., frame_position); + module->AddNode(trdmod1_frame1vol, 1, trd_frame1_trans); + trd_frame1_trans = new TGeoTranslation("", 0., -(activeAreaY / 2. + frameWidth / 2.), frame_position); + module->AddNode(trdmod1_frame1vol, 2, trd_frame1_trans); + + // frame2 + TGeoBBox* trd_frame2 = new TGeoBBox("trd_frame2", frameWidth / 2., activeAreaY / 2., frame_thickness / 2.); + TGeoVolume* trdmod1_frame2vol = new TGeoVolume("frame2", trd_frame2, frameVolMed); + trdmod1_frame2vol->SetLineColor(kRed); + + // translations + TGeoTranslation* trd_frame2_trans = new TGeoTranslation("", activeAreaX / 2. + frameWidth / 2., 0., frame_position); + module->AddNode(trdmod1_frame2vol, 1, trd_frame2_trans); + trd_frame2_trans = new TGeoTranslation("", -(activeAreaX / 2. + frameWidth / 2.), 0., frame_position); + module->AddNode(trdmod1_frame2vol, 2, trd_frame2_trans); + } + + if (IncludePadplane) { + // Pad Copper + TGeoBBox* trd_padcopper = new TGeoBBox("trd_padcopper", sizeX / 2., sizeY / 2., padcopper_thickness / 2.); + TGeoVolume* trdmod1_padcoppervol = new TGeoVolume("padcopper", trd_padcopper, padcopperVolMed); + // TGeoVolume* trdmod1_padcoppervol = new + // TGeoVolume(Form("module%d_padcopper", moduleType), trd_padcopper, + // padcopperVolMed); + // TGeoVolume* trdmod1_padcoppervol = new + // TGeoVolume(Form("trd1mod%dpadcopper", moduleType), trd_padcopper, + // padcopperVolMed); + trdmod1_padcoppervol->SetLineColor(kOrange); + TGeoTranslation* trd_padcopper_trans = new TGeoTranslation("", 0., 0., padcopper_position); + module->AddNode(trdmod1_padcoppervol, 1, trd_padcopper_trans); + + // Pad Plane + TGeoBBox* trd_padpcb = new TGeoBBox("trd_padpcb", sizeX / 2., sizeY / 2., padplane_thickness / 2.); + TGeoVolume* trdmod1_padpcbvol = new TGeoVolume("padplane", trd_padpcb, padpcbVolMed); + // TGeoVolume* trdmod1_padpcbvol = new + // TGeoVolume(Form("module%d_padplane", moduleType), trd_padpcb, + // padpcbVolMed); + // TGeoVolume* trdmod1_padpcbvol = new + // TGeoVolume(Form("trd1mod%dpadplane", moduleType), trd_padpcb, + // padpcbVolMed); + trdmod1_padpcbvol->SetLineColor(kBlue); + TGeoTranslation* trd_padpcb_trans = new TGeoTranslation("", 0., 0., padplane_position); + module->AddNode(trdmod1_padpcbvol, 1, trd_padpcb_trans); + } + + if (IncludeBackpanel) { + // Honeycomb + TGeoBBox* trd_honeycomb = new TGeoBBox("trd_honeycomb", sizeX / 2., sizeY / 2., honeycomb_thickness / 2.); + TGeoVolume* trdmod1_honeycombvol = new TGeoVolume("honeycomb", trd_honeycomb, honeycombVolMed); + // TGeoVolume* trdmod1_honeycombvol = new + // TGeoVolume(Form("module%d_honeycomb", moduleType), trd_honeycomb, + // honeycombVolMed); + // TGeoVolume* trdmod1_honeycombvol = new + // TGeoVolume(Form("trd1mod%dhoneycomb", moduleType), trd_honeycomb, + // honeycombVolMed); + trdmod1_honeycombvol->SetLineColor(kOrange); + TGeoTranslation* trd_honeycomb_trans = new TGeoTranslation("", 0., 0., honeycomb_position); + module->AddNode(trdmod1_honeycombvol, 1, trd_honeycomb_trans); + + // Carbon fiber layers + TGeoBBox* trd_carbon = new TGeoBBox("trd_carbon", sizeX / 2., sizeY / 2., carbon_thickness / 2.); + TGeoVolume* trdmod1_carbonvol = new TGeoVolume("carbonsheet", trd_carbon, carbonVolMed); + // TGeoVolume* trdmod1_carbonvol = new + // TGeoVolume(Form("module%d_carbonsheet", moduleType), trd_carbon, + // carbonVolMed); + // TGeoVolume* trdmod1_carbonvol = new TGeoVolume(Form("trd1mod%dcarbon", + // moduleType), trd_carbon, carbonVolMed); + trdmod1_carbonvol->SetLineColor(kGreen); + TGeoTranslation* trd_carbon_trans = new TGeoTranslation("", 0., 0., carbon_position); + module->AddNode(trdmod1_carbonvol, 1, trd_carbon_trans); + } + + if (IncludeAluLedge) { + // Al-ledge + TGeoBBox* trd_aluledge1 = new TGeoBBox("trd_aluledge1", sizeY / 2., aluminium_width / 2., aluminium_thickness / 2.); + TGeoVolume* trdmod1_aluledge1vol = new TGeoVolume("aluledge1", trd_aluledge1, aluledgeVolMed); + trdmod1_aluledge1vol->SetLineColor(kRed); + + // translations + TGeoTranslation* trd_aluledge1_trans = + new TGeoTranslation("", 0., sizeY / 2. - aluminium_width / 2., aluminium_position); + module->AddNode(trdmod1_aluledge1vol, 1, trd_aluledge1_trans); + trd_aluledge1_trans = new TGeoTranslation("", 0., -(sizeY / 2. - aluminium_width / 2.), aluminium_position); + module->AddNode(trdmod1_aluledge1vol, 2, trd_aluledge1_trans); + + // Al-ledge + TGeoBBox* trd_aluledge2 = + new TGeoBBox("trd_aluledge2", aluminium_width / 2., sizeY / 2. - aluminium_width, aluminium_thickness / 2.); + TGeoVolume* trdmod1_aluledge2vol = new TGeoVolume("aluledge2", trd_aluledge2, aluledgeVolMed); + trdmod1_aluledge2vol->SetLineColor(kRed); + + // translations + TGeoTranslation* trd_aluledge2_trans = + new TGeoTranslation("", sizeX / 2. - aluminium_width / 2., 0., aluminium_position); + module->AddNode(trdmod1_aluledge2vol, 1, trd_aluledge2_trans); + trd_aluledge2_trans = new TGeoTranslation("", -(sizeX / 2. - aluminium_width / 2.), 0., aluminium_position); + module->AddNode(trdmod1_aluledge2vol, 2, trd_aluledge2_trans); + } + + // FEBs + if (IncludeFebs) { + // assemblies + TGeoVolumeAssembly* trd_feb_vol = new TGeoVolumeAssembly("febvol"); // the mother volume of all FEBs + TGeoVolumeAssembly* trd_feb_box = + new TGeoVolumeAssembly("febbox"); // volume for inclined FEBs, then shifted along y + // TGeoVolumeAssembly* trd_feb_vol = new + // TGeoVolumeAssembly(Form("module%d_febvol", moduleType)); // the mother + // volume of all FEBs + // TGeoVolumeAssembly* trd_feb_box = new + // TGeoVolumeAssembly(Form("module%d_febbox", moduleType)); // volume for + // inclined FEBs, then shifted along y + // TGeoVolumeAssembly* trd_feb_vol = new + // TGeoVolumeAssembly(Form("trd1mod%dfebvol", moduleType)); // the mother + // volume of all FEBs + // TGeoVolumeAssembly* trd_feb_box = new + // TGeoVolumeAssembly(Form("trd1mod%dfebbox", moduleType)); // volume for + // inclined FEBs, then shifted along y + + // translations + rotations + TGeoTranslation* trd_feb_trans1; // center to corner + TGeoTranslation* trd_feb_trans2; // corner back + TGeoRotation* trd_feb_rotation; // rotation around x axis + TGeoTranslation* trd_feb_y_position; // shift to y position on TRD + // TGeoTranslation *trd_feb_null; // no displacement + + // replaced by matrix operation (see below) + // // Double_t yback, zback; + // // TGeoCombiTrans *trd_feb_placement; + // // // fix Z back offset 0.3 at some point + // // yback = - sin(feb_rotation_angle/180*3.141) * feb_width /2.; + // // zback = - (1-cos(feb_rotation_angle/180*3.141)) * feb_width /2. + // + 0.3; + // // trd_feb_placement = new TGeoCombiTrans(0, feb_pos_y + yback, + // zback, trd_feb_rotation); + // // trd_feb_box->AddNode(trdmod1_feb, iFeb+1, trd_feb_placement); + + // trd_feb_null = new TGeoTranslation("", 0., 0., 0.); // empty + // operation + trd_feb_trans1 = new TGeoTranslation("", 0., -feb_thickness / 2., + -feb_width / 2.); // move bottom right corner to center + trd_feb_trans2 = new TGeoTranslation("", 0., feb_thickness / 2., + feb_width / 2.); // move bottom right corner back + trd_feb_rotation = new TGeoRotation(); + trd_feb_rotation->RotateX(feb_rotation_angle[moduleType - 1]); + + TGeoHMatrix* incline_feb = new TGeoHMatrix(""); + + // (*incline_feb) = (*trd_feb_null); // OK + // (*incline_feb) = (*trd_feb_y_position); // OK + // (*incline_feb) = (*trd_feb_trans1); // OK + // (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_y_position); // OK + // (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_trans2); // OK + // (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_rotation); // OK + // (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_rotation) * + // (*trd_feb_trans2) * (*trd_feb_y_position); // not OK + // trd_feb_y_position is displaced in rotated coordinate system + + // matrix operation to rotate FEB PCB around its corner on the backanel + (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_rotation) * (*trd_feb_trans2); // OK + + // Create all FEBs and place them in an assembly which will be added to the + // TRD module + TGeoBBox* trd_feb = new TGeoBBox("trd_feb", activeAreaX / 2., feb_thickness / 2., + feb_width / 2.); // the FEB itself - as a cuboid + TGeoVolume* trdmod1_feb = new TGeoVolume("feb", trd_feb, febVolMed); // the FEB made of a certain medium + // TGeoVolume* trdmod1_feb = new TGeoVolume(Form("module%d_feb", + // moduleType), trd_feb, febVolMed); // the FEB made of a certain + // medium + // TGeoVolume* trdmod1_feb = new TGeoVolume(Form("trd1mod%dfeb", + // moduleType), trd_feb, febVolMed); // the FEB made of a certain + // medium + trdmod1_feb->SetLineColor(kYellow); // set yellow color + trd_feb_box->AddNode(trdmod1_feb, 1, incline_feb); + // now we have an inclined FEB + + // ASICs + if (IncludeAsics) { + Double_t asic_pos; + Double_t asic_pos_x; + TGeoTranslation* trd_asic_trans0; // ASIC on FEB x position + TGeoTranslation* trd_asic_trans1; // center to corner + TGeoTranslation* trd_asic_trans2; // corner back + TGeoRotation* trd_asic_rotation; // rotation around x axis + + trd_asic_trans1 = new TGeoTranslation("", 0., -(feb_thickness + asic_offset + asic_thickness / 2.), + -feb_width / 2.); // move ASIC center to FEB corner + trd_asic_trans2 = new TGeoTranslation("", 0., feb_thickness + asic_offset + asic_thickness / 2., + feb_width / 2.); // move FEB corner back to asic center + trd_asic_rotation = new TGeoRotation(); + trd_asic_rotation->RotateX(feb_rotation_angle[moduleType - 1]); + + TGeoHMatrix* incline_asic; + + // put many ASICs on each inclined FEB + TGeoBBox* trd_asic = new TGeoBBox("trd_asic", asic_width / 2., asic_thickness / 2., + asic_width / 2.); // ASIC dimensions + // TODO: use Silicon as ASICs material + TGeoVolume* trdmod1_asic = new TGeoVolume("asic", trd_asic, asicVolMed); // the ASIC made of a certain medium + // TGeoVolume* trdmod1_asic = new TGeoVolume(Form("module%d_asic", + // moduleType), trd_asic, asicVolMed); // the ASIC made of a + // certain medium + // TGeoVolume* trdmod1_asic = new TGeoVolume(Form("trd1mod%dasic", + // moduleType), trd_asic, asicVolMed); // the ASIC made of a + // certain medium + trdmod1_asic->SetLineColor(kBlue); // set blue color for ASICs + + Int_t nofAsics = AsicsPerFeb[moduleType - 1] % 100; + Int_t groupAsics = AsicsPerFeb[moduleType - 1] / 100; // either 1 or 2 or 3 (new ultimate) + + if ((nofAsics == 16) && (activeAreaX < 60)) asic_distance = 0.0; // for 57 cm // 0.1; // for 60 cm + else + asic_distance = 0.4; + + for (Int_t iAsic = 0; iAsic < (nofAsics / groupAsics); iAsic++) { + if (groupAsics == 1) // single ASICs + { + asic_pos = (iAsic + 0.5) / nofAsics - 0.5; // equal spacing of ASICs + // on the FEB, e.g. for + // no=3 : -1/3, 0, +1/3 + + // ASIC 1 + asic_pos_x = asic_pos * activeAreaX; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness / 2. + asic_thickness / 2. + asic_offset, + 0.); // move asic on top of FEB + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, iAsic + 1, + incline_asic); // now we have ASICs on the inclined FEB + } + + if (groupAsics == 2) // pairs of ASICs + { + asic_pos = + (iAsic + 0.5) / (nofAsics / groupAsics) - 0.5; // equal spacing of ASICs on the FEB, e.g. for no=3 : + // -1/3, 0, +1/3 + + // ASIC 1 + asic_pos_x = asic_pos * activeAreaX + (0.5 + asic_distance / 2.) * asic_width; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness / 2. + asic_thickness / 2. + asic_offset, + 0.); // move asic on top of FEB); + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, 2 * iAsic + 1, + incline_asic); // now we have ASICs on the inclined FEB + + // ASIC 2 + asic_pos_x = asic_pos * activeAreaX - (0.5 + asic_distance / 2.) * asic_width; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness / 2. + asic_thickness / 2. + asic_offset, + 0.); // move asic on top of FEB + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, 2 * iAsic + 2, + incline_asic); // now we have ASICs on the inclined FEB + } + + if (groupAsics == 3) // triplets of ASICs + { + asic_pos = + (iAsic + 0.5) / (nofAsics / groupAsics) - 0.5; // equal spacing of ASICs on the FEB, e.g. for no=3 : + // -1/3, 0, +1/3 + + // ASIC 1 + asic_pos_x = asic_pos * activeAreaX + 1.1 * asic_width; // (0.5 + asic_distance/2.) * asic_width; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness / 2. + asic_thickness / 2. + asic_offset, + 0.); // move asic on top of FEB); + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, 3 * iAsic + 1, + incline_asic); // now we have ASICs on the inclined FEB + + // ASIC 2 + asic_pos_x = asic_pos * activeAreaX; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness / 2. + asic_thickness / 2. + asic_offset, + 0.); // move asic on top of FEB + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, 3 * iAsic + 2, + incline_asic); // now we have ASICs on the inclined FEB + + // ASIC 3 + asic_pos_x = asic_pos * activeAreaX - 1.1 * asic_width; // (0.5 + asic_distance/2.) * asic_width; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness / 2. + asic_thickness / 2. + asic_offset, + 0.); // move asic on top of FEB + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, 3 * iAsic + 3, + incline_asic); // now we have ASICs on the inclined FEB + } + } + // now we have an inclined FEB with ASICs + } + + // now go on with FEB placement + Double_t feb_pos; + Double_t feb_pos_y; + + Int_t nofFebs = FebsPerModule[moduleType - 1]; + for (Int_t iFeb = 0; iFeb < nofFebs; iFeb++) { + feb_pos = (iFeb + 0.5) / nofFebs - 0.5; // equal spacing of FEBs on the backpanel + // cout << "feb_pos " << iFeb << ": " << feb_pos << endl; + feb_pos_y = feb_pos * activeAreaY; + feb_pos_y += feb_width / 2. * sin(feb_rotation_angle[moduleType - 1] * acos(-1.) / 180.); + + // shift inclined FEB in y to its final position + trd_feb_y_position = new TGeoTranslation("", 0., feb_pos_y, + feb_z_offset); // with additional fixed offset in z direction + // trd_feb_y_position = new TGeoTranslation("", 0., feb_pos_y, + // 0.0); // touching the backpanel with the corner + trd_feb_vol->AddNode(trd_feb_box, iFeb + 1, + trd_feb_y_position); // position FEB in y + } + + if (IncludeRobs1D) { + // GBTx ROBs + Double_t rob_size_x = 20.0; // 13.0; // 130 mm + Double_t rob_size_y = 9.0; // 4.5; // 45 mm + Double_t rob_offset = 1.2; + Double_t rob_thickness = feb_thickness; + + TGeoVolumeAssembly* trd_rob_box = + new TGeoVolumeAssembly("robbox"); // volume for inclined FEBs, then shifted along y + TGeoBBox* trd_rob = new TGeoBBox("trd_rob", rob_size_x / 2., rob_size_y / 2., + rob_thickness / 2.); // the ROB itself + TGeoVolume* trdmod1_rob = new TGeoVolume("rob", trd_rob, febVolMed); // the ROB made of a certain medium + trdmod1_rob->SetLineColor(kRed); // set color + + // TGeoHMatrix *incline_rob = new TGeoHMatrix(""); + trd_rob_box->AddNode(trdmod1_rob, 1); + + // GBTXs + Double_t gbtx_pos; + Double_t gbtx_pos_x; + Double_t gbtx_pos_y; + TGeoTranslation* trd_gbtx_trans1; // center to corner + + // GBTX parameters + const Double_t gbtx_thickness = 0.25; // 2.5 mm + const Double_t gbtx_width = 3.0; // 2.0; 1.0; // 1 cm + + // put many GBTXs on each inclined FEB + TGeoBBox* trd_gbtx = new TGeoBBox("trd_gbtx", gbtx_width / 2., gbtx_width / 2., + gbtx_thickness / 2.); // GBTX dimensions + TGeoVolume* trdmod1_gbtx = new TGeoVolume("gbtx", trd_gbtx, asicVolMed); // the GBTX made of a certain medium + trdmod1_gbtx->SetLineColor(kGreen); // set color for GBTXs + + Int_t nofGbtxs = GbtxPerRob[moduleType - 1] % 100; + Int_t groupGbtxs = GbtxPerRob[moduleType - 1] / 100; // usually 1 + + // nofGbtxs = 7; + // groupGbtxs = 1; + + Int_t nofGbtxX = (nofGbtxs - 1) / 2. + 1; // +1 is for GBTx master + Int_t nofGbtxY = 2; + + Double_t gbtx_distance = 0.4; + Int_t iGbtx = 1; + + for (Int_t iGbtxX = 0; iGbtxX < nofGbtxX; iGbtxX++) { + gbtx_pos = (iGbtxX + 0.5) / nofGbtxX - 0.5; // equal spacing of GBTXs on + // the FEB, e.g. for no=3 : + // -1/3, 0, +1/3 + gbtx_pos_x = -gbtx_pos * rob_size_x; + + if (iGbtxX > 0) + for (Int_t iGbtxY = 0; iGbtxY < nofGbtxY; iGbtxY++) { + gbtx_pos = (iGbtxY + 0.5) / nofGbtxY - 0.5; // equal spacing of + // GBTXs on the FEB, + // e.g. for no=3 : -1/3, + // 0, +1/3 + gbtx_pos_y = gbtx_pos * rob_size_y; + + trd_gbtx_trans1 = new TGeoTranslation("", gbtx_pos_x, gbtx_pos_y, + rob_thickness / 2. + gbtx_thickness / 2.); // move gbtx on top of ROB + trd_rob_box->AddNode(trdmod1_gbtx, iGbtx++, + trd_gbtx_trans1); // now we have GBTXs on the ROB + } + else { + gbtx_pos_y = 0; + + trd_gbtx_trans1 = new TGeoTranslation("", gbtx_pos_x, gbtx_pos_y, + rob_thickness / 2. + gbtx_thickness / 2.); // move gbtx on top of ROB + trd_rob_box->AddNode(trdmod1_gbtx, iGbtx++, + trd_gbtx_trans1); // now we have GBTXs on the ROB + } + } + + // now go on with ROB placement + Double_t rob_pos; + Double_t rob_pos_y; + TGeoTranslation* trd_rob_y_position; // shift to y position on TRD + + Int_t nofRobs = RobsPerModule[moduleType - 1]; + for (Int_t iRob = 0; iRob < nofRobs; iRob++) { + rob_pos = (iRob + 0.5) / nofRobs - 0.5; // equal spacing of ROBs on the backpanel + rob_pos_y = rob_pos * activeAreaY; + + // shift inclined ROB in y to its final position + if (feb_rotation_angle[moduleType - 1] == 90) // if FEB parallel to backpanel + trd_rob_y_position = new TGeoTranslation("", 0., rob_pos_y, + -feb_width / 2. + rob_offset); // place ROBs close to FEBs + else { + // Int_t rob_z_pos = 0.; // test where ROB is placed by + // default + Int_t rob_z_pos = + -feb_width / 2. + feb_width * cos(feb_rotation_angle[moduleType - 1] * acos(-1.) / 180.) + rob_offset; + if (rob_z_pos > feb_width / 2.) // if the rob is too far out + { + rob_z_pos = feb_width / 2. - rob_thickness; // place ROBs at end of feb volume + std::cout << "GBTx ROB was outside of the FEB volume, check " + "overlap with FEB" + << std::endl; + } + trd_rob_y_position = new TGeoTranslation("", 0., rob_pos_y, rob_z_pos); + } + trd_feb_vol->AddNode(trd_rob_box, iRob + 1, + trd_rob_y_position); // position FEB in y + } + + } // IncludeGbtx + + // put FEB box on module + TGeoTranslation* trd_febvolume_trans = new TGeoTranslation("", 0., 0., febvolume_position); + gGeoMan->GetVolume(name)->AddNode(trd_feb_vol, 1, + trd_febvolume_trans); // put febvolume at + // correct z + // position wrt to + // the module + } + + // DE123 + + return module; +} + +//________________________________________________________________________________________________ +// TRD Bucharest module definition +TGeoTranslation* tr(NULL); +TString sexpr; +void addFlatCableHoles(const Char_t* name) +{ + printf("addFlatCableHoles(%s)\n", name); + sexpr = name; + sexpr += "_bd"; + for (Int_t c(0); c < 9; c++) { + printf("c[%d]\n", c); + for (Int_t r(0); r < 10; r++) { + printf("r[%d]\n", r); + tr = new TGeoTranslation(Form("t%s%d%02d", name, c, r), (c - 4) * 6, 1.35 + 2.7 * r, 0.); + tr->RegisterYourself(); + sexpr += Form("-%s_fc:t%s%d%02d", name, name, c, r); + } + for (Int_t r(10); r < 20; r++) { + printf("r[%d]\n", r); + tr = new TGeoTranslation(Form("t%s%d%02d", name, c, r), (c - 4) * 6, -1.35 - 2.7 * (r - 10), 0.); + tr->RegisterYourself(); + sexpr += Form("-%s_fc:t%s%d%02d", name, name, c, r); + } + } +} + +TGeoVolume* create_trd2d_module_type(Int_t moduleType) +{ + Info("create_trd2d_module_type", "Bulding Bucharest Module [%s].", moduleType == 9 ? "TRD2D" : "TRD-2DH"); + Int_t detTypeIdx = moduleType == 9 ? 2 : 3; + Double_t sizeX = DetectorSizeX[detTypeIdx]; + Double_t sizeY = DetectorSizeY[detTypeIdx]; + Double_t frameWidth = FrameWidth[detTypeIdx]; + Double_t activeAreaX = sizeX - 2 * frameWidth; + Double_t activeAreaY = sizeY - 2 * frameWidth; + + TGeoMedium* keepVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + TGeoMedium* radVolMed = gGeoMan->GetMedium(RadiatorVolumeMedium); + TGeoMedium* latticeVolMed = gGeoMan->GetMedium(LatticeVolumeMedium); + TGeoMedium* kaptonVolMed = gGeoMan->GetMedium(KaptonVolumeMedium); + TGeoMedium* gasVolMed = gGeoMan->GetMedium(GasVolumeMedium); + TGeoMedium* padcopperVolMed = gGeoMan->GetMedium(PadCopperVolumeMedium); + TGeoMedium* padpcbVolMed = gGeoMan->GetMedium(PadPcbVolumeMedium); + TGeoMedium* honeycombVolMed = gGeoMan->GetMedium(HoneycombVolumeMedium); + TGeoMedium* carbonVolMed = gGeoMan->GetMedium(CarbonVolumeMedium); + // TGeoMedium* mylarVolMed = gGeoMan->GetMedium(MylarVolumeMedium); + // TGeoMedium* electronicsVolMed = + // gGeoMan->GetMedium(ElectronicsVolumeMedium); + TGeoMedium* frameVolMed = gGeoMan->GetMedium(FrameVolumeMedium); + TGeoMedium* febVolMed = gGeoMan->GetMedium(FebVolumeMedium); + TGeoMedium* asicVolMed = gGeoMan->GetMedium(AsicVolumeMedium); + TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium); + + TString name = Form("module%d", moduleType); + TGeoVolume* module = new TGeoVolumeAssembly(name); + + if (IncludeRadiator) { // Radiator + TGeoBBox* trd_radiator = new TGeoBBox("trd_radiator", sizeX / 2., sizeY / 2., radiator_thickness / 2.); + TGeoVolume* trdmod1_radvol = new TGeoVolume("Radiator", trd_radiator, radVolMed); + trdmod1_radvol->SetLineColor(kRed); + trdmod1_radvol->SetTransparency(50); // (60); // (70); // set transparency for the TRD radiator + TGeoTranslation* trd_radiator_trans = new TGeoTranslation("", 0., 0., radiator_position); + module->AddNode(trdmod1_radvol, 1, trd_radiator_trans); + } + + Double_t winIn_C_thickness = 0.02; + Double_t winIn_HC_thickness = 1.; + Double_t winIn_thickness = winIn_HC_thickness + /*2**/ winIn_C_thickness; + if (IncludeLattice) { // Entrance window in the case of the Bucharest + // prototype + Info("create_trd2d_module_type", "make entrance widow ..."); + // Carbon fiber layers + TGeoBBox* winIn_C = new TGeoBBox("winIn_C", 0.3 + activeAreaX / 2., 0.9 + activeAreaY / 2., winIn_C_thickness / 2.); + TGeoVolume* vol_winIn_C = new TGeoVolume("vol_winIn_C", winIn_C, carbonVolMed); + vol_winIn_C->SetLineColor(kGray); + // Honeycomb layer + TGeoBBox* winIn_HC = + new TGeoBBox("winIn_HC", -0.3 + activeAreaX / 2., 0.3 + activeAreaY / 2., winIn_HC_thickness / 2.); + TGeoVolume* vol_winIn_HC = new TGeoVolume("vol_winIn_HC", winIn_HC, honeycombVolMed); + vol_winIn_HC->SetLineColor(kOrange); + // framex + TGeoBBox* winIn_fx = + new TGeoBBox("winIn_fx", -0.3 + activeAreaX / 2, WIN_Frame_thickness / 2, winIn_HC_thickness / 2.); + TGeoVolume* vol_winIn_fx = new TGeoVolume("vol_winIn_fx", winIn_fx, frameVolMed); + vol_winIn_fx->SetLineColor(kBlue); + // framey + TGeoBBox* winIn_fy = + new TGeoBBox("winIn_fy", WIN_Frame_thickness / 2, (1.8 + activeAreaY) / 2, winIn_HC_thickness / 2.); + TGeoVolume* vol_winIn_fy = new TGeoVolume("vol_winIn_fy", winIn_fy, frameVolMed); + vol_winIn_fy->SetLineColor(kCyan); + // Add up all components + TGeoVolumeAssembly* trd_win_in = new TGeoVolumeAssembly("EntranceWin"); + trd_win_in->AddNode(vol_winIn_fx, 1, new TGeoTranslation("", 0., 0.6 + activeAreaY / 2., 0)); + trd_win_in->AddNode(vol_winIn_fx, 2, new TGeoTranslation("", 0., -(activeAreaY / 2. + 0.6), 0)); + trd_win_in->AddNode(vol_winIn_fy, 1, new TGeoTranslation("", activeAreaX / 2., 0., 0)); + trd_win_in->AddNode(vol_winIn_fy, 2, new TGeoTranslation("", -activeAreaX / 2., 0., 0)); + + trd_win_in->AddNode(vol_winIn_HC, 1); + trd_win_in->AddNode(vol_winIn_C, 1, + new TGeoTranslation("", 0., 0., 0.5 * (winIn_HC_thickness + winIn_C_thickness))); + // trd_win_in->AddNode(vol_winIn_C, 2, + // new TGeoTranslation("", 0., 0., + // -(winIn_thickness-winIn_C_thickness)/2.)); + module->AddNode(trd_win_in, 1, + new TGeoTranslation( + "", 0., 0., gasBu_position - gas_thickness / 2. - winIn_C_thickness - winIn_HC_thickness / 2.)); + } + + // Gas. The volume has to be defined only for pads (read-out) area. Take care + // in the DigiPara definition + TGeoBBox* trd_gas = new TGeoBBox("trd_gas", 0.5 * activeAreaX, 0.5 * activeAreaY, 0.5 * gas_thickness); + TGeoVolume* vol_gas = new TGeoVolume("gas", trd_gas, gasVolMed); + vol_gas->SetLineColor(kRed + 3); // trdmod1_gasvol->SetTransparency(40); + TGeoBBox* trd_gas_dstr = new TGeoBBox("trd_gas_dstr", 0.5 * activeAreaX, 0.2, 0.5 * gas_thickness); + TGeoVolume* vol_gas_dstr = new TGeoVolume("inlet", trd_gas_dstr, gasVolMed); + vol_gas_dstr->SetLineColor(kRed); + module->AddNode(vol_gas, 0, new TGeoTranslation("", 0., 0., gasBu_position)); + module->AddNode(vol_gas_dstr, 0, new TGeoTranslation("", 0., 0.5 * activeAreaY + 0.2, gasBu_position)); + module->AddNode(vol_gas_dstr, 1, new TGeoTranslation("", 0., -0.5 * activeAreaY - 0.2, gasBu_position)); + + const Double_t pp_pads_thickness = 0.0025; + const Double_t pp_pcb_thickness = 0.0360; + const Double_t pp_hc_thickness = 0.2; + const Double_t pp_c_thickness = 0.05; + const Double_t pp_thickness = pp_pads_thickness + pp_pcb_thickness + pp_hc_thickness + pp_c_thickness; + if (IncludePadplane) { + const Char_t* ppn = (detTypeIdx == 2 ? "pp" : "pph"); + Info("create_trd2d_module_type", "make pad-plane ..."); + // Pad Copper + TGeoBBox* trd_pp = new TGeoBBox(Form("%s_cu", ppn), activeAreaX / 2., activeAreaY / 2., pp_pads_thickness / 2.); + TGeoVolume* vol_trd_pp = new TGeoVolume(Form("vol_%s_cu", ppn), trd_pp, padcopperVolMed); + vol_trd_pp->SetLineColor(kRed); + // Pad Plane + TGeoBBox* trd_ppPCB = + new TGeoBBox(Form("%s_pcb", ppn), 1.0 + activeAreaX / 2., 0.9 + activeAreaY / 2., pp_pcb_thickness / 2.); + TGeoVolume* vol_trd_ppPCB = new TGeoVolume(Form("vol_%s_pcb", ppn), trd_ppPCB, padpcbVolMed); + vol_trd_ppPCB->SetLineColor(kGreen); + // Pad Plane HC + TGeoBBox* trd_ppHC_bd = + new TGeoBBox(Form("%s_hc_bd", ppn), 1.0 + activeAreaX / 2., 0.9 + activeAreaY / 2., pp_hc_thickness / 2.); + TGeoBBox* trd_ppHC_fc = new TGeoBBox(Form("%s_hc_fc", ppn), 2.4 / 2., 0.8 / 2., (1.e-4 + pp_hc_thickness) / 2.); + // if(detTypeIdx==2) addFlatCableHoles(Form("%s_hc", ppn)); + // TGeoCompositeShape* trd_ppHC = new TGeoCompositeShape(Form("%s_hc", ppn), + // sexpr.Data()); + TGeoVolume* vol_trd_ppHC = new TGeoVolume(Form("vol_%s_hc", ppn), trd_ppHC_bd, honeycombVolMed); + vol_trd_ppHC->SetLineColor(kOrange); + // Pad Plane C fiber + TGeoBBox* trd_ppC_bd = + new TGeoBBox(Form("%s_c_bd", ppn), 1.0 + activeAreaX / 2., 0.9 + activeAreaY / 2., pp_c_thickness / 2.); + TGeoBBox* trd_ppC_fc = new TGeoBBox(Form("%s_c_fc", ppn), 2.4 / 2., 0.8 / 2., (1.e-4 + pp_c_thickness) / 2.); + // if(detTypeIdx==2) addFlatCableHoles(Form("%s_c", ppn)); + // TGeoCompositeShape* trd_ppC = new TGeoCompositeShape(Form("%s_c", ppn), + // sexpr.Data()); + TGeoVolume* vol_trd_ppC = new TGeoVolume(Form("vol_%s_c", ppn), trd_ppC_bd, carbonVolMed); + vol_trd_ppC->SetLineColor(kGray); + + // Add up all components + TGeoVolumeAssembly* vol_pp = new TGeoVolumeAssembly("PadPlane"); + vol_pp->AddNode(vol_trd_pp, 1, new TGeoTranslation("", 0., 0., -pp_thickness / 2 + pp_pads_thickness / 2)); + vol_pp->AddNode(vol_trd_ppPCB, 1, + new TGeoTranslation("", 0., 0., -pp_thickness / 2 + pp_pads_thickness + pp_pcb_thickness / 2)); + vol_pp->AddNode( + vol_trd_ppHC, 1, + new TGeoTranslation("", 0., 0., -pp_thickness / 2 + pp_pads_thickness + pp_pcb_thickness + pp_hc_thickness / 2)); + vol_pp->AddNode(vol_trd_ppC, 1, new TGeoTranslation("", 0., 0., pp_thickness / 2 - pp_c_thickness / 2)); + module->AddNode(vol_pp, 1, + new TGeoTranslation("", 0., 0., gasBu_position + gas_thickness / 2. + pp_thickness / 2.)); + } + + if (IncludeGasFrame) { + Info("create_trd2d_module_type", "make gas frame ..."); + // framex + TGeoBBox* frame_fx0 = new TGeoBBox("frame_fx0", activeAreaX / 2., 0.5 / 2., gas_thickness / 2.); + TGeoVolume* vol_frame_fx0 = new TGeoVolume("vol_frame_fx0", frame_fx0, frameVolMed); + vol_frame_fx0->SetLineColor(kYellow - 2); + Double_t frame_fx1_thickness = winIn_thickness + gas_thickness + pp_thickness; + TGeoBBox* frame_fx1 = new TGeoBBox("frame_fx1", 1. + activeAreaX / 2., 0.3 / 2., frame_fx1_thickness / 2.); + TGeoVolume* vol_frame_fx1 = new TGeoVolume("vol_frame_fx1", frame_fx1, frameVolMed); + vol_frame_fx1->SetLineColor(kViolet); // vol_frame_fx1->SetTransparency(50); + + // framey + TGeoBBox* frame_fy_0 = new TGeoBBox("frame_fy_0", 0.7 / 2., (1.8 + activeAreaY) / 2., winIn_thickness / 2.); + TGeoVolume* vol_frame_fy_0 = new TGeoVolume("vol_frame_fy_0", frame_fy_0, frameVolMed); + vol_frame_fy_0->SetLineColor(kBlue); + TGeoBBox* frame_fy_1 = new TGeoBBox("frame_fy_1", 1.0 / 2., (1.8 + activeAreaY) / 2., + 0.4 / 2.); // catode wire support + TGeoVolume* vol_frame_fy_1 = new TGeoVolume("vol_frame_fy_1", frame_fy_1, frameVolMed); + vol_frame_fy_1->SetLineColor(kBlue - 3); + TGeoBBox* frame_fy_2 = new TGeoBBox("frame_fy_2", 0.7 / 2., (1.8 + activeAreaY) / 2., + 0.4 / 2.); // anode wire support + TGeoVolume* vol_frame_fy_2 = new TGeoVolume("vol_frame_fy_2", frame_fy_2, frameVolMed); + vol_frame_fy_2->SetLineColor(kOrange + 4); + TGeoBBox* frame_fy_3 = new TGeoBBox("frame_fy_3", 0.4 / 2., (1.8 + activeAreaY) / 2., + 0.4 / 2.); // pad-plane support + TGeoVolume* vol_frame_fy_3 = new TGeoVolume("vol_frame_fy_3", frame_fy_3, frameVolMed); + vol_frame_fy_3->SetLineColor(kYellow + 3); + // add up framey components + TGeoVolumeAssembly* vol_frame_fy0 = + new TGeoVolumeAssembly("vol_frame_fy0"); // the mother volume of wire support ledge + vol_frame_fy0->AddNode(vol_frame_fy_0, 1, + new TGeoTranslation("", -0.3 - 0.7 / 2., 0., -(0.4 * 1.5 + winIn_thickness / 2.))); + vol_frame_fy0->AddNode(vol_frame_fy_1, 1, new TGeoTranslation("", -1.0 / 2., 0., -0.4)); + vol_frame_fy0->AddNode(vol_frame_fy_2, 1, new TGeoTranslation("", -0.7 / 2., 0., 0.)); + vol_frame_fy0->AddNode(vol_frame_fy_3, 1, new TGeoTranslation("", -0.4 / 2., 0., 0.4)); + TGeoBBox* frame_fy1 = new TGeoBBox("frame_fy1", 0.3 / 2., 1.2 + activeAreaY / 2., frame_fx1_thickness / 2.); + TGeoVolume* vol_frame_fy1 = new TGeoVolume("vol_frame_fy1", frame_fy1, frameVolMed); + vol_frame_fy1->SetLineColor(kViolet + 2); // vol_frame_fy1->SetTransparency(50); + + // Add up all frames + Double_t frame_fx1_position = -winIn_thickness - gas_thickness / 2. + frame_fx1_thickness / 2.; + TGeoVolumeAssembly* trd_gas_frame = new TGeoVolumeAssembly("Frame"); // the mother volume of gas frame + trd_gas_frame->AddNode(vol_frame_fx0, 1, new TGeoTranslation("", 0., activeAreaY / 2. + 0.4 + 0.5 / 2, 0)); + trd_gas_frame->AddNode(vol_frame_fx0, 2, new TGeoTranslation("", 0., -(activeAreaY / 2. + 0.4 + 0.5 / 2), 0)); + trd_gas_frame->AddNode(vol_frame_fx1, 1, + new TGeoTranslation("", 0., activeAreaY / 2. + 0.4 + 0.5 + 0.3 / 2, frame_fx1_position)); + trd_gas_frame->AddNode(vol_frame_fx1, 2, + new TGeoTranslation("", 0., -(activeAreaY / 2. + 0.4 + 0.5 + 0.3 / 2), frame_fx1_position)); + + trd_gas_frame->AddNode(vol_frame_fy0, 1, new TGeoTranslation("", -activeAreaX / 2., 0., 0)); + TGeoRotation* fy_rot = new TGeoRotation(); + fy_rot->RotateZ(180.); + TGeoTranslation* fy_tra = new TGeoTranslation("", -activeAreaX / 2., 0., 0); + TGeoHMatrix* fy_transform = new TGeoHMatrix(""); + (*fy_transform) = (*fy_rot) * (*fy_tra); + trd_gas_frame->AddNode(vol_frame_fy0, 2, fy_transform); + trd_gas_frame->AddNode(vol_frame_fy1, 1, + new TGeoTranslation("", activeAreaX / 2. + 1.0 + 0.3 / 2, 0, frame_fx1_position)); + trd_gas_frame->AddNode(vol_frame_fy1, 2, + new TGeoTranslation("", -(activeAreaX / 2. + 1.0 + 0.3 / 2), 0, frame_fx1_position)); + + // add Al reinforcements on the edges of the gas frame + if (moduleType == 9) { + // y direction + TGeoBBox* frame_al_y0 = new TGeoBBox("frame_al_y0", 0.4 / 2., (sizeY - 1.4) / 2., 1.8 / 2.); + TGeoVolume* vol_frame_al_y0 = new TGeoVolume("vol_frame_al_y0", frame_al_y0, aluminiumVolMed); + trd_gas_frame->AddNode(vol_frame_al_y0, 1, new TGeoTranslation("", -0.5 * sizeX + 1, 0, -1.)); + trd_gas_frame->AddNode(vol_frame_al_y0, 2, new TGeoTranslation("", +0.5 * sizeX - 1, 0, -1.)); + // + TGeoBBox* frame_al_y1 = new TGeoBBox("frame_al_y1", 2.5 / 2., (sizeY - 1.4) / 2., 0.4 / 2.); + TGeoVolume* vol_frame_al_y1 = new TGeoVolume("vol_frame_al_y1", frame_al_y1, aluminiumVolMed); + trd_gas_frame->AddNode(vol_frame_al_y1, 1, new TGeoTranslation("", -0.5 * sizeX + 1 - 2.5 + 1.05, 0, -0.3)); + trd_gas_frame->AddNode(vol_frame_al_y1, 2, new TGeoTranslation("", +0.5 * sizeX - 1 + 2.5 - 1.05, 0, -0.3)); + // connector to frame + TGeoBBox* frame_al_y2 = new TGeoBBox("frame_al_y2", 2.5 / 2., (sizeY + 5) / 2., 0.8 / 2.); + TGeoVolume* vol_frame_al_y2 = new TGeoVolume("vol_frame_al_y2", frame_al_y2, aluminiumVolMed); + trd_gas_frame->AddNode(vol_frame_al_y2, 1, new TGeoTranslation("", -0.5 * sizeX - 0.45, 0, -0.9)); + trd_gas_frame->AddNode(vol_frame_al_y2, 2, new TGeoTranslation("", +0.5 * sizeX + 0.45, 0, -0.9)); + + // x direction + sizeY = 58.2; // dirty fix for the TRD-2D @ mCBM 21 + TGeoBBox* frame_al_x0 = new TGeoBBox("frame_al_x0", (sizeX - 2.4) / 2., 0.4 / 2, 2.5 / 2.); + TGeoVolume* vol_frame_al_x0 = new TGeoVolume("vol_frame_al_x0", frame_al_x0, aluminiumVolMed); + trd_gas_frame->AddNode(vol_frame_al_x0, 1, new TGeoTranslation("", 0, -0.5 * (sizeY + 0.4), 0)); + trd_gas_frame->AddNode(vol_frame_al_x0, 2, new TGeoTranslation("", 0, +0.5 * (sizeY + 0.4), 0)); + // ==== + TGeoBBox* frame_al_x1 = new TGeoBBox("frame_al_x1", (sizeX - 2.4) / 2., 2.5 / 2., 0.4 / 2); + TGeoVolume* vol_frame_al_x1 = new TGeoVolume("vol_frame_al_x1", frame_al_x1, aluminiumVolMed); + trd_gas_frame->AddNode(vol_frame_al_x1, 1, new TGeoTranslation("", 0, -0.5 * (sizeY + 2.5), -0.5 * (2.5 + 0.4))); + trd_gas_frame->AddNode(vol_frame_al_x1, 2, new TGeoTranslation("", 0, +0.5 * (sizeY + 2.5), -0.5 * (2.5 + 0.4))); + } + + module->AddNode(trd_gas_frame, 1, new TGeoTranslation("", 0., 0., gasBu_position)); + } + + const Double_t bp_hc_thickness = 2.; + const Double_t bp_pcb_thickness = 0.05; + const Double_t bp_cu_thickness = 0.003; + const Double_t bp_thickness = bp_cu_thickness + bp_hc_thickness + bp_pcb_thickness; + const Double_t bp_position = gasBu_position + 0.5 * gas_thickness + pp_thickness; + if (IncludeBackpanel) { + Info("create_trd2d_module_type", "make backpanel ..."); + // Honeycomb board and flat-cable hole + TGeoBBox* bp_hc_bd = new TGeoBBox("bp_hc_bd", activeAreaX / 2., activeAreaY / 2., bp_hc_thickness / 2.); + TGeoBBox* bp_hc_fc = new TGeoBBox("bp_hc_fc", 2.4 / 2., 0.8 / 2., (1.e-4 + bp_hc_thickness) / 2.); + // if(detTypeIdx==2) addFlatCableHoles("bp_hc"); + // TGeoCompositeShape* bp_hc = new TGeoCompositeShape("bp_hc", + // sexpr.Data()); + TGeoVolume* vol_bp_hc = new TGeoVolume(".vol_bp_hc", bp_hc_bd, honeycombVolMed); + vol_bp_hc->SetLineColor(kOrange); + // Screen fibre-glass support (PCB) + TGeoBBox* bp_pcb_bd = + new TGeoBBox("bp_pcb_bd", 0.5 + activeAreaX / 2., 0.5 + activeAreaY / 2., bp_pcb_thickness / 2.); + TGeoBBox* bp_pcb_fc = new TGeoBBox("bp_pcb_fc", 2.4 / 2., 0.8 / 2., (1.e-3 + bp_pcb_thickness) / 2.); + // if(detTypeIdx==2) addFlatCableHoles("bp_pcb"); + // TGeoCompositeShape* bp_pcb = new TGeoCompositeShape("bp_pcb", + // sexpr.Data()); + TGeoVolume* vol_bp_pcb = new TGeoVolume("vol_bp_pcb", bp_pcb_bd, padpcbVolMed); + vol_bp_pcb->SetLineColor(kGreen); + // Pad Copper + TGeoBBox* bp_cu_bd = new TGeoBBox("bp_cu_bd", 0.5 + activeAreaX / 2., 0.5 + activeAreaY / 2., bp_cu_thickness / 2.); + TGeoBBox* bp_cu_fc = new TGeoBBox("bp_cu_fc", 2.4 / 2., 0.8 / 2., (1.e-3 + bp_cu_thickness) / 2.); + // if(detTypeIdx==2) addFlatCableHoles("bp_cu"); + // TGeoCompositeShape* bp_cu = new TGeoCompositeShape("bp_cu", + // sexpr.Data()); + TGeoVolume* vol_bp_cu = new TGeoVolume("vol_bp_cu", bp_cu_bd, padcopperVolMed); + vol_bp_cu->SetLineColor(kRed); + + TGeoBBox* bp_fx = new TGeoBBox("bp_fx", activeAreaX / 2., 0.5 / 2., bp_hc_thickness / 2.); + TGeoVolume* vol_bp_fx = new TGeoVolume("vol_bp_fx", bp_fx, frameVolMed); + vol_bp_fx->SetLineColor(kViolet); // vol_gas_fx1->SetTransparency(50); + TGeoBBox* bp_fy = new TGeoBBox("bp_fy", 0.5 / 2, 0.5 + 0.5 * activeAreaY, bp_hc_thickness / 2.); + TGeoVolume* vol_bp_fy = new TGeoVolume("vol_bp_fy", bp_fy, frameVolMed); + vol_bp_fy->SetLineColor(kViolet + 2); + + // Add up all components + TGeoVolumeAssembly* trd_supp = new TGeoVolumeAssembly("BackPanel"); + trd_supp->AddNode(vol_bp_hc, 1); + trd_supp->AddNode(vol_bp_pcb, 1, new TGeoTranslation("", 0., 0., 0.5 * (bp_hc_thickness + bp_pcb_thickness))); + trd_supp->AddNode( + vol_bp_cu, 1, new TGeoTranslation("", 0., 0., 0.5 * (bp_hc_thickness + 2 * bp_pcb_thickness + bp_cu_thickness))); + trd_supp->AddNode(vol_bp_fx, 1, new TGeoTranslation("", 0., 0.5 * (0.5 + activeAreaY), 0)); + trd_supp->AddNode(vol_bp_fx, 2, new TGeoTranslation("", 0., -0.5 * (0.5 + activeAreaY), 0)); + trd_supp->AddNode(vol_bp_fy, 1, new TGeoTranslation("", 0.5 * (0.5 + activeAreaX), 0., 0.)); + trd_supp->AddNode(vol_bp_fy, 2, new TGeoTranslation("", -0.5 * (0.5 + activeAreaX), 0., 0.)); + module->AddNode( + trd_supp, 1, + new TGeoTranslation("", 0., 0., gasBu_position + 0.5 * gas_thickness + pp_thickness + 0.5 * bp_hc_thickness)); + } + + // FEBs + // ROB FASP + const Double_t FASPRO_zspace = 1.5; // gap size between boards + const Double_t FASPRO_length = 17.9; // length of FASP FEBs in cm + const Double_t FASPRO_width = 5.12; // width of FASP FEBs in cm + const Double_t FASPRO_dx = 0.01; // + const Double_t FASPRO_dy = 0.28; // + const Double_t FASPRO_thickness = 0.17; + const Double_t FASPRO_position = bp_position + bp_thickness + FASPRO_zspace; + const Double_t GETS_length = 13.9; // length of PolarFire FEBs in cm + const Double_t GETS_width = 5.12; // width of PolarFire FEBs in cm + const Double_t GETS_thickness = 0.2; + const Double_t GA01_length = 5.; // length of LV FEBs in cm + const Double_t GA01_width = 5.1; // width of LV FEBs in cm + const Double_t GA01_thickness = 0.2; + + // ASIC parameters + const Double_t fasp_size[] = {1.2, 1.2, 0.2}; // FASP package and interposer size 1.5x1.5 cm2 + const Double_t faspConn_size[] = {2.1, 0.3, 0.6}; // FASP package and interposer size 1.5x1.5 cm2 + const Double_t fasp_xoffset = 6.0; // ASIC offset from ROC middle (horizontally) + const Double_t fasp_yoffset = 1.35; // ASIC offset from DET connector (vertical) + const Double_t fpga_size[] = {1.2, 1.2, 0.2}; // PolarFire FPGA package size 1.5x1.5 cm2 + // FMC+ connector definition + const Double_t FMCwidth = 2.0; // width of a MF FMC connector + const Double_t FMClength = 5.6; // length of a MF FMC connector + const Double_t FMCheight = 1.13; // height of a MF FMC connector + const Double_t FMCsuppD = 0.8; // outer radius of FMC connector side supports + const Double_t FMCsuppX = 0.6; // FMC connector side supports + // GETS2C-ROB3 connector boord parameters + const Double_t robConn_size_x = 3.9; // 15.0; + const Double_t robConn_size_y = 15.0; + // const Double_t robConn_xoffset = 6.0; + // SATA+ connector definition + const Double_t SATAwidth = 0.7; // width of a SATA connector on GA01 + const Double_t SATAlength = 1.7; // length of a SATA connector on GA01 + const Double_t SATAheight = 0.8; // height of a SATA connector on GA01 + // GA01 connector definition + const Double_t BGAwidth = 0.4; // width of a GETS to GA01 connector + const Double_t BGAlength = 4.5; // length of a GETS to GA01 connector + const Double_t BGAheight = 0.8; // height of a GETS to GA01 connector + if (IncludeFebs) { + Info("create_trd2d_module_type", "make FEBs ..."); + + // Create all FEBs and place them in an assembly which will be added to the + // TRD module + // FASPRO board + TGeoBBox* faspro_bd = new TGeoBBox("faspro_bd", FASPRO_length / 2., FASPRO_width / 2., FASPRO_thickness / 2.); + TGeoVolume* vol_faspro_bd = new TGeoVolume("vol_faspro_bd", faspro_bd, febVolMed); + vol_faspro_bd->SetLineColor(kGreen + 3); // vol_faspro_bd->SetTransparency(50); + // GETS board + TGeoBBox* gets_bd = new TGeoBBox("gets_bd", GETS_length / 2., GETS_width / 2., GETS_thickness / 2.); + TGeoVolume* vol_gets_bd = new TGeoVolume("vol_gets_bd", gets_bd, febVolMed); + vol_gets_bd->SetLineColor(kGreen + 3); // vol_gets_bd->SetTransparency(50); + // GA01 board + TGeoBBox* ga01_bd = new TGeoBBox("ga01_bd", GA01_length / 2., GA01_width / 2., GA01_thickness / 2.); + TGeoVolume* vol_ga01_bd = new TGeoVolume("vol_ga01_bd", ga01_bd, febVolMed); + vol_ga01_bd->SetLineColor(kGreen + 7); // vol_gets_bd->SetTransparency(50); + + // Create connectors + // FMC connector + TGeoBBox* fmc_conn = new TGeoBBox("fmc_conn", 0.5 * FMClength, 0.5 * FMCwidth, 0.5 * FMCheight); + TGeoVolume* vol_fmc_conn = new TGeoVolume("vol_fmc_conn", fmc_conn, febVolMed); + vol_fmc_conn->SetLineColor(kGray + 2); + TGeoTube* fmc_connSupp = new TGeoTube("fmc_connSupp", 0, 0.5 * FMCsuppD, 0.5 * FMCheight); + TGeoVolume* vol_fmc_connSupp = new TGeoVolume("vol_fmc_connSupp", fmc_connSupp, aluminiumVolMed); // support Al + vol_fmc_connSupp->SetLineColor(kGray); + TGeoVolumeAssembly* fmc_connect = new TGeoVolumeAssembly("FMC"); + fmc_connect->AddNode(vol_fmc_conn, 1); + fmc_connect->AddNode(vol_fmc_connSupp, 1, new TGeoTranslation("", 0.5 * FMClength + FMCsuppX, 0, 0.)); + fmc_connect->AddNode(vol_fmc_connSupp, 2, new TGeoTranslation("", -(0.5 * FMClength + FMCsuppX), 0, 0.)); + // SATA connectors + TGeoBBox* sata_conn = new TGeoBBox("sata_conn", 0.5 * SATAwidth, 0.5 * SATAlength, 0.5 * SATAheight); + TGeoVolume* vol_sata_conn = new TGeoVolume("vol_sata_conn", sata_conn, febVolMed); + vol_sata_conn->SetLineColor(kGray + 2); + // BGA connectors + TGeoBBox* bga_conn = new TGeoBBox("bga_conn", 0.5 * BGAwidth, 0.5 * BGAlength, 0.5 * BGAheight); + TGeoVolume* vol_bga_conn = new TGeoVolume("vol_bga_conn", bga_conn, febVolMed); + vol_bga_conn->SetLineColor(kGray + 2); + + // Create GA01 board + TGeoVolumeAssembly* ga01 = new TGeoVolumeAssembly("GA01"); + ga01->AddNode(vol_ga01_bd, 1); + Float_t sataConnPosX[] = {2, 1.2, -1.}, sataConnPosY[] = {0, 1.5, 1}; + for (Int_t ic(-2); ic <= 2; ic++) { + ga01->AddNode(vol_sata_conn, ic + 2, + new TGeoTranslation("", sataConnPosX[abs(ic)], (ic > 0 ? 1 : -1) * sataConnPosY[abs(ic)], + 0.5 * (GA01_thickness + SATAheight))); + } + ga01->AddNode(vol_bga_conn, 1, + new TGeoTranslation("", -0.5 * GA01_length + 0.5, 0, -0.5 * (GA01_thickness + BGAheight))); + + // Add up all elements of FASPRO + TGeoVolumeAssembly* faspro = new TGeoVolumeAssembly("FASPRO"); + faspro->AddNode(vol_faspro_bd, 1); + faspro->AddNode(fmc_connect, 0, new TGeoTranslation("", 0, 0, 0.5 * FMCheight + 0.5 * FASPRO_thickness)); + Double_t GETS_zpos = 0.5 * FASPRO_thickness + FMCheight + 0.5 * GETS_thickness; + faspro->AddNode(vol_gets_bd, 1, new TGeoTranslation("", 0, 0, GETS_zpos)); + Double_t GA01_zpos = GETS_zpos + 0.5 * GETS_thickness + BGAheight + 0.5 * GA01_thickness; + faspro->AddNode(ga01, 1, new TGeoTranslation("", 0.5 * GETS_length + 0.5 * GA01_length - 1., 0, GA01_zpos)); + + // ASICs + if (IncludeAsics) { + Info("create_trd2d_module_type", "make ASICs ..."); + TGeoBBox* fasp_asic = new TGeoBBox("fasp_asic", 0.5 * fasp_size[0], 0.5 * fasp_size[1], 0.5 * fasp_size[2]); + TGeoVolume* vol_fasp_asic = new TGeoVolume("FASP", fasp_asic, padpcbVolMed); + vol_fasp_asic->SetLineColor(kBlack); + TGeoBBox* fasp_conn = + new TGeoBBox("fasp_conn", 0.5 * faspConn_size[0], 0.5 * faspConn_size[1], 0.5 * faspConn_size[2]); + TGeoVolume* vol_fasp_conn = new TGeoVolume("fasp_conn", fasp_conn, padpcbVolMed); + vol_fasp_conn->SetLineColor(kRed + 4); + for (Int_t cAsic(-1), iAsic(0); cAsic <= 1; cAsic++) { + faspro->AddNode(vol_fasp_asic, iAsic, + new TGeoTranslation("", cAsic * fasp_xoffset, fasp_yoffset, + -1 * (0.5 * FASPRO_thickness + 0.5 * fasp_size[2]))); + faspro->AddNode(vol_fasp_conn, iAsic, + new TGeoTranslation("", cAsic * fasp_xoffset, 0.5 * FASPRO_width - 0.2 - 0.5 * faspConn_size[1], + -1 * (0.5 * FASPRO_thickness + 0.5 * faspConn_size[2]))); + iAsic++; + faspro->AddNode(vol_fasp_asic, iAsic, + new TGeoTranslation("", cAsic * fasp_xoffset, -fasp_yoffset, + -1 * (0.5 * FASPRO_thickness + 0.5 * fasp_size[2]))); + faspro->AddNode(vol_fasp_conn, iAsic, + new TGeoTranslation("", cAsic * fasp_xoffset, + -(0.5 * FASPRO_width - 0.2 - 0.5 * faspConn_size[1]), + -1 * (0.5 * FASPRO_thickness + 0.5 * faspConn_size[2]))); + iAsic++; + } + + TGeoBBox* fpga_asic = new TGeoBBox("fpga_asic", 0.5 * fpga_size[0], 0.5 * fpga_size[1], 0.5 * fpga_size[2]); + TGeoVolume* vol_fpga_asic = new TGeoVolume("FPGA", fpga_asic, asicVolMed); + vol_fpga_asic->SetLineColor(kBlack); + faspro->AddNode(vol_fpga_asic, 0, + new TGeoTranslation("", 0, -fasp_yoffset, GETS_zpos + 0.5 * GETS_thickness + 0.5 * fpga_size[2])); + faspro->AddNode(vol_fpga_asic, 1, + new TGeoTranslation("", 0, fasp_yoffset, GETS_zpos + 0.5 * GETS_thickness + 0.5 * fpga_size[2])); + } + // supports for electronics + TGeoBBox* faspro_fy = new TGeoBBox("faspro_fy", 0.4 / 2, 0.5 + 0.5 * activeAreaY, 0.5 * (FASPRO_zspace - 0.2)); + TGeoVolume* vol_faspro_fy = new TGeoVolume("faspro_fy", faspro_fy, frameVolMed); + vol_faspro_fy->SetLineColor(kViolet + 2); // vol_faspro_fy->SetTransparency(50); + + // now go on with FEB placement + TGeoVolumeAssembly* vol_feb = new TGeoVolumeAssembly("FEB"); // the mother volume of all FEBs + if (moduleType == 9) { // define ROB placement fot large 2D chamber + // add offset wrt chamber edge for the TRD2D@mCBM22 + /// as the first flat coulmn is skipped (AB 05.05.2022) + const float xoffset = -6.; + Int_t cFeb(0); + for (Int_t iFeb(0); cFeb < 2; cFeb++) { + vol_feb->AddNode(vol_faspro_fy, cFeb+1, + new TGeoTranslation("", xoffset + (cFeb - 0.5) * (FASPRO_length + FASPRO_dx), 0., + -0.5 * (FASPRO_thickness + FASPRO_zspace) + 0.05)); + for (Int_t rFeb(-4); rFeb <= 4; rFeb++) { + vol_feb->AddNode(faspro, iFeb++, + new TGeoTranslation("", xoffset + cFeb*(FASPRO_length+FASPRO_dx), + rFeb*(FASPRO_width+FASPRO_dy), 0)); + } + } + vol_feb->AddNode(vol_faspro_fy, cFeb + 1, + new TGeoTranslation("", xoffset + (cFeb - 0.5) * (FASPRO_length + FASPRO_dx), 0., + -0.5 * (FASPRO_thickness + FASPRO_zspace))); + } + else { // define ROB placement fot small 2D hybrid chamber + TGeoRotation* faspro_rot = new TGeoRotation("faspro_rot"); + faspro_rot->RotateX(180.); + faspro_rot->RegisterYourself(); + TGeoTranslation* faspro_pos = new TGeoTranslation("", -4, 1.5 * FASPRO_width + 0.5, -FASPRO_zspace); + TGeoHMatrix* faspro_mx = new TGeoHMatrix(""); + (*faspro_mx) = (*faspro_pos) * (*faspro_rot); + vol_feb->AddNode(faspro, 5, faspro_mx); + } + + if (IncludeRobs2D) { + Info("create_trd2d_module_type", "make ROBs ..."); + TGeoVolumeAssembly* crob = new TGeoVolumeAssembly("C-ROB"); + TGeoBBox* crob_bd = new TGeoBBox("crob_bd", rob_size_x / 2., rob_size_y / 2., rob_thickness / 2.); + TGeoVolume* vol_crob_bd = new TGeoVolume("crob_bd", crob_bd, febVolMed); // the ROB made of PCB + vol_crob_bd->SetLineColor(kRed + 8); // set color + TGeoRotation* crob_fmc_rot = new TGeoRotation("crob_fmc_rot"); + crob_fmc_rot->RotateZ(90.); + crob_fmc_rot->RegisterYourself(); + TGeoTranslation* crob_fmc_tra = new TGeoTranslation("crob_fmc_tra", 0., 0.5 * (FMCwidth - robConn_size_x) + 0.2, + 0.5 * (FMCheight + rob_thickness)); + crob_fmc_tra->RegisterYourself(); + TGeoHMatrix* crob_fmc_transform = new TGeoHMatrix(""); + (*crob_fmc_transform) = (*crob_fmc_rot) * (*crob_fmc_tra); + // Add GETS - CROB interface + TGeoBBox* crob_addapt = new TGeoBBox("crob_addapt", robConn_size_x / 2., robConn_size_y / 2., rob_thickness / 2.); + TGeoVolume* vol_crob_addapt = new TGeoVolume("crob_addapt", crob_addapt, febVolMed); // the ROB made of PCB + vol_crob_addapt->SetLineColor(kRed + 6); // set color + crob->AddNode(vol_crob_addapt, 0); + crob->AddNode(fmc_connect, 1, crob_fmc_transform); + crob->AddNode(vol_crob_bd, 1, + new TGeoTranslation("", -0.5 * (rob_size_x - robConn_size_x) + 1.5, 0., FMCheight + rob_thickness)); + + // GBTXs + TGeoBBox* crob_gbtx = new TGeoBBox("crob_gbtx", gbtx_width / 2., gbtx_width / 2., gbtx_thickness / 2.); + TGeoVolume* vol_crob_gbtx = new TGeoVolume("crob_gbtx", crob_gbtx, asicVolMed); + vol_crob_gbtx->SetLineColor(kGreen); + // place 3 GBTXs on each C-ROC + Double_t gbtx_pos_x = 0.5 * (-rob_size_x + gbtx_width) - 1.5 /*-0.5*/; + Double_t gbtx_pos_y = 0.5 * (rob_size_y - gbtx_width) - 0.5; + crob->AddNode(vol_crob_gbtx, 0, + new TGeoTranslation("", gbtx_pos_x, gbtx_pos_y, FMCheight + rob_thickness + 0.5 * gbtx_thickness)); + crob->AddNode(vol_crob_gbtx, 1, + new TGeoTranslation("", gbtx_pos_x, -gbtx_pos_y, FMCheight + rob_thickness + 0.5 * gbtx_thickness)); + crob->AddNode(vol_crob_gbtx, 2, + new TGeoTranslation("", gbtx_pos_x + 5., 0., FMCheight + rob_thickness + 0.5 * gbtx_thickness)); + // Info("create_trd2d_module_type", "place ROBs ..."); + // // now go on with ROB placement + // Int_t nofRobs = RobsPerModule[ 2 ], nofRobsHalf(nofRobs/2); + // for (Int_t iRob = 0, jRob(0); iRob < nofRobsHalf; iRob++) { + // printf("ROB[%d]\n", iRob); + // Double_t rob_pos = (iRob + 0.5) / nofRobsHalf - 0.5, // + // equal spacing of ROBs on the backpanel + // rob_pos_y = rob_pos * activeAreaY; + // vol_feb->AddNode(crob, jRob++, new TGeoTranslation("", + // -0.5*(FASPRO_length+FASPRO_dx), rob_pos_y, LVB_pos)); + // TGeoRotation *crob_rot = new TGeoRotation("crob_rot"); + // crob_rot->RotateZ(180.); crob_rot->RegisterYourself(); + // TGeoTranslation *crob_tra = new TGeoTranslation("crob_tra", + // 0.5*(FASPRO_length+FASPRO_dx), rob_pos_y, LVB_pos); + // crob_tra->RegisterYourself(); + // TGeoHMatrix *crob_transform = new TGeoHMatrix(""); + // (*crob_transform)=(*crob_tra)*(*crob_rot); + // vol_feb->AddNode(crob, jRob++, crob_transform); + // } + } // IncludeGbtx + + // put FEB box on module + module->AddNode(vol_feb, 1, new TGeoTranslation("", 0., 0., FASPRO_position)); // put febvolume at + // correct z position + // wrt to the module + } + + return module; +} + +Int_t copy_nr(Int_t stationNr, Int_t copyNr, Int_t isRotated, Int_t planeNr, Int_t modinplaneNr) +{ + if (modinplaneNr > 128) + printf("Warning: too many modules in this layer %02d (max 128 according to " + "CbmTrdAddress)\n", + planeNr); + + return (stationNr * 100000000 // 1 digit + + copyNr * 1000000 // 2 digit + + isRotated * 100000 // 1 digit + + planeNr * 1000 // 2 digit + + modinplaneNr * 1); // 3 digit +} + +void create_detector_layers(Int_t layerId) +{ + Int_t module_id = 0; + Int_t layerType = LayerType[layerId] / 10; // this is also a station number + Int_t isRotated = LayerType[layerId] % 10; // is 1 for layers 2,4, ... + + TGeoRotation* module_rotation = new TGeoRotation(); + + Int_t stationNr = layerType; + + // rotation is now done in the for loop for each module individually + // if ( isRotated == 1 ) { + // module_rotation = new TGeoRotation(); + // module_rotation->RotateZ(90.); + // } else { + // module_rotation = new TGeoRotation(); + // module_rotation->RotateZ( 0.); + // } + + Int_t innerarray_size1 = LayerArraySize[layerType - 1][0]; + Int_t innerarray_size2 = LayerArraySize[layerType - 1][1]; + const Int_t* innerLayer; + + Int_t outerarray_size1 = LayerArraySize[layerType - 1][2]; + Int_t outerarray_size2 = LayerArraySize[layerType - 1][3]; + const Int_t* outerLayer; + + if (1 == layerType) { + innerLayer = (Int_t*) layer1i; + outerLayer = (Int_t*) layer1o; + } + else if (2 == layerType) { + innerLayer = (Int_t*) layer2i; + outerLayer = (Int_t*) layer2o; + } + else if (3 == layerType) { + innerLayer = (Int_t*) layer3i; + outerLayer = (Int_t*) layer3o; + } + else { + std::cout << "Type of layer not known" << std::endl; + } + Info("create_detector_layers", "Layer id(%d) type(%d)", layerId, layerType); + + // add layer keeping volume + TString layername = Form("layer%02d", PlaneId[layerId]); + TGeoVolume* layer = new TGeoVolumeAssembly(layername); + + // compute layer copy number + Int_t i = LayerType[layerId] / 10 * 10000 // 1 digit // fStation + + LayerType[layerId] % 10 * 1000 // 1 digit // isRotated + + LayerNrInStation[layerId] * 100 // 1 digit // fLayer + + PlaneId[layerId]; // 2 digits // fPlane // layer type as leading + // digit in copy number of layer + gGeoMan->GetVolume(geoVersion)->AddNode(layer, i); + + // Int_t i = 100 + PlaneId[layerId]; + // gGeoMan->GetVolume(geoVersion)->AddNode(layer, 1); + // cout << layername << endl; + + Double_t ExplodeScale = 1.00; + if (DoExplode) // if explosion, set scale + ExplodeScale = ExplodeFactor; + + Int_t modId = 0; // module id, only within this layer + + Int_t copyNrIn[4] = {0, 0, 0, 0}; // copy number for each module type + for (Int_t type = 1; type <= 4; type++) { + for (Int_t j = (innerarray_size1 - 1); j >= 0; j--) { // start from the bottom + for (Int_t i = 0; i < innerarray_size2; i++) { + module_id = *(innerLayer + (j * innerarray_size2 + i)); + if (module_id / 100 == type) { + Info("create_detector_layers", "add module[%d] of type[%d]", module_id, type); + Int_t y = -(j - 2); + Int_t x = i - 2; + + // displacement + Double_t dx = 0; + Double_t dy = 0; + Double_t dz = 0; + + if (DisplaceRandom) { + dx = (r3.Rndm() - .5) * 2 * maxdx; // max +- 0.1 cm shift + dy = (r3.Rndm() - .5) * 2 * maxdy; // max +- 0.1 cm shift + dz = (r3.Rndm() - .5) * 2 * maxdz; // max +- 1.0 cm shift + } + + Double_t xPos = DetectorSizeX[0] * x * ExplodeScale + dx; + Double_t yPos = DetectorSizeY[0] * y * ExplodeScale + dy; + copyNrIn[type - 1]++; + modId++; + + // statistics per layer and module type + ModuleStats[layerId][type - 1]++; + + // Int_t copy = copy_nr_modid(stationNr, layerNrInStation, + // copyNrIn[type - 1], PlaneId[layerId], modId); // with + // modID + // Int_t copy = copy_nr(stationNr, copyNrIn[type - 1], + // isRotated, PlaneId[layerId], modId); + + // take care of FEB orientation - away from beam + Int_t copy = 0; + module_rotation = new TGeoRotation(); // need to renew rotation to + // start from 0 degree angle + if (isRotated == 0) // layer 1,3 ... + { + copy = copy_nr(stationNr, copyNrIn[type - 1], module_id / 10 % 10, PlaneId[layerId], modId); + module_rotation->RotateZ((module_id / 10 % 10) * 90.); // rotate module by 0 or 180 + // degrees, see layer[1-3][i,o] - + // vertical pads + } + else // layer 2,4 ... + { + copy = copy_nr(stationNr, copyNrIn[type - 1], module_id % 10, PlaneId[layerId], modId); + module_rotation->RotateZ((module_id % 10) * 90.); // rotate module + // by 90 or 270 + // degrees, see + // layer[1-3][i,o] + // - horizontal + // pads + } + + // rotation + Double_t drotx = 0; + Double_t droty = 0; + Double_t drotz = 0; + + if (RotateRandom) { + drotx = (r3.Rndm() - .5) * 2 * maxdrotx; + droty = (r3.Rndm() - .5) * 2 * maxdroty; + drotz = (r3.Rndm() - .5) * 2 * maxdrotz; + + module_rotation->RotateZ(drotz); + module_rotation->RotateY(droty); + module_rotation->RotateX(drotx); + } + + TGeoCombiTrans* module_placement = + new TGeoCombiTrans(xPos, yPos, LayerPosition[layerId] + LayerThickness / 2 + dz, + module_rotation); // shift by half layer thickness + // gGeoMan->GetVolume(geoVersion)->AddNode(gModules[type - + // 1], copy, module_placement); + // add module to layer + gGeoMan->GetVolume(layername)->AddNode(gModules[type - 1], copy, module_placement); + // + } + } + } + } + + Int_t copyNrOut[4] = {0, 0, 0, 0}; // copy number for each module type + for (Int_t type = 5; type <= 8; type++) { + for (Int_t j = (outerarray_size1 - 1); j >= 0; j--) { // start from the bottom + for (Int_t i = 0; i < outerarray_size2; i++) { + module_id = *(outerLayer + (j * outerarray_size2 + i)); + if (module_id / 100 == type) { + Info("create_detector_layers", "add module[%d] of type[%d]", module_id, type); + Int_t y = -(j - 4); + Int_t x = i - 5; + + // displacement + Double_t dx = 0; + Double_t dy = 0; + Double_t dz = 0; + + if (DisplaceRandom) { + dx = (r3.Rndm() - .5) * 2 * maxdx; // max +- 0.1 cm shift + dy = (r3.Rndm() - .5) * 2 * maxdy; // max +- 0.1 cm shift + dz = (r3.Rndm() - .5) * 2 * maxdz; // max +- 1.0 cm shift + } + + Double_t xPos = DetectorSizeX[1] * x * ExplodeScale + dx; + Double_t yPos = DetectorSizeY[1] * y * ExplodeScale + dy; + copyNrOut[type - 5]++; + modId++; + + // statistics per layer and module type + ModuleStats[layerId][type - 1]++; + + // Int_t copy = copy_nr_modid(stationNr, layerNrInStation, + // copyNrOut[type - 5], PlaneId[layerId], modId); // with + // modID + // Int_t copy = copy_nr(stationNr, copyNrOut[type - 5], + // isRotated, PlaneId[layerId], modId); + + // take care of FEB orientation - away from beam + Int_t copy = 0; + module_rotation = new TGeoRotation(); // need to renew rotation to + // start from 0 degree angle + if (isRotated == 0) // layer 1,3 ... + { + copy = copy_nr(stationNr, copyNrOut[type - 5], module_id / 10 % 10, PlaneId[layerId], modId); + module_rotation->RotateZ((module_id / 10 % 10) * 90.); // rotate module by 0 or 180 + // degrees, see layer[1-3][i,o] - + // vertical pads + } + else // layer 2,4 ... + { + copy = copy_nr(stationNr, copyNrOut[type - 5], module_id % 10, PlaneId[layerId], modId); + module_rotation->RotateZ((module_id % 10) * 90.); // rotate module + // by 90 or 270 + // degrees, see + // layer[1-3][i,o] + // - horizontal + // pads + } + + // rotation + Double_t drotx = 0; + Double_t droty = 0; + Double_t drotz = 0; + + if (RotateRandom) { + drotx = (r3.Rndm() - .5) * 2 * maxdrotx; + droty = (r3.Rndm() - .5) * 2 * maxdroty; + drotz = (r3.Rndm() - .5) * 2 * maxdrotz; + + module_rotation->RotateZ(drotz); + module_rotation->RotateY(droty); + module_rotation->RotateX(drotx); + } + + Double_t frameref_angle = 0; + Double_t layer_angle = 0; + + cout << "layer " << layerId << " ---" << endl; + frameref_angle = atan((DetectorSizeX[1] / 2. - FrameWidth[1]) / (zfront[setupid] + 3 * LayerThickness)); + // frameref_angle = 15. / 180. * acos(-1); // set a fixed + // reference angle + cout << "reference angle " << frameref_angle * 180 / acos(-1) << endl; + + layer_angle = atan((DetectorSizeX[1] / 2. - FrameWidth[1]) / (zfront[setupid] + layerId * LayerThickness)); + cout << "layer angle " << layer_angle * 180 / acos(-1) << endl; + // DEDE + // xPos = tan( frameref_angle ) * (zfront[setupid] + layerId * + // LayerThickness) - (DetectorSizeX[1]/2. - FrameWidth[1]); // shift + // module along x-axis + xPos = 0; + // DE update gibbets accordingly in lines 3401 ff + if (layerId == 0) { + xPos += 0.0; // offset in x of TRD2D + yPos += 0.0; // offset in y of TRD2D + } + if (layerId == 1) { + xPos += 0.0; // offset in x of upstream TRD1D + yPos += -6.0; // offset in y of upstream TRD1D + } + if (layerId == 2) { + xPos += -6.0; // offset in x of downstream TRD1D + yPos += 0.0; // offset in y of downstream TRD1D + } + cout << "DETRD1D layer " << layerId << " - xPos " << xPos << " - yPos " << yPos << endl; + + layer_angle = + atan((DetectorSizeX[1] / 2. - FrameWidth[1] + xPos) / (zfront[setupid] + layerId * LayerThickness)); + cout << "corrected angle " << layer_angle * 180 / acos(-1) << endl; + + // Double_t frameangle[4] = {0}; + // for ( Int_t ilayer = 3; ilayer >= 0; ilayer--) + // { + // frameangle[ilayer] = atan( (DetectorSizeX[1]/2. - + // FrameWidth[1]) / (zfront[setupid] + ilayer * + // LayerThickness) ); + // cout << "layer " << ilayer << " - angle " << + // frameangle[ilayer] * 180 / acos(-1) << endl; + // + // xPos = (DetectorSizeX[1]/2. - FrameWidth[1]); + // cout << "layer " << ilayer << " - xPos " << xPos << + // endl; + // + // xPos = tan( frameangle[3] ) * (zfront[setupid] + ilayer + // * LayerThickness); + // cout << "layer " << ilayer << " - xPos " << xPos << + // endl; + // + // xPos = (DetectorSizeX[1]/2. - FrameWidth[1]) - ( tan( + // frameangle[3] ) * (zfront[setupid] + ilayer * + // LayerThickness) ); // shift module along x-axis + // cout << "layer " << ilayer << " - xPos " << xPos << + // endl; + // } + + TGeoCombiTrans* module_placement = + new TGeoCombiTrans(xPos, yPos, LayerPosition[layerId] + LayerThickness / 2 + dz, + module_rotation); // shift by half layer thickness + + // add module to layer + gGeoMan->GetVolume(layername)->AddNode(gModules[type - 1], copy, module_placement); + // + } + } + } + } + + // install TRD2D detectors in the TRD setup + Int_t type = -1; + if (layerId == 1 && layerType == 2) type = 10; + if (layerId == 0 && layerType == 2) type = 9; + if (type < 0) return; + Info("create_detector_layers", "add module[0x%p] of type[%d]", (void*) gModules[type - 1], type); + + // Set positions of the TRD2D wrt front TRD1D + Double_t xPos = 0.5 * DetectorSizeX[2]; + + Double_t yPos = 2.5 * 5.12; // check with FASPRO_width; + Double_t zPos = 0.; + + if (layerId == 0) { + xPos = 0; + yPos = 0; + zPos = 9.8; // 2024 - relative to zfront + } + if (layerId == 1) { + xPos = xPos - 22.5; + yPos = yPos - 12.5; + zPos = 3.0; + } + + // AB 05.05.2022 + // update position of the TRD2D wrt the center of FEE operated area + xPos += -3.; + + // statistics per layer and module type + ModuleStats[layerId][type - 1]++; + + module_rotation = new TGeoRotation(); + // DESH + TGeoCombiTrans* module_placement = + new TGeoCombiTrans(xPos, yPos, LayerPosition[0] - (layerId - 1) * LayerThickness / 2 + zPos, + module_rotation); // shift by half layer thickness + Int_t copy = copy_nr(1, 1, 0, PlaneId[layerId], 1); + gGeoMan->GetVolume(layername)->AddNode(gModules[type - 1], copy, module_placement); +} + +void create_mag_field_vector() +{ + const TString cbmfield_01 = "cbm_field"; + TGeoVolume* cbmfield_1 = new TGeoVolumeAssembly(cbmfield_01); + + TGeoMedium* copperVolMed = gGeoMan->GetMedium(PadCopperVolumeMedium); // define Volume Medium + + TGeoRotation* rotx090 = new TGeoRotation("rotx090"); + rotx090->RotateX(90.); // rotate 90 deg around x-axis + TGeoRotation* rotx270 = new TGeoRotation("rotx270"); + rotx270->RotateX(270.); // rotate 270 deg around x-axis + + Int_t tube_length = 500; + Int_t cone_length = 120; + Int_t cone_width = 280; + + // field tube + TGeoTube* trd_field = new TGeoTube("", 0., 100 / 2., tube_length / 2.); + TGeoVolume* trdmod1_fieldvol = new TGeoVolume("tube", trd_field, copperVolMed); + trdmod1_fieldvol->SetLineColor(kRed); + trdmod1_fieldvol->SetTransparency(30); // transparency for the TRD + TGeoTranslation* trd_field_trans = new TGeoTranslation("", 0., 0., 0.); // tube position + cbmfield_1->AddNode(trdmod1_fieldvol, 1, trd_field_trans); + + // field cone + TGeoCone* trd_cone = new TGeoCone("", cone_length / 2., 0., cone_width / 2., 0., 0.); + TGeoVolume* trdmod1_conevol = new TGeoVolume("cone", trd_cone, copperVolMed); + trdmod1_conevol->SetLineColor(kRed); + trdmod1_conevol->SetTransparency(30); // transparency for the TRD + TGeoTranslation* trd_cone_trans = new TGeoTranslation("", 0., 0., (tube_length + cone_length) / 2.); // cone position + cbmfield_1->AddNode(trdmod1_conevol, 1, trd_cone_trans); + + TGeoCombiTrans* field_combi01 = new TGeoCombiTrans(0., 0., 40., rotx270); // point in +y direction + gGeoMan->GetVolume(geoVersion)->AddNode(cbmfield_1, 1, field_combi01); + + // TGeoCombiTrans* field_combi02 = new TGeoCombiTrans( 200., 0., 0., + // rotx090); // point in -y direction + // gGeoMan->GetVolume(geoVersion)->AddNode(cbmfield_1, 2, field_combi02); +} + +void create_gibbet_support() +{ + const TString gibbet_01 = "gibbet_bars_trd1"; + TGeoVolume* gibbet_1 = new TGeoVolumeAssembly(gibbet_01); + + TGeoBBox* gibbet1; + TGeoBBox* gibbet2; + TGeoBBox* gibbet3; + TGeoBBox* gibbet4; + + TGeoVolume* gibbet1_vol; + TGeoVolume* gibbet2_vol; + TGeoVolume* gibbet3_vol; + TGeoVolume* gibbet4_vol; + + TGeoTranslation* gibbet1_trans; + TGeoTranslation* gibbet2_trans; + TGeoTranslation* gibbet3_trans; + TGeoTranslation* gibbet4_trans; + TGeoTranslation* gibbet5_trans; + + Int_t x_offset = 0.0; // x position of gibbet rim towards module + // Int_t x_offset = -10.0; // x position of gibbet rim towards module + + const Int_t kColor1010n = kAzure + 8; // gibbet color + const Int_t kColor1010s = kGray; // gibbet color + const Int_t kColor0305n = kBlue; // gibbet color + + TGeoMedium* k1010nVolMed = gGeoMan->GetMedium(Kanya10x10nVolumeMedium); + TGeoMedium* k1010sVolMed = gGeoMan->GetMedium(Kanya10x10sVolumeMedium); + TGeoMedium* k0305nVolMed = gGeoMan->GetMedium(Kanya03x05nVolumeMedium); + + const Int_t kanya01 = 105; // kanyahoritop + const Int_t kanya02 = 90; // kanyavertnear + const Int_t kanya03 = 150; // kanyavertpill + + const Int_t gapx = 5; // gap in x direction + const Int_t gapy = 2; // gap in y direction + const Int_t gapxpill = 2; // gap in x direction between vertical pillars + + // horizontal gibbet 2020 + gibbet1 = new TGeoBBox("gibbet1", kanya01 / 2., gibbet_width / 2., gibbet_thickness / 2.); + gibbet1_vol = new TGeoVolume("gibbetvol1", gibbet1, k1010nVolMed); + gibbet1_vol->SetLineColor(kColor1010n); + + // translations + gibbet1_trans = new TGeoTranslation("", (kanya01 - DetectorSizeX[1]) / 2. - gapx + x_offset, + (DetectorSizeY[1] + gibbet_width) / 2. + gapy, 0.); + gibbet_1->AddNode(gibbet1_vol, 1, gibbet1_trans); + + // vertical gibbet 2020 + gibbet2 = new TGeoBBox("gibbet2", gibbet_width / 2., kanya02 / 2., gibbet_thickness / 2.); + gibbet2_vol = new TGeoVolume("gibbetvol2", gibbet2, k1010nVolMed); + gibbet2_vol->SetLineColor(kColor1010n); + + // translations + gibbet2_trans = new TGeoTranslation("", -(DetectorSizeX[1] + gibbet_width) / 2. - gapx + x_offset, + (DetectorSizeY[1] - kanya02) / 2. + gapy + 2 * gibbet_width, 0.); + gibbet_1->AddNode(gibbet2_vol, 2, gibbet2_trans); + + // vertical gibbet pillar 2020 + gibbet3 = new TGeoBBox("gibbet3", gibbet_width / 2., kanya03 / 2., gibbet_thickness / 2.); + gibbet3_vol = new TGeoVolume("gibbetvol3", gibbet3, k1010sVolMed); + gibbet3_vol->SetLineColor(kColor1010s); + + // translations + gibbet3_trans = + new TGeoTranslation("", -(DetectorSizeX[1] + 3 * gibbet_width) / 2. - gapx - gapxpill + x_offset, 0., 0.); + gibbet_1->AddNode(gibbet3_vol, 3, gibbet3_trans); + + // vertical mount rails 2020 + gibbet4 = new TGeoBBox("gibbet4", rail_width / 2., (DetectorSizeY[1] + gapy) / 2., rail_thickness / 2.); + gibbet4_vol = new TGeoVolume("gibbetvol4", gibbet4, k0305nVolMed); + gibbet4_vol->SetLineColor(kColor0305n); + + // translations + gibbet4_trans = new TGeoTranslation("", -(DetectorSizeX[1] - rail_width) / 2. + x_offset, +gapy / 2., 0.); + gibbet_1->AddNode(gibbet4_vol, 4, gibbet4_trans); + + // translations + gibbet5_trans = new TGeoTranslation("", (DetectorSizeX[1] - rail_width) / 2. + x_offset, +gapy / 2., 0.); + gibbet_1->AddNode(gibbet4_vol, 5, gibbet5_trans); + + Int_t l; + Double_t xPos = 0; + Double_t yPos = 0; + for (l = 0; l < 4; l++) + if ((ShowLayer[l]) && (BusBarOrientation[l] == 1)) // if geometry contains layer l + { + TString layername = Form("layer%02d", l + 1); + if (l == 0) { + xPos = 0.0; // offset in x of TRD2D + yPos = 0.0; // offset in y of TRD2D + } + if (l == 1) { + xPos = 0.0; // offset in x of upstream TRD1D + yPos = -6.0; // offset in y of upstream TRD1D + } + if (l == 2) { + xPos = -6.0; // offset in x of downstream TRD1D + yPos = 0.0; // offset in y of downstream TRD1D + } + TGeoTranslation* gibbet_placement = + new TGeoTranslation(xPos, yPos, LayerPosition[l] + LayerThickness / 2. + gibbet_position); + gGeoMan->GetVolume(layername)->AddNode(gibbet_1, l, gibbet_placement); + } +} + +void create_power_bars_vertical() +{ + const TString power_01 = "power_bars_trd1"; + TGeoVolume* power_1 = new TGeoVolumeAssembly(power_01); + + TGeoBBox* power1; + TGeoBBox* power2; + + TGeoVolume* power1_vol; + TGeoVolume* power2_vol; + + TGeoTranslation* power1_trans; + TGeoTranslation* power2_trans; + + const Int_t kColor = kBlue; // bus bar color + + TGeoMedium* powerBusVolMed = gGeoMan->GetMedium(PowerBusVolumeMedium); + + // powerbus - horizontal short + power1 = new TGeoBBox("power1", (DetectorSizeX[1] - DetectorSizeX[0] - powerbar_width) / 2., powerbar_width / 2., + powerbar_thickness / 2.); + power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed); + power1_vol->SetLineColor(kColor); + + // translations + power1_trans = new TGeoTranslation("", 1 * (DetectorSizeX[1] - DetectorSizeY[0] / 2.), 1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power1_vol, 1, power1_trans); + + power1_trans = new TGeoTranslation("", -1 * (DetectorSizeX[1] - DetectorSizeY[0] / 2.), -1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power1_vol, 2, power1_trans); + + // powerbus - horizontal long + power1 = + new TGeoBBox("power1", (DetectorSizeX[0] - powerbar_width) / 2., powerbar_width / 2., powerbar_thickness / 2.); + power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed); + power1_vol->SetLineColor(kColor); + + // translations + power1_trans = new TGeoTranslation("", -1 * DetectorSizeX[0], 1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power1_vol, 3, power1_trans); + + power1_trans = new TGeoTranslation("", 1 * DetectorSizeX[0], -1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power1_vol, 4, power1_trans); + + // powerbus - vertical long + power2 = + new TGeoBBox("power2", powerbar_width / 2., (5 * DetectorSizeY[1] + powerbar_width) / 2., powerbar_thickness / 2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", -3.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 1, power2_trans); + power2_trans = new TGeoTranslation("", 3.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 2, power2_trans); + + power2_trans = new TGeoTranslation("", -2.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 3, power2_trans); + power2_trans = new TGeoTranslation("", 2.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 4, power2_trans); + + power2_trans = new TGeoTranslation("", -1.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 5, power2_trans); + power2_trans = new TGeoTranslation("", 1.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 6, power2_trans); + + // powerbus - vertical middle + power2 = + new TGeoBBox("power2", powerbar_width / 2., (3 * DetectorSizeY[1] + powerbar_width) / 2., powerbar_thickness / 2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", -1.5 * DetectorSizeX[0], 0., 0.); + power_1->AddNode(power2_vol, 7, power2_trans); + power2_trans = new TGeoTranslation("", 1.5 * DetectorSizeX[0], 0., 0.); + power_1->AddNode(power2_vol, 8, power2_trans); + + // powerbus - vertical short 1 + power2 = new TGeoBBox("power2", powerbar_width / 2., 1 * DetectorSizeY[1] / 2., powerbar_thickness / 2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + // power2_vol->SetLineColor(kRed); + + // translations + power2_trans = new TGeoTranslation("", -0.5 * DetectorSizeX[1], (2.0 * DetectorSizeY[1] + powerbar_width / 2.), 0.); + power_1->AddNode(power2_vol, 9, power2_trans); + power2_trans = new TGeoTranslation("", 0.5 * DetectorSizeX[1], -(2.0 * DetectorSizeY[1] + powerbar_width / 2.), 0.); + power_1->AddNode(power2_vol, 10, power2_trans); + + // powerbus - vertical short 2 + power2 = + new TGeoBBox("power2", powerbar_width / 2., (1 * DetectorSizeY[1] + powerbar_width) / 2., powerbar_thickness / 2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", -0.5 * DetectorSizeX[1], -2.0 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 11, power2_trans); + power2_trans = new TGeoTranslation("", 0.5 * DetectorSizeX[1], 2.0 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 12, power2_trans); + + // powerbus - vertical short 3 + power2 = new TGeoBBox("power2", powerbar_width / 2., (2 * DetectorSizeY[0] + powerbar_width / 2.) / 2., + powerbar_thickness / 2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", -0.5 * DetectorSizeX[0], (1.5 * DetectorSizeY[0] + powerbar_width / 4.), 0.); + power_1->AddNode(power2_vol, 11, power2_trans); + power2_trans = new TGeoTranslation("", 0.5 * DetectorSizeX[0], -(1.5 * DetectorSizeY[0] + powerbar_width / 4.), 0.); + power_1->AddNode(power2_vol, 12, power2_trans); + + Int_t l; + for (l = 0; l < 4; l++) + if ((ShowLayer[l]) && (BusBarOrientation[l] == 1)) // if geometry contains layer l + { + TString layername = Form("layer%02d", l + 1); + TGeoTranslation* power_placement = + new TGeoTranslation(0, 0, LayerPosition[l] + LayerThickness / 2. + powerbar_position); + gGeoMan->GetVolume(layername)->AddNode(power_1, l, power_placement); + } +} + +void create_power_bars_horizontal() +{ + const TString power_01 = "power_bars_trd1"; + TGeoVolume* power_1 = new TGeoVolumeAssembly(power_01); + + TGeoBBox* power1; + TGeoBBox* power2; + + TGeoVolume* power1_vol; + TGeoVolume* power2_vol; + + TGeoTranslation* power1_trans; + TGeoTranslation* power2_trans; + + const Int_t kColor = kBlue; // bus bar color + + TGeoMedium* powerBusVolMed = gGeoMan->GetMedium(PowerBusVolumeMedium); + + // powerbus - vertical short + power1 = new TGeoBBox("power1", powerbar_width / 2., (DetectorSizeY[1] - DetectorSizeY[0] - powerbar_width) / 2., + powerbar_thickness / 2.); + power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed); + power1_vol->SetLineColor(kColor); + + // translations + power1_trans = new TGeoTranslation("", 1.5 * DetectorSizeX[1], -1 * (DetectorSizeY[1] - DetectorSizeY[0] / 2.), 0.); + power_1->AddNode(power1_vol, 1, power1_trans); + + power1_trans = new TGeoTranslation("", -1.5 * DetectorSizeX[1], 1 * (DetectorSizeY[1] - DetectorSizeY[0] / 2.), 0.); + power_1->AddNode(power1_vol, 2, power1_trans); + + // powerbus - vertical long + power1 = + new TGeoBBox("power1", powerbar_width / 2., (DetectorSizeY[0] - powerbar_width) / 2., powerbar_thickness / 2.); + power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed); + power1_vol->SetLineColor(kColor); + + // translations + power1_trans = new TGeoTranslation("", 1.5 * DetectorSizeX[1], 1 * DetectorSizeY[0], 0.); + power_1->AddNode(power1_vol, 3, power1_trans); + + power1_trans = new TGeoTranslation("", -1.5 * DetectorSizeX[1], -1 * DetectorSizeY[0], 0.); + power_1->AddNode(power1_vol, 4, power1_trans); + + // powerbus - horizontal long + power2 = + new TGeoBBox("power2", (7 * DetectorSizeX[1] + powerbar_width) / 2., powerbar_width / 2., powerbar_thickness / 2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", 0., -2.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 1, power2_trans); + power2_trans = new TGeoTranslation("", 0., 2.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 2, power2_trans); + + power2_trans = new TGeoTranslation("", 0., -1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 3, power2_trans); + power2_trans = new TGeoTranslation("", 0., 1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 4, power2_trans); + + // powerbus - horizontal middle + power2 = + new TGeoBBox("power2", (3 * DetectorSizeX[1] + powerbar_width) / 2., powerbar_width / 2., powerbar_thickness / 2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", 0., -1.5 * DetectorSizeY[0], 0.); + power_1->AddNode(power2_vol, 7, power2_trans); + power2_trans = new TGeoTranslation("", 0., 1.5 * DetectorSizeY[0], 0.); + power_1->AddNode(power2_vol, 8, power2_trans); + + // powerbus - horizontal short 1 + power2 = new TGeoBBox("power2", 2 * DetectorSizeX[1] / 2., powerbar_width / 2., powerbar_thickness / 2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + // power2_vol->SetLineColor(kRed); + + // translations + power2_trans = new TGeoTranslation("", (2.5 * DetectorSizeX[1] + powerbar_width / 2.), 0.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 9, power2_trans); + power2_trans = new TGeoTranslation("", -(2.5 * DetectorSizeX[1] + powerbar_width / 2.), -0.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 10, power2_trans); + + // powerbus - horizontal short 2 + power2 = + new TGeoBBox("power2", (2 * DetectorSizeX[1] + powerbar_width) / 2., powerbar_width / 2., powerbar_thickness / 2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", -2.5 * DetectorSizeX[1], 0.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 11, power2_trans); + power2_trans = new TGeoTranslation("", 2.5 * DetectorSizeX[1], -0.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 12, power2_trans); + + // powerbus - horizontal short 3 + power2 = new TGeoBBox("power2", (2 * DetectorSizeX[0] + powerbar_width / 2.) / 2., powerbar_width / 2., + powerbar_thickness / 2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", (1.5 * DetectorSizeX[0] + powerbar_width / 4.), 0.5 * DetectorSizeY[0], 0.); + power_1->AddNode(power2_vol, 11, power2_trans); + power2_trans = new TGeoTranslation("", -(1.5 * DetectorSizeX[0] + powerbar_width / 4.), -0.5 * DetectorSizeY[0], 0.); + power_1->AddNode(power2_vol, 12, power2_trans); + + Int_t l; + for (l = 0; l < 4; l++) + if ((ShowLayer[l]) && (BusBarOrientation[l] == 0)) // if geometry contains layer l + { + TString layername = Form("layer%02d", l + 1); + TGeoTranslation* power_placement = + new TGeoTranslation(0, 0, LayerPosition[l] + LayerThickness / 2. + powerbar_position); + gGeoMan->GetVolume(layername)->AddNode(power_1, l, power_placement); + } +} + +void create_xtru_supports() +{ + const TString trd_01 = "support_trd1"; + TGeoVolume* trd_1 = new TGeoVolumeAssembly(trd_01); + + const TString trd_02 = "support_trd2"; + TGeoVolume* trd_2 = new TGeoVolumeAssembly(trd_02); + + const TString trd_03 = "support_trd3"; + TGeoVolume* trd_3 = new TGeoVolumeAssembly(trd_03); + + // const TString trdSupport = "supportframe"; + // TGeoVolume* trdsupport = new TGeoVolumeAssembly(trdSupport); + // + // trdsupport->AddNode(trd_1, 1); + // trdsupport->AddNode(trd_2, 2); + // trdsupport->AddNode(trd_3, 3); + + TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium); // define Volume Medium + + const Double_t x[12] = {-15, -15, -1, -1, -15, -15, 15, 15, 1, 1, 15, 15}; // IPB 400 + const Double_t y[12] = {-20, -18, -18, 18, 18, 20, + 20, 18, 18, -18, -18, -20}; // 30 x 40 cm in size, 2 cm wall thickness + const Double_t Hwid = -2 * x[0]; // 30 + const Double_t Hhei = -2 * y[0]; // 40 + + Double_t AperX[3] = {450., 550., 600.}; // inner aperture in X of support structure for stations 1,2,3 + Double_t AperY[3] = {350., 450., 500.}; // inner aperture in Y of support structure for stations 1,2,3 + Double_t PilPosX; + Double_t BarPosY; + + const Double_t BeamHeight = 570; // beamline is at 5.7m above floor + + Double_t PilPosZ[6]; // PilPosZ + // PilPosZ[0] = LayerPosition[0] + LayerThickness/2.; + // PilPosZ[1] = LayerPosition[3] + LayerThickness/2.; + // PilPosZ[2] = LayerPosition[4] + LayerThickness/2.; + // PilPosZ[3] = LayerPosition[7] + LayerThickness/2.; + // PilPosZ[4] = LayerPosition[8] + LayerThickness/2.; + // PilPosZ[5] = LayerPosition[9] + LayerThickness/2.; + + PilPosZ[0] = LayerPosition[0] + 15; + PilPosZ[1] = LayerPosition[3] - 15 + LayerThickness; + PilPosZ[2] = LayerPosition[4] + 15; + PilPosZ[3] = LayerPosition[7] - 15 + LayerThickness; + PilPosZ[4] = LayerPosition[8] + 15; + PilPosZ[5] = LayerPosition[9] - 15 + LayerThickness; + + // cout << "PilPosZ[0]: " << PilPosZ[0] << endl; + // cout << "PilPosZ[1]: " << PilPosZ[1] << endl; + + TGeoRotation* rotx090 = new TGeoRotation("rotx090"); + rotx090->RotateX(90.); // rotate 90 deg around x-axis + TGeoRotation* roty090 = new TGeoRotation("roty090"); + roty090->RotateY(90.); // rotate 90 deg around y-axis + TGeoRotation* rotz090 = new TGeoRotation("rotz090"); + rotz090->RotateZ(90.); // rotate 90 deg around y-axis + TGeoRotation* roty270 = new TGeoRotation("roty270"); + roty270->RotateY(270.); // rotate 270 deg around y-axis + + TGeoRotation* rotzx01 = new TGeoRotation("rotzx01"); + rotzx01->RotateZ(90.); // rotate 90 deg around z-axis + rotzx01->RotateX(90.); // rotate 90 deg around x-axis + + // TGeoRotation *rotxz01 = new TGeoRotation("rotxz01"); + // rotxz01->RotateX( 90.); // rotate 90 deg around x-axis + // rotxz01->RotateZ( 90.); // rotate 90 deg around z-axis + + Double_t ang1 = atan(3. / 4.) * 180. / acos(-1.); + // cout << "DEDE " << ang1 << endl; + // Double_t sin1 = acos(-1.); + // cout << "DEDE " << sin1 << endl; + TGeoRotation* rotx080 = new TGeoRotation("rotx080"); + rotx080->RotateX(90. - ang1); // rotate 80 deg around x-axis + TGeoRotation* rotx100 = new TGeoRotation("rotx100"); + rotx100->RotateX(90. + ang1); // rotate 100 deg around x-axis + + TGeoRotation* rotxy01 = new TGeoRotation("rotxy01"); + rotxy01->RotateX(90.); // rotate 90 deg around x-axis + rotxy01->RotateZ(-ang1); // rotate ang1 around rotated y-axis + + TGeoRotation* rotxy02 = new TGeoRotation("rotxy02"); + rotxy02->RotateX(90.); // rotate 90 deg around x-axis + rotxy02->RotateZ(ang1); // rotate ang1 around rotated y-axis + + //------------------- + // vertical pillars (Y) + //------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + TGeoXtru* trd_H_vert1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_vert1->DefinePolygon(12, x, y); + trd_H_vert1->DefineSection(0, -(AperY[0] + Hhei), 0, 0, 1.0); + trd_H_vert1->DefineSection(1, BeamHeight, 0, 0, 1.0); + TGeoVolume* trd_H_vert_vol1 = new TGeoVolume("trd_H_y_01", trd_H_vert1, aluminiumVolMed); + trd_H_vert_vol1->SetLineColor(kYellow); + PilPosX = AperX[0]; + + TGeoCombiTrans* trd_H_vert_combi01 = new TGeoCombiTrans((PilPosX + Hhei / 2.), 0., PilPosZ[0], rotzx01); + trd_1->AddNode(trd_H_vert_vol1, 11, trd_H_vert_combi01); + TGeoCombiTrans* trd_H_vert_combi02 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), 0., PilPosZ[0], rotzx01); + trd_1->AddNode(trd_H_vert_vol1, 12, trd_H_vert_combi02); + TGeoCombiTrans* trd_H_vert_combi03 = new TGeoCombiTrans((PilPosX + Hhei / 2.), 0., PilPosZ[1], rotzx01); + trd_1->AddNode(trd_H_vert_vol1, 13, trd_H_vert_combi03); + TGeoCombiTrans* trd_H_vert_combi04 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), 0., PilPosZ[1], rotzx01); + trd_1->AddNode(trd_H_vert_vol1, 14, trd_H_vert_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoXtru* trd_H_vert1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_vert1->DefinePolygon(12, x, y); + trd_H_vert1->DefineSection(0, -(AperY[1] + Hhei), 0, 0, 1.0); + trd_H_vert1->DefineSection(1, BeamHeight, 0, 0, 1.0); + TGeoVolume* trd_H_vert_vol1 = new TGeoVolume("trd_H_y_02", trd_H_vert1, aluminiumVolMed); + trd_H_vert_vol1->SetLineColor(kYellow); + PilPosX = AperX[1]; + + TGeoCombiTrans* trd_H_vert_combi01 = new TGeoCombiTrans((PilPosX + Hhei / 2.), 0., PilPosZ[2], rotzx01); + trd_2->AddNode(trd_H_vert_vol1, 21, trd_H_vert_combi01); + TGeoCombiTrans* trd_H_vert_combi02 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), 0., PilPosZ[2], rotzx01); + trd_2->AddNode(trd_H_vert_vol1, 22, trd_H_vert_combi02); + TGeoCombiTrans* trd_H_vert_combi03 = new TGeoCombiTrans((PilPosX + Hhei / 2.), 0., PilPosZ[3], rotzx01); + trd_2->AddNode(trd_H_vert_vol1, 23, trd_H_vert_combi03); + TGeoCombiTrans* trd_H_vert_combi04 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), 0., PilPosZ[3], rotzx01); + trd_2->AddNode(trd_H_vert_vol1, 24, trd_H_vert_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoXtru* trd_H_vert1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_vert1->DefinePolygon(12, x, y); + trd_H_vert1->DefineSection(0, -(AperY[2] + Hhei), 0, 0, 1.0); + trd_H_vert1->DefineSection(1, BeamHeight, 0, 0, 1.0); + TGeoVolume* trd_H_vert_vol1 = new TGeoVolume("trd_H_y_03", trd_H_vert1, aluminiumVolMed); + trd_H_vert_vol1->SetLineColor(kYellow); + PilPosX = AperX[2]; + + TGeoCombiTrans* trd_H_vert_combi01 = new TGeoCombiTrans((PilPosX + Hhei / 2.), 0., PilPosZ[4], rotzx01); + trd_3->AddNode(trd_H_vert_vol1, 31, trd_H_vert_combi01); + TGeoCombiTrans* trd_H_vert_combi02 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), 0., PilPosZ[4], rotzx01); + trd_3->AddNode(trd_H_vert_vol1, 32, trd_H_vert_combi02); + TGeoCombiTrans* trd_H_vert_combi03 = new TGeoCombiTrans((PilPosX + Hhei / 2.), 0., PilPosZ[5], rotzx01); + trd_3->AddNode(trd_H_vert_vol1, 33, trd_H_vert_combi03); + TGeoCombiTrans* trd_H_vert_combi04 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), 0., PilPosZ[5], rotzx01); + trd_3->AddNode(trd_H_vert_vol1, 34, trd_H_vert_combi04); + } + + //------------------- + // horizontal supports (X) + //------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + TGeoXtru* trd_H_hori1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_hori1->DefinePolygon(12, x, y); + trd_H_hori1->DefineSection(0, -AperX[0], 0, 0, 1.0); + trd_H_hori1->DefineSection(1, AperX[0], 0, 0, 1.0); + TGeoVolume* trd_H_hori_vol1 = new TGeoVolume("trd_H_x_01", trd_H_hori1, aluminiumVolMed); + trd_H_hori_vol1->SetLineColor(kRed); + BarPosY = AperY[0]; + + TGeoCombiTrans* trd_H_hori_combi01 = new TGeoCombiTrans(0., (BarPosY + Hhei / 2.), PilPosZ[0], roty090); + trd_1->AddNode(trd_H_hori_vol1, 11, trd_H_hori_combi01); + TGeoCombiTrans* trd_H_hori_combi02 = new TGeoCombiTrans(0., -(BarPosY + Hhei / 2.), PilPosZ[0], roty090); + trd_1->AddNode(trd_H_hori_vol1, 12, trd_H_hori_combi02); + TGeoCombiTrans* trd_H_hori_combi03 = new TGeoCombiTrans(0., (BarPosY + Hhei / 2.), PilPosZ[1], roty090); + trd_1->AddNode(trd_H_hori_vol1, 13, trd_H_hori_combi03); + TGeoCombiTrans* trd_H_hori_combi04 = new TGeoCombiTrans(0., -(BarPosY + Hhei / 2.), PilPosZ[1], roty090); + trd_1->AddNode(trd_H_hori_vol1, 14, trd_H_hori_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoXtru* trd_H_hori1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_hori1->DefinePolygon(12, x, y); + trd_H_hori1->DefineSection(0, -AperX[1], 0, 0, 1.0); + trd_H_hori1->DefineSection(1, AperX[1], 0, 0, 1.0); + TGeoVolume* trd_H_hori_vol1 = new TGeoVolume("trd_H_x_02", trd_H_hori1, aluminiumVolMed); + trd_H_hori_vol1->SetLineColor(kRed); + BarPosY = AperY[1]; + + TGeoCombiTrans* trd_H_hori_combi01 = new TGeoCombiTrans(0., (BarPosY + Hhei / 2.), PilPosZ[2], roty090); + trd_2->AddNode(trd_H_hori_vol1, 21, trd_H_hori_combi01); + TGeoCombiTrans* trd_H_hori_combi02 = new TGeoCombiTrans(0., -(BarPosY + Hhei / 2.), PilPosZ[2], roty090); + trd_2->AddNode(trd_H_hori_vol1, 22, trd_H_hori_combi02); + TGeoCombiTrans* trd_H_hori_combi03 = new TGeoCombiTrans(0., (BarPosY + Hhei / 2.), PilPosZ[3], roty090); + trd_2->AddNode(trd_H_hori_vol1, 23, trd_H_hori_combi03); + TGeoCombiTrans* trd_H_hori_combi04 = new TGeoCombiTrans(0., -(BarPosY + Hhei / 2.), PilPosZ[3], roty090); + trd_2->AddNode(trd_H_hori_vol1, 24, trd_H_hori_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoXtru* trd_H_hori1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_hori1->DefinePolygon(12, x, y); + trd_H_hori1->DefineSection(0, -AperX[2], 0, 0, 1.0); + trd_H_hori1->DefineSection(1, AperX[2], 0, 0, 1.0); + TGeoVolume* trd_H_hori_vol1 = new TGeoVolume("trd_H_x_03", trd_H_hori1, aluminiumVolMed); + trd_H_hori_vol1->SetLineColor(kRed); + BarPosY = AperY[2]; + + TGeoCombiTrans* trd_H_hori_combi01 = new TGeoCombiTrans(0., (BarPosY + Hhei / 2.), PilPosZ[4], roty090); + trd_3->AddNode(trd_H_hori_vol1, 31, trd_H_hori_combi01); + TGeoCombiTrans* trd_H_hori_combi02 = new TGeoCombiTrans(0., -(BarPosY + Hhei / 2.), PilPosZ[4], roty090); + trd_3->AddNode(trd_H_hori_vol1, 32, trd_H_hori_combi02); + TGeoCombiTrans* trd_H_hori_combi03 = new TGeoCombiTrans(0., (BarPosY + Hhei / 2.), PilPosZ[5], roty090); + trd_3->AddNode(trd_H_hori_vol1, 33, trd_H_hori_combi03); + TGeoCombiTrans* trd_H_hori_combi04 = new TGeoCombiTrans(0., -(BarPosY + Hhei / 2.), PilPosZ[5], roty090); + trd_3->AddNode(trd_H_hori_vol1, 34, trd_H_hori_combi04); + } + + //------------------- + // horizontal supports (Z) + //------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + TGeoXtru* trd_H_slope1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_slope1->DefinePolygon(12, x, y); + trd_H_slope1->DefineSection(0, -(PilPosZ[1] - PilPosZ[0] - Hwid) / 2., 0, 0, 1.0); + trd_H_slope1->DefineSection(1, +(PilPosZ[1] - PilPosZ[0] - Hwid) / 2., 0, 0, 1.0); + TGeoVolume* trd_H_slope_vol1 = new TGeoVolume("trd_H_z_01", trd_H_slope1, aluminiumVolMed); + trd_H_slope_vol1->SetLineColor(kGreen); + PilPosX = AperX[0]; + BarPosY = AperY[0]; + + TGeoCombiTrans* trd_H_slope_combi01 = + new TGeoCombiTrans((PilPosX + Hhei / 2.), (BarPosY + Hhei - Hwid / 2.), (PilPosZ[0] + PilPosZ[1]) / 2., rotz090); + trd_1->AddNode(trd_H_slope_vol1, 11, trd_H_slope_combi01); + TGeoCombiTrans* trd_H_slope_combi02 = + new TGeoCombiTrans(-(PilPosX + Hhei / 2.), (BarPosY + Hhei - Hwid / 2.), (PilPosZ[0] + PilPosZ[1]) / 2., rotz090); + trd_1->AddNode(trd_H_slope_vol1, 12, trd_H_slope_combi02); + TGeoCombiTrans* trd_H_slope_combi03 = + new TGeoCombiTrans((PilPosX + Hhei / 2.), -(BarPosY + Hhei - Hwid / 2.), (PilPosZ[0] + PilPosZ[1]) / 2., rotz090); + trd_1->AddNode(trd_H_slope_vol1, 13, trd_H_slope_combi03); + TGeoCombiTrans* trd_H_slope_combi04 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), -(BarPosY + Hhei - Hwid / 2.), + (PilPosZ[0] + PilPosZ[1]) / 2., rotz090); + trd_1->AddNode(trd_H_slope_vol1, 14, trd_H_slope_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoXtru* trd_H_slope1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_slope1->DefinePolygon(12, x, y); + trd_H_slope1->DefineSection(0, -(PilPosZ[3] - PilPosZ[2] - Hwid) / 2., 0, 0, 1.0); + trd_H_slope1->DefineSection(1, +(PilPosZ[3] - PilPosZ[2] - Hwid) / 2., 0, 0, 1.0); + TGeoVolume* trd_H_slope_vol1 = new TGeoVolume("trd_H_z_02", trd_H_slope1, aluminiumVolMed); + trd_H_slope_vol1->SetLineColor(kGreen); + PilPosX = AperX[1]; + BarPosY = AperY[1]; + + TGeoCombiTrans* trd_H_slope_combi01 = + new TGeoCombiTrans((PilPosX + Hhei / 2.), (BarPosY + Hhei - Hwid / 2.), (PilPosZ[2] + PilPosZ[3]) / 2., rotz090); + trd_2->AddNode(trd_H_slope_vol1, 21, trd_H_slope_combi01); + TGeoCombiTrans* trd_H_slope_combi02 = + new TGeoCombiTrans(-(PilPosX + Hhei / 2.), (BarPosY + Hhei - Hwid / 2.), (PilPosZ[2] + PilPosZ[3]) / 2., rotz090); + trd_2->AddNode(trd_H_slope_vol1, 22, trd_H_slope_combi02); + TGeoCombiTrans* trd_H_slope_combi03 = + new TGeoCombiTrans((PilPosX + Hhei / 2.), -(BarPosY + Hhei - Hwid / 2.), (PilPosZ[2] + PilPosZ[3]) / 2., rotz090); + trd_2->AddNode(trd_H_slope_vol1, 23, trd_H_slope_combi03); + TGeoCombiTrans* trd_H_slope_combi04 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), -(BarPosY + Hhei - Hwid / 2.), + (PilPosZ[2] + PilPosZ[3]) / 2., rotz090); + trd_2->AddNode(trd_H_slope_vol1, 24, trd_H_slope_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoXtru* trd_H_slope1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_slope1->DefinePolygon(12, x, y); + trd_H_slope1->DefineSection(0, -(PilPosZ[5] - PilPosZ[4] - Hwid) / 2., 0, 0, 1.0); + trd_H_slope1->DefineSection(1, +(PilPosZ[5] - PilPosZ[4] - Hwid) / 2., 0, 0, 1.0); + TGeoVolume* trd_H_slope_vol1 = new TGeoVolume("trd_H_z_03", trd_H_slope1, aluminiumVolMed); + trd_H_slope_vol1->SetLineColor(kGreen); + PilPosX = AperX[2]; + BarPosY = AperY[2]; + + TGeoCombiTrans* trd_H_slope_combi01 = + new TGeoCombiTrans((PilPosX + Hhei / 2.), (BarPosY + Hhei - Hwid / 2.), (PilPosZ[4] + PilPosZ[5]) / 2., rotz090); + trd_3->AddNode(trd_H_slope_vol1, 31, trd_H_slope_combi01); + TGeoCombiTrans* trd_H_slope_combi02 = + new TGeoCombiTrans(-(PilPosX + Hhei / 2.), (BarPosY + Hhei - Hwid / 2.), (PilPosZ[4] + PilPosZ[5]) / 2., rotz090); + trd_3->AddNode(trd_H_slope_vol1, 32, trd_H_slope_combi02); + TGeoCombiTrans* trd_H_slope_combi03 = + new TGeoCombiTrans((PilPosX + Hhei / 2.), -(BarPosY + Hhei - Hwid / 2.), (PilPosZ[4] + PilPosZ[5]) / 2., rotz090); + trd_3->AddNode(trd_H_slope_vol1, 33, trd_H_slope_combi03); + TGeoCombiTrans* trd_H_slope_combi04 = new TGeoCombiTrans(-(PilPosX + Hhei / 2.), -(BarPosY + Hhei - Hwid / 2.), + (PilPosZ[4] + PilPosZ[5]) / 2., rotz090); + trd_3->AddNode(trd_H_slope_vol1, 34, trd_H_slope_combi04); + } + + if (IncludeLabels) { + + Int_t text_height = 40; + Int_t text_thickness = 8; + + TGeoTranslation* tr200 = + new TGeoTranslation(0., (AperY[0] + Hhei + text_height / 2.), PilPosZ[0] - 15 + text_thickness / 2.); + TGeoTranslation* tr201 = + new TGeoTranslation(0., (AperY[1] + Hhei + text_height / 2.), PilPosZ[2] - 15 + text_thickness / 2.); + TGeoTranslation* tr202 = + new TGeoTranslation(0., (AperY[2] + Hhei + text_height / 2.), PilPosZ[4] - 15 + text_thickness / 2.); + + TGeoCombiTrans* tr203 = + new TGeoCombiTrans(-(AperX[0] + Hhei + text_thickness / 2.), (AperY[0] + Hhei - Hwid - text_height / 2.), + (PilPosZ[0] + PilPosZ[1]) / 2., roty090); + TGeoCombiTrans* tr204 = + new TGeoCombiTrans(-(AperX[1] + Hhei + text_thickness / 2.), (AperY[1] + Hhei - Hwid - text_height / 2.), + (PilPosZ[2] + PilPosZ[3]) / 2., roty090); + TGeoCombiTrans* tr205 = + new TGeoCombiTrans(-(AperX[2] + Hhei + text_thickness / 2.), (AperY[2] + Hhei - Hwid - text_height / 2.), + (PilPosZ[4] + PilPosZ[5]) / 2., roty090); + + TGeoCombiTrans* tr206 = + new TGeoCombiTrans((AperX[0] + Hhei + text_thickness / 2.), (AperY[0] + Hhei - Hwid - text_height / 2.), + (PilPosZ[0] + PilPosZ[1]) / 2., roty270); + TGeoCombiTrans* tr207 = + new TGeoCombiTrans((AperX[1] + Hhei + text_thickness / 2.), (AperY[1] + Hhei - Hwid - text_height / 2.), + (PilPosZ[2] + PilPosZ[3]) / 2., roty270); + TGeoCombiTrans* tr208 = + new TGeoCombiTrans((AperX[2] + Hhei + text_thickness / 2.), (AperY[2] + Hhei - Hwid - text_height / 2.), + (PilPosZ[4] + PilPosZ[5]) / 2., roty270); + + TGeoVolume* trdbox1 = new TGeoVolumeAssembly("trdbox1"); // volume for TRD text (108, 40, 8) + TGeoVolume* trdbox2 = new TGeoVolumeAssembly("trdbox2"); // volume for TRD text (108, 40, 8) + TGeoVolume* trdbox3 = new TGeoVolumeAssembly("trdbox3"); // volume for TRD text (108, 40, 8) + add_trd_labels(trdbox1, trdbox2, trdbox3); + + // final placement + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + // trd_1->AddNode(trdbox1, 1, tr200); + trd_1->AddNode(trdbox1, 4, tr203); + trd_1->AddNode(trdbox1, 7, tr206); + } + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + // trd_2->AddNode(trdbox2, 2, tr201); + trd_2->AddNode(trdbox2, 5, tr204); + trd_2->AddNode(trdbox2, 8, tr207); + } + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + // trd_3->AddNode(trdbox3, 3, tr202); + trd_3->AddNode(trdbox3, 6, tr205); + trd_3->AddNode(trdbox3, 9, tr208); + } + } + + // gGeoMan->GetVolume(geoVersion)->AddNode(trdsupport,1); + + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_1, 1); + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_2, 2); + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_3, 3); +} + +void add_trd_labels(TGeoVolume* trdbox1, TGeoVolume* trdbox2, TGeoVolume* trdbox3) +{ + // write TRD (the 3 characters) in a simple geometry + TGeoMedium* textVolMed = gGeoMan->GetMedium(TextVolumeMedium); + + Int_t Tcolor = kBlue; // kRed; + Int_t Rcolor = kBlue; // kRed; // kRed; + Int_t Dcolor = kBlue; // kRed; // kYellow; + Int_t Icolor = kBlue; // kRed; + + // define transformations for letter pieces + // T + TGeoTranslation* tr01 = new TGeoTranslation(0., -4., 0.); + TGeoTranslation* tr02 = new TGeoTranslation(0., 16., 0.); + + // R + TGeoTranslation* tr11 = new TGeoTranslation(10, 0., 0.); + TGeoTranslation* tr12 = new TGeoTranslation(2, 0., 0.); + TGeoTranslation* tr13 = new TGeoTranslation(2, 16., 0.); + TGeoTranslation* tr14 = new TGeoTranslation(-2, 8., 0.); + TGeoTranslation* tr15 = new TGeoTranslation(-6, 0., 0.); + + // D + TGeoTranslation* tr21 = new TGeoTranslation(12., 0., 0.); + TGeoTranslation* tr22 = new TGeoTranslation(6., 16., 0.); + TGeoTranslation* tr23 = new TGeoTranslation(6., -16., 0.); + TGeoTranslation* tr24 = new TGeoTranslation(4., 0., 0.); + + // I + TGeoTranslation* tr31 = new TGeoTranslation(0., 0., 0.); + TGeoTranslation* tr32 = new TGeoTranslation(0., 16., 0.); + TGeoTranslation* tr33 = new TGeoTranslation(0., -16., 0.); + + // make letter T + // TGeoVolume *T = geom->MakeBox("T", Vacuum, 25., 25., 5.); + // T->SetVisibility(kFALSE); + TGeoVolume* T = new TGeoVolumeAssembly("Tbox"); // volume for T + + TGeoBBox* Tbar1b = new TGeoBBox("trd_Tbar1b", 4., 16., 4.); // | vertical + TGeoVolume* Tbar1 = new TGeoVolume("Tbar1", Tbar1b, textVolMed); + Tbar1->SetLineColor(Tcolor); + T->AddNode(Tbar1, 1, tr01); + TGeoBBox* Tbar2b = new TGeoBBox("trd_Tbar2b", 16, 4., 4.); // - top + TGeoVolume* Tbar2 = new TGeoVolume("Tbar2", Tbar2b, textVolMed); + Tbar2->SetLineColor(Tcolor); + T->AddNode(Tbar2, 1, tr02); + + // make letter R + // TGeoVolume *R = geom->MakeBox("R", Vacuum, 25., 25., 5.); + // R->SetVisibility(kFALSE); + TGeoVolume* R = new TGeoVolumeAssembly("Rbox"); // volume for R + + TGeoBBox* Rbar1b = new TGeoBBox("trd_Rbar1b", 4., 20, 4.); + TGeoVolume* Rbar1 = new TGeoVolume("Rbar1", Rbar1b, textVolMed); + Rbar1->SetLineColor(Rcolor); + R->AddNode(Rbar1, 1, tr11); + TGeoBBox* Rbar2b = new TGeoBBox("trd_Rbar2b", 4., 4., 4.); + TGeoVolume* Rbar2 = new TGeoVolume("Rbar2", Rbar2b, textVolMed); + Rbar2->SetLineColor(Rcolor); + R->AddNode(Rbar2, 1, tr12); + R->AddNode(Rbar2, 2, tr13); + TGeoTubeSeg* Rtub1b = new TGeoTubeSeg("trd_Rtub1b", 4., 12, 4., 90., 270.); + TGeoVolume* Rtub1 = new TGeoVolume("Rtub1", (TGeoShape*) Rtub1b, textVolMed); + Rtub1->SetLineColor(Rcolor); + R->AddNode(Rtub1, 1, tr14); + TGeoArb8* Rbar3b = new TGeoArb8("trd_Rbar3b", 4.); + TGeoVolume* Rbar3 = new TGeoVolume("Rbar3", Rbar3b, textVolMed); + Rbar3->SetLineColor(Rcolor); + TGeoArb8* arb = (TGeoArb8*) Rbar3->GetShape(); + arb->SetVertex(0, 12., -4.); + arb->SetVertex(1, 0., -20.); + arb->SetVertex(2, -8., -20.); + arb->SetVertex(3, 4., -4.); + arb->SetVertex(4, 12., -4.); + arb->SetVertex(5, 0., -20.); + arb->SetVertex(6, -8., -20.); + arb->SetVertex(7, 4., -4.); + R->AddNode(Rbar3, 1, tr15); + + // make letter D + // TGeoVolume *D = geom->MakeBox("D", Vacuum, 25., 25., 5.); + // D->SetVisibility(kFALSE); + TGeoVolume* D = new TGeoVolumeAssembly("Dbox"); // volume for D + + TGeoBBox* Dbar1b = new TGeoBBox("trd_Dbar1b", 4., 20, 4.); + TGeoVolume* Dbar1 = new TGeoVolume("Dbar1", Dbar1b, textVolMed); + Dbar1->SetLineColor(Dcolor); + D->AddNode(Dbar1, 1, tr21); + TGeoBBox* Dbar2b = new TGeoBBox("trd_Dbar2b", 2., 4., 4.); + TGeoVolume* Dbar2 = new TGeoVolume("Dbar2", Dbar2b, textVolMed); + Dbar2->SetLineColor(Dcolor); + D->AddNode(Dbar2, 1, tr22); + D->AddNode(Dbar2, 2, tr23); + TGeoTubeSeg* Dtub1b = new TGeoTubeSeg("trd_Dtub1b", 12, 20, 4., 90., 270.); + TGeoVolume* Dtub1 = new TGeoVolume("Dtub1", (TGeoShape*) Dtub1b, textVolMed); + Dtub1->SetLineColor(Dcolor); + D->AddNode(Dtub1, 1, tr24); + + // make letter I + TGeoVolume* I = new TGeoVolumeAssembly("Ibox"); // volume for I + + TGeoBBox* Ibar1b = new TGeoBBox("trd_Ibar1b", 4., 12., 4.); // | vertical + TGeoVolume* Ibar1 = new TGeoVolume("Ibar1", Ibar1b, textVolMed); + Ibar1->SetLineColor(Icolor); + I->AddNode(Ibar1, 1, tr31); + TGeoBBox* Ibar2b = new TGeoBBox("trd_Ibar2b", 10., 4., 4.); // - top + TGeoVolume* Ibar2 = new TGeoVolume("Ibar2", Ibar2b, textVolMed); + Ibar2->SetLineColor(Icolor); + I->AddNode(Ibar2, 1, tr32); + I->AddNode(Ibar2, 2, tr33); + + // build text block "TRD" <32> + 8 + <28> + 8 + <32> = 108 + + // TGeoBBox *trdboxb = new TGeoBBox("", 108./2, 40./2, 8./2); + // TGeoVolume *trdbox = new TGeoVolume("trdboxb", trdboxb, textVolMed); + // trdbox->SetVisibility(kFALSE); + + // TGeoVolume* trdbox[0] = new TGeoVolumeAssembly("trdbox1"); // volume for + // TRD text (108, 40, 8) + // TGeoVolume* trdbox[1] = new TGeoVolumeAssembly("trdbox2"); // volume for + // TRD text (108, 40, 8) + // TGeoVolume* trdbox[2] = new TGeoVolumeAssembly("trdbox3"); // volume for + // TRD text (108, 40, 8) + + TGeoTranslation* tr100 = new TGeoTranslation(38., 0., 0.); + TGeoTranslation* tr101 = new TGeoTranslation(0., 0., 0.); + TGeoTranslation* tr102 = new TGeoTranslation(-38., 0., 0.); + + // TGeoTranslation *tr103 = new TGeoTranslation( -70., 0., 0.); // on the + // same line + // TGeoTranslation *tr104 = new TGeoTranslation( -86., 0., 0.); // on the + // same line + // TGeoTranslation *tr105 = new TGeoTranslation(-102., 0., 0.); // on the + // same line + + TGeoTranslation* tr110 = new TGeoTranslation(0., -50., 0.); + TGeoTranslation* tr111 = new TGeoTranslation(8., -50., 0.); + TGeoTranslation* tr112 = new TGeoTranslation(-8., -50., 0.); + TGeoTranslation* tr113 = new TGeoTranslation(16., -50., 0.); + TGeoTranslation* tr114 = new TGeoTranslation(-16., -50., 0.); + + TGeoTranslation* tr200 = new TGeoTranslation(0., 0., 0.); + TGeoTranslation* tr201 = new TGeoTranslation(0., -50., 0.); + TGeoTranslation* tr202 = new TGeoTranslation(0., -100., 0.); + + TGeoTranslation* tr210 = new TGeoTranslation(0., -150., 0.); + TGeoTranslation* tr213 = new TGeoTranslation(16., -150., 0.); + TGeoTranslation* tr214 = new TGeoTranslation(-16., -150., 0.); + + // station 1 + trdbox1->AddNode(T, 1, tr100); + trdbox1->AddNode(R, 1, tr101); + trdbox1->AddNode(D, 1, tr102); + + trdbox1->AddNode(I, 1, tr110); + + // station 2 + trdbox2->AddNode(T, 1, tr100); + trdbox2->AddNode(R, 1, tr101); + trdbox2->AddNode(D, 1, tr102); + + trdbox2->AddNode(I, 1, tr111); + trdbox2->AddNode(I, 2, tr112); + + //// station 3 + // trdbox3->AddNode(T, 1, tr100); + // trdbox3->AddNode(R, 1, tr101); + // trdbox3->AddNode(D, 1, tr102); + // + // trdbox3->AddNode(I, 1, tr110); + // trdbox3->AddNode(I, 2, tr113); + // trdbox3->AddNode(I, 3, tr114); + + // station 3 + trdbox3->AddNode(T, 1, tr200); + trdbox3->AddNode(R, 1, tr201); + trdbox3->AddNode(D, 1, tr202); + + trdbox3->AddNode(I, 1, tr210); + trdbox3->AddNode(I, 2, tr213); + trdbox3->AddNode(I, 3, tr214); + + // TGeoScale *sc100 = new TGeoScale( 36./50., 36./50., 1.); // text is + // vertical 50 cm, H-bar opening is 36 cm + // + // // scale text + // TGeoHMatrix *mat100 = new TGeoHMatrix(""); + // TGeoHMatrix *mat101 = new TGeoHMatrix(""); + // TGeoHMatrix *mat102 = new TGeoHMatrix(""); + // (*mat100) = (*tr100) * (*sc100); + // (*mat101) = (*tr101) * (*sc100); + // (*mat102) = (*tr102) * (*sc100); + // + // trdbox->AddNode(T, 1, mat100); + // trdbox->AddNode(R, 1, mat101); + // trdbox->AddNode(D, 1, mat102); + + // // final placement + // // TGeoTranslation *tr103 = new TGeoTranslation(0., 400., 500.); + // gGeoMan->GetVolume(geoVersion)->AddNode(trdbox, 1, new + // TGeoTranslation(0., 400., 500.)); + // gGeoMan->GetVolume(geoVersion)->AddNode(trdbox, 2, new + // TGeoTranslation(0., 500., 600.)); + // gGeoMan->GetVolume(geoVersion)->AddNode(trdbox, 3, new + // TGeoTranslation(0., 600., 700.)); + + // return trdbox; +} + +void create_box_supports() +{ + const TString trd_01 = "support_trd1"; + TGeoVolume* trd_1 = new TGeoVolumeAssembly(trd_01); + + const TString trd_02 = "support_trd2"; + TGeoVolume* trd_2 = new TGeoVolumeAssembly(trd_02); + + const TString trd_03 = "support_trd3"; + TGeoVolume* trd_3 = new TGeoVolumeAssembly(trd_03); + + // const TString trdSupport = "supportframe"; + // TGeoVolume* trdsupport = new TGeoVolumeAssembly(trdSupport); + // + // trdsupport->AddNode(trd_1, 1); + // trdsupport->AddNode(trd_2, 2); + // trdsupport->AddNode(trd_3, 3); + + TGeoMedium* keepVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium); // define Volume Medium + + const Int_t I_height = 40; // cm // I profile properties + const Int_t I_width = 30; // cm // I profile properties + const Int_t I_thick = 2; // cm // I profile properties + + const Double_t BeamHeight = 570; // beamline is at 5.7m above the floor + const Double_t PlatformHeight = 234; // platform is 2.34m above the floor + const Double_t PlatformOffset = 1; // distance to platform + + // Double_t AperX[3] = { 450., 550., 600.}; // 100 cm modules // inner + // aperture in X of support structure for stations 1,2,3 + // Double_t AperY[3] = { 350., 450., 500.}; // 100 cm modules // inner + // aperture in Y of support structure for stations 1,2,3 + + const Double_t AperX[3] = {4.5 * DetectorSizeX[1], 5.5 * DetectorSizeX[1], + 6 * DetectorSizeX[1]}; // inner aperture in X of + // support structure for + // stations 1,2,3 + const Double_t AperY[3] = {3.5 * DetectorSizeY[1], 4.5 * DetectorSizeY[1], + 5 * DetectorSizeY[1]}; // inner aperture in Y of + // support structure for + // stations 1,2,3 + // platform + const Double_t AperYbot[3] = {BeamHeight - (PlatformHeight + PlatformOffset + I_height), 4.5 * DetectorSizeY[1], + 5 * DetectorSizeY[1]}; // inner aperture for station1 + + const Double_t xBarPosYtop[3] = {AperY[0] + I_height / 2., AperY[1] + I_height / 2., AperY[2] + I_height / 2.}; + const Double_t xBarPosYbot[3] = {AperYbot[0] + I_height / 2., xBarPosYtop[1], xBarPosYtop[2]}; + + const Double_t zBarPosYtop[3] = {AperY[0] + I_height - I_width / 2., AperY[1] + I_height - I_width / 2., + AperY[2] + I_height - I_width / 2.}; + const Double_t zBarPosYbot[3] = {AperYbot[0] + I_height - I_width / 2., zBarPosYtop[1], zBarPosYtop[2]}; + + Double_t PilPosX; + Double_t PilPosZ[6]; // PilPosZ + + PilPosZ[0] = LayerPosition[0] + I_width / 2.; + PilPosZ[1] = LayerPosition[3] - I_width / 2. + LayerThickness; + PilPosZ[2] = LayerPosition[4] + I_width / 2.; + PilPosZ[3] = LayerPosition[7] - I_width / 2. + LayerThickness; + PilPosZ[4] = LayerPosition[8] + I_width / 2.; + PilPosZ[5] = LayerPosition[9] - I_width / 2. + LayerThickness; + + // cout << "PilPosZ[0]: " << PilPosZ[0] << endl; + // cout << "PilPosZ[1]: " << PilPosZ[1] << endl; + + TGeoRotation* rotx090 = new TGeoRotation("rotx090"); + rotx090->RotateX(90.); // rotate 90 deg around x-axis + TGeoRotation* roty090 = new TGeoRotation("roty090"); + roty090->RotateY(90.); // rotate 90 deg around y-axis + TGeoRotation* rotz090 = new TGeoRotation("rotz090"); + rotz090->RotateZ(90.); // rotate 90 deg around y-axis + TGeoRotation* roty270 = new TGeoRotation("roty270"); + roty270->RotateY(270.); // rotate 270 deg around y-axis + + TGeoRotation* rotzx01 = new TGeoRotation("rotzx01"); + rotzx01->RotateZ(90.); // rotate 90 deg around z-axis + rotzx01->RotateX(90.); // rotate 90 deg around x-axis + + TGeoRotation* rotzx02 = new TGeoRotation("rotzx02"); + rotzx02->RotateZ(270.); // rotate 270 deg around z-axis + rotzx02->RotateX(90.); // rotate 90 deg around x-axis + + Double_t ang1 = atan(3. / 4.) * 180. / acos(-1.); + // cout << "DEDE " << ang1 << endl; + // Double_t sin1 = acos(-1.); + // cout << "DEDE " << sin1 << endl; + TGeoRotation* rotx080 = new TGeoRotation("rotx080"); + rotx080->RotateX(90. - ang1); // rotate 80 deg around x-axis + TGeoRotation* rotx100 = new TGeoRotation("rotx100"); + rotx100->RotateX(90. + ang1); // rotate 100 deg around x-axis + + TGeoRotation* rotxy01 = new TGeoRotation("rotxy01"); + rotxy01->RotateX(90.); // rotate 90 deg around x-axis + rotxy01->RotateZ(-ang1); // rotate ang1 around rotated y-axis + + TGeoRotation* rotxy02 = new TGeoRotation("rotxy02"); + rotxy02->RotateX(90.); // rotate 90 deg around x-axis + rotxy02->RotateZ(ang1); // rotate ang1 around rotated y-axis + + //------------------- + // vertical pillars (Y) + //------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + // TGeoBBox* trd_I_vert1_keep = new TGeoBBox("", I_thick /2., I_height + // /2. - I_thick, (BeamHeight + (AperY[0]+I_height) ) /2.); + TGeoBBox* trd_I_vert1_keep = new TGeoBBox("trd_I_vert1_keep", I_thick / 2., I_height / 2. - I_thick, + ((AperYbot[0] + I_height) + (AperY[0] + I_height)) / 2.); + TGeoVolume* trd_I_vert1 = new TGeoVolume("trd_I_y11", trd_I_vert1_keep, aluminiumVolMed); + // TGeoBBox* trd_I_vert2_keep = new TGeoBBox("", I_width /2., + // I_thick /2., (BeamHeight + (AperY[0]+I_height) ) /2.); + TGeoBBox* trd_I_vert2_keep = new TGeoBBox("trd_I_vert2_keep", I_width / 2., I_thick / 2., + ((AperYbot[0] + I_height) + (AperY[0] + I_height)) / 2.); + TGeoVolume* trd_I_vert2 = new TGeoVolume("trd_I_y12", trd_I_vert2_keep, aluminiumVolMed); + + trd_I_vert1->SetLineColor(kGreen); // kBlue); // Yellow); // kOrange); + trd_I_vert2->SetLineColor(kGreen); // kBlue); // Yellow); // kOrange); + + TGeoTranslation* ty01 = new TGeoTranslation("ty01", 0., 0., 0.); + TGeoTranslation* ty02 = new TGeoTranslation("ty02", 0., (I_height - I_thick) / 2., 0.); + TGeoTranslation* ty03 = new TGeoTranslation("ty03", 0., -(I_height - I_thick) / 2., 0.); + + // TGeoBBox* trd_I_vert_vol1_keep = new TGeoBBox("", I_width /2., + // I_height /2., (BeamHeight + (AperY[0]+I_height) ) /2.); + TGeoBBox* trd_I_vert_vol1_keep = new TGeoBBox("trd_I_vert_vol1_keep", I_width / 2., I_height / 2., + ((AperYbot[0] + I_height) + (AperY[0] + I_height)) / 2.); + TGeoVolume* trd_I_vert_vol1 = new TGeoVolume("trd_I_y10", trd_I_vert_vol1_keep, keepVolMed); + + // set green color for keeping volume of I profile, seen with + // gGeoManager->SetVisLevel(2) + trd_I_vert_vol1->SetLineColor(kGreen); + + // build I-bar trd_I_vert_vol1 + trd_I_vert_vol1->AddNode(trd_I_vert1, 1, ty01); + trd_I_vert_vol1->AddNode(trd_I_vert2, 2, ty02); + trd_I_vert_vol1->AddNode(trd_I_vert2, 3, ty03); + + // close gap to horizontal z-bars + TGeoBBox* trd_I_vert3_keep = + new TGeoBBox("trd_I_vert3_keep", (I_width - I_thick) / 2. / 2., I_height / 2. - I_thick, I_thick / 2.); + TGeoVolume* trd_I_vert3 = new TGeoVolume("trd_I_y13", trd_I_vert3_keep, aluminiumVolMed); + trd_I_vert3->SetLineColor(kGreen); + // TGeoTranslation *ty04 = new TGeoTranslation("ty04", (I_thick/2. + + // (I_width-I_thick)/2./2.), 0., -( (AperYbot[0]+I_height) + + // (AperY[0]+I_height) - I_width) /2.); // top + // TGeoTranslation *ty05 = new TGeoTranslation("ty05", (I_thick/2. + + // (I_width-I_thick)/2./2.), 0., ( (AperYbot[0]+I_height) + + // (AperY[0]+I_height) - I_width) /2.); // bottom + TGeoTranslation* ty04 = new TGeoTranslation("ty04", (I_thick / 2. + (I_width - I_thick) / 2. / 2.), 0., + -(zBarPosYbot[0] + zBarPosYtop[0]) / 2.); // top + TGeoTranslation* ty05 = new TGeoTranslation("ty05", (I_thick / 2. + (I_width - I_thick) / 2. / 2.), 0., + (zBarPosYbot[0] + zBarPosYtop[0]) / 2.); // bottom + trd_I_vert_vol1->AddNode(trd_I_vert3, 4, ty04); + trd_I_vert_vol1->AddNode(trd_I_vert3, 5, ty05); + + PilPosX = AperX[0]; + + TGeoCombiTrans* trd_I_vert_combi01 = new TGeoCombiTrans( + (PilPosX + I_height / 2.), -((AperYbot[0] + I_height) - (AperY[0] + I_height)) / 2., PilPosZ[0], rotzx01); + trd_1->AddNode(trd_I_vert_vol1, 11, trd_I_vert_combi01); + TGeoCombiTrans* trd_I_vert_combi02 = new TGeoCombiTrans( + -(PilPosX + I_height / 2.), -((AperYbot[0] + I_height) - (AperY[0] + I_height)) / 2., PilPosZ[0], rotzx01); + trd_1->AddNode(trd_I_vert_vol1, 12, trd_I_vert_combi02); + TGeoCombiTrans* trd_I_vert_combi03 = new TGeoCombiTrans( + (PilPosX + I_height / 2.), -((AperYbot[0] + I_height) - (AperY[0] + I_height)) / 2., PilPosZ[1], rotzx02); + trd_1->AddNode(trd_I_vert_vol1, 13, trd_I_vert_combi03); + TGeoCombiTrans* trd_I_vert_combi04 = new TGeoCombiTrans( + -(PilPosX + I_height / 2.), -((AperYbot[0] + I_height) - (AperY[0] + I_height)) / 2., PilPosZ[1], rotzx02); + trd_1->AddNode(trd_I_vert_vol1, 14, trd_I_vert_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoBBox* trd_I_vert1_keep = new TGeoBBox("trd_I_vert1_keep", I_thick / 2., I_height / 2. - I_thick, + (BeamHeight + (AperY[1] + I_height)) / 2.); + TGeoVolume* trd_I_vert1 = new TGeoVolume("trd_I_y21", trd_I_vert1_keep, aluminiumVolMed); + TGeoBBox* trd_I_vert2_keep = + new TGeoBBox("trd_I_vert2_keep", I_width / 2., I_thick / 2., (BeamHeight + (AperY[1] + I_height)) / 2.); + TGeoVolume* trd_I_vert2 = new TGeoVolume("trd_I_y22", trd_I_vert2_keep, aluminiumVolMed); + + trd_I_vert1->SetLineColor(kGreen); + trd_I_vert2->SetLineColor(kGreen); + + TGeoTranslation* ty01 = new TGeoTranslation("ty01", 0., 0., 0.); + TGeoTranslation* ty02 = new TGeoTranslation("ty02", 0., (I_height - I_thick) / 2., 0.); + TGeoTranslation* ty03 = new TGeoTranslation("ty03", 0., -(I_height - I_thick) / 2., 0.); + + TGeoBBox* trd_I_vert_vol1_keep = + new TGeoBBox("trd_I_vert_vol1_keep", I_width / 2., I_height / 2., (BeamHeight + (AperY[1] + I_height)) / 2.); + TGeoVolume* trd_I_vert_vol1 = new TGeoVolume("trd_I_y20", trd_I_vert_vol1_keep, keepVolMed); + + // set green color for keeping volume of I profile, seen with + // gGeoManager->SetVisLevel(2) + trd_I_vert_vol1->SetLineColor(kGreen); + + // build I-bar trd_I_vert_vol1 + trd_I_vert_vol1->AddNode(trd_I_vert1, 1, ty01); + trd_I_vert_vol1->AddNode(trd_I_vert2, 2, ty02); + trd_I_vert_vol1->AddNode(trd_I_vert2, 3, ty03); + + // close gap to horizontal z-bars + TGeoBBox* trd_I_vert3_keep = + new TGeoBBox("trd_I_vert3_keep", (I_width - I_thick) / 2. / 2., I_height / 2. - I_thick, I_thick / 2.); + TGeoVolume* trd_I_vert3 = new TGeoVolume("trd_I_y23", trd_I_vert3_keep, aluminiumVolMed); + trd_I_vert3->SetLineColor(kGreen); + TGeoTranslation* ty04 = new TGeoTranslation("ty04", (I_thick / 2. + (I_width - I_thick) / 2. / 2.), 0., + -(BeamHeight + (AperY[1] + I_height) - I_width) / 2.); // top + TGeoTranslation* ty05 = new TGeoTranslation("ty05", (I_thick / 2. + (I_width - I_thick) / 2. / 2.), 0., + -(BeamHeight - (AperY[1] + I_height)) / 2. + zBarPosYbot[1]); // bottom + trd_I_vert_vol1->AddNode(trd_I_vert3, 4, ty04); + trd_I_vert_vol1->AddNode(trd_I_vert3, 5, ty05); + + PilPosX = AperX[1]; + + TGeoCombiTrans* trd_I_vert_combi01 = + new TGeoCombiTrans((PilPosX + I_height / 2.), -(BeamHeight - (AperY[1] + I_height)) / 2., PilPosZ[2], rotzx01); + trd_2->AddNode(trd_I_vert_vol1, 21, trd_I_vert_combi01); + TGeoCombiTrans* trd_I_vert_combi02 = + new TGeoCombiTrans(-(PilPosX + I_height / 2.), -(BeamHeight - (AperY[1] + I_height)) / 2., PilPosZ[2], rotzx01); + trd_2->AddNode(trd_I_vert_vol1, 22, trd_I_vert_combi02); + TGeoCombiTrans* trd_I_vert_combi03 = + new TGeoCombiTrans((PilPosX + I_height / 2.), -(BeamHeight - (AperY[1] + I_height)) / 2., PilPosZ[3], rotzx02); + trd_2->AddNode(trd_I_vert_vol1, 23, trd_I_vert_combi03); + TGeoCombiTrans* trd_I_vert_combi04 = + new TGeoCombiTrans(-(PilPosX + I_height / 2.), -(BeamHeight - (AperY[1] + I_height)) / 2., PilPosZ[3], rotzx02); + trd_2->AddNode(trd_I_vert_vol1, 24, trd_I_vert_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoBBox* trd_I_vert1_keep = new TGeoBBox("trd_I_vert1_keep", I_thick / 2., I_height / 2. - I_thick, + (BeamHeight + (AperY[2] + I_height)) / 2.); + TGeoVolume* trd_I_vert1 = new TGeoVolume("trd_I_y31", trd_I_vert1_keep, aluminiumVolMed); + TGeoBBox* trd_I_vert2_keep = + new TGeoBBox("trd_I_vert2_keep", I_width / 2., I_thick / 2., (BeamHeight + (AperY[2] + I_height)) / 2.); + TGeoVolume* trd_I_vert2 = new TGeoVolume("trd_I_y32", trd_I_vert2_keep, aluminiumVolMed); + + trd_I_vert1->SetLineColor(kGreen); + trd_I_vert2->SetLineColor(kGreen); + + TGeoTranslation* ty01 = new TGeoTranslation("ty01", 0., 0., 0.); + TGeoTranslation* ty02 = new TGeoTranslation("ty02", 0., (I_height - I_thick) / 2., 0.); + TGeoTranslation* ty03 = new TGeoTranslation("ty03", 0., -(I_height - I_thick) / 2., 0.); + + TGeoBBox* trd_I_vert_vol1_keep = + new TGeoBBox("trd_I_vert_vol1_keep", I_width / 2., I_height / 2., (BeamHeight + (AperY[2] + I_height)) / 2.); + TGeoVolume* trd_I_vert_vol1 = new TGeoVolume("trd_I_y30", trd_I_vert_vol1_keep, keepVolMed); + + // set green color for keeping volume of I profile, seen with + // gGeoManager->SetVisLevel(2) + trd_I_vert_vol1->SetLineColor(kGreen); + + // build I-bar trd_I_vert_vol1 + trd_I_vert_vol1->AddNode(trd_I_vert1, 1, ty01); + trd_I_vert_vol1->AddNode(trd_I_vert2, 2, ty02); + trd_I_vert_vol1->AddNode(trd_I_vert2, 3, ty03); + + // close gap to horizontal z-bars + TGeoBBox* trd_I_vert3_keep = + new TGeoBBox("trd_I_vert3_keep", (I_width - I_thick) / 2. / 2., I_height / 2. - I_thick, I_thick / 2.); + TGeoVolume* trd_I_vert3 = new TGeoVolume("trd_I_y33", trd_I_vert3_keep, aluminiumVolMed); + trd_I_vert3->SetLineColor(kGreen); + TGeoTranslation* ty04 = new TGeoTranslation("ty04", (I_thick / 2. + (I_width - I_thick) / 2. / 2.), 0., + -(BeamHeight + (AperY[2] + I_height) - I_width) / 2.); // top + TGeoTranslation* ty05 = new TGeoTranslation("ty05", (I_thick / 2. + (I_width - I_thick) / 2. / 2.), 0., + -(BeamHeight - (AperY[2] + I_height)) / 2. + zBarPosYbot[2]); // bottom + trd_I_vert_vol1->AddNode(trd_I_vert3, 4, ty04); + trd_I_vert_vol1->AddNode(trd_I_vert3, 5, ty05); + + PilPosX = AperX[2]; + + TGeoCombiTrans* trd_I_vert_combi01 = + new TGeoCombiTrans((PilPosX + I_height / 2.), -(BeamHeight - (AperY[2] + I_height)) / 2., PilPosZ[4], rotzx01); + trd_3->AddNode(trd_I_vert_vol1, 31, trd_I_vert_combi01); + TGeoCombiTrans* trd_I_vert_combi02 = + new TGeoCombiTrans(-(PilPosX + I_height / 2.), -(BeamHeight - (AperY[2] + I_height)) / 2., PilPosZ[4], rotzx01); + trd_3->AddNode(trd_I_vert_vol1, 32, trd_I_vert_combi02); + TGeoCombiTrans* trd_I_vert_combi03 = + new TGeoCombiTrans((PilPosX + I_height / 2.), -(BeamHeight - (AperY[2] + I_height)) / 2., PilPosZ[5], rotzx02); + trd_3->AddNode(trd_I_vert_vol1, 33, trd_I_vert_combi03); + TGeoCombiTrans* trd_I_vert_combi04 = + new TGeoCombiTrans(-(PilPosX + I_height / 2.), -(BeamHeight - (AperY[2] + I_height)) / 2., PilPosZ[5], rotzx02); + trd_3->AddNode(trd_I_vert_vol1, 34, trd_I_vert_combi04); + } + + //------------------- + // horizontal supports (X) + //------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + TGeoBBox* trd_I_hori1_keep = new TGeoBBox("trd_I_hori1_keep", I_thick / 2., I_height / 2. - I_thick, AperX[0]); + TGeoVolume* trd_I_hori1 = new TGeoVolume("trd_I_x11", trd_I_hori1_keep, aluminiumVolMed); + TGeoBBox* trd_I_hori2_keep = new TGeoBBox("trd_I_hori2_keep", I_width / 2., I_thick / 2., AperX[0]); + TGeoVolume* trd_I_hori2 = new TGeoVolume("trd_I_x12", trd_I_hori2_keep, aluminiumVolMed); + + trd_I_hori1->SetLineColor(kRed); // Yellow); + trd_I_hori2->SetLineColor(kRed); // Yellow); + + TGeoTranslation* tx01 = new TGeoTranslation("tx01", 0., 0., 0.); + TGeoTranslation* tx02 = new TGeoTranslation("tx02", 0., (I_height - I_thick) / 2., 0.); + TGeoTranslation* tx03 = new TGeoTranslation("tx03", 0., -(I_height - I_thick) / 2., 0.); + + TGeoBBox* trd_I_hori_vol1_keep = new TGeoBBox("trd_I_hori_vol1_keep", I_width / 2., I_height / 2., AperX[0]); + TGeoVolume* trd_I_hori_vol1 = new TGeoVolume("trd_I_x10", trd_I_hori_vol1_keep, keepVolMed); + + // set red color for keeping volume of I profile, seen with + // gGeoManager->SetVisLevel(2) + trd_I_hori_vol1->SetLineColor(kRed); + + // build I-bar trd_I_hori_vol1 + trd_I_hori_vol1->AddNode(trd_I_hori1, 1, tx01); + trd_I_hori_vol1->AddNode(trd_I_hori2, 2, tx02); + trd_I_hori_vol1->AddNode(trd_I_hori2, 3, tx03); + + TGeoCombiTrans* trd_I_hori_combi01 = new TGeoCombiTrans(0., xBarPosYtop[0], PilPosZ[0], roty090); + trd_1->AddNode(trd_I_hori_vol1, 11, trd_I_hori_combi01); + TGeoCombiTrans* trd_I_hori_combi02 = new TGeoCombiTrans(0., -xBarPosYbot[0], PilPosZ[0], roty090); + trd_1->AddNode(trd_I_hori_vol1, 12, trd_I_hori_combi02); + TGeoCombiTrans* trd_I_hori_combi03 = new TGeoCombiTrans(0., xBarPosYtop[0], PilPosZ[1], roty090); + trd_1->AddNode(trd_I_hori_vol1, 13, trd_I_hori_combi03); + TGeoCombiTrans* trd_I_hori_combi04 = new TGeoCombiTrans(0., -xBarPosYbot[0], PilPosZ[1], roty090); + trd_1->AddNode(trd_I_hori_vol1, 14, trd_I_hori_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoBBox* trd_I_hori1_keep = new TGeoBBox("trd_I_hori1_keep", I_thick / 2., I_height / 2. - I_thick, AperX[1]); + TGeoVolume* trd_I_hori1 = new TGeoVolume("trd_I_x21", trd_I_hori1_keep, aluminiumVolMed); + TGeoBBox* trd_I_hori2_keep = new TGeoBBox("trd_I_hori2_keep", I_width / 2., I_thick / 2., AperX[1]); + TGeoVolume* trd_I_hori2 = new TGeoVolume("trd_I_x22", trd_I_hori2_keep, aluminiumVolMed); + + trd_I_hori1->SetLineColor(kRed); + trd_I_hori2->SetLineColor(kRed); + + TGeoTranslation* tx01 = new TGeoTranslation("tx01", 0., 0., 0.); + TGeoTranslation* tx02 = new TGeoTranslation("tx02", 0., (I_height - I_thick) / 2., 0.); + TGeoTranslation* tx03 = new TGeoTranslation("tx03", 0., -(I_height - I_thick) / 2., 0.); + + TGeoBBox* trd_I_hori_vol1_keep = new TGeoBBox("trd_I_hori_vol1_keep", I_width / 2., I_height / 2., AperX[1]); + TGeoVolume* trd_I_hori_vol1 = new TGeoVolume("trd_I_x20", trd_I_hori_vol1_keep, keepVolMed); + + // set red color for keeping volume of I profile, seen with + // gGeoManager->SetVisLevel(2) + trd_I_hori_vol1->SetLineColor(kRed); + + // build I-bar trd_I_hori_vol1 + trd_I_hori_vol1->AddNode(trd_I_hori1, 1, tx01); + trd_I_hori_vol1->AddNode(trd_I_hori2, 2, tx02); + trd_I_hori_vol1->AddNode(trd_I_hori2, 3, tx03); + + TGeoCombiTrans* trd_I_hori_combi01 = new TGeoCombiTrans(0., xBarPosYtop[1], PilPosZ[2], roty090); + trd_2->AddNode(trd_I_hori_vol1, 21, trd_I_hori_combi01); + TGeoCombiTrans* trd_I_hori_combi02 = new TGeoCombiTrans(0., -xBarPosYbot[1], PilPosZ[2], roty090); + trd_2->AddNode(trd_I_hori_vol1, 22, trd_I_hori_combi02); + TGeoCombiTrans* trd_I_hori_combi03 = new TGeoCombiTrans(0., xBarPosYtop[1], PilPosZ[3], roty090); + trd_2->AddNode(trd_I_hori_vol1, 23, trd_I_hori_combi03); + TGeoCombiTrans* trd_I_hori_combi04 = new TGeoCombiTrans(0., -xBarPosYbot[1], PilPosZ[3], roty090); + trd_2->AddNode(trd_I_hori_vol1, 24, trd_I_hori_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoBBox* trd_I_hori1_keep = new TGeoBBox("trd_I_hori1_keep", I_thick / 2., I_height / 2. - I_thick, AperX[2]); + TGeoVolume* trd_I_hori1 = new TGeoVolume("trd_I_x31", trd_I_hori1_keep, aluminiumVolMed); + TGeoBBox* trd_I_hori2_keep = new TGeoBBox("trd_I_hori2_keep", I_width / 2., I_thick / 2., AperX[2]); + TGeoVolume* trd_I_hori2 = new TGeoVolume("trd_I_x32", trd_I_hori2_keep, aluminiumVolMed); + + trd_I_hori1->SetLineColor(kRed); + trd_I_hori2->SetLineColor(kRed); + + TGeoTranslation* tx01 = new TGeoTranslation("tx01", 0., 0., 0.); + TGeoTranslation* tx02 = new TGeoTranslation("tx02", 0., (I_height - I_thick) / 2., 0.); + TGeoTranslation* tx03 = new TGeoTranslation("tx03", 0., -(I_height - I_thick) / 2., 0.); + + TGeoBBox* trd_I_hori_vol1_keep = new TGeoBBox("trd_I_hori_vol1_keep", I_width / 2., I_height / 2., AperX[2]); + TGeoVolume* trd_I_hori_vol1 = new TGeoVolume("trd_I_x30", trd_I_hori_vol1_keep, keepVolMed); + + // set red color for keeping volume of I profile, seen with + // gGeoManager->SetVisLevel(2) + trd_I_hori_vol1->SetLineColor(kRed); + + // build I-bar trd_I_hori_vol1 + trd_I_hori_vol1->AddNode(trd_I_hori1, 1, tx01); + trd_I_hori_vol1->AddNode(trd_I_hori2, 2, tx02); + trd_I_hori_vol1->AddNode(trd_I_hori2, 3, tx03); + + TGeoCombiTrans* trd_I_hori_combi01 = new TGeoCombiTrans(0., xBarPosYtop[2], PilPosZ[4], roty090); + trd_3->AddNode(trd_I_hori_vol1, 31, trd_I_hori_combi01); + TGeoCombiTrans* trd_I_hori_combi02 = new TGeoCombiTrans(0., -xBarPosYbot[2], PilPosZ[4], roty090); + trd_3->AddNode(trd_I_hori_vol1, 32, trd_I_hori_combi02); + TGeoCombiTrans* trd_I_hori_combi03 = new TGeoCombiTrans(0., xBarPosYtop[2], PilPosZ[5], roty090); + trd_3->AddNode(trd_I_hori_vol1, 33, trd_I_hori_combi03); + TGeoCombiTrans* trd_I_hori_combi04 = new TGeoCombiTrans(0., -xBarPosYbot[2], PilPosZ[5], roty090); + trd_3->AddNode(trd_I_hori_vol1, 34, trd_I_hori_combi04); + } + + //------------------- + // horizontal supports (Z) + //------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + TGeoBBox* trd_I_slope1_keep = new TGeoBBox("trd_I_slope1_keep", I_thick / 2., I_height / 2. - I_thick, + (PilPosZ[1] - PilPosZ[0] - I_width) / 2.); + TGeoVolume* trd_I_slope1 = new TGeoVolume("trd_I_z11", trd_I_slope1_keep, aluminiumVolMed); + TGeoBBox* trd_I_slope2_keep = + new TGeoBBox("trd_I_slope2_keep", I_width / 2., I_thick / 2., (PilPosZ[1] - PilPosZ[0] - I_width) / 2.); + TGeoVolume* trd_I_slope2 = new TGeoVolume("trd_I_z12", trd_I_slope2_keep, aluminiumVolMed); + + trd_I_slope1->SetLineColor(kYellow); + trd_I_slope2->SetLineColor(kYellow); + + TGeoTranslation* tz01 = new TGeoTranslation("tz01", 0., 0., 0.); + TGeoTranslation* tz02 = new TGeoTranslation("tz02", 0., (I_height - I_thick) / 2., 0.); + TGeoTranslation* tz03 = new TGeoTranslation("tz03", 0., -(I_height - I_thick) / 2., 0.); + + TGeoBBox* trd_I_slope_vol1_keep = + new TGeoBBox("trd_I_slope_vol1_keep", I_width / 2., I_height / 2., (PilPosZ[1] - PilPosZ[0] - I_width) / 2.); + TGeoVolume* trd_I_slope_vol1 = new TGeoVolume("trd_I_z10", trd_I_slope_vol1_keep, keepVolMed); + + // set yellow color for keeping volume of I profile, seen with + // gGeoManager->SetVisLevel(2) + trd_I_slope_vol1->SetLineColor(kYellow); + + // build I-bar trd_I_slope_vol1 + trd_I_slope_vol1->AddNode(trd_I_slope1, 1, tz01); + trd_I_slope_vol1->AddNode(trd_I_slope2, 2, tz02); + trd_I_slope_vol1->AddNode(trd_I_slope2, 3, tz03); + + PilPosX = AperX[0]; + + TGeoCombiTrans* trd_I_slope_combi01 = + new TGeoCombiTrans((PilPosX + I_height / 2.), zBarPosYtop[0], (PilPosZ[0] + PilPosZ[1]) / 2., rotz090); + trd_1->AddNode(trd_I_slope_vol1, 11, trd_I_slope_combi01); + TGeoCombiTrans* trd_I_slope_combi02 = + new TGeoCombiTrans(-(PilPosX + I_height / 2.), zBarPosYtop[0], (PilPosZ[0] + PilPosZ[1]) / 2., rotz090); + trd_1->AddNode(trd_I_slope_vol1, 12, trd_I_slope_combi02); + TGeoCombiTrans* trd_I_slope_combi03 = + new TGeoCombiTrans((PilPosX + I_height / 2.), -zBarPosYbot[0], (PilPosZ[0] + PilPosZ[1]) / 2., rotz090); + trd_1->AddNode(trd_I_slope_vol1, 13, trd_I_slope_combi03); + TGeoCombiTrans* trd_I_slope_combi04 = + new TGeoCombiTrans(-(PilPosX + I_height / 2.), -zBarPosYbot[0], (PilPosZ[0] + PilPosZ[1]) / 2., rotz090); + trd_1->AddNode(trd_I_slope_vol1, 14, trd_I_slope_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoBBox* trd_I_slope1_keep = new TGeoBBox("trd_I_slope1_keep", I_thick / 2., I_height / 2. - I_thick, + (PilPosZ[3] - PilPosZ[2] - I_width) / 2.); + TGeoVolume* trd_I_slope1 = new TGeoVolume("trd_I_z21", trd_I_slope1_keep, aluminiumVolMed); + TGeoBBox* trd_I_slope2_keep = + new TGeoBBox("trd_I_slope2_keep", I_width / 2., I_thick / 2., (PilPosZ[3] - PilPosZ[2] - I_width) / 2.); + TGeoVolume* trd_I_slope2 = new TGeoVolume("trd_I_z22", trd_I_slope2_keep, aluminiumVolMed); + + trd_I_slope1->SetLineColor(kYellow); + trd_I_slope2->SetLineColor(kYellow); + + TGeoTranslation* tz01 = new TGeoTranslation("tz01", 0., 0., 0.); + TGeoTranslation* tz02 = new TGeoTranslation("tz02", 0., (I_height - I_thick) / 2., 0.); + TGeoTranslation* tz03 = new TGeoTranslation("tz03", 0., -(I_height - I_thick) / 2., 0.); + + TGeoBBox* trd_I_slope_vol1_keep = + new TGeoBBox("trd_I_slope_vol1_keep", I_width / 2., I_height / 2., (PilPosZ[3] - PilPosZ[2] - I_width) / 2.); + TGeoVolume* trd_I_slope_vol1 = new TGeoVolume("trd_I_z20", trd_I_slope_vol1_keep, keepVolMed); + + // set yellow color for keeping volume of I profile, seen with + // gGeoManager->SetVisLevel(2) + trd_I_slope_vol1->SetLineColor(kYellow); + + // build I-bar trd_I_slope_vol1 + trd_I_slope_vol1->AddNode(trd_I_slope1, 1, tz01); + trd_I_slope_vol1->AddNode(trd_I_slope2, 2, tz02); + trd_I_slope_vol1->AddNode(trd_I_slope2, 3, tz03); + + PilPosX = AperX[1]; + + TGeoCombiTrans* trd_I_slope_combi01 = + new TGeoCombiTrans((PilPosX + I_height / 2.), zBarPosYtop[1], (PilPosZ[2] + PilPosZ[3]) / 2., rotz090); + trd_2->AddNode(trd_I_slope_vol1, 21, trd_I_slope_combi01); + TGeoCombiTrans* trd_I_slope_combi02 = + new TGeoCombiTrans(-(PilPosX + I_height / 2.), zBarPosYtop[1], (PilPosZ[2] + PilPosZ[3]) / 2., rotz090); + trd_2->AddNode(trd_I_slope_vol1, 22, trd_I_slope_combi02); + TGeoCombiTrans* trd_I_slope_combi03 = + new TGeoCombiTrans((PilPosX + I_height / 2.), -zBarPosYbot[1], (PilPosZ[2] + PilPosZ[3]) / 2., rotz090); + trd_2->AddNode(trd_I_slope_vol1, 23, trd_I_slope_combi03); + TGeoCombiTrans* trd_I_slope_combi04 = + new TGeoCombiTrans(-(PilPosX + I_height / 2.), -zBarPosYbot[1], (PilPosZ[2] + PilPosZ[3]) / 2., rotz090); + trd_2->AddNode(trd_I_slope_vol1, 24, trd_I_slope_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoBBox* trd_I_slope1_keep = new TGeoBBox("trd_I_slope1_keep", I_thick / 2., I_height / 2. - I_thick, + (PilPosZ[5] - PilPosZ[4] - I_width) / 2.); + TGeoVolume* trd_I_slope1 = new TGeoVolume("trd_I_z31", trd_I_slope1_keep, aluminiumVolMed); + TGeoBBox* trd_I_slope2_keep = + new TGeoBBox("trd_I_slope2_keep", I_width / 2., I_thick / 2., (PilPosZ[5] - PilPosZ[4] - I_width) / 2.); + TGeoVolume* trd_I_slope2 = new TGeoVolume("trd_I_z32", trd_I_slope2_keep, aluminiumVolMed); + + trd_I_slope1->SetLineColor(kYellow); + trd_I_slope2->SetLineColor(kYellow); + + TGeoTranslation* tz01 = new TGeoTranslation("tz01", 0., 0., 0.); + TGeoTranslation* tz02 = new TGeoTranslation("tz02", 0., (I_height - I_thick) / 2., 0.); + TGeoTranslation* tz03 = new TGeoTranslation("tz03", 0., -(I_height - I_thick) / 2., 0.); + + TGeoBBox* trd_I_slope_vol1_keep = + new TGeoBBox("trd_I_slope_vol1_keep", I_width / 2., I_height / 2., (PilPosZ[5] - PilPosZ[4] - I_width) / 2.); + TGeoVolume* trd_I_slope_vol1 = new TGeoVolume("trd_I_z30", trd_I_slope_vol1_keep, keepVolMed); + + // set yellow color for keeping volume of I profile, seen with + // gGeoManager->SetVisLevel(2) + trd_I_slope_vol1->SetLineColor(kYellow); + + // build I-bar trd_I_slope_vol1 + trd_I_slope_vol1->AddNode(trd_I_slope1, 1, tz01); + trd_I_slope_vol1->AddNode(trd_I_slope2, 2, tz02); + trd_I_slope_vol1->AddNode(trd_I_slope2, 3, tz03); + + PilPosX = AperX[2]; + + TGeoCombiTrans* trd_I_slope_combi01 = + new TGeoCombiTrans((PilPosX + I_height / 2.), zBarPosYtop[2], (PilPosZ[4] + PilPosZ[5]) / 2., rotz090); + trd_3->AddNode(trd_I_slope_vol1, 31, trd_I_slope_combi01); + TGeoCombiTrans* trd_I_slope_combi02 = + new TGeoCombiTrans(-(PilPosX + I_height / 2.), zBarPosYtop[2], (PilPosZ[4] + PilPosZ[5]) / 2., rotz090); + trd_3->AddNode(trd_I_slope_vol1, 32, trd_I_slope_combi02); + TGeoCombiTrans* trd_I_slope_combi03 = + new TGeoCombiTrans((PilPosX + I_height / 2.), -zBarPosYbot[2], (PilPosZ[4] + PilPosZ[5]) / 2., rotz090); + trd_3->AddNode(trd_I_slope_vol1, 33, trd_I_slope_combi03); + TGeoCombiTrans* trd_I_slope_combi04 = + new TGeoCombiTrans(-(PilPosX + I_height / 2.), -zBarPosYbot[2], (PilPosZ[4] + PilPosZ[5]) / 2., rotz090); + trd_3->AddNode(trd_I_slope_vol1, 34, trd_I_slope_combi04); + } + + if (IncludeLabels) { + + Int_t text_height = 40; + Int_t text_thickness = 8; + + TGeoTranslation* tr200 = new TGeoTranslation(0., (AperY[0] + I_height + text_height / 2.), + PilPosZ[0] - I_width / 2. + text_thickness / 2.); + TGeoTranslation* tr201 = new TGeoTranslation(0., (AperY[1] + I_height + text_height / 2.), + PilPosZ[2] - I_width / 2. + text_thickness / 2.); + TGeoTranslation* tr202 = new TGeoTranslation(0., (AperY[2] + I_height + text_height / 2.), + PilPosZ[4] - I_width / 2. + text_thickness / 2.); + + TGeoCombiTrans* tr203 = + new TGeoCombiTrans(-(AperX[0] + I_height + text_thickness / 2.), + (AperY[0] + I_height - I_width - text_height / 2.), (PilPosZ[0] + PilPosZ[1]) / 2., roty090); + TGeoCombiTrans* tr204 = + new TGeoCombiTrans(-(AperX[1] + I_height + text_thickness / 2.), + (AperY[1] + I_height - I_width - text_height / 2.), (PilPosZ[2] + PilPosZ[3]) / 2., roty090); + TGeoCombiTrans* tr205 = + new TGeoCombiTrans(-(AperX[2] + I_height + text_thickness / 2.), + (AperY[2] + I_height - I_width - text_height / 2.), (PilPosZ[4] + PilPosZ[5]) / 2., roty090); + + TGeoCombiTrans* tr206 = + new TGeoCombiTrans((AperX[0] + I_height + text_thickness / 2.), + (AperY[0] + I_height - I_width - text_height / 2.), (PilPosZ[0] + PilPosZ[1]) / 2., roty270); + TGeoCombiTrans* tr207 = + new TGeoCombiTrans((AperX[1] + I_height + text_thickness / 2.), + (AperY[1] + I_height - I_width - text_height / 2.), (PilPosZ[2] + PilPosZ[3]) / 2., roty270); + TGeoCombiTrans* tr208 = + new TGeoCombiTrans((AperX[2] + I_height + text_thickness / 2.), + (AperY[2] + I_height - I_width - text_height / 2.), (PilPosZ[4] + PilPosZ[5]) / 2., roty270); + + TGeoVolume* trdbox1 = new TGeoVolumeAssembly("trdbox1"); // volume for TRD text (108, 40, 8) + TGeoVolume* trdbox2 = new TGeoVolumeAssembly("trdbox2"); // volume for TRD text (108, 40, 8) + TGeoVolume* trdbox3 = new TGeoVolumeAssembly("trdbox3"); // volume for TRD text (108, 40, 8) + add_trd_labels(trdbox1, trdbox2, trdbox3); + + // final placement + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + // trd_1->AddNode(trdbox1, 1, tr200); + trd_1->AddNode(trdbox1, 4, tr203); + trd_1->AddNode(trdbox1, 7, tr206); + } + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + // trd_2->AddNode(trdbox2, 2, tr201); + trd_2->AddNode(trdbox2, 5, tr204); + trd_2->AddNode(trdbox2, 8, tr207); + } + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + // trd_3->AddNode(trdbox3, 3, tr202); + trd_3->AddNode(trdbox3, 6, tr205); + trd_3->AddNode(trdbox3, 9, tr208); + } + } + + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_1, 1); + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_2, 2); + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_3, 3); +} diff --git a/setup/setup_mcbm_beam_2024_03_22_gold.C b/setup/setup_mcbm_beam_2024_03_22_gold.C index 5f480b0..0465b54 100644 --- a/setup/setup_mcbm_beam_2024_03_22_gold.C +++ b/setup/setup_mcbm_beam_2024_03_22_gold.C @@ -8,6 +8,7 @@ // clang-format off +// 2024-04-08 - AP - corrected TRD1D Y module rotation // 2024-03-27 - DE - add STS v24b, positions according to the cave // 2024-03-26 - DE - add TOF v24b, positions according to the cave // 2024-03-26 - DE - add TRD v24b, positions according to the cave @@ -84,7 +85,7 @@ void setup_mcbm_beam_2024_03_22_gold() { // TString muchGeoTag = "v22k_mcbm"; // 2 GEM layers and 1 RPC // done - TString trdGeoTag = "v24b_mcbm"; // 1x TRD-2D + 2x TRD-1D type 5 modules + TString trdGeoTag = "v24c_mcbm"; // 1x TRD-2D + 2x TRD-1D type 5 modules // done TString tofGeoTag = "v24b_mcbm"; // horizontal modules diff --git a/trd/trd_v24c_mcbm.geo.info b/trd/trd_v24c_mcbm.geo.info new file mode 100644 index 0000000..667b6c1 --- /dev/null +++ b/trd/trd_v24c_mcbm.geo.info @@ -0,0 +1,85 @@ +# +## trd_v24c_mcbm information file +# + +# created 20240412 + +# envelope, in TRD local system +0.000000 cm start of TRD (z) +120.600000 cm end of TRD (z) + +# generated TRD layers + 1 2 3 planeID + +# z-positions of layer front, in TRD local system +0.000000 cm z-position of layer 1 +40.200000 cm z-position of layer 2 +80.400000 cm z-position of layer 3 + +# flags +support structure is : NOT included +radiator is : NOT included +lattice grid is : included +kapton window is : included +gas frame is : included +padplane is : included +backpanel is : included +Aluminium ledge is : included +Gibbet support is : included +Power bus bars are : NOT included +asics are : included +front-end boards are : included +1D GBTX readout boards are : NOT included +2D GBTX readout boards are : included + +# modules + mod1 mod2 mod3 mod4 mod5 mod6 mod7 mod8 mod9 mod10 total +--------------------------------------------------------------------------------- + 0 0 0 0 0 0 0 0 1 0 layer 1 + 0 0 0 0 1 0 0 0 0 0 layer 2 + 0 0 0 0 1 0 0 0 0 0 layer 3 + +--------------------------------------------------------------------------------- + 0 0 0 0 2 0 0 0 1 0 3 number of modules +# febs + 9s 5s 6s 18 12 8 4 3 18 18 FEBs per module + 0 ultimate FEBs + 0s 0s 0s 0 super FEBs + 24 0 0 0 24 regular FEBs + 0 0 0 0 24 0 0 0 18 0 42 number of FEBs +# asics + 10 10 10 10 9 8 8 8 10 10 ASICs per FEB + 90 50 60 180 108 64 32 24 180 180 ASICs per module + 0 0 0 0 216 0 0 0 180 0 396 number of ASICs +# gbtx + 15 10 5 18 0 10 5 3 18 18 GBTXs per module + 0 0 0 0 0 0 0 0 18 0 18 number of GBTXs + 555 55 5 333333 0 55 5 3 333333 333333 GBTX ROB types on module + 0 0 0 0 0 0 0 0 0 0 0 number of GBTX ROB7 + 0 0 0 0 0 0 0 0 0 0 0 number of GBTX ROB5 + 0 0 0 0 0 0 0 0 6 0 6 number of GBTX ROB3 +# e-links + 180 100 120 360 216 128 64 48 360 360 792 e-links used + 210 140 70 252 0 140 70 42 252 252 252 e-links available + - - - - - - - - 142.9% - 314.3% e-link efficiency + +# channels + 1440 800 960 2880 3456 2048 1024 768 2880 2880 channels per module + 160 160 160 160 288 256 256 256 160 160 channels per feb + 0 0 0 0 6912 0 0 0 2880 0 9792 channels used + 0s 0s 0s 0F 6912 0 0 0 2880F 0F 12672 channels available + 22.7%u 0.0%s 54.5%r channel ratio + + 77.3% channel efficiency + + 2.94 m2 total surface + 2.76 m2 total active area + 0.03 m3 total gas volume + 2.82 cm2/ch average channel size +3541.67 ch/m2 channels per m2 active area + +# gas volume position, in TRD local system + 1.6000 cm position of gas volume - layer 1 + 41.8000 cm position of gas volume - layer 2 + 82.0000 cm position of gas volume - layer 3 + diff --git a/trd/trd_v24c_mcbm.geo.root b/trd/trd_v24c_mcbm.geo.root new file mode 100644 index 0000000000000000000000000000000000000000..bac269349a1b26c0f36496bea8615b7dfda3adee GIT binary patch literal 17393 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 L&!Yg^K)PQ6)X{BM literal 0 HcmV?d00001 -- GitLab