From 80e0fc7590cb0a4603bcfa89f57da9dc49388270 Mon Sep 17 00:00:00 2001 From: David Emschermann <d.emschermann@gsi.de> Date: Tue, 30 Apr 2024 17:03:29 +0200 Subject: [PATCH] Add new STS geometry v24c, shift of STS in Z direction/axis as per the measurement in the CAVE, provided by Mehulkumar Shiroya Made reproducible --- macro/sts/mcbm/create_stsgeo_v24c.C | 2781 +++++++++++++++++++++++++++ sts/sts_v24c_mcbm.geo.info | 143 ++ sts/sts_v24c_mcbm.geo.root | Bin 0 -> 14598 bytes 3 files changed, 2924 insertions(+) create mode 100644 macro/sts/mcbm/create_stsgeo_v24c.C create mode 100644 sts/sts_v24c_mcbm.geo.info create mode 100644 sts/sts_v24c_mcbm.geo.root diff --git a/macro/sts/mcbm/create_stsgeo_v24c.C b/macro/sts/mcbm/create_stsgeo_v24c.C new file mode 100644 index 0000000..cee407b --- /dev/null +++ b/macro/sts/mcbm/create_stsgeo_v24c.C @@ -0,0 +1,2781 @@ +/* Copyright (C) 2012-2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: David Emschermann [committer] */ + +/****************************************************************************** + ** Creation of STS geometry in ROOT format (TGeo). + ** + ** @file create_stsgeo_v24b.C + ** @author David Emschermann <d.emschermann@gsi.de> + ** @author Volker Friese <v.friese@gsi.de> + ** @since 15 June 2012 + ** @date 09.05.2014 + ** @author Tomas Balog <T.Balog@gsi.de> + ** + ** 2024-04-29 - MS - v24c: based on v24b, shift STS in Z to position measured in the cave + ** as it was seen that the station 0 module position was not correct + ** and the measurement was done again in the CAVE. The position of + ** the Back-side of the STS box was expected to be at 57.8 cm. + ** We opened the side wall of the sts-box and did the measurement + ** inside the box for the placement of the C-Frames. + ** The thickness of the back-side wall is 0.5 cm which means from + ** inside the box (57.8-0.5=57.3) the last C-Frame edge is at 7 cm + ** away (50.3). The edge of the front wall from out-side is at 22.8 cm + ** (35 cm away from the backside wall). And the first module box wall + ** from the wall is 1.6 cm away. + ** 2024-03-27 - DE - v24b: based on v24a, shift STS in z to position measured in the cave + ** 2024-03-26 - DE - v24a: add preliminary version of mSTS v24a for the 2024_03_22 gold setup + ** 2024-02-06 - DE - v24a: position the STS sensors as measured in the cave + ** 2023-06-29 - DE - v23b: add a 6x6 cm2 module at z=16.5 cm, keep STS box around 2x2 and 3x3 (from v22e) + ** 2023-06-27 - DE - v23a: add a 6x6 cm2 module at z=14.0 cm (nominal), keep STS box around 2x2 and 3x3 (from v22e) + ** 2023-02-09 - DE - v22f: decrease distance between statios 0 and 1 from 140 mm to 135 mm, to reflect CAD + ** 2023-02-09 - DE - v22f: increase gap between units of a station gkLadderGapZ from 10 mm to 12 mm, to reflect CAD + ** 2023-02-09 - DE - v22f: shift ladder U2 downwards in y by 2.2 mm + ** 2023-02-08 - DE - v22f: introduce ladder type 12 (based on 10) for U2, but with original gkSectorOverlapY of 4.6 mm + ** 2022-09-13 - DE - v22e: correct gkSectorOverlapY to 9.0 mm for the ladder type 10 (with 12 cm sensors) + ** 2022-03-18 - DE - v22d: add position offset for mSTS 2022_03_22_iron as surveyed in the cave + ** 2022-02-01 - DE - v22b: add position offset for mSTS 07_2021 as surveyed in the cave + ** 2022-01-25 - DE - v22a: add a aluminium box around v20e + ** 2020-05-16 - DE - v20e: swap ladders in unit 3 - 3x 6x6 on beam side + ** 2020-03-21 - DE - v20d: build mSTS for March 2020 - 1 ladder - shift -3 cm in x + ** 2020-03-11 - DE - v20c: build mSTS for March 2021 - 5 ladders + ** 2020-03-11 - DE - v20b: build mSTS for May 2020 - 2 ladders + ** 2020-03-11 - DE - v20a: build mSTS for March 2020 - 1 ladder + ** + ** 2019-12-04 - DE - v19d: build 2nd mSTS v19d station from one 6x6 and one 6x12 cm x cm sensors + ** 2019-12-04 - DE - v19c: build 1st mSTS v19c station at nominal position + ** 2019-08-12 - DE - v19a: mSTS as built in March 2019 - the mSTS FEBs are in the bottom + ** 2019-03-15 - DE - v18n: mSTS as built in March 2019 - downstream ladder of station 0 at position of station 1 + ** 2018-01-18 - DE - v18g: set overlaps in X and Y according to mSTS CAD model + ** + ** v18f: flip orientation of carbon ladders for primary beam left of mSTS, change z-positions to 30 and 45 cm + ** v18e: 2 stations, derived from v15b, 1st 2x2, 2nd of 3x3 sensor array, sensor size 6x6 cm2 with carbon ladder supports + ** v18d: 2 stations of 3x3 sensor array, sensor size 6x6 cm2 with carbon ladder supports + ** v18c: (causes segfault due to divide) 2 stations of 3x3 sensor array, sensor size 6x6 cm2 with carbon ladder supports + ** v18b: 2 stations of 4x4 sensor array, sensor size 6x6 cm2 + ** v18a: 2 stations of 3x3 sensor array, sensor size 6x6 cm2 + ** + ** v15b: introduce modified carbon ladders from v13z + ** v15a: with flipped ladder orientation for stations 0,2,4,6 to match CAD design + ** + ** TODO: + ** + ** DONE: + ** v15b - use carbon macaroni as ladder support + ** v15b - introduce a small gap between lowest sensor and carbon ladder + ** v15b - build small cones for the first 2 stations + ** v15b - within a station the ladders of adjacent units should not touch eachother - set gkLadderGapZ to 10 mm + ** v15b - for all ladders set an even number of ladder elements + ** v15b - z offset of cones to ladders should not be 0.3 by default, but 0.26 + ** v15b - within a station the ladders should be aligned in z, defined either by the unit or the ladder with most sensors + ** v15b - get rid of cone overlap in stations 7 and 8 - done by adapting rHole size + ** + ** The geometry hierarachy is: + ** + ** 1. Sensors (see function CreateSensors) + ** The sensors are the active volumes and the lowest geometry level. + ** They are built as TGeoVolumes, shape box, material silicon. + ** x size is determined by strip pitch 58 mu and 1024 strips + ** plus guard ring of 1.3 mm at each border -> 6.1992 cm. + ** Sensor type 1 is half of that (3.0792 cm). + ** y size is determined by strip length (2.2 / 4.2 / 6.3 cm) plus + ** guard ring of 1.3 mm at top and bottom -> 2.46 / 4.46 / 6.46 cm. + ** z size is a parameter, to be set by gkSensorThickness. + ** + ** 2. Sectors (see function CreateSectors) + ** Sectors consist of several chained sensors. These are arranged + ** vertically on top of each other with a gap to be set by + ** gkChainGapY. Sectors are constructed as TGeoVolumeAssembly. + ** The sectors are auxiliary volumes used for proper placement + ** of the sensor(s) in the module. They do not show up in the + ** final geometry. + ** + ** 3. Modules (see function ConstructModule) + ** A module is a readout unit, consisting of one sensor or + ** a chain of sensors (see sector) and a cable. + ** The cable extends from the top of the sector vertically to the + ** top of the halfladder the module is placed in. The cable and module + ** volume thus depend on the vertical position of the sector in + ** the halfladder. The cables consist of silicon with a thickness to be + ** set by gkCableThickness. + ** Modules are constructed as TGeoVolume, shape box, medium gStsMedium. + ** The module construction can be switched off (gkConstructCables) + ** to reproduce older geometries. + ** + ** 4. Halfladders (see function ConstructHalfLadder) + ** A halfladder is a vertical assembly of several modules. The modules + ** are placed vertically such that their sectors overlap by + ** gkSectorOverlapY. They are displaced in z direction to allow for the + ** overlap in y by gkSectorGapZ. + ** The horizontal placement of modules in the halfladder can be choosen + ** to left aligned or right aligned, which only matters if sensors of + ** different x size are involved. + ** Halfladders are constructed as TGeoVolumeAssembly. + ** + ** 5. Ladders (see function CreateLadders and ConstructLadder) + ** A ladder is a vertical assembly of two halfladders, and is such the + ** vertical building block of a station. The second (bottom) half ladder + ** is rotated upside down. The vertical arrangement is such that the + ** inner sectors of the two halfladders have the overlap gkSectorOverlapY + ** (function CreateLadder) or that there is a vertical gap for the beam + ** hole (function CreateLadderWithGap). + ** Ladders are constructed as TGeoVolumeAssembly. + ** + ** 6. Stations (see function ConstructStation) + ** A station represents one layer of the STS geometry: one measurement + ** at (approximately) a given z position. It consist of several ladders + ** arranged horizontally to cover the acceptance. + ** The ladders are arranged such that there is a horizontal overlap + ** between neighbouring ladders (gkLadderOverLapX) and a vertical gap + ** to allow for this overlap (gkLadderGapZ). Each second ladder is + ** rotated around its y axis to face away from or into the beam. + ** Stations are constructed as TGeoVolumes, shape box minus tube (for + ** the beam hole), material gStsMedium. + ** + ** 7. STS + ** The STS is a volume hosting the entire detectors system. It consists + ** of several stations located at different z positions. + ** The STS is constructed as TGeoVolume, shape box minus cone (for the + ** beam pipe), material gStsMedium. The size of the box is computed to + ** enclose all stations. + *****************************************************************************/ + + +// Remark: With the proper steering variables, this should exactly reproduce +// the geometry version v11b of A. Kotynia's described in the ASCII format. +// The only exception is a minimal difference in the z position of the +// sectors/sensors. This is because of ladder types 2 and 4 containing the half +// sensors around the beam hole (stations 1,2 and 3). In v11b, the two ladders +// covering the beam hole cannot be transformed into each other by rotations, +// but only by a reflection. This means they are constructionally different. +// To avoid introducing another two ladder types, the difference in z position +// was accepted. + + +// Differences to v12: +// gkChainGap reduced from 1 mm to 0 +// gkCableThickness increased from 100 mum to 200 mum (2 cables per module) +// gkSectorOverlapY reduced from 3 mm to 2.4 mm +// New sensor types 05 and 06 +// New sector types 07 and 08 +// Re-definiton of ladders (17 types instead of 8) +// Re-definiton of station from new ladders + + +#include "TGeoCompositeShape.h" +#include "TGeoCone.h" +#include "TGeoManager.h" +#include "TGeoPara.h" +#include "TGeoTube.h" + +#include <iomanip> +#include <iostream> + + +// ------------- Installation offset ----------------------------------- + +// position in x and y agrees within 2 mm to CbmRoot geometry (01.02.2022) +const Double_t gOffX = 0.0; // Offset from nominal position +const Double_t gOffY = 0.0; // Offset from nominal position +// 2023 +// const Double_t gOffZ = 5.0; // Offset from nominal position +// 2024 +const Double_t gOffZ = 4.55; // Offset from nominal position + +const Bool_t IncludeBox = true; // false; // true, if STS box is plotted + +// ------------- Steering variables ----------------------------------- + +// ---> Horizontal width of sensors [cm] +const Double_t gkSensorSizeX = 6.2092; + +// ---> Thickness of sensors [cm] +const Double_t gkSensorThickness = 0.03; + +// ---> Vertical gap between chained sensors [cm] +const Double_t gkChainGapY = 0.00; + +// ---> Thickness of cables [cm] +const Double_t gkCableThickness = 0.02; + +// ---> Horizontal overlap of neighbouring ladders [cm] +const Double_t gkLadderOverlapX = 0.25; // delta X - Oleg CAD 14/05/2020 + +// ---> Vertical overlap of neighbouring sectors in a ladder [cm] +const Double_t gkSectorOverlapY = 0.46; // delta Y - Oleg CAD 14/05/2020 +const Double_t gkSectorOverlapYL10 = 0.90; // for ladders with 124 mm sensors - Oleg CAD 13/09/2022 + +// ---> Gap in z between neighbouring sectors in a ladder [cm] +const Double_t gkSectorGapZ = 0.17; // gap + thickness = pitch // delta Z pitch = 0.20 - Oleg CAD 14/05/2020 + +// ---> Gap in z between neighbouring ladders [cm] +const Double_t gkLadderGapZ = 1.20; // DEJH -> 0.90 / 0.50 +// v22e const Double_t gkLadderGapZ = 1.00; // DEJH -> 0.90 / 0.50 + +// ---> Gap in z between lowest sector to carbon support structure [cm] +const Double_t gkSectorGapZFrame = 0.10; + +// ---> Switch to construct / not to construct readout cables +const Bool_t gkConstructCables = kTRUE; + +// ---> Switch to construct / not to construct frames +const Bool_t gkConstructCones = kFALSE; // kFALSE; // switch this false for v15a +const Bool_t gkConstructFrames = kTRUE; // kFALSE; // switch this false for v15a +const Bool_t gkConstructSmallFrames = kTRUE; // kFALSE; +const Bool_t gkCylindricalFrames = kTRUE; // kFALSE; + +// ---> Size of the frame +const Double_t gkFrameThickness = 0.2; +const Double_t gkThinFrameThickness = 0.05; +const Double_t gkFrameStep = 4.0; // size of frame cell along y direction + +const Double_t gkCylinderDiaInner = + 0.07; // properties of cylindrical carbon supports, see CBM-STS Integration Meeting (10 Jul 2015) +const Double_t gkCylinderDiaOuter = + 0.15; // properties of cylindrical carbon supports, see CBM-STS Integration Meeting (10 Jul 2015) + +// ---------------------------------------------------------------------------- + + +// -------------- Parameters of beam pipe in the STS region -------------- +// ---> Needed to compute stations and STS such as to avoid overlaps +const Double_t gkPipeZ1 = 22.0; +const Double_t gkPipeR1 = 1.8; +const Double_t gkPipeZ2 = 50.0; +const Double_t gkPipeR2 = 1.8; +const Double_t gkPipeZ3 = 125.0; +const Double_t gkPipeR3 = 5.5; + +//DE const Double_t gkPipeZ1 = 27.0; +//DE const Double_t gkPipeR1 = 1.05; +//DE const Double_t gkPipeZ2 = 160.0; +//DE const Double_t gkPipeR2 = 3.25; +// ---------------------------------------------------------------------------- + + +// ------------- Other global variables ----------------------------------- +// ---> STS medium (for every volume except silicon) +TGeoMedium* gStsMedium = NULL; // will be set later +// ---> TGeoManager (too lazy to write out 'Manager' all the time +TGeoManager* gGeoMan = NULL; // will be set later +// ---------------------------------------------------------------------------- + +Int_t CreateSubplates(); +Int_t CreatePlates(); +Int_t CreateSensors(); +Int_t CreateSectors(); +Int_t CreateLadders(); +void CheckVolume(TGeoVolume* volume); +void CheckVolume(TGeoVolume* volume, fstream& file); +TGeoVolume* ConstructFrameElement(const TString& name, TGeoVolume* frameBoxVol, Double_t x); +TGeoVolume* ConstructSmallCone(Double_t coneDz); +TGeoVolume* ConstructBigCone(Double_t coneDz); +TGeoVolume* ConstructHalfLadder(Int_t ladderid, const TString& name, Int_t nSectors, Int_t* sectorTypes, char align); +TGeoVolume* ConstructLadder(Int_t LadderIndex, TGeoVolume* halfLadderU, TGeoVolume* halfLadderD, Double_t shiftZ); +TGeoVolume* ConstructLadderWithGap(Int_t LadderIndex, TGeoVolume* halfLadderU, TGeoVolume* halfLadderD, Double_t gapY); +TGeoVolume* ConstructStation(Int_t iStation, Int_t nLadders, Int_t* ladderTypes, Double_t rHole); + +// ============================================================================ +// ====== Main function ===== +// ============================================================================ + +void create_stsgeo_v24c(const char* geoTag = "v24c_mcbm") +{ + + // ------- Geometry file name (output) ---------------------------------- + TString geoFileName = "sts_"; + geoFileName = geoFileName + geoTag + ".geo.root?reproducible"; + // -------------------------------------------------------------------------- + + + // ------- Open info file ----------------------------------------------- + TString infoFileName = geoFileName; + infoFileName.ReplaceAll("root", "info"); + fstream infoFile; + infoFile.open(infoFileName.Data(), fstream::out); + infoFile << "STS geometry created with create_stsgeo_v24c.C" << endl << endl; + infoFile << "Global variables: " << endl; + infoFile << "Sensor thickness = " << gkSensorThickness << " cm" << endl; + infoFile << "Vertical gap in sensor chain = " << gkChainGapY << " cm" << endl; + infoFile << "Vertical overlap of sensors = " << gkSectorOverlapY << " cm" << endl; + infoFile << "Gap in z between neighbour sensors = " << gkSectorGapZ << " cm" << endl; + infoFile << "Horizontal overlap of sensors = " << gkLadderOverlapX << " cm" << endl; + infoFile << "Gap in z between neighbour ladders = " << gkLadderGapZ << " cm" << endl; + if (gkConstructCables) infoFile << "Cable thickness = " << gkCableThickness << " cm" << endl; + else + infoFile << "No cables" << endl; + infoFile << endl; + infoFile << "Beam pipe: R1 = " << gkPipeR1 << " cm at z = " << gkPipeZ1 << " cm" << endl; + infoFile << "Beam pipe: R2 = " << gkPipeR2 << " cm at z = " << gkPipeZ2 << " cm" << endl; + infoFile << "Beam pipe: R3 = " << gkPipeR3 << " cm at z = " << gkPipeZ3 << " cm" << endl; + // -------------------------------------------------------------------------- + + // Load FairRunSim to ensure the correct unit system + FairRunSim* sim = new FairRunSim(); + + // ------- Load media from media file ----------------------------------- + FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader"); + FairGeoInterface* geoFace = geoLoad->getGeoInterface(); + TString geoPath = gSystem->Getenv("VMCWORKDIR"); + TString medFile = geoPath + "/geometry/media.geo"; + geoFace->setMediaFile(medFile); + geoFace->readMedia(); + gGeoMan = gGeoManager; + // -------------------------------------------------------------------------- + + + // ----------------- Get and create the required media ----------------- + FairGeoMedia* geoMedia = geoFace->getMedia(); + FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder(); + + // ---> air + FairGeoMedium* mAir = geoMedia->getMedium("air"); + if (!mAir) Fatal("Main", "FairMedium air not found"); + geoBuild->createMedium(mAir); + TGeoMedium* air = gGeoMan->GetMedium("air"); + if (!air) Fatal("Main", "Medium air not found"); + + // ---> silicon + FairGeoMedium* mSilicon = geoMedia->getMedium("silicon"); + if (!mSilicon) Fatal("Main", "FairMedium silicon not found"); + geoBuild->createMedium(mSilicon); + TGeoMedium* silicon = gGeoMan->GetMedium("silicon"); + if (!silicon) Fatal("Main", "Medium silicon not found"); + + // ---> carbon + FairGeoMedium* mCarbon = geoMedia->getMedium("carbon"); + if (!mCarbon) Fatal("Main", "FairMedium carbon not found"); + geoBuild->createMedium(mCarbon); + TGeoMedium* carbon = gGeoMan->GetMedium("carbon"); + if (!carbon) Fatal("Main", "Medium carbon not found"); + + // ---> aluminium + FairGeoMedium* mAluminium = geoMedia->getMedium("aluminium"); + if (!mAluminium) Fatal("Main", "FairMedium aluminium not found"); + geoBuild->createMedium(mAluminium); + TGeoMedium* aluminium = gGeoMan->GetMedium("aluminium"); + if (!aluminium) Fatal("Main", "Medium aluminium not found"); + + // ---> STScable + FairGeoMedium* mSTScable = geoMedia->getMedium("STScable"); + if (!mSTScable) Fatal("Main", "FairMedium STScable not found"); + geoBuild->createMedium(mSTScable); + TGeoMedium* STScable = gGeoMan->GetMedium("STScable"); + if (!STScable) Fatal("Main", "Medium STScable not found"); + + // --- + gStsMedium = air; + // -------------------------------------------------------------------------- + + + // -------------- Create geometry and top volume ------------------------- + gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom"); + gGeoMan->SetName("STSgeom"); + TGeoVolume* top = new TGeoVolumeAssembly("TOP"); + gGeoMan->SetTopVolume(top); + // -------------------------------------------------------------------------- + + + // -------------- Create media ------------------------------------------ + /* + cout << endl; + cout << "===> Creating media...."; + cout << CreateMedia(); + cout << " media created" << endl; + TList* media = gGeoMan->GetListOfMedia(); + for (Int_t iMedium = 0; iMedium < media->GetSize(); iMedium++ ) { + cout << "Medium " << iMedium << ": " + << ((TGeoMedium*) media->At(iMedium))->GetName() << endl; + } + gStsMedium = gGeoMan->GetMedium("air"); + if ( ! gStsMedium ) Fatal("Main", "medium sts_air not found"); + */ + // -------------------------------------------------------------------------- + + // --------------- Create sensors --------------------------------------- + cout << endl << endl; + cout << "===> Creating sensors...." << endl << endl; + infoFile << endl << "Sensors: " << endl; + Int_t nSensors = CreateSensors(); + for (Int_t iSensor = 1; iSensor <= nSensors; iSensor++) { + TString name = Form("Sensor%02d", iSensor); + TGeoVolume* sensor = gGeoMan->GetVolume(name); + + // add color to sensors + if (iSensor == 1) sensor->SetLineColor(kYellow); + if (iSensor == 2) sensor->SetLineColor(kRed); + if (iSensor == 3) sensor->SetLineColor(kBlue); + if (iSensor == 4) sensor->SetLineColor(kAzure + 7); + if (iSensor == 5) sensor->SetLineColor(kGreen); + if (iSensor == 6) sensor->SetLineColor(kYellow); + + CheckVolume(sensor); + CheckVolume(sensor, infoFile); + } + // -------------------------------------------------------------------------- + + + // ---------------- Create sectors -------------------------------------- + cout << endl << endl; + cout << "===> Creating sectors...." << endl; + infoFile << endl << "Sectors: " << endl; + Int_t nSectors = CreateSectors(); + for (Int_t iSector = 1; iSector <= nSectors; iSector++) { + cout << endl; + TString name = Form("Sector%02d", iSector); + TGeoVolume* sector = gGeoMan->GetVolume(name); + CheckVolume(sector); + CheckVolume(sector, infoFile); + } + // -------------------------------------------------------------------------- + + + // ---------------- Create ladders -------------------------------------- + TString name = ""; + cout << endl << endl; + cout << "===> Creating ladders...." << endl; + infoFile << endl << "Ladders:" << endl; + Int_t nLadders = CreateLadders(); + for (Int_t iLadder = 1; iLadder <= nLadders; iLadder++) { + cout << endl; + name = Form("Ladder%02d", iLadder); + TGeoVolume* ladder = gGeoMan->GetVolume(name); + CheckVolume(ladder); + CheckVolume(ladder, infoFile); + CheckVolume(ladder->GetNode(0)->GetVolume(), infoFile); + } + // -------------------------------------------------------------------------- + + + // ---------------- Create cone ----------------------------------------- + Double_t coneDz = 1.64; + TGeoVolume* coneSmallVolum = ConstructSmallCone(coneDz); + if (!coneSmallVolum) Fatal("ConstructSmallCone", "Volume Cone not found"); + TGeoVolume* coneBigVolum = ConstructBigCone(coneDz); + if (!coneBigVolum) Fatal("ConstructBigCone", "Volume Cone not found"); + // -------------------------------------------------------------------------- + + + // ---------------- Create stations ------------------------------------- + // Float_t statPos[8] = {30., 40., 50., 60., 70., 80., 90., 100.}; + //DE23 Float_t statPos[8] = {13.75, 28.25, 41.75, 50., 60., 70., 80., 90.}; + // Float_t statPos[8] = {14., 28., 42., 50., 60., 70., 80., 90.}; + // 2023 + // Float_t statPos[8] = {11.5, 28., 42., 50., 60., 70., 80., 90.}; + // 2024 + // + // from cave (Jens) + // hier die Sensorpositionen in Z-Richtung für das mSTS Upgrade. + // Target to Station 0: dZ=170 165 + // Station 0 to 1: dZ=125 290 + // Station 1 to 2: dZ=135 425 + // + // 2024 + + //Float_t statPos[8] = {16.5, 29.0, 42.5, 50., 60., 70., 80., 90.}; + Float_t statPos[8] = {12.065, 26.50, 40.0, 50., 60., 70., 80., 90.}; + // + // Float_t statPos[8] = {30., 45., 50., 60., 70., 80., 90., 100.}; + + cout << endl << endl; + cout << "===> Creating stations...." << endl; + infoFile << endl << "Stations: "; + nLadders = 0; + Int_t ladderTypes[20]; + Double_t statZ = 0.; + Double_t rHole = 0.; + TGeoBBox* statShape = NULL; + TGeoTranslation* statTrans = NULL; + + + // --- Station 01: 8 ladders, type 3 2 2 1 1 2 2 3 + cout << endl; + statZ = 30.; + rHole = 2.0; + nLadders = 1; + ladderTypes[0] = 13; + TGeoVolume* station01 = ConstructStation(0, nLadders, ladderTypes, rHole); + + CheckVolume(station01); + CheckVolume(station01, infoFile); + infoFile << "Position z = " << statPos[0] << endl; + + + // --- Station 02: 12 ladders, type 4 3 3 2 2 1 1 2 2 3 3 4 + cout << endl; + statZ = 40.; + rHole = 2.0; + nLadders = 3; + nLadders = 2; + ladderTypes[0] = 9; + ladderTypes[1] = 9; +// v22e ladderTypes[0] = 10; +// v22e ladderTypes[1] = 10; +// v22e ladderTypes[2] = 11; // triple ladder + TGeoVolume* station02 = ConstructStation(1, nLadders, ladderTypes, rHole); + + CheckVolume(station02); + CheckVolume(station02, infoFile); + infoFile << "Position z = " << statPos[1] << endl; + + + // --- Station 03: 12 ladders, type 8 7 6 6 6 5 5 6 6 6 7 8 + cout << endl; + statZ = 50.; + rHole = 2.9; + nLadders = 3; + ladderTypes[0] = 10; + ladderTypes[1] = 12; + ladderTypes[2] = 11; // triple ladder + TGeoVolume* station03 = ConstructStation(2, nLadders, ladderTypes, rHole); + + CheckVolume(station03); + CheckVolume(station03, infoFile); + infoFile << "Position z = " << statPos[2] << endl; + + + // // --- Station 04: 14 ladders, type 9 8 7 6 6 6 5 5 6 6 7 8 9 + // cout << endl; + // statZ = 60.; + // rHole = 2.9; + // nLadders = 14; + // ladderTypes[0] = 15; // 42; // 9; + // ladderTypes[1] = 14; // 34; // 8; + // ladderTypes[2] = 13; // 33; // 7; + // ladderTypes[3] = 12; // 32; // 6; + // ladderTypes[4] = 12; // 32; // 6; + // ladderTypes[5] = 12; // 32; // 6; + // ladderTypes[6] = 4; // 41; // 5; + // ladderTypes[7] = 4; // 41; // 5; + // ladderTypes[8] = 12; // 32; // 6; + // ladderTypes[9] = 12; // 32; // 6; + // ladderTypes[10] = 12; // 32; // 6; + // ladderTypes[11] = 13; // 33; // 7; + // ladderTypes[12] = 14; // 34; // 8; + // ladderTypes[13] = 15; // 42; // 9; + // TGeoVolume* station04 = ConstructStation(3, nLadders, ladderTypes, rHole); + // + // if (gkConstructCones) { + // // upstream + // TGeoRotation* coneRot41 = new TGeoRotation; + // coneRot41->RotateZ(-90); + // coneRot41->RotateY(180); + // // TGeoCombiTrans* conePosRot41 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.3-gkLadderGapZ/2., coneRot41); + // TGeoCombiTrans* conePosRot41 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.285-gkLadderGapZ/2., coneRot41); + // station04->AddNode(coneBigVolum, 1, conePosRot41); + // + // // downstream + // TGeoRotation* coneRot42 = new TGeoRotation; + // coneRot42->RotateZ(-90); + // // TGeoCombiTrans* conePosRot42 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.3+gkLadderGapZ/2., coneRot42); + // TGeoCombiTrans* conePosRot42 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.285+gkLadderGapZ/2., coneRot42); + // station04->AddNode(coneBigVolum, 2, conePosRot42); + // + // station04->GetShape()->ComputeBBox(); + // } + // + // CheckVolume(station04); + // CheckVolume(station04, infoFile); + // infoFile << "Position z = " << statPos[3] << endl; + // + // + // // --- Station 05: 14 ladders, type 14 13 12 12 11 11 10 10 11 11 12 12 13 14 + // cout << endl; + // statZ = 70.; + // rHole = 3.7; + // nLadders = 14; + // ladderTypes[0] = 19; // 55; // 14; + // ladderTypes[1] = 18; // 54; // 13; + // ladderTypes[2] = 17; // 53; // 12; + // ladderTypes[3] = 17; // 53; // 12; + // ladderTypes[4] = 16; // 52; // 11; + // ladderTypes[5] = 16; // 52; // 11; + // ladderTypes[6] = 5; // 51; // 23; // 10; + // ladderTypes[7] = 5; // 51; // 23; // 10; + // ladderTypes[8] = 16; // 52; // 11; + // ladderTypes[9] = 16; // 52; // 11; + // ladderTypes[10] = 17; // 53; // 12; + // ladderTypes[11] = 17; // 53; // 12; + // ladderTypes[12] = 18; // 54; // 13; + // ladderTypes[13] = 19; // 55; // 14; + // TGeoVolume* station05 = ConstructStation(4, nLadders, ladderTypes, rHole); + // + // if (gkConstructCones) { + // // upstream + // TGeoRotation* coneRot51 = new TGeoRotation; + // coneRot51->RotateZ(90); + // coneRot51->RotateY(180); + // // TGeoCombiTrans* conePosRot51 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.3-gkLadderGapZ/2., coneRot51); + // TGeoCombiTrans* conePosRot51 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.285-gkLadderGapZ/2., coneRot51); + // station05->AddNode(coneBigVolum, 1, conePosRot51); + // + // // downstream + // TGeoRotation* coneRot52 = new TGeoRotation; + // coneRot52->RotateZ(90); + // // TGeoCombiTrans* conePosRot52 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.3+gkLadderGapZ/2., coneRot52); + // TGeoCombiTrans* conePosRot52 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.285+gkLadderGapZ/2., coneRot52); + // station05->AddNode(coneBigVolum, 2, conePosRot52); + // + // station05->GetShape()->ComputeBBox(); + // } + // + // CheckVolume(station05); + // CheckVolume(station05, infoFile); + // infoFile << "Position z = " << statPos[4] << endl; + // + // + // // --- Station 06: 14 ladders, type 14 13 12 12 11 11 10 10 11 11 12 12 13 14 + // cout << endl; + // statZ = 80.; + // rHole = 3.7; + // nLadders = 14; + // ladderTypes[0] = 19; // 55; // 14; + // ladderTypes[1] = 18; // 54; // 13; + // ladderTypes[2] = 17; // 53; // 12; + // ladderTypes[3] = 17; // 53; // 12; + // ladderTypes[4] = 16; // 52; // 11; + // ladderTypes[5] = 16; // 52; // 11; + // ladderTypes[6] = 6; // 61; // 10; + // ladderTypes[7] = 6; // 61; // 10; + // ladderTypes[8] = 16; // 52; // 11; + // ladderTypes[9] = 16; // 52; // 11; + // ladderTypes[10] = 17; // 53; // 12; + // ladderTypes[11] = 17; // 53; // 12; + // ladderTypes[12] = 18; // 54; // 13; + // ladderTypes[13] = 19; // 55; // 14; + // TGeoVolume* station06 = ConstructStation(5, nLadders, ladderTypes, rHole); + // + // if (gkConstructCones) { + // // upstream + // TGeoRotation* coneRot61 = new TGeoRotation; + // coneRot61->RotateZ(-90); + // coneRot61->RotateY(180); + // // TGeoCombiTrans* conePosRot61 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.3-gkLadderGapZ/2., coneRot61); + // TGeoCombiTrans* conePosRot61 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.285-gkLadderGapZ/2., coneRot61); + // station06->AddNode(coneBigVolum, 1, conePosRot61); + // + // // downstream + // TGeoRotation* coneRot62 = new TGeoRotation; + // coneRot62->RotateZ(-90); + // // TGeoCombiTrans* conePosRot62 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.3+gkLadderGapZ/2., coneRot62); + // TGeoCombiTrans* conePosRot62 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.285+gkLadderGapZ/2., coneRot62); + // station06->AddNode(coneBigVolum, 2, conePosRot62); + // + // station06->GetShape()->ComputeBBox(); + // } + // + // CheckVolume(station06); + // CheckVolume(station06, infoFile); + // infoFile << "Position z = " << statPos[5] << endl; + // + // + // // --- Station 07: 16 ladders, type 14 13 17 17 16 16 16 15 15 16 16 16 17 17 13 14 + // cout << endl; + // statZ = 90.; + // rHole = 4.2; + // nLadders = 16; + // ladderTypes[0] = 21; // 73; // 17; + // ladderTypes[1] = 19; // 55; // 14; + // ladderTypes[2] = 18; // 54; // 13; + // ladderTypes[3] = 20; // 72; // 16; + // ladderTypes[4] = 20; // 72; // 16; + // ladderTypes[5] = 20; // 72; // 16; + // ladderTypes[6] = 20; // 72; // 16; + // ladderTypes[7] = 7; // 71; // 15; + // ladderTypes[8] = 7; // 71; // 15; + // ladderTypes[9] = 20; // 72; // 16; + // ladderTypes[10] = 20; // 72; // 16; + // ladderTypes[11] = 20; // 72; // 16; + // ladderTypes[12] = 20; // 72; // 16; + // ladderTypes[13] = 18; // 54; // 13; + // ladderTypes[14] = 19; // 55; // 14; + // ladderTypes[15] = 21; // 73; // 17; + // TGeoVolume* station07 = ConstructStation(6, nLadders, ladderTypes, rHole); + // + // if (gkConstructCones) { + // // upstream + // TGeoRotation* coneRot71 = new TGeoRotation; + // coneRot71->RotateZ(90); + // coneRot71->RotateY(180); + // // TGeoCombiTrans* conePosRot71 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.3-gkLadderGapZ/2., coneRot71); + // TGeoCombiTrans* conePosRot71 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.285-gkLadderGapZ/2., coneRot71); + // station07->AddNode(coneBigVolum, 1, conePosRot71); + // + // // downstream + // TGeoRotation* coneRot72 = new TGeoRotation; + // coneRot72->RotateZ(90); + // // TGeoCombiTrans* conePosRot72 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.3+gkLadderGapZ/2., coneRot72); + // TGeoCombiTrans* conePosRot72 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.285+gkLadderGapZ/2., coneRot72); + // station07->AddNode(coneBigVolum, 2, conePosRot72); + // + // station07->GetShape()->ComputeBBox(); + // } + // + // CheckVolume(station07); + // CheckVolume(station07, infoFile); + // infoFile << "Position z = " << statPos[6] << endl; + // + // + // // --- Station 08: 16 ladders, type 14 13 17 17 16 16 16 15 15 16 16 16 17 17 13 14 + // cout << endl; + // statZ = 100.; + // rHole = 4.2; + // nLadders = 16; + // ladderTypes[0] = 19; // 55; // 14; + // ladderTypes[1] = 17; // 53; // 12; + // ladderTypes[2] = 23; // 83; // 20; + // ladderTypes[3] = 22; // 82; // 19; + // ladderTypes[4] = 22; // 82; // 19; + // ladderTypes[5] = 22; // 82; // 19; + // ladderTypes[6] = 22; // 82; // 19; + // ladderTypes[7] = 8; // 81; // 18; + // ladderTypes[8] = 8; // 81; // 18; + // ladderTypes[9] = 22; // 82; // 19; + // ladderTypes[10] = 22; // 82; // 19; + // ladderTypes[11] = 22; // 82; // 19; + // ladderTypes[12] = 22; // 82; // 19; + // ladderTypes[13] = 23; // 83; // 20; + // ladderTypes[14] = 17; // 53; // 12; + // ladderTypes[15] = 19; // 55; // 14; + // TGeoVolume* station08 = ConstructStation(7, nLadders, ladderTypes, rHole); + // + // if (gkConstructCones) { + // // upstream + // TGeoRotation* coneRot81 = new TGeoRotation; + // coneRot81->RotateZ(-90); + // coneRot81->RotateY(180); + // // TGeoCombiTrans* conePosRot81 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.3-gkLadderGapZ/2., coneRot81); + // TGeoCombiTrans* conePosRot81 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.285-gkLadderGapZ/2., coneRot81); + // station08->AddNode(coneBigVolum, 1, conePosRot81); + // + // // downstream + // TGeoRotation* coneRot82 = new TGeoRotation; + // coneRot82->RotateZ(-90); + // // TGeoCombiTrans* conePosRot82 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.3+gkLadderGapZ/2., coneRot82); + // TGeoCombiTrans* conePosRot82 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.285+gkLadderGapZ/2., coneRot82); + // station08->AddNode(coneBigVolum, 2, conePosRot82); + // + // station08->GetShape()->ComputeBBox(); + // } + // + // CheckVolume(station08); + // CheckVolume(station08, infoFile); + // infoFile << "Position z = " << statPos[7] << endl; + // -------------------------------------------------------------------------- + + + // --------------- Create subplates --------------------------------------- + cout << endl << endl; + cout << "===> Creating subplates...." << endl << endl; + infoFile << endl << "Subplates: " << endl; + Int_t nSubplates = CreateSubplates(); + for (Int_t iSubplate = 1; iSubplate <= nSubplates; iSubplate++) { + TString name = Form("Subplate%02d", iSubplate); + TGeoVolume* subplate = gGeoMan->GetVolume(name); + + // add color to plates + subplate->SetTransparency(60); + if (iSubplate == 1) subplate->SetLineColor(kOrange); // kOrange); + if (iSubplate == 2) subplate->SetLineColor(kOrange); // kRed); + if (iSubplate == 3) subplate->SetLineColor(kOrange); // kGreen); + + if (iSubplate == 4) subplate->SetLineColor(kOrange); // kRed); + if (iSubplate == 5) subplate->SetLineColor(kOrange); // kOrange); + if (iSubplate == 6) subplate->SetLineColor(kOrange); // kCyan); + + if (iSubplate == 7) subplate->SetLineColor(kOrange); // kRed); + + if (iSubplate == 8) subplate->SetLineColor(kOrange); // kGreen); + if (iSubplate == 9) subplate->SetLineColor(kOrange); // kGreen); + if (iSubplate == 10) subplate->SetLineColor(kOrange); // kGreen); + + // CheckVolume(plate); + // CheckVolume(plate, infoFile); + } + // -------------------------------------------------------------------------- + + // --------------- Create plates --------------------------------------- + cout << endl << endl; + cout << "===> Creating plates...." << endl << endl; + infoFile << endl << "Plates: " << endl; + Int_t nPlates = CreatePlates(); + for (Int_t iPlate = 1; iPlate <= nPlates; iPlate++) { + TString name = Form("Plate%02d", iPlate); + TGeoVolume* plate = gGeoMan->GetVolume(name); + // CheckVolume(plate); + // CheckVolume(plate, infoFile); + } + // -------------------------------------------------------------------------- + + + // --------------- Create STS volume ------------------------------------ + cout << endl << endl; + cout << "===> Creating STS...." << endl; + + TString stsName = "sts_"; + stsName += geoTag; + + // --- Determine size of STS box + Double_t stsX = 0.; + Double_t stsY = 0.; + Double_t stsZ = 0.; + Double_t stsBorder = 2 * 5.; // 5 cm space for carbon ladders on each side + Int_t nStation = 3; // set number of stations + for (Int_t iStation = 1; iStation <= nStation; iStation++) { + TString statName = Form("Station%02d", iStation); + TGeoVolume* station = gGeoMan->GetVolume(statName); + TGeoBBox* shape = (TGeoBBox*) station->GetShape(); + stsX = TMath::Max(stsX, 2. * shape->GetDX()); + stsY = TMath::Max(stsY, 2. * shape->GetDY()); + cout << "Station " << iStation << ": Y " << stsY << endl; + } + // --- Some border around the stations + stsX += stsBorder; + stsY += stsBorder; + stsZ = (statPos[2] - statPos[1]) + stsBorder; + Double_t stsPosZ = 0.5 * (statPos[2] + statPos[1]); +// stsZ = (statPos[1] - statPos[0]) + stsBorder; +// Double_t stsPosZ = 0.5 * (statPos[1] + statPos[0]); + + // --- Create box around the stations + TGeoBBox* stsBox = new TGeoBBox("stsBox", stsX / 2., stsY / 2., stsZ / 2.); + cout << "size of STS box: x " << stsX << " - y " << stsY << " - z " << stsZ << endl; + + // // --- Create cone hosting the beam pipe + // // --- One straight section with constant radius followed by a cone + // Double_t z1 = statPos[0] - 0.5 * stsBorder; // start of STS box + // Double_t z2 = gkPipeZ2; + // Double_t z3 = statPos[1] + 0.5 * stsBorder; // end of STS box + // Double_t r1 = BeamPipeRadius(z1); + // Double_t r2 = BeamPipeRadius(z2); + // Double_t r3 = BeamPipeRadius(z3); + // r1 += 0.01; // safety margin + // r2 += 0.01; // safety margin + // r3 += 0.01; // safety margin + // + // cout << endl; + // cout << z1 << " " << r1 << endl; + // cout << z2 << " " << r2 << endl; + // cout << z3 << " " << r3 << endl; + // + // cout << endl; + // cout << "station1 : " << BeamPipeRadius(statPos[0]) << endl; + // cout << "station2 : " << BeamPipeRadius(statPos[1]) << endl; + // cout << "station3 : " << BeamPipeRadius(statPos[2]) << endl; + // cout << "station4 : " << BeamPipeRadius(statPos[3]) << endl; + // cout << "station5 : " << BeamPipeRadius(statPos[4]) << endl; + // cout << "station6 : " << BeamPipeRadius(statPos[5]) << endl; + // cout << "station7 : " << BeamPipeRadius(statPos[6]) << endl; + // cout << "station8 : " << BeamPipeRadius(statPos[7]) << endl; + // + // // TGeoPcon* cutout = new TGeoPcon("stsCone", 0., 360., 3); // 2.*TMath::Pi(), 3); + // // cutout->DefineSection(0, z1, 0., r1); + // // cutout->DefineSection(1, z2, 0., r2); + // // cutout->DefineSection(2, z3, 0., r3); + // new TGeoTrd2("stsCone1", r1, r2, r1, r2, (z2-z1)/2.+.1); // add .1 in z length for a clean cutout + // TGeoTranslation *trans1 = new TGeoTranslation("trans1", 0., 0., -(z3-z1)/2.+(z2-z1)/2.); + // trans1->RegisterYourself(); + // new TGeoTrd2("stsCone2", r2, r3, r2, r3, (z3-z2)/2.+.1); // add .1 in z length for a clean cutout + // TGeoTranslation *trans2 = new TGeoTranslation("trans2", 0., 0., +(z3-z1)/2.-(z3-z2)/2.); + // trans2->RegisterYourself(); + + //DE Double_t z1 = statPos[0] - 0.5 * stsBorder; // start of STS box + //DE Double_t z2 = statPos[7] + 0.5 * stsBorder; // end of STS box + //DE Double_t slope = (gkPipeR2 - gkPipeR1) / (gkPipeZ2 - gkPipeZ1); + //DE Double_t r1 = gkPipeR1 + slope * (z1 - gkPipeZ1); // at start of STS + //DE Double_t r2 = gkPipeR1 + slope * (z2 - gkPipeZ1); // at end of STS + //DE r1 += 0.1; // safety margin + //DE r2 += 0.1; // safety margin + //DE // new TGeoCone("stsCone", stsZ/2., 0., r1, 0., r2); + //DE new TGeoTrd2("stsCone", r1, r2, r1, r2, stsZ/2.); + + // --- Create STS volume + // TGeoShape* stsShape = new TGeoCompositeShape("stsShape", + // "stsBox-stsCone1:trans1-stsCone2:trans2"); + // TGeoVolume* sts = new TGeoVolume(stsName.Data(), stsShape, gStsMedium); + // TGeoVolume* sts = new TGeoVolume(stsName.Data(), stsBox, gStsMedium); + TGeoVolumeAssembly* sts = new TGeoVolumeAssembly(stsName.Data()); // do not produce keeping volumes + + // --- Place stations in the STS + for (Int_t iStation = 1; iStation <= nStation; iStation++) { + TString statName = Form("Station%02d", iStation); + TGeoVolume* station = gGeoMan->GetVolume(statName); + Double_t posZ = statPos[iStation - 1] - stsPosZ; + TGeoTranslation* trans = new TGeoTranslation(0., 0., posZ); // standard + sts->AddNode(station, iStation, trans); + sts->GetShape()->ComputeBBox(); + } + + + // plates + if (IncludeBox) + for (Int_t iPlate = 1; iPlate <= nPlates; iPlate++) { + TString platName = Form("Plate%02d", iPlate); + TGeoVolume* plate = gGeoMan->GetVolume(platName); + TGeoTranslation* boxdz01 = new TGeoTranslation("ty01", 0, 0, 2.50); // v23a - shift to 2x2 and 3x3 stations + sts->AddNode(plate, iPlate, boxdz01); + // sts->AddNode(plate, iPlate); + sts->GetShape()->ComputeBBox(); + } + + cout << endl; + CheckVolume(sts); + // -------------------------------------------------------------------------- + + + // --------------- Finish ----------------------------------------------- + TGeoTranslation* stsTrans = new TGeoTranslation(gOffX, gOffY, stsPosZ + gOffZ); + top->AddNode(sts, 1, stsTrans); + top->GetShape()->ComputeBBox(); + cout << endl << endl; + CheckVolume(top); + cout << endl << endl; + gGeoMan->CloseGeometry(); + gGeoMan->CheckOverlaps(0.0001); + gGeoMan->PrintOverlaps(); + gGeoMan->Test(); + + TFile* geoFile = new TFile(geoFileName, "RECREATE"); + sts->Export(geoFileName); + cout << endl; + cout << "Geometry " << sts->GetName() << " exported to " << geoFileName << endl; + geoFile->Close(); + + geoFile = new TFile(geoFileName, "UPDATE"); + stsTrans->Write(); + geoFile->Close(); + + TString geoFileName_ = "sts_"; + geoFileName_ = geoFileName_ + geoTag + "_geo.root?reproducible"; + + geoFile = new TFile(geoFileName_, "RECREATE"); + gGeoMan->Write(); // use this is you want GeoManager format in the output + geoFile->Close(); + + top->Draw("ogl"); + gGeoManager->SetVisLevel(6); + + infoFile.close(); + + // create medialist for this geometry + TString createmedialist = gSystem->Getenv("VMCWORKDIR"); + createmedialist += "/macro/geometry/create_medialist.C"; + std::cout << "Loading macro " << createmedialist << std::endl; + gROOT->LoadMacro(createmedialist); + gROOT->ProcessLine("create_medialist(\"\", false)"); +} +// ============================================================================ +// ====== End of main function ===== +// ============================================================================ + + +// **************************************************************************** +// ***** Definition of media, sensors, sectors and ladders ***** +// ***** ***** +// ***** Decoupled from main function for better readability ***** +// **************************************************************************** + + +/** =========================================================================== + ** Create media + ** + ** Currently created: air, active silicon, passive silion + ** + ** Not used for the time being + **/ +Int_t CreateMedia() +{ + + Int_t nMedia = 0; + Double_t density = 0.; + + // --- Material air + density = 1.205e-3; // [g/cm^3] + TGeoMixture* matAir = new TGeoMixture("sts_air", 3, density); + matAir->AddElement(14.0067, 7, 0.755); // Nitrogen + matAir->AddElement(15.999, 8, 0.231); // Oxygen + matAir->AddElement(39.948, 18, 0.014); // Argon + + // --- Material silicon + density = 2.33; // [g/cm^3] + TGeoElement* elSi = gGeoMan->GetElementTable()->GetElement(14); + TGeoMaterial* matSi = new TGeoMaterial("matSi", elSi, density); + + + // --- Air (passive) + TGeoMedium* medAir = new TGeoMedium("air", nMedia++, matAir); + medAir->SetParam(0, 0.); // is passive + medAir->SetParam(1, 1.); // is in magnetic field + medAir->SetParam(2, 20.); // max. field [kG] + medAir->SetParam(6, 0.001); // boundary crossing precision [cm] + + + // --- Active silicon for sensors + TGeoMedium* medSiAct = new TGeoMedium("silicon", nMedia++, matSi); + medSiAct->SetParam(0, 1.); // is active + medSiAct->SetParam(1, 1.); // is in magnetic field + medSiAct->SetParam(2, 20.); // max. field [kG] + medSiAct->SetParam(6, 0.001); // boundary crossing precisison [cm] + + // --- Passive silicon for cables + TGeoMedium* medSiPas = new TGeoMedium("carbon", nMedia++, matSi); + medSiPas->SetParam(0, 0.); // is passive + medSiPas->SetParam(1, 1.); // is in magnetic field + medSiPas->SetParam(2, 20.); // max. field [kG] + medSiPas->SetParam(6, 0.001); // boundary crossing precisison [cm] + + return nMedia; +} +/** ======================================================================= **/ + + +/** ======================================================================= **/ +Int_t CreateSubplates() +{ + + Int_t nSubplates = 0; + + Double_t xSize = 0.; + Double_t ySize = 0.; + Double_t zSize = 0.5; // cm // gkSubplateThickness; + TGeoMedium* aluminium = gGeoMan->GetMedium("aluminium"); + + // xsize 830 / (830 - 115+137-12) = 590 + + // ysize 518 / 222 / 125 = 865 + // ysize 530 / 198 / 137 // corrected for 12 mm rim + + // center z-axis in front cutout + // ysize 518 + 222/2. = 629 + // ysize 530 + 198/2. = 629 + + // center z-axis in front cutout + // xsize 830/2. - (115 + 137)/2. = 415 - 126 = 289 + + // --- Subplate type 01: front plate (83.0 cm x 86.5 cm) + xSize = 83.0; // cm + ySize = 53.0; // cm + TGeoBBox* shape_subplate01 = new TGeoBBox("subplate01", xSize / 2., ySize / 2., zSize / 2.); + new TGeoVolume("Subplate01", shape_subplate01, aluminium); + nSubplates++; + + // --- Subplate type 02: front plate (83.0 cm x 86.5 cm) + xSize = 59.0; // cm + ySize = 19.8; // cm + TGeoBBox* shape_subplate02 = new TGeoBBox("subplate02", xSize / 2., ySize / 2., zSize / 2.); + new TGeoVolume("Subplate02", shape_subplate02, aluminium); + nSubplates++; + + // --- Subplate type 03: front plate (83.0 cm x 86.5 cm) + xSize = 83.0; // cm + ySize = 13.7; // cm + TGeoBBox* shape_subplate03 = new TGeoBBox("subplate03", xSize / 2., ySize / 2., zSize / 2.); + new TGeoVolume("Subplate03", shape_subplate03, aluminium); + nSubplates++; + + // xsize 830 / (830 - 340 - 25) = 465 + // ysize 483 / 293 / 89 = 865 + + // center z-axis in back cutout + // ysize 483 + 293/2. = 629.5 + + // center z-axis in backside cutout + // xsize 830/2. - ( 340/2. + 25 ) = 415 - 220 = 195 + + // --- Subplate type 04: front plate (83.0 cm x 86.5 cm) + xSize = 83.0; // cm + ySize = 48.3; // cm + TGeoBBox* shape_subplate04 = new TGeoBBox("subplate04", xSize / 2., ySize / 2., zSize / 2.); + new TGeoVolume("Subplate04", shape_subplate04, aluminium); + nSubplates++; + + // --- Subplate type 05: front plate (83.0 cm x 86.5 cm) + xSize = 46.5; // cm + ySize = 29.3; // cm + TGeoBBox* shape_subplate05 = new TGeoBBox("subplate05", xSize / 2., ySize / 2., zSize / 2.); + new TGeoVolume("Subplate05", shape_subplate05, aluminium); + nSubplates++; + + // --- Subplate type 06: front plate (83.0 cm x 86.5 cm) + xSize = 83.0; // cm + ySize = 8.9; // cm + TGeoBBox* shape_subplate06 = new TGeoBBox("subplate06", xSize / 2., ySize / 2., zSize / 2.); + new TGeoVolume("Subplate06", shape_subplate06, aluminium); + nSubplates++; + + // bottom / top + // --- Subplate type 07: bottom/top plate (83.0 cm x 34.0 cm) + xSize = 83.0; // cm + ySize = 34.0; // cm + TGeoBBox* shape_subplate07 = new TGeoBBox("subplate07", xSize / 2., zSize / 2., ySize / 2.); + new TGeoVolume("Subplate07", shape_subplate07, aluminium); + nSubplates++; + + // right + // --- Subplate type 08: right plate + xSize = 85.5; // cm + ySize = 34.0; // cm + TGeoBBox* shape_subplate08 = new TGeoBBox("subplate08", zSize / 2., xSize / 2., ySize / 2.); + new TGeoVolume("Subplate08", shape_subplate08, aluminium); + nSubplates++; + + // left bottom + // --- Subplate type 09: left plate + xSize = 52.5; // cm + ySize = 34.0; // cm + TGeoBBox* shape_subplate09 = new TGeoBBox("subplate09", zSize / 2., xSize / 2., ySize / 2.); + new TGeoVolume("Subplate09", shape_subplate09, aluminium); + nSubplates++; + + // left top + // --- Subplate type 10: left plate + xSize = 13.2; // cm + ySize = 34.0; // cm + TGeoBBox* shape_subplate10 = new TGeoBBox("subplate10", zSize / 2., xSize / 2., ySize / 2.); + new TGeoVolume("Subplate10", shape_subplate10, aluminium); + nSubplates++; + + /* + xSize = 82.0; // cm + ySize = 50.0; // cm + TGeoBBox* shape_subplate01 = new TGeoBBox("subplate01", xSize / 2., ySize / 2., 1.5 / 2.); + new TGeoVolume("Subplate11", shape_subplate01, aluminium); + nSubplates++; + + */ + + + return nSubplates; +} +/** ======================================================================= **/ + +/** ======================================================================= **/ +Int_t CreatePlates() +{ + + Int_t nPlates = 0; + + Double_t box_dx = 83.0; // cm + Double_t box_dy = 86.5; // cm + + // Double_t dx = 0; // cm + // Double_t dx = -(box_dx/2 - 19.5); // cm - backside center + // Double_t dx = -(box_dx/2 - 12.6); // cm - frontside center + Double_t dx = -box_dx / 2 + 15.7; // cm - from CAD drawing + + Double_t dy = box_dy / 2 - 62.9; // cm - from CAD drawing 23,6 cm + + // Double_t box_dz_inner = 0; // cm + Double_t box_dz_inner = 34.0; // cm + + TGeoVolume* subplate01 = gGeoMan->GetVolume("Subplate01"); + TGeoVolume* subplate02 = gGeoMan->GetVolume("Subplate02"); + TGeoVolume* subplate03 = gGeoMan->GetVolume("Subplate03"); + TGeoBBox* box01 = (TGeoBBox*) subplate01->GetShape(); + TGeoBBox* box02 = (TGeoBBox*) subplate02->GetShape(); + TGeoBBox* box03 = (TGeoBBox*) subplate03->GetShape(); + + TGeoVolume* subplate04 = gGeoMan->GetVolume("Subplate04"); + TGeoVolume* subplate05 = gGeoMan->GetVolume("Subplate05"); + TGeoVolume* subplate06 = gGeoMan->GetVolume("Subplate06"); + TGeoBBox* box04 = (TGeoBBox*) subplate04->GetShape(); + TGeoBBox* box05 = (TGeoBBox*) subplate05->GetShape(); + TGeoBBox* box06 = (TGeoBBox*) subplate06->GetShape(); + + TGeoVolume* subplate07 = gGeoMan->GetVolume("Subplate07"); + TGeoBBox* box07 = (TGeoBBox*) subplate07->GetShape(); + + TGeoVolume* subplate08 = gGeoMan->GetVolume("Subplate08"); + TGeoBBox* box08 = (TGeoBBox*) subplate08->GetShape(); + + TGeoVolume* subplate09 = gGeoMan->GetVolume("Subplate09"); + TGeoBBox* box09 = (TGeoBBox*) subplate09->GetShape(); + + TGeoVolume* subplate10 = gGeoMan->GetVolume("Subplate10"); + TGeoBBox* box10 = (TGeoBBox*) subplate10->GetShape(); + + // --- Plate type 1: front plate made of 3 subplates + TGeoVolumeAssembly* plate01 = new TGeoVolumeAssembly("Plate01"); + Double_t sy01 = -box_dy / 2. + box01->GetDY(); + Double_t sz01 = -(box01->GetDZ() + box_dz_inner / 2.); + TGeoTranslation* ty01 = new TGeoTranslation("ty01", dx, sy01 + dy, sz01); + plate01->AddNode(subplate01, 1, ty01); + Double_t sx02 = -box_dx / 2. + box02->GetDX(); + Double_t sy02 = -box_dy / 2. + box01->GetDY() * 2 + box02->GetDY(); + TGeoTranslation* ty02 = new TGeoTranslation("ty02", sx02 + dx, sy02 + dy, sz01); + plate01->AddNode(subplate02, 2, ty02); + Double_t sy03 = -box_dy / 2. + box01->GetDY() * 2 + box02->GetDY() * 2 + box03->GetDY(); + TGeoTranslation* ty03 = new TGeoTranslation("ty03", dx, sy03 + dy, sz01); + plate01->AddNode(subplate03, 3, ty03); + plate01->GetShape()->ComputeBBox(); + nPlates++; + + // --- Plate type 2: back plate made of 3 subplates + TGeoVolumeAssembly* plate02 = new TGeoVolumeAssembly("Plate02"); + Double_t sy04 = -box_dy / 2. + box04->GetDY(); + Double_t sz04 = box04->GetDZ() + box_dz_inner / 2.; + TGeoTranslation* ty04 = new TGeoTranslation("ty04", dx, sy04 + dy, sz04); + plate02->AddNode(subplate04, 1, ty04); + Double_t sx05 = -box_dx / 2. + box05->GetDX(); + Double_t sy05 = -box_dy / 2. + box04->GetDY() * 2 + box05->GetDY(); + TGeoTranslation* ty05 = new TGeoTranslation("ty05", sx05 + dx, sy05 + dy, sz04); + plate02->AddNode(subplate05, 2, ty05); + Double_t sy06 = -box_dy / 2. + box04->GetDY() * 2 + box05->GetDY() * 2 + box06->GetDY(); + TGeoTranslation* ty06 = new TGeoTranslation("ty06", dx, sy06 + dy, sz04); + plate02->AddNode(subplate06, 3, ty06); + plate02->GetShape()->ComputeBBox(); + nPlates++; + + // --- Plate type 3: bottom plate + TGeoVolumeAssembly* plate03 = new TGeoVolumeAssembly("Plate03"); + Double_t sy07 = box_dy / 2. - box07->GetDY(); + TGeoTranslation* ty07 = new TGeoTranslation("ty07", dx, -sy07 + dy, 0.); + plate03->AddNode(subplate07, 1, ty07); + plate03->GetShape()->ComputeBBox(); + nPlates++; + + // --- Plate type 4: top plate + TGeoVolumeAssembly* plate04 = new TGeoVolumeAssembly("Plate04"); + TGeoTranslation* ty17 = new TGeoTranslation("ty17", dx, sy07 + dy, 0.); + plate04->AddNode(subplate07, 1, ty17); + plate04->GetShape()->ComputeBBox(); + nPlates++; + + // --- Plate type 5: -x plate + TGeoVolumeAssembly* plate05 = new TGeoVolumeAssembly("Plate05"); + Double_t sx08 = box_dx / 2. - box08->GetDX(); + TGeoTranslation* ty08 = new TGeoTranslation("ty08", -sx08 + dx, dy, 0.); + plate05->AddNode(subplate08, 1, ty08); + plate05->GetShape()->ComputeBBox(); + nPlates++; + + // --- Plate type 6: +x plate (shorted due to beampipe) + TGeoVolumeAssembly* plate06 = new TGeoVolumeAssembly("Plate06"); + Double_t sy09 = -box_dy / 2. + box09->GetDY() + 2 * box09->GetDX(); + TGeoTranslation* ty09 = new TGeoTranslation("ty09", sx08 + dx, sy09 + dy, 0.); + plate06->AddNode(subplate09, 1, ty09); + plate06->GetShape()->ComputeBBox(); + nPlates++; + + // --- Plate type 7: +x plate (shorted due to beampipe) + TGeoVolumeAssembly* plate07 = new TGeoVolumeAssembly("Plate07"); + Double_t sy10 = -box_dy / 2. + box10->GetDY() + 2 * box10->GetDX(); + TGeoTranslation* ty10 = new TGeoTranslation("ty10", sx08 + dx, -sy10 + dy, 0.); + plate07->AddNode(subplate10, 1, ty10); + plate07->GetShape()->ComputeBBox(); + nPlates++; + + return nPlates; +} +/** ======================================================================= **/ + + +/** =========================================================================== + ** Create sensors + ** + ** Sensors are created as volumes with box shape and active silicon as medium. + ** Four kinds of sensors: 3.2x2.2, 6.2x2.2, 6.2x4.2, 6.2x6.2 + **/ +Int_t CreateSensors() +{ + + Int_t nSensors = 0; + + Double_t xSize = 0.; + Double_t ySize = 0.; + Double_t zSize = gkSensorThickness; + TGeoMedium* silicon = gGeoMan->GetMedium("silicon"); + + + // --- Sensor type 01: Small sensor (6.2 cm x 2.2 cm) + xSize = gkSensorSizeX; + ySize = 2.2; + TGeoBBox* shape_sensor01 = new TGeoBBox("sensor01", xSize / 2., ySize / 2., zSize / 2.); + new TGeoVolume("Sensor01", shape_sensor01, silicon); + nSensors++; + + + // --- Sensor type 02: Medium sensor (6.2 cm x 4.2 cm) + xSize = gkSensorSizeX; + ySize = 4.2; + TGeoBBox* shape_sensor02 = new TGeoBBox("sensor02", xSize / 2., ySize / 2., zSize / 2.); + new TGeoVolume("Sensor02", shape_sensor02, silicon); + nSensors++; + + + // --- Sensor type 03: Big sensor (6.2 cm x 6.2 cm) + xSize = gkSensorSizeX; + ySize = 6.2; + TGeoBBox* shape_sensor03 = new TGeoBBox("sensor03", xSize / 2., ySize / 2., zSize / 2.); + new TGeoVolume("Sensor03", shape_sensor03, silicon); + nSensors++; + + + // --- Sensor type 04: Big sensor (6.2 cm x 12.4 cm) + xSize = gkSensorSizeX; + ySize = 12.4; + TGeoBBox* shape_sensor04 = new TGeoBBox("sensor04", xSize / 2., ySize / 2., zSize / 2.); + new TGeoVolume("Sensor04", shape_sensor04, silicon); + nSensors++; + + + // below are extra small sensors, those are not available in the CAD model + + // --- Sensor Type 05: Half small sensor (4 cm x 2.5 cm) + xSize = 4.0; + ySize = 2.5; + TGeoBBox* shape_sensor05 = new TGeoBBox("sensor05", xSize / 2., ySize / 2., zSize / 2.); + new TGeoVolume("Sensor05", shape_sensor05, silicon); + nSensors++; + + + // --- Sensor type 06: Additional "in hole" sensor (3.1 cm x 4.2 cm) + xSize = 3.1; + ySize = 4.2; + TGeoBBox* shape_sensor06 = new TGeoBBox("sensor06", xSize / 2., ySize / 2., zSize / 2.); + new TGeoVolume("Sensor06", shape_sensor06, silicon); + nSensors++; + + + // --- Sensor type 07: Mini Medium sensor (1.5 cm x 4.2 cm) + xSize = 1.5; + ySize = 4.2; + TGeoBBox* shape_sensor07 = new TGeoBBox("sensor07", xSize / 2., ySize / 2., zSize / 2.); + new TGeoVolume("Sensor07", shape_sensor07, silicon); + nSensors++; + + + return nSensors; +} +/** ======================================================================= **/ + + +/** =========================================================================== + ** Create sectors + ** + ** A sector is either a single sensor or several chained sensors. + ** It is implemented as TGeoVolumeAssembly. + ** Currently available: + ** - single sensors of type 1 - 4 + ** - two chained sensors of type 4 + ** - three chained sensors of type 4 + **/ +Int_t CreateSectors() +{ + + Int_t nSectors = 0; + + TGeoVolume* sensor01 = gGeoMan->GetVolume("Sensor01"); + TGeoVolume* sensor02 = gGeoMan->GetVolume("Sensor02"); + TGeoVolume* sensor03 = gGeoMan->GetVolume("Sensor03"); + TGeoVolume* sensor04 = gGeoMan->GetVolume("Sensor04"); + TGeoVolume* sensor05 = gGeoMan->GetVolume("Sensor05"); + TGeoVolume* sensor06 = gGeoMan->GetVolume("Sensor06"); + TGeoVolume* sensor07 = gGeoMan->GetVolume("Sensor07"); + // TGeoBBox* box4 = (TGeoBBox*) sensor04->GetShape(); + + // --- Sector type 1: single sensor of type 1 + TGeoVolumeAssembly* sector01 = new TGeoVolumeAssembly("Sector01"); + sector01->AddNode(sensor01, 1); + sector01->GetShape()->ComputeBBox(); + nSectors++; + + // --- Sector type 2: single sensor of type 2 + TGeoVolumeAssembly* sector02 = new TGeoVolumeAssembly("Sector02"); + sector02->AddNode(sensor02, 1); + sector02->GetShape()->ComputeBBox(); + nSectors++; + + // --- Sector type 3: single sensor of type 3 + TGeoVolumeAssembly* sector03 = new TGeoVolumeAssembly("Sector03"); + sector03->AddNode(sensor03, 1); + sector03->GetShape()->ComputeBBox(); + nSectors++; + + // --- Sector type 4: single sensor of type 4 + TGeoVolumeAssembly* sector04 = new TGeoVolumeAssembly("Sector04"); + sector04->AddNode(sensor04, 1); + sector04->GetShape()->ComputeBBox(); + nSectors++; + + // --- Sector type 5: single sensor of type 5 + TGeoVolumeAssembly* sector05 = new TGeoVolumeAssembly("Sector05"); + sector05->AddNode(sensor05, 1); + sector05->GetShape()->ComputeBBox(); + nSectors++; + + // --- Sector type 6: single sensor of type 6 + TGeoVolumeAssembly* sector06 = new TGeoVolumeAssembly("Sector06"); + sector06->AddNode(sensor06, 1); + sector06->GetShape()->ComputeBBox(); + nSectors++; + + // --- Sector type 7: single sensor of type 7 + TGeoVolumeAssembly* sector07 = new TGeoVolumeAssembly("Sector07"); + sector07->AddNode(sensor07, 1); + sector07->GetShape()->ComputeBBox(); + nSectors++; + + // // --- Sector type 5: two sensors of type 4 + // TGeoVolumeAssembly* sector05 = new TGeoVolumeAssembly("Sector05"); + // Double_t shift5 = 0.5 * gkChainGapY + box4->GetDY(); + // TGeoTranslation* transD5 = + // new TGeoTranslation("td", 0., -1. * shift5, 0.); + // TGeoTranslation* transU5 = + // new TGeoTranslation("tu", 0., shift5, 0.); + // sector05->AddNode(sensor04, 1, transD5); + // sector05->AddNode(sensor04, 2, transU5); + // sector05->GetShape()->ComputeBBox(); + // nSectors++; + + return nSectors; +} +/** ======================================================================= **/ + + +/** =========================================================================== + ** Create ladders + ** + ** Ladders are the building blocks of the stations. They contain + ** several modules placed one after the other along the z axis + ** such that the sectors are arranged vertically (with overlap). + ** + ** A ladder is constructed out of two half ladders, the second of which + ** is rotated in the x-y plane by 180 degrees and displaced + ** in z direction. + **/ +Int_t CreateLadders() +{ + + Int_t nLadders = 0; + + // --- Some variables + Int_t nSectors = 0; + Int_t sectorTypes[10]; + TGeoBBox* shape = NULL; + TString s0name; + TGeoVolume* s0vol = NULL; + TGeoVolume* halfLadderU = NULL; + TGeoVolume* halfLadderD = NULL; + Double_t shiftZ = 0.; + Double_t ladderY = 0.; + Double_t gapY = 0.; + + + // --- Ladder 01 x-mirror of 02: 10 sectors, type 4 4 3 2 1 1 2 3 4 4 + nSectors = 5; + sectorTypes[0] = 1; + sectorTypes[1] = 2; + sectorTypes[2] = 3; + sectorTypes[3] = 4; + sectorTypes[4] = 4; + s0name = Form("Sector%02d", sectorTypes[0]); + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + shiftZ = 2. * shape->GetDZ() + gkSectorGapZ; + halfLadderU = ConstructHalfLadder(1, "HalfLadder01u", nSectors, sectorTypes, 'r'); // mirrored + halfLadderD = ConstructHalfLadder(1, "HalfLadder01d", nSectors, sectorTypes, 'l'); // mirrored + ConstructLadder(1, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 02: 10 sectors, type 4 4 3 2 1 1 2 3 4 4 + nSectors = 5; + sectorTypes[0] = 1; + sectorTypes[1] = 2; + sectorTypes[2] = 3; + sectorTypes[3] = 4; + sectorTypes[4] = 4; + s0name = Form("Sector%02d", sectorTypes[0]); + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + shiftZ = 2. * shape->GetDZ() + gkSectorGapZ; + halfLadderU = ConstructHalfLadder(2, "HalfLadder02u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(2, "HalfLadder02d", nSectors, sectorTypes, 'r'); + ConstructLadder(2, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + //===================================================================================== + + // --- Ladder 13: 1 sector, type 3 + nSectors = 1; + sectorTypes[0] = 3; + s0name = Form("Sector%02d", sectorTypes[0]); + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + shiftZ = 2. * shape->GetDZ() + gkSectorGapZ; + // + // top half ladder only (FEBs in the top) + // + halfLadderU = ConstructHalfLadder(13, "HalfLadder13u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(13, "HalfLadder13d", 0, sectorTypes, 'r'); + // halfLadderD = ConstructHalfLadder(13, "HalfLadder13d", nSectors, sectorTypes, 'r'); + ConstructLadder(13, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 09: 2 sectors, type 3 3 - mSTS + nSectors = 2; + sectorTypes[0] = 3; + sectorTypes[1] = 3; + s0name = Form("Sector%02d", sectorTypes[0]); + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + shiftZ = 2. * shape->GetDZ() + gkSectorGapZ; + // + // bottom half ladder only + // + // halfLadderU = ConstructHalfLadder(9, "HalfLadder09u", nSectors, sectorTypes, 'l'); + halfLadderU = ConstructHalfLadder(9, "HalfLadder09u", 0, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(9, "HalfLadder09d", nSectors, sectorTypes, 'r'); + // + ConstructLadder(9, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 10: 2 sectors, type 3 4 - mSTS + nSectors = 2; + sectorTypes[0] = 3; + sectorTypes[1] = 4; + s0name = Form("Sector%02d", sectorTypes[0]); + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + shiftZ = 2. * shape->GetDZ() + gkSectorGapZ; + // + // bottom half ladder only + // + // halfLadderU = ConstructHalfLadder(10, "HalfLadder10u", nSectors, sectorTypes, 'l'); + halfLadderU = ConstructHalfLadder(10, "HalfLadder10u", 0, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(10, "HalfLadder10d", nSectors, sectorTypes, 'r'); + // + ConstructLadder(10, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 11: 3 sectors, type 3 3 3 - mSTS + nSectors = 3; + sectorTypes[0] = 3; + sectorTypes[1] = 3; + sectorTypes[2] = 3; + s0name = Form("Sector%02d", sectorTypes[0]); + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + shiftZ = 2. * shape->GetDZ() + gkSectorGapZ; + // + // bottom half ladder only + // + // halfLadderU = ConstructHalfLadder(11, "HalfLadder11u", nSectors, sectorTypes, 'l'); + halfLadderU = ConstructHalfLadder(11, "HalfLadder11u", 0, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(11, "HalfLadder11d", nSectors, sectorTypes, 'r'); + // + ConstructLadder(11, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 12: 2 sectors, type 3 4 - mSTS - y-overlap different from 10 + nSectors = 2; + sectorTypes[0] = 3; + sectorTypes[1] = 4; + s0name = Form("Sector%02d", sectorTypes[0]); + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + shiftZ = 2. * shape->GetDZ() + gkSectorGapZ; + // + // bottom half ladder only + // + // halfLadderU = ConstructHalfLadder(12, "HalfLadder12u", nSectors, sectorTypes, 'l'); + halfLadderU = ConstructHalfLadder(12, "HalfLadder12u", 0, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(12, "HalfLadder12d", nSectors, sectorTypes, 'r'); + // + ConstructLadder(12, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + //===================================================================================== + + // --- Ladder 03 x-mirror of 04: 10 sectors, type 5 4 3 3 6 6 3 3 4 5 + nSectors = 5; + sectorTypes[0] = 6; + sectorTypes[1] = 3; + sectorTypes[2] = 3; + sectorTypes[3] = 4; + sectorTypes[4] = 5; + s0name = Form("Sector%02d", sectorTypes[0]); + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + shiftZ = 2. * shape->GetDZ() + gkSectorGapZ; + halfLadderU = ConstructHalfLadder(3, "HalfLadder03u", nSectors, sectorTypes, 'r'); // mirrored + halfLadderD = ConstructHalfLadder(3, "HalfLadder03d", nSectors, sectorTypes, 'l'); // mirrored + ConstructLadder(3, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 04: 10 sectors, type 5 4 3 3 6 6 3 3 4 5 + nSectors = 5; + sectorTypes[0] = 6; + sectorTypes[1] = 3; + sectorTypes[2] = 3; + sectorTypes[3] = 4; + sectorTypes[4] = 5; + s0name = Form("Sector%02d", sectorTypes[0]); + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + shiftZ = 2. * shape->GetDZ() + gkSectorGapZ; + halfLadderU = ConstructHalfLadder(4, "HalfLadder04u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(4, "HalfLadder04d", nSectors, sectorTypes, 'r'); + ConstructLadder(4, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 14: 6 sensors, type 5 4 3 3 4 5 + nSectors = 3; + sectorTypes[0] = 3; + sectorTypes[1] = 4; + sectorTypes[2] = 5; + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + ladderY = 2. * shape->GetDY(); + halfLadderU = ConstructHalfLadder(14, "HalfLadder14u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(14, "HalfLadder14d", nSectors, sectorTypes, 'r'); + shape = (TGeoBBox*) halfLadderU->GetShape(); + ConstructLadder(14, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 15: 4 sectors, type 4 4 4 4 + nSectors = 2; + sectorTypes[0] = 4; + sectorTypes[1] = 4; + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + ladderY = 2. * shape->GetDY(); + halfLadderU = ConstructHalfLadder(15, "HalfLadder15u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(15, "HalfLadder15d", nSectors, sectorTypes, 'r'); + shape = (TGeoBBox*) halfLadderU->GetShape(); + ConstructLadder(15, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 05 x-mirror of 06: 10 sectors, type 5 5 4 3 7 7 3 4 5 5 + nSectors = 5; + sectorTypes[0] = 7; + sectorTypes[1] = 3; + sectorTypes[2] = 4; + sectorTypes[3] = 5; + sectorTypes[4] = 5; + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + ladderY = 2. * shape->GetDY(); + halfLadderU = ConstructHalfLadder(5, "HalfLadder05u", nSectors, sectorTypes, 'r'); // mirrored + halfLadderD = ConstructHalfLadder(5, "HalfLadder05d", nSectors, sectorTypes, 'l'); // mirrored + shape = (TGeoBBox*) halfLadderU->GetShape(); + ConstructLadder(5, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 06: 10 sectors, type 5 5 4 3 7 7 3 4 5 5 + nSectors = 5; + sectorTypes[0] = 7; + sectorTypes[1] = 3; + sectorTypes[2] = 4; + sectorTypes[3] = 5; + sectorTypes[4] = 5; + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + ladderY = 2. * shape->GetDY(); + halfLadderU = ConstructHalfLadder(6, "HalfLadder06u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(6, "HalfLadder06d", nSectors, sectorTypes, 'r'); + shape = (TGeoBBox*) halfLadderU->GetShape(); + ConstructLadder(6, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 16: 10 sectors, type 5 5 4 3 3 3 3 4 5 5 + nSectors = 5; + sectorTypes[0] = 3; + sectorTypes[1] = 3; + sectorTypes[2] = 4; + sectorTypes[3] = 5; + sectorTypes[4] = 5; + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + ladderY = 2. * shape->GetDY(); + halfLadderU = ConstructHalfLadder(16, "HalfLadder16u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(16, "HalfLadder16d", nSectors, sectorTypes, 'r'); + shape = (TGeoBBox*) halfLadderU->GetShape(); + ConstructLadder(16, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 17: 8 sectors, type 5 5 4 3 3 4 5 5 + nSectors = 4; + sectorTypes[0] = 3; + sectorTypes[1] = 4; + sectorTypes[2] = 5; + sectorTypes[3] = 5; + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + ladderY = 2. * shape->GetDY(); + halfLadderU = ConstructHalfLadder(17, "HalfLadder17u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(17, "HalfLadder17d", nSectors, sectorTypes, 'r'); + shape = (TGeoBBox*) halfLadderU->GetShape(); + ConstructLadder(17, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 18: 6 sectors, type 5 5 4 4 5 5 + nSectors = 3; + sectorTypes[0] = 4; + sectorTypes[1] = 5; + sectorTypes[2] = 5; + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + ladderY = 2. * shape->GetDY(); + halfLadderU = ConstructHalfLadder(18, "HalfLadder18u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(18, "HalfLadder18d", nSectors, sectorTypes, 'r'); + shape = (TGeoBBox*) halfLadderU->GetShape(); + ConstructLadder(18, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 19: 4 sectors, type 5 5 5 5 + nSectors = 2; + sectorTypes[0] = 5; + sectorTypes[1] = 5; + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + ladderY = 2. * shape->GetDY(); + halfLadderU = ConstructHalfLadder(19, "HalfLadder19u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(19, "HalfLadder19d", nSectors, sectorTypes, 'r'); + shape = (TGeoBBox*) halfLadderU->GetShape(); + ConstructLadder(19, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 07: 10 sectors, type 5 5 4 3 3 gap 3 3 4 5 5, with gap + nSectors = 5; + sectorTypes[0] = 3; + sectorTypes[1] = 3; + sectorTypes[2] = 4; + sectorTypes[3] = 5; + sectorTypes[4] = 5; + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + ladderY = 2. * shape->GetDY(); + halfLadderU = ConstructHalfLadder(7, "HalfLadder07u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(7, "HalfLadder07d", nSectors, sectorTypes, 'r'); + shape = (TGeoBBox*) halfLadderU->GetShape(); + gapY = 4.4; + ConstructLadderWithGap(7, halfLadderU, halfLadderD, 2 * gapY); + nLadders++; + + + // --- Ladder 20: 10 sectors, type 5 5 5 3 2 2 3 5 5 5 + nSectors = 5; + sectorTypes[0] = 2; + sectorTypes[1] = 3; + sectorTypes[2] = 5; + sectorTypes[3] = 5; + sectorTypes[4] = 5; + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + ladderY = 2. * shape->GetDY(); + halfLadderU = ConstructHalfLadder(20, "HalfLadder20u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(20, "HalfLadder20d", nSectors, sectorTypes, 'r'); + shape = (TGeoBBox*) halfLadderU->GetShape(); + ConstructLadder(20, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 21: 2 sectors, type 5 5 + nSectors = 1; + sectorTypes[0] = 5; + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + ladderY = 2. * shape->GetDY(); + halfLadderU = ConstructHalfLadder(21, "HalfLadder21u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(21, "HalfLadder21d", nSectors, sectorTypes, 'r'); + shape = (TGeoBBox*) halfLadderU->GetShape(); + ConstructLadder(21, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 08: 8 sectors, type 5 5 5 4 gap 4 5 5 5, with gap + nSectors = 4; + sectorTypes[0] = 4; + sectorTypes[1] = 5; + sectorTypes[2] = 5; + sectorTypes[3] = 5; + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + ladderY = 2. * shape->GetDY(); + halfLadderU = ConstructHalfLadder(8, "HalfLadder08u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(8, "HalfLadder08d", nSectors, sectorTypes, 'r'); + shape = (TGeoBBox*) halfLadderU->GetShape(); + gapY = 4.57; + ConstructLadderWithGap(8, halfLadderU, halfLadderD, 2 * gapY); + nLadders++; + + + // --- Ladder 22: 10 sectors, type 5 5 5 4 3 3 4 5 5 5 + nSectors = 5; + sectorTypes[0] = 3; + sectorTypes[1] = 4; + sectorTypes[2] = 5; + sectorTypes[3] = 5; + sectorTypes[4] = 5; + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + ladderY = 2. * shape->GetDY(); + halfLadderU = ConstructHalfLadder(22, "HalfLadder22u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(22, "HalfLadder22d", nSectors, sectorTypes, 'r'); + shape = (TGeoBBox*) halfLadderU->GetShape(); + ConstructLadder(22, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 23: 10 sectors, type 5 5 4 4 3 3 4 4 5 5 + nSectors = 5; + sectorTypes[0] = 3; + sectorTypes[1] = 4; + sectorTypes[2] = 4; + sectorTypes[3] = 5; + sectorTypes[4] = 5; + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + ladderY = 2. * shape->GetDY(); + halfLadderU = ConstructHalfLadder(23, "HalfLadder23u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(23, "HalfLadder23d", nSectors, sectorTypes, 'r'); + shape = (TGeoBBox*) halfLadderU->GetShape(); + ConstructLadder(23, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + return nLadders; +} +/** ======================================================================= **/ + + +// **************************************************************************** +// ***** ***** +// ***** Generic functions for the construction of STS elements ***** +// ***** ***** +// ***** module: volume (made of a sector and a cable) ***** +// ***** haf ladder: assembly (made of modules) ***** +// ***** ladder: assembly (made of two half ladders) ***** +// ***** station: volume (made of ladders) ***** +// ***** ***** +// **************************************************************************** + + +/** =========================================================================== + ** Construct a module + ** + ** A module is a sector plus the readout cable extending from the + ** top of the sector. The cable is made from passive silicon. + ** The cable has the same x size as the sector. + ** Its thickness is given by the global variable gkCableThickness. + ** The cable length is a parameter. + ** The sensor(s) of the sector is/are placed directly in the module; + ** the sector is just auxiliary for the proper placement. + ** + ** Arguments: + ** name volume name + ** sector pointer to sector volume + ** cableLength length of cable + **/ +TGeoVolume* ConstructModule(const char* name, TGeoVolume* sector, Double_t cableLength) +{ + + // --- Check sector volume + if (!sector) Fatal("CreateModule", "Sector volume not found!"); + + // --- Get size of sector + TGeoBBox* box = (TGeoBBox*) sector->GetShape(); + Double_t sectorX = 2. * box->GetDX(); + Double_t sectorY = 2. * box->GetDY(); + Double_t sectorZ = 2. * box->GetDZ(); + + // --- Get size of cable + Double_t cableX = sectorX; + Double_t cableY = cableLength; + Double_t cableZ = gkCableThickness; + + // --- Create module volume + Double_t moduleX = TMath::Max(sectorX, cableX); + Double_t moduleY = sectorY + cableLength; + Double_t moduleZ = TMath::Max(sectorZ, cableZ); + TGeoVolume* module = gGeoManager->MakeBox(name, gStsMedium, moduleX / 2., moduleY / 2., moduleZ / 2.); + + // --- Position of sector in module + // --- Sector is centred in x and z and aligned to the bottom + Double_t sectorXpos = 0.; + Double_t sectorYpos = 0.5 * (sectorY - moduleY); + Double_t sectorZpos = 0.; + + + // --- Get sensor(s) from sector + Int_t nSensors = sector->GetNdaughters(); + for (Int_t iSensor = 0; iSensor < nSensors; iSensor++) { + TGeoNode* sensor = sector->GetNode(iSensor); + + // --- Calculate position of sensor in module + const Double_t* xSensTrans = sensor->GetMatrix()->GetTranslation(); + Double_t sensorXpos = 0.; + Double_t sensorYpos = sectorYpos + xSensTrans[1]; + Double_t sensorZpos = 0.; + TGeoTranslation* sensTrans = new TGeoTranslation("sensTrans", sensorXpos, sensorYpos, sensorZpos); + + // --- Add sensor volume to module + TGeoVolume* sensVol = sensor->GetVolume(); + module->AddNode(sensor->GetVolume(), iSensor + 1, sensTrans); + module->GetShape()->ComputeBBox(); + } + + + // --- Create cable volume, if necessary, and place it in module + // --- Cable is centred in x and z and aligned to the top + if (gkConstructCables && cableLength > 0.0001) { + TString cableName = TString(name) + "_cable"; + TGeoMedium* cableMedium = gGeoMan->GetMedium("STScable"); + if (!cableMedium) Fatal("CreateModule", "Medium STScable not found!"); + TGeoVolume* cable = gGeoManager->MakeBox(cableName.Data(), cableMedium, cableX / 2., cableY / 2., cableZ / 2.); + // add color to cables + cable->SetLineColor(kOrange); + cable->SetTransparency(60); + Double_t cableXpos = 0.; + Double_t cableYpos = sectorY + 0.5 * cableY - 0.5 * moduleY; + Double_t cableZpos = 0.; + TGeoTranslation* cableTrans = new TGeoTranslation("cableTrans", cableXpos, cableYpos, cableZpos); + module->AddNode(cable, 1, cableTrans); + module->GetShape()->ComputeBBox(); + } + + return module; +} +/** ======================================================================= **/ + + +/** =========================================================================== + ** Construct a half ladder + ** + ** A half ladder is a virtual volume (TGeoVolumeAssembly) consisting + ** of several modules arranged on top of each other. The modules + ** have a given overlap in y and a displacement in z to allow for the + ** overlap. + ** + ** The typ of sectors / modules to be placed must be specified: + ** 1 = sensor01 + ** 2 = sensor02 + ** 3 = sensor03 + ** 4 = sensor04 + ** 5 = 2 x sensor04 (chained) + ** 6 = 3 x sensor04 (chained) + ** The cable is added automatically from the top of each sensor to + ** the top of the half ladder. + ** The alignment can be left (l) or right (r), which matters in the + ** case of different x sizes of sensors (e.g. SensorType01). + ** + ** Arguments: + ** name volume name + ** nSectors number of sectors + ** sectorTypes array with sector types + ** align horizontal alignment of sectors + **/ +TGeoVolume* ConstructHalfLadder(Int_t ladderid, const TString& name, Int_t nSectors, Int_t* sectorTypes, char align) +{ + + // --- Create half ladder volume assembly + TGeoVolumeAssembly* halfLadder = new TGeoVolumeAssembly(name); + + // --- Determine size of ladder + Double_t ladderX = 0.; + Double_t ladderY = 0.; + Double_t ladderZ = 0.; + for (Int_t iSector = 0; iSector < nSectors; iSector++) { + TString sectorName = Form("Sector%02d", sectorTypes[iSector]); + TGeoVolume* sector = gGeoMan->GetVolume(sectorName); + if (!sector) Fatal("ConstructHalfLadder", (char*) Form("Volume %s not found", sectorName.Data())); + TGeoBBox* box = (TGeoBBox*) sector->GetShape(); + // --- Ladder x size equals largest sector x size + ladderX = TMath::Max(ladderX, 2. * box->GetDX()); + // --- Ladder y size is sum of sector ysizes + ladderY += 2. * box->GetDY(); + // --- Ladder z size is sum of sector z sizes + ladderZ += 2. * box->GetDZ(); + } + // --- Subtract overlaps in y + if (ladderid != 10) + ladderY -= Double_t(nSectors - 1) * gkSectorOverlapY; + else + ladderY -= Double_t(nSectors - 1) * gkSectorOverlapYL10; + // --- Add gaps in z direction + ladderZ += Double_t(nSectors - 1) * gkSectorGapZ; + + + // --- Create and place modules + Bool_t L12firstpass = true; // false, if ladder was shifted already once + Double_t yPosSect = -0.5 * ladderY; + Double_t zPosMod = -0.5 * ladderZ; + for (Int_t iSector = 0; iSector < nSectors; iSector++) { + TString sectorName = Form("Sector%02d", sectorTypes[iSector]); + TGeoVolume* sector = gGeoMan->GetVolume(sectorName); + TGeoBBox* box = (TGeoBBox*) sector->GetShape(); + Double_t sectorX = 2. * box->GetDX(); + Double_t sectorY = 2. * box->GetDY(); + Double_t sectorZ = 2. * box->GetDZ(); + yPosSect += 0.5 * sectorY; // Position of sector in ladder + if (L12firstpass == true) + if (ladderid == 12) + { + L12firstpass = false; // false, if ladder was shifted already once + yPosSect += (gkSectorOverlapYL10 - gkSectorOverlapY) / 2.; // shift ladder type 12 downwards by 2.2 mm + // cout << "DE20230209 " << (gkSectorOverlapYL10 - gkSectorOverlapY) / 2. << endl; + } + Double_t cableLength = 0.5 * ladderY - yPosSect - 0.5 * sectorY; + TString moduleName = name + "_" + Form("Module%02d", sectorTypes[iSector]); + TGeoVolume* module = ConstructModule(moduleName.Data(), sector, cableLength); + + TGeoBBox* shapeMod = (TGeoBBox*) module->GetShape(); + Double_t moduleX = 2. * shapeMod->GetDX(); + Double_t moduleY = 2. * shapeMod->GetDY(); + Double_t moduleZ = 2. * shapeMod->GetDZ(); + Double_t xPosMod = 0.; + if (align == 'l') xPosMod = 0.5 * (moduleX - ladderX); // left aligned + else if (align == 'r') + xPosMod = 0.5 * (ladderX - moduleX); // right aligned + else + xPosMod = 0.; // centred in x + Double_t yPosMod = 0.5 * (ladderY - moduleY); // top aligned + zPosMod += 0.5 * moduleZ; + TGeoTranslation* trans = new TGeoTranslation("t", xPosMod, yPosMod, zPosMod); + // // DEDE + // // drop 2nd module on this halfladder for mSTS Nov 2019 + // // halfLadder->AddNode(module, iSector+1, trans); + // if (ladderid == 9) cout << "DE333 " << iSector << endl; + // if (ladderid == 9) + // if (iSector == 0) + // halfLadder->AddNode(module, iSector+1, trans); + + halfLadder->AddNode(module, iSector + 1, trans); + halfLadder->GetShape()->ComputeBBox(); + if (ladderid != 10) + yPosSect += 0.5 * sectorY - gkSectorOverlapY; + else + yPosSect += 0.5 * sectorY - gkSectorOverlapYL10; + zPosMod += 0.5 * moduleZ + gkSectorGapZ; + } + + CheckVolume(halfLadder); + cout << endl; + + return halfLadder; +} +/** ======================================================================= **/ + + +/** =========================================================================== + ** Add a carbon support to a ladder + ** + ** Arguments: + ** LadderIndex ladder number + ** ladder pointer to ladder + ** xu size of halfladder + ** ladderY height of ladder along y + ** ladderZ thickness of ladder along z + **/ +void AddCarbonLadder(Int_t LadderIndex, TGeoVolume* ladder, Double_t xu, Double_t ladderY, Double_t ladderZ) +{ + + // --- Some variables + TString name = Form("Ladder%02d", LadderIndex); + Int_t i; + Double_t j; + + Int_t YnumOfFrameBoxes = (Int_t)(ladderY / gkFrameStep) + 1; // calculate number of elements + if (LadderIndex == 1 || LadderIndex == 2) // set even number of ladder elements for these ladders in station 1 and 2 + YnumOfFrameBoxes--; + // if (LadderIndex == 3 || LadderIndex == 4) // set even number of ladder elements for these ladders in station 3 and 4 + // YnumOfFrameBoxes++; + YnumOfFrameBoxes += YnumOfFrameBoxes % 2; // use even number of frame elements for all ladders + + // cout << "DE: lad " << LadderIndex << " inum " << YnumOfFrameBoxes << endl; + + // DEDE + TGeoBBox* fullFrameShp = new TGeoBBox(name + "_FullFrameBox_shp", xu / 2., gkFrameStep / 2., + (xu / 2. + sqrt(2.) * gkFrameThickness / 2.) / 2.); + // TGeoBBox* fullFrameShp = new TGeoBBox (name+"_FullFrameBox_shp", xu/2., gkFrameStep/2., (gkSectorGapZFrame+xu/2.+sqrt(2.)*gkFrameThickness/2.)/2.); + TGeoVolume* fullFrameBoxVol = new TGeoVolume(name + "_FullFrameBox", fullFrameShp, gStsMedium); + + // cout << "DE: frame Z size " << (xu/2.+sqrt(2.)*gkFrameThickness/2.) << " cm" << endl; + + ConstructFrameElement("FrameBox", fullFrameBoxVol, xu / 2.); + TGeoRotation* fullFrameRot = new TGeoRotation; + fullFrameRot->RotateY(180); + + Int_t inum = YnumOfFrameBoxes; // 6; // 9; + for (i = 1; i <= inum; i++) { + j = -(inum - 1) / 2. + (i - 1); + // cout << "DE: i " << i << " j " << j << endl; + + if (LadderIndex <= 2) // central ladders in stations 1 to 8 + { + if ((j >= -1) && (j <= 1)) // keep the inner 4 elements free for the cone + continue; + } + else if (LadderIndex <= 8) // central ladders in stations 1 to 8 + { + if ((j >= -2) && (j <= 2)) // keep the inner 4 elements free for the cone + continue; + } + + // DEDE + ladder->AddNode(fullFrameBoxVol, i, + new TGeoCombiTrans(name + "_FullFrameBox_posrot", 0., j * gkFrameStep, + -ladderZ / 2. - (xu / 2. + sqrt(2.) * gkFrameThickness / 2.) / 2., + fullFrameRot)); + // ladder->AddNode(fullFrameBoxVol, i, new TGeoCombiTrans(name+"_FullFrameBox_posrot", 0., j*gkFrameStep, -ladderZ/2.-(gkSectorGapZFrame+xu/2.+sqrt(2.)*gkFrameThickness/2.)/2., fullFrameRot)); + } + // cout << endl; + ladder->GetShape()->ComputeBBox(); +} +/** ======================================================================= **/ + + +/** =========================================================================== + ** Construct a ladder out of two half ladders + ** + ** The second half ladder will be rotated by 180 degrees + ** in the x-y plane. The two half ladders will be put on top of each + ** other with a vertical overlap and displaced in z bz shiftZ. + ** + ** Arguments: + ** name volume name + ** halfLadderU pointer to upper half ladder + ** halfLadderD pointer to lower half ladder + ** shiftZ relative displacement along the z axis + **/ + +TGeoVolume* ConstructLadder(Int_t LadderIndex, TGeoVolume* halfLadderU, TGeoVolume* halfLadderD, Double_t shiftZ) +{ + + // --- Some variables + TGeoBBox* shape = NULL; + + // --- Dimensions of half ladders + shape = (TGeoBBox*) halfLadderU->GetShape(); + Double_t xu = 2. * shape->GetDX(); + Double_t yu = 2. * shape->GetDY(); + Double_t zu = 2. * shape->GetDZ(); + + shape = (TGeoBBox*) halfLadderD->GetShape(); + Double_t xd = 2. * shape->GetDX(); + Double_t yd = 2. * shape->GetDY(); + Double_t zd = 2. * shape->GetDZ(); + + // --- Create ladder volume assembly + TString name = Form("Ladder%02d", LadderIndex); + TGeoVolumeAssembly* ladder = new TGeoVolumeAssembly(name); + Double_t ladderX = TMath::Max(xu, xd); + // Double_t ladderY = yu + yd - gkSectorOverlapY; + Double_t ladderY = TMath::Max(yu, yd); + Double_t ladderZ = TMath::Max(zu, zd + shiftZ); + + // --- Place half ladders + Double_t xPosU = 0.; // centred in x + Double_t yPosU = 0.5 * (ladderY - yu); // top aligned + Double_t zPosU = 0.5 * (ladderZ - zu); // front aligned + TGeoTranslation* tu = new TGeoTranslation("tu", xPosU, yPosU, zPosU); + ladder->AddNode(halfLadderU, 1, tu); + + Double_t xPosD = 0.; // centred in x + Double_t yPosD = 0.5 * (yd - ladderY); // bottom aligned + Double_t zPosD = 0.5 * (zd - ladderZ); // back aligned + + // cout << "DEEEE: li " << LadderIndex + // << " || xu " << xu << " yu " << yu << " zu " << zu + // << " || xd " << xd << " yd " << yd << " zd " << zd + // << " || ypu " << yPosU << " ypd " << yPosD + // << endl; + + if (yu == 0) // if no top (= only bottom) half ladder + { + yPosD = 0.5 * (ladderY - yd); // top aligned + zPosD = 0.5 * (ladderZ - zd); // back aligned + } + TGeoRotation* rd = new TGeoRotation(); + rd->RotateZ(180.); + TGeoCombiTrans* cd = new TGeoCombiTrans(xPosD, yPosD, zPosD, rd); + ladder->AddNode(halfLadderD, 2, cd); + ladder->GetShape()->ComputeBBox(); + + // ---------------- Create and place frame boxes ------------------------ + + if (gkConstructFrames) + // AddCarbonLadder(LadderIndex, ladder, xu, ladderY, ladderZ); // take width of top HL + AddCarbonLadder(LadderIndex, ladder, ladderX, ladderY, ladderZ); // take width of any HL + + // -------------------------------------------------------------------------- + + return ladder; +} +/** ======================================================================= **/ + + +/** =========================================================================== + ** Construct a ladder out of two half ladders with vertical gap + ** + ** The second half ladder will be rotated by 180 degrees + ** in the x-y plane. The two half ladders will be put on top of each + ** other with a vertical gap. + ** + ** Arguments: + ** name volume name + ** halfLadderU pointer to upper half ladder + ** halfLadderD pointer to lower half ladder + ** gapY vertical gap + **/ + +TGeoVolume* ConstructLadderWithGap(Int_t LadderIndex, TGeoVolume* halfLadderU, TGeoVolume* halfLadderD, Double_t gapY) +{ + + // --- Some variables + TGeoBBox* shape = NULL; + Int_t i; + Double_t j; + + // --- Dimensions of half ladders + shape = (TGeoBBox*) halfLadderU->GetShape(); + Double_t xu = 2. * shape->GetDX(); + Double_t yu = 2. * shape->GetDY(); + Double_t zu = 2. * shape->GetDZ(); + + shape = (TGeoBBox*) halfLadderD->GetShape(); + Double_t xd = 2. * shape->GetDX(); + Double_t yd = 2. * shape->GetDY(); + Double_t zd = 2. * shape->GetDZ(); + + // --- Create ladder volume assembly + TString name = Form("Ladder%02d", LadderIndex); + TGeoVolumeAssembly* ladder = new TGeoVolumeAssembly(name); + Double_t ladderX = TMath::Max(xu, xd); + Double_t ladderY = yu + yd + gapY; + Double_t ladderZ = TMath::Max(zu, zd); + + // --- Place half ladders + Double_t xPosU = 0.; // centred in x + Double_t yPosU = 0.5 * (ladderY - yu); // top aligned + Double_t zPosU = 0.5 * (ladderZ - zu); // front aligned + TGeoTranslation* tu = new TGeoTranslation("tu", xPosU, yPosU, zPosU); + ladder->AddNode(halfLadderU, 1, tu); + + Double_t xPosD = 0.; // centred in x + Double_t yPosD = 0.5 * (yd - ladderY); // bottom aligned + Double_t zPosD = 0.5 * (zd - ladderZ); // back aligned + TGeoRotation* rd = new TGeoRotation(); + rd->RotateZ(180.); + TGeoCombiTrans* cd = new TGeoCombiTrans(xPosD, yPosD, zPosD, rd); + ladder->AddNode(halfLadderD, 2, cd); + ladder->GetShape()->ComputeBBox(); + + // ---------------- Create and place frame boxes ------------------------ + + if (gkConstructFrames) AddCarbonLadder(LadderIndex, ladder, xu, ladderY, ladderZ); + + // -------------------------------------------------------------------------- + + return ladder; +} +/** ======================================================================= **/ + + +/** =========================================================================== + ** Construct a station + ** + ** The station volume is the minimal box comprising all ladders + ** minus a tube accomodating the beam pipe. + ** + ** The ladders are arranged horizontally from left to right with + ** a given overlap in x. + ** Every second ladder is slightly displaced upstream from the centre + ** z plane and facing downstream, the others are slightly displaced + ** downstream and facing upstream (rotated around the y axis). + ** + ** Arguments: + ** name volume name + ** nLadders number of ladders + ** ladderTypes array of ladder types + ** rHole radius of inner hole + **/ + +// TGeoVolume* ConstructStation(const char* name, +// Int_t iStation, + +TGeoVolume* ConstructStation(Int_t iStation, Int_t nLadders, Int_t* ladderTypes, Double_t rHole) +{ + + TString name; + name = Form("Station%02d", iStation + 1); // 1,2,3,4,5,6,7,8 + // name = Form("Station%02d", iStation); // 0,1,2,3,4,5,6,7 - Station00 missing in output + + // --- Some local variables + TGeoShape* statShape = NULL; + TGeoBBox* ladderShape = NULL; + TGeoBBox* shape = NULL; + TGeoVolume* ladder = NULL; + TString ladderName; + + + // --- Determine size of station from ladders + Double_t statX = 0.; + Double_t statY = 0.; + Double_t statZeven = 0.; + Double_t statZodd = 0.; + Double_t statZ = 0.; + for (Int_t iLadder = 0; iLadder < nLadders; iLadder++) { + Int_t ladderType = ladderTypes[iLadder]; + ladderName = Form("Ladder%02d", ladderType); + ladder = gGeoManager->GetVolume(ladderName); + if (!ladder) Fatal("ConstructStation", Form("Volume %s not found", ladderName.Data())); + shape = (TGeoBBox*) ladder->GetShape(); + statX += 2. * shape->GetDX(); + statY = TMath::Max(statY, 2. * shape->GetDY()); + if (iLadder % 2) statZeven = TMath::Max(statZeven, 2. * shape->GetDZ()); + else + statZodd = TMath::Max(statZodd, 2. * shape->GetDZ()); + } + statX -= Double_t(nLadders - 1) * gkLadderOverlapX; + statZ = statZeven + gkLadderGapZ + statZodd; + + // --- Create station volume + TString boxName(name); + boxName += "_box"; + + cout << "before statZ/2.: " << statZ / 2. << endl; + statZ = 2 * 4.5; // changed Z size of the station for cone and gkLadderGapZ + cout << "fixed to statZ/2.: " << statZ / 2. << endl; + TGeoBBox* statBox = new TGeoBBox(boxName, statX / 2., statY / 2., statZ / 2.); + + // TString tubName(name); + // tubName += "_tub"; + // TString expression = boxName + "-" + tubName; + // // TGeoTube* statTub = new TGeoTube(tubName, 0., rHole, statZ/2.); + // // TGeoBBox* statTub = new TGeoBBox(tubName, rHole, rHole, statZ/2.); + // TGeoBBox* statTub = new TGeoBBox(tubName, rHole, rHole, statZ/2.+.1); // .1 opens the hole in z direction + // + // statShape = new TGeoCompositeShape(name, expression.Data()); + // TGeoVolume* station = new TGeoVolume(name, statShape, gStsMedium); + // TGeoVolume* station = new TGeoVolume(name, statBox, gStsMedium); + TGeoVolumeAssembly* station = new TGeoVolumeAssembly(name); // do not produce keeping volumes + + Double_t subtractedVal; + + // --- Place ladders in station + cout << "xPos0: " << statX << endl; + Double_t xPos = -0.5 * statX; + cout << "xPos1: " << xPos << endl; + Double_t yPos = 0.; + Double_t zPos = 0.; + + Double_t maxdz = 0.; + for (Int_t iLadder = 0; iLadder < nLadders; iLadder++) { + Int_t ladderType = ladderTypes[iLadder]; + ladderName = Form("Ladder%02d", ladderType); + ladder = gGeoManager->GetVolume(ladderName); + shape = (TGeoBBox*) ladder->GetShape(); + if (maxdz < shape->GetDZ()) maxdz = shape->GetDZ(); + } + + for (Int_t iLadder = 0; iLadder < nLadders; iLadder++) { + Int_t ladderType = ladderTypes[iLadder]; + ladderName = Form("Ladder%02d", ladderType); + ladder = gGeoManager->GetVolume(ladderName); + shape = (TGeoBBox*) ladder->GetShape(); + xPos += shape->GetDX(); + cout << "xPos2: " << xPos << endl; + yPos = 0.; // vertically centred + TGeoRotation* rot = new TGeoRotation(); + + if (gkConstructFrames) + // DEDE + subtractedVal = sqrt(2.) * gkFrameThickness / 2. + shape->GetDX(); + // subtractedVal = 2*gkSectorGapZFrame + sqrt(2.)*gkFrameThickness/2. + shape->GetDX(); + else + subtractedVal = 0.; + + // zPos = 0.5 * gkLadderGapZ + (shape->GetDZ()-subtractedVal/2.); // non z-aligned ladders + zPos = 0.5 * gkLadderGapZ + (2 * maxdz - shape->GetDZ() - subtractedVal / 2.); // z-aligned ladders + + cout << "DE ladder" << ladderTypes[iLadder] << " dx: " << shape->GetDX() << " dy: " << shape->GetDY() + << " dz: " << shape->GetDZ() << " max dz: " << maxdz << endl; + + cout << "DE ladder" << ladderTypes[iLadder] << " fra: " << gkFrameThickness / 2. << " sub: " << subtractedVal + << " zpo: " << zPos << endl + << endl; + + // mCBM + if ((iStation % 2 == 0) && (iStation >= 1)) // flip ladders to reproduce CAD layout + + // if (iStation % 2 == 0) // flip ladders for even stations to reproduce CAD layout + // even station 0,2,4,6 + // if (iStation % 2 == 1) // flip ladders for odd stations to reproduce CAD layout + // odd station 1,3,5,7 + { + // --- Unrotated ladders --- downstream + if ((nLadders / 2 + iLadder) % 2) { + // zPos = 0.5 * gkLadderGapZ + (shape->GetDZ()-subtractedVal/2.); + rot->RotateY(180.); + } + // --- Rotated ladders --- upstream + else { + // zPos = -0.5 * gkLadderGapZ - (shape->GetDZ()-subtractedVal/2.); + zPos = -zPos; + } + } + else + // odd station 1,3,5,7 + { + // --- Unrotated ladders --- upstream + if ((nLadders / 2 + iLadder) % 2) { + // zPos = -0.5 * gkLadderGapZ - (shape->GetDZ()-subtractedVal/2.); + zPos = -zPos; + } + // --- Rotated ladders --- downstream + else { + // zPos = 0.5 * gkLadderGapZ + (shape->GetDZ()-subtractedVal/2.); + rot->RotateY(180.); + // zPos += 14.; // move STS ladder from position of C-frame #1 to C-frame #3 - March 2019 version + } + } + + TGeoCombiTrans* trans = new TGeoCombiTrans(xPos, yPos, zPos, rot); + + // enable or disable units + // Unit -1 + if ((ladderType == 13) && (iLadder + 1 == 1)) { + cout << "including " << ladderName << " " << ladderType << " " << iLadder + 1 << endl; + station->AddNode(ladder, iLadder + 1, trans); + } + + // Unit 0 + if ((ladderType == 9) && (iLadder + 1 == 1)) { + cout << "including " << ladderName << " " << ladderType << " " << iLadder + 1 << endl; + station->AddNode(ladder, iLadder + 1, trans); + } + + // Unit 1 + if ((ladderType == 9) && (iLadder + 1 == 2)) { + cout << "including " << ladderName << " " << ladderType << " " << iLadder + 1 << endl; + station->AddNode(ladder, iLadder + 1, trans); + } + + // Unit 2 + if ((ladderType == 12) && (iLadder + 1 == 2)) { + cout << "including " << ladderName << " " << ladderType << " " << iLadder + 1 << endl; + station->AddNode(ladder, iLadder + 1, trans); + } + + // Unit 3 right (far from beam) + if ((ladderType == 10) && (iLadder + 1 == 1)) { + cout << "including " << ladderName << " " << ladderType << " " << iLadder + 1 << endl; + station->AddNode(ladder, iLadder + 1, trans); + } + + // Unit 3 left (close to beam) + if ((ladderType == 11) && (iLadder + 1 == 3)) { + cout << "including " << ladderName << " " << ladderType << " " << iLadder + 1 << endl; + station->AddNode(ladder, iLadder + 1, trans); + } + + // include all ladders + // station->AddNode(ladder, iLadder+1, trans); + + // // drop upstream ladder for mSTS Nov 2019 + // // station->AddNode(ladder, iLadder+1, trans); + // cout << "DE222 " << iLadder << endl; + // if (iLadder == 1) station->AddNode(ladder, iLadder+1, trans); + + station->GetShape()->ComputeBBox(); + xPos += shape->GetDX() - gkLadderOverlapX; + cout << "xPos3: " << xPos << endl; + } + + return station; +} +/** ======================================================================= **/ + + +/** =========================================================================== + ** Volume information for debugging + **/ +void CheckVolume(TGeoVolume* volume) +{ + + TGeoBBox* shape = (TGeoBBox*) volume->GetShape(); + cout << volume->GetName() << ": size " << fixed << setprecision(4) << setw(7) << 2. * shape->GetDX() << " x " + << setw(7) << 2. * shape->GetDY() << " x " << setw(7) << 2. * shape->GetDZ(); + if (volume->IsAssembly()) cout << ", assembly"; + else { + if (volume->GetMedium()) cout << ", medium " << volume->GetMedium()->GetName(); + else + cout << ", " + << "\033[31m" + << " no medium" + << "\033[0m"; + } + cout << endl; + if (volume->GetNdaughters()) { + cout << "Daughters: " << endl; + for (Int_t iNode = 0; iNode < volume->GetNdaughters(); iNode++) { + TGeoNode* node = volume->GetNode(iNode); + TGeoBBox* shape = (TGeoBBox*) node->GetVolume()->GetShape(); + cout << setw(15) << node->GetName() << ", size " << fixed << setprecision(3) << setw(6) << 2. * shape->GetDX() + << " x " << setw(6) << 2. * shape->GetDY() << " x " << setw(6) << 2. * shape->GetDZ() << ", position ( "; + TGeoMatrix* matrix = node->GetMatrix(); + const Double_t* pos = matrix->GetTranslation(); + cout << setfill(' '); + cout << fixed << setw(8) << pos[0] << ", " << setw(8) << pos[1] << ", " << setw(8) << pos[2] << " )" << endl; + } + } +} +/** ======================================================================= **/ + + +/** =========================================================================== + ** Volume information for output to file + **/ +void CheckVolume(TGeoVolume* volume, fstream& file) +{ + + if (!file) return; + + TGeoBBox* shape = (TGeoBBox*) volume->GetShape(); + file << volume->GetName() << ": size " << fixed << setprecision(4) << setw(7) << 2. * shape->GetDX() << " x " + << setw(7) << 2. * shape->GetDY() << " x " << setw(7) << 2. * shape->GetDZ(); + if (volume->IsAssembly()) file << ", assembly"; + else { + if (volume->GetMedium()) file << ", medium " << volume->GetMedium()->GetName(); + else + file << ", " + << "\033[31m" + << " no medium" + << "\033[0m"; + } + file << endl; + if (volume->GetNdaughters()) { + file << "Contains: "; + for (Int_t iNode = 0; iNode < volume->GetNdaughters(); iNode++) + file << volume->GetNode(iNode)->GetVolume()->GetName() << " "; + file << endl; + } +} +/** ======================================================================= **/ + + +/** =========================================================================== + ** Calculate beam pipe outer radius for a given z + **/ +Double_t BeamPipeRadius(Double_t z) +{ + if (z < gkPipeZ2) return gkPipeR1; + Double_t slope = (gkPipeR3 - gkPipeR2) / (gkPipeZ3 - gkPipeZ2); + return gkPipeR2 + slope * (z - gkPipeZ2); +} +/** ======================================================================= **/ + + +/** ======================================================================= **/ +TGeoVolume* ConstructFrameElement(const TString& name, TGeoVolume* frameBoxVol, Double_t x) +{ + // --- Material of the frames + TGeoMedium* framesMaterial = gGeoMan->GetMedium("carbon"); + + Double_t t = gkFrameThickness / 2.; + + // --- Main vertical pillars + // TGeoBBox* frameVertPillarShp = new TGeoBBox(name + "_vertpillar_shape", t, gkFrameStep/2., t); // square crossection, along y + // TGeoVolume* frameVertPillarVol = new TGeoVolume(name + "_vertpillar", frameVertPillarShp, framesMaterial); + // frameVertPillarVol->SetLineColor(kGreen); + // frameBoxVol->AddNode(frameVertPillarVol, 1, new TGeoTranslation(name + "_vertpillar_pos_1", x-t, 0., -(x+sqrt(2.)*t-2.*t)/2.)); + // frameBoxVol->AddNode(frameVertPillarVol, 2, new TGeoTranslation(name + "_vertpillar_pos_2", -(x-t), 0., -(x+sqrt(2.)*t-2.*t)/2.)); + + TGeoBBox* frameVertPillarShp; + if (gkCylindricalFrames) + // TGeoBBox* frameVertPillarShp = new TGeoTube(name + "_vertpillar_shape", 0, t, gkFrameStep/2.); // circle crossection, along z + frameVertPillarShp = new TGeoTube(name + "_vertpillar_shape", gkCylinderDiaInner / 2., gkCylinderDiaOuter / 2., + gkFrameStep / 2.); // circle crossection, along z + else + frameVertPillarShp = new TGeoBBox(name + "_vertpillar_shape", t, t, + gkFrameStep / 2.); // square crossection, along z + TGeoVolume* frameVertPillarVol = new TGeoVolume(name + "_vertpillar", frameVertPillarShp, framesMaterial); + frameVertPillarVol->SetLineColor(kGreen); + + TGeoRotation* xRot90 = new TGeoRotation; + xRot90->RotateX(90.); + frameBoxVol->AddNode( + frameVertPillarVol, 1, + new TGeoCombiTrans(name + "_vertpillar_pos_1", x - t, 0., -(x + sqrt(2.) * t - 2. * t) / 2., xRot90)); + frameBoxVol->AddNode( + frameVertPillarVol, 2, + new TGeoCombiTrans(name + "_vertpillar_pos_2", -(x - t), 0., -(x + sqrt(2.) * t - 2. * t) / 2., xRot90)); + + // TGeoRotation* vertRot = new TGeoRotation(name + "_vertpillar_rot_1", 90., 45., -90.); + TGeoRotation* vertRot = new TGeoRotation; + vertRot->RotateX(90.); + vertRot->RotateY(45.); + frameBoxVol->AddNode(frameVertPillarVol, 3, + new TGeoCombiTrans(name + "_vertpillar_pos_3", 0., 0., (x - sqrt(2.) * t) / 2., vertRot)); + + // --- Small horizontal pillar + TGeoBBox* frameHorPillarShp = + new TGeoBBox(name + "_horpillar_shape", x - 2. * t, gkThinFrameThickness / 2., gkThinFrameThickness / 2.); + TGeoVolume* frameHorPillarVol = new TGeoVolume(name + "_horpillar", frameHorPillarShp, framesMaterial); + frameHorPillarVol->SetLineColor(kCyan); + frameBoxVol->AddNode(frameHorPillarVol, 1, + new TGeoTranslation(name + "_horpillar_pos_1", 0., -gkFrameStep / 2. + gkThinFrameThickness / 2., + -(x + sqrt(2.) * t - 2. * t) / 2.)); + + if (gkConstructSmallFrames) { + + // --- Small sloping pillar + TGeoPara* frameSlopePillarShp = + new TGeoPara(name + "_slopepillar_shape", (x - 2. * t) / TMath::Cos(31.4 / 180. * TMath::Pi()), + gkThinFrameThickness / 2., gkThinFrameThickness / 2., 31.4, 0., 90.); + TGeoVolume* frameSlopePillarVol = new TGeoVolume(name + "_slopepillar", frameSlopePillarShp, framesMaterial); + frameSlopePillarVol->SetLineColor(kCyan); + TGeoRotation* slopeRot = new TGeoRotation(name + "_slopepillar_rot_1", 0., 0., 31.4); + TGeoCombiTrans* slopeTrRot = + new TGeoCombiTrans(name + "_slopepillar_posrot_1", 0., 0., -(x + sqrt(2.) * t - 2. * t) / 2., slopeRot); + + frameBoxVol->AddNode(frameSlopePillarVol, 1, slopeTrRot); + + Double_t angl = 23.; + // --- Small sub pillar + TGeoPara* frameSubPillarShp = + new TGeoPara(name + "_subpillar_shape", (sqrt(2) * (x / 2. - t) - t / 2.) / TMath::Cos(angl / 180. * TMath::Pi()), + gkThinFrameThickness / 2., gkThinFrameThickness / 2., angl, 0., 90.); + TGeoVolume* frameSubPillarVol = new TGeoVolume(name + "_subpillar", frameSubPillarShp, framesMaterial); + frameSubPillarVol->SetLineColor(kMagenta); + + Double_t posZ = t * (1. - 3. / (2. * sqrt(2.))); + + // one side of X direction + TGeoRotation* subRot1 = new TGeoRotation(name + "_subpillar_rot_1", 90., 45., -90. + angl); + TGeoCombiTrans* subTrRot1 = + new TGeoCombiTrans(name + "_subpillar_posrot_1", -(-x / 2. + t - t / (2. * sqrt(2.))), 1., posZ, subRot1); + + TGeoRotation* subRot2 = new TGeoRotation(name + "_subpillar_rot_2", 90., -90. - 45., -90. + angl); + TGeoCombiTrans* subTrRot2 = + new TGeoCombiTrans(name + "_subpillar_posrot_2", -(-x / 2. + t - t / (2. * sqrt(2.))), -1., posZ, subRot2); + + // other side of X direction + TGeoRotation* subRot3 = new TGeoRotation(name + "_subpillar_rot_3", 90., 90. + 45., -90. + angl); + TGeoCombiTrans* subTrRot3 = + new TGeoCombiTrans(name + "_subpillar_posrot_3", -x / 2. + t - t / (2. * sqrt(2.)), 1., posZ, subRot3); + + TGeoRotation* subRot4 = new TGeoRotation(name + "_subpillar_rot_4", 90., -45., -90. + angl); + TGeoCombiTrans* subTrRot4 = + new TGeoCombiTrans(name + "_subpillar_posrot_4", -x / 2. + t - t / (2. * sqrt(2.)), -1., posZ, subRot4); + + frameBoxVol->AddNode(frameSubPillarVol, 1, subTrRot1); + frameBoxVol->AddNode(frameSubPillarVol, 2, subTrRot2); + frameBoxVol->AddNode(frameSubPillarVol, 3, subTrRot3); + frameBoxVol->AddNode(frameSubPillarVol, 4, subTrRot4); + // frameBoxVol->GetShape()->ComputeBBox(); + } + + return frameBoxVol; +} +/** ======================================================================= **/ + +/** ======================================================================= **/ +TGeoVolume* ConstructSmallCone(Double_t coneDz) +{ + // --- Material of the frames + TGeoMedium* framesMaterial = gGeoMan->GetMedium("carbon"); + + // --- Outer cone + // TGeoConeSeg* A = new TGeoConeSeg ("A", coneDz, 6., 7.6, 6., 6.04, 0., 180.); + // TGeoBBox* B = new TGeoBBox ("B", 8., 6., 10.); + + Double_t radius = 3.0; + Double_t thickness = 0.04; // 0.4 mm + // TGeoConeSeg* A = new TGeoConeSeg ("A", coneDz, 3., 3.2, 3., 3.2, 0., 180.); + TGeoConeSeg* A = new TGeoConeSeg("A", coneDz, radius, radius + thickness, radius, radius + thickness, 0., 180.); + TGeoBBox* B = new TGeoBBox("B", 8., 6., 10.); + + TGeoCombiTrans* M = new TGeoCombiTrans("M"); + M->RotateX(45.); + M->SetDy(-5.575); + M->SetDz(6.935); + M->RegisterYourself(); + + TGeoShape* coneShp = new TGeoCompositeShape("Cone_shp", "A-B:M"); + TGeoVolume* coneVol = new TGeoVolume("Cone", coneShp, framesMaterial); + coneVol->SetLineColor(kGreen); + // coneVol->RegisterYourself(); + + // // --- Inner cone + // Double_t thickness = 0.02; + // Double_t thickness2 = 0.022; + // // TGeoConeSeg* A2 = new TGeoConeSeg ("A2", coneDz-thickness, 6.+thickness, 7.6-thickness2, 5.99+thickness, 6.05-thickness2, 0., 180.); + // TGeoConeSeg* A2 = new TGeoConeSeg ("A2", coneDz-thickness, 3.+thickness, 4.6-thickness2, 2.99+thickness, 3.05-thickness2, 0., 180.); + // + // TGeoCombiTrans* M2 = new TGeoCombiTrans ("M2"); + // M2->RotateX (45.); + // M2->SetDy (-5.575+thickness*sqrt(2.)); + // M2->SetDz (6.935); + // M2->RegisterYourself(); + // + // TGeoShape* coneShp2 = new TGeoCompositeShape ("Cone2_shp", "A2-B:M2"); + // TGeoVolume* coneVol2 = new TGeoVolume ("Cone2", coneShp2, gStsMedium); + // coneVol2->SetLineColor(kGreen); + //// coneVol2->RegisterYourself(); + // + // coneVol->AddNode(coneVol2, 1); + + return coneVol; +} +/** ======================================================================= **/ + +/** ======================================================================= **/ +TGeoVolume* ConstructBigCone(Double_t coneDz) +{ + // --- Material of the frames + TGeoMedium* framesMaterial = gGeoMan->GetMedium("carbon"); + + // --- Outer cone + TGeoConeSeg* bA = new TGeoConeSeg("bA", coneDz, 6., 7.6, 6., 6.04, 0., 180.); + TGeoBBox* bB = new TGeoBBox("bB", 8., 6., 10.); + + TGeoCombiTrans* bM = new TGeoCombiTrans("bM"); + bM->RotateX(45.); + bM->SetDy(-5.575); + bM->SetDz(6.935); + bM->RegisterYourself(); + + TGeoShape* coneBigShp = new TGeoCompositeShape("ConeBig_shp", "bA-bB:bM"); + TGeoVolume* coneBigVol = new TGeoVolume("ConeBig", coneBigShp, framesMaterial); + coneBigVol->SetLineColor(kGreen); + // coneBigVol->RegisterYourself(); + + // --- Inner cone + Double_t thickness = 0.02; + Double_t thickness2 = 0.022; + TGeoConeSeg* bA2 = new TGeoConeSeg("bA2", coneDz - thickness, 6. + thickness, 7.6 - thickness2, 5.99 + thickness, + 6.05 - thickness2, 0., 180.); + + TGeoCombiTrans* bM2 = new TGeoCombiTrans("bM2"); + bM2->RotateX(45.); + bM2->SetDy(-5.575 + thickness * sqrt(2.)); + bM2->SetDz(6.935); + bM2->RegisterYourself(); + + TGeoShape* coneBigShp2 = new TGeoCompositeShape("ConeBig2_shp", "bA2-bB:bM2"); + TGeoVolume* coneBigVol2 = new TGeoVolume("ConeBig2", coneBigShp2, gStsMedium); + coneBigVol2->SetLineColor(kGreen); + // coneBigVol2->RegisterYourself(); + + coneBigVol->AddNode(coneBigVol2, 1); + + return coneBigVol; +} +/** ======================================================================= **/ diff --git a/sts/sts_v24c_mcbm.geo.info b/sts/sts_v24c_mcbm.geo.info new file mode 100644 index 0000000..31f09e6 --- /dev/null +++ b/sts/sts_v24c_mcbm.geo.info @@ -0,0 +1,143 @@ +STS geometry created with create_stsgeo_v24c.C + +Global variables: +Sensor thickness = 0.03 cm +Vertical gap in sensor chain = 0 cm +Vertical overlap of sensors = 0.46 cm +Gap in z between neighbour sensors = 0.17 cm +Horizontal overlap of sensors = 0.25 cm +Gap in z between neighbour ladders = 1.2 cm +Cable thickness = 0.02 cm + +Beam pipe: R1 = 1.8 cm at z = 22 cm +Beam pipe: R2 = 1.8 cm at z = 50 cm +Beam pipe: R3 = 5.5 cm at z = 125 cm + +Sensors: +Sensor01: size 6.2092 x 2.2000 x 0.0300, medium silicon +Sensor02: size 6.2092 x 4.2000 x 0.0300, medium silicon +Sensor03: size 6.2092 x 6.2000 x 0.0300, medium silicon +Sensor04: size 6.2092 x 12.4000 x 0.0300, medium silicon +Sensor05: size 4.0000 x 2.5000 x 0.0300, medium silicon +Sensor06: size 3.1000 x 4.2000 x 0.0300, medium silicon +Sensor07: size 1.5000 x 4.2000 x 0.0300, medium silicon + +Sectors: +Sector01: size 6.2092 x 2.2000 x 0.0300, assembly +Contains: Sensor01 +Sector02: size 6.2092 x 4.2000 x 0.0300, assembly +Contains: Sensor02 +Sector03: size 6.2092 x 6.2000 x 0.0300, assembly +Contains: Sensor03 +Sector04: size 6.2092 x 12.4000 x 0.0300, assembly +Contains: Sensor04 +Sector05: size 4.0000 x 2.5000 x 0.0300, assembly +Contains: Sensor05 +Sector06: size 3.1000 x 4.2000 x 0.0300, assembly +Contains: Sensor06 +Sector07: size 1.5000 x 4.2000 x 0.0300, assembly +Contains: Sensor07 + +Ladders: +Ladder01: size 6.2092 x 35.5600 x 4.2760, assembly +Contains: HalfLadder01u HalfLadder01d Ladder01_FullFrameBox Ladder01_FullFrameBox Ladder01_FullFrameBox Ladder01_FullFrameBox Ladder01_FullFrameBox Ladder01_FullFrameBox +HalfLadder01u: size 6.2092 x 35.5600 x 0.8300, assembly +Contains: HalfLadder01u_Module01 HalfLadder01u_Module02 HalfLadder01u_Module03 HalfLadder01u_Module04 HalfLadder01u_Module04 +Ladder02: size 6.2092 x 35.5600 x 4.2760, assembly +Contains: HalfLadder02u HalfLadder02d Ladder02_FullFrameBox Ladder02_FullFrameBox Ladder02_FullFrameBox Ladder02_FullFrameBox Ladder02_FullFrameBox Ladder02_FullFrameBox +HalfLadder02u: size 6.2092 x 35.5600 x 0.8300, assembly +Contains: HalfLadder02u_Module01 HalfLadder02u_Module02 HalfLadder02u_Module03 HalfLadder02u_Module04 HalfLadder02u_Module04 +Ladder03: size 6.2092 x 32.0000 x 4.2760, assembly +Contains: HalfLadder03u HalfLadder03d Ladder03_FullFrameBox Ladder03_FullFrameBox Ladder03_FullFrameBox Ladder03_FullFrameBox +HalfLadder03u: size 6.2092 x 29.6600 x 0.8300, assembly +Contains: HalfLadder03u_Module06 HalfLadder03u_Module03 HalfLadder03u_Module03 HalfLadder03u_Module04 HalfLadder03u_Module05 +Ladder04: size 6.2092 x 32.0000 x 4.2760, assembly +Contains: HalfLadder04u HalfLadder04d Ladder04_FullFrameBox Ladder04_FullFrameBox Ladder04_FullFrameBox Ladder04_FullFrameBox +HalfLadder04u: size 6.2092 x 29.6600 x 0.8300, assembly +Contains: HalfLadder04u_Module06 HalfLadder04u_Module03 HalfLadder04u_Module03 HalfLadder04u_Module04 HalfLadder04u_Module05 +Ladder05: size 6.2092 x 32.0000 x 4.2760, assembly +Contains: HalfLadder05u HalfLadder05d Ladder05_FullFrameBox Ladder05_FullFrameBox Ladder05_FullFrameBox Ladder05_FullFrameBox +HalfLadder05u: size 6.2092 x 25.9600 x 0.8300, assembly +Contains: HalfLadder05u_Module07 HalfLadder05u_Module03 HalfLadder05u_Module04 HalfLadder05u_Module05 HalfLadder05u_Module05 +Ladder06: size 6.2092 x 32.0000 x 4.2760, assembly +Contains: HalfLadder06u HalfLadder06d Ladder06_FullFrameBox Ladder06_FullFrameBox Ladder06_FullFrameBox Ladder06_FullFrameBox +HalfLadder06u: size 6.2092 x 25.9600 x 0.8300, assembly +Contains: HalfLadder06u_Module07 HalfLadder06u_Module03 HalfLadder06u_Module04 HalfLadder06u_Module05 HalfLadder06u_Module05 +Ladder07: size 6.2092 x 72.0000 x 4.0760, assembly +Contains: HalfLadder07u HalfLadder07d Ladder07_FullFrameBox Ladder07_FullFrameBox Ladder07_FullFrameBox Ladder07_FullFrameBox Ladder07_FullFrameBox Ladder07_FullFrameBox Ladder07_FullFrameBox Ladder07_FullFrameBox Ladder07_FullFrameBox Ladder07_FullFrameBox Ladder07_FullFrameBox Ladder07_FullFrameBox Ladder07_FullFrameBox Ladder07_FullFrameBox +HalfLadder07u: size 6.2092 x 27.9600 x 0.8300, assembly +Contains: HalfLadder07u_Module03 HalfLadder07u_Module03 HalfLadder07u_Module04 HalfLadder07u_Module05 HalfLadder07u_Module05 +Ladder08: size 6.2092 x 48.0000 x 3.8760, assembly +Contains: HalfLadder08u HalfLadder08d Ladder08_FullFrameBox Ladder08_FullFrameBox Ladder08_FullFrameBox Ladder08_FullFrameBox Ladder08_FullFrameBox Ladder08_FullFrameBox Ladder08_FullFrameBox Ladder08_FullFrameBox +HalfLadder08u: size 6.2092 x 18.5200 x 0.6300, assembly +Contains: HalfLadder08u_Module04 HalfLadder08u_Module05 HalfLadder08u_Module05 HalfLadder08u_Module05 +Ladder09: size 6.2092 x 16.0000 x 3.6760, assembly +Contains: HalfLadder09u HalfLadder09d Ladder09_FullFrameBox Ladder09_FullFrameBox Ladder09_FullFrameBox Ladder09_FullFrameBox +HalfLadder09u: size 0.0000 x 0.0000 x 0.0000, assembly +Ladder10: size 6.2092 x 24.0000 x 3.6760, assembly +Contains: HalfLadder10u HalfLadder10d Ladder10_FullFrameBox Ladder10_FullFrameBox Ladder10_FullFrameBox Ladder10_FullFrameBox Ladder10_FullFrameBox Ladder10_FullFrameBox +HalfLadder10u: size 0.0000 x 0.0000 x 0.0000, assembly +Ladder11: size 6.2092 x 24.0000 x 3.8760, assembly +Contains: HalfLadder11u HalfLadder11d Ladder11_FullFrameBox Ladder11_FullFrameBox Ladder11_FullFrameBox Ladder11_FullFrameBox Ladder11_FullFrameBox Ladder11_FullFrameBox +HalfLadder11u: size 0.0000 x 0.0000 x 0.0000, assembly +Ladder12: size 6.2092 x 24.0000 x 3.6760, assembly +Contains: HalfLadder12u HalfLadder12d Ladder12_FullFrameBox Ladder12_FullFrameBox Ladder12_FullFrameBox Ladder12_FullFrameBox Ladder12_FullFrameBox Ladder12_FullFrameBox +HalfLadder12u: size 0.0000 x 0.0000 x 0.0000, assembly +Ladder13: size 6.2092 x 8.0000 x 3.4460, assembly +Contains: HalfLadder13u HalfLadder13d Ladder13_FullFrameBox Ladder13_FullFrameBox +HalfLadder13u: size 6.2092 x 6.2000 x 0.0300, assembly +Contains: HalfLadder13u_Module03 +Ladder14: size 6.2092 x 24.0000 x 3.8760, assembly +Contains: HalfLadder14u HalfLadder14d Ladder14_FullFrameBox Ladder14_FullFrameBox Ladder14_FullFrameBox Ladder14_FullFrameBox Ladder14_FullFrameBox Ladder14_FullFrameBox +HalfLadder14u: size 6.2092 x 20.1800 x 0.4300, assembly +Contains: HalfLadder14u_Module03 HalfLadder14u_Module04 HalfLadder14u_Module05 +Ladder15: size 6.2092 x 32.0000 x 3.6760, assembly +Contains: HalfLadder15u HalfLadder15d Ladder15_FullFrameBox Ladder15_FullFrameBox Ladder15_FullFrameBox Ladder15_FullFrameBox Ladder15_FullFrameBox Ladder15_FullFrameBox Ladder15_FullFrameBox Ladder15_FullFrameBox +HalfLadder15u: size 6.2092 x 24.3400 x 0.2300, assembly +Contains: HalfLadder15u_Module04 HalfLadder15u_Module04 +Ladder16: size 6.2092 x 32.0000 x 4.2760, assembly +Contains: HalfLadder16u HalfLadder16d Ladder16_FullFrameBox Ladder16_FullFrameBox Ladder16_FullFrameBox Ladder16_FullFrameBox Ladder16_FullFrameBox Ladder16_FullFrameBox Ladder16_FullFrameBox Ladder16_FullFrameBox +HalfLadder16u: size 6.2092 x 27.9600 x 0.8300, assembly +Contains: HalfLadder16u_Module03 HalfLadder16u_Module03 HalfLadder16u_Module04 HalfLadder16u_Module05 HalfLadder16u_Module05 +Ladder17: size 6.2092 x 24.0000 x 4.0760, assembly +Contains: HalfLadder17u HalfLadder17d Ladder17_FullFrameBox Ladder17_FullFrameBox Ladder17_FullFrameBox Ladder17_FullFrameBox Ladder17_FullFrameBox Ladder17_FullFrameBox +HalfLadder17u: size 6.2092 x 22.2200 x 0.6300, assembly +Contains: HalfLadder17u_Module03 HalfLadder17u_Module04 HalfLadder17u_Module05 HalfLadder17u_Module05 +Ladder18: size 6.2092 x 24.0000 x 3.8760, assembly +Contains: HalfLadder18u HalfLadder18d Ladder18_FullFrameBox Ladder18_FullFrameBox Ladder18_FullFrameBox Ladder18_FullFrameBox Ladder18_FullFrameBox Ladder18_FullFrameBox +HalfLadder18u: size 6.2092 x 16.4800 x 0.4300, assembly +Contains: HalfLadder18u_Module04 HalfLadder18u_Module05 HalfLadder18u_Module05 +Ladder19: size 4.0000 x 8.0000 x 2.5714, assembly +Contains: HalfLadder19u HalfLadder19d Ladder19_FullFrameBox Ladder19_FullFrameBox +HalfLadder19u: size 4.0000 x 4.5400 x 0.2300, assembly +Contains: HalfLadder19u_Module05 HalfLadder19u_Module05 +Ladder20: size 6.2092 x 24.0000 x 4.2760, assembly +Contains: HalfLadder20u HalfLadder20d Ladder20_FullFrameBox Ladder20_FullFrameBox Ladder20_FullFrameBox Ladder20_FullFrameBox Ladder20_FullFrameBox Ladder20_FullFrameBox +HalfLadder20u: size 6.2092 x 16.0600 x 0.8300, assembly +Contains: HalfLadder20u_Module02 HalfLadder20u_Module03 HalfLadder20u_Module05 HalfLadder20u_Module05 HalfLadder20u_Module05 +Ladder21: size 4.0000 x 8.0000 x 2.3714, assembly +Contains: HalfLadder21u HalfLadder21d Ladder21_FullFrameBox Ladder21_FullFrameBox +HalfLadder21u: size 4.0000 x 2.5000 x 0.0300, assembly +Contains: HalfLadder21u_Module05 +Ladder22: size 6.2092 x 32.0000 x 4.2760, assembly +Contains: HalfLadder22u HalfLadder22d Ladder22_FullFrameBox Ladder22_FullFrameBox Ladder22_FullFrameBox Ladder22_FullFrameBox Ladder22_FullFrameBox Ladder22_FullFrameBox Ladder22_FullFrameBox Ladder22_FullFrameBox +HalfLadder22u: size 6.2092 x 24.2600 x 0.8300, assembly +Contains: HalfLadder22u_Module03 HalfLadder22u_Module04 HalfLadder22u_Module05 HalfLadder22u_Module05 HalfLadder22u_Module05 +Ladder23: size 6.2092 x 40.0000 x 4.2760, assembly +Contains: HalfLadder23u HalfLadder23d Ladder23_FullFrameBox Ladder23_FullFrameBox Ladder23_FullFrameBox Ladder23_FullFrameBox Ladder23_FullFrameBox Ladder23_FullFrameBox Ladder23_FullFrameBox Ladder23_FullFrameBox Ladder23_FullFrameBox Ladder23_FullFrameBox +HalfLadder23u: size 6.2092 x 34.1600 x 0.8300, assembly +Contains: HalfLadder23u_Module03 HalfLadder23u_Module04 HalfLadder23u_Module04 HalfLadder23u_Module05 HalfLadder23u_Module05 + +Stations: Station01: size 6.2092 x 8.0000 x 3.4460, assembly +Contains: Ladder13 +Position z = 12.0650 +Station02: size 12.1684 x 16.0000 x 8.5520, assembly +Contains: Ladder09 Ladder09 +Position z = 26.5000 +Station03: size 18.1276 x 24.0000 x 8.9520, assembly +Contains: Ladder10 Ladder12 Ladder11 +Position z = 40.0000 + +Subplates: + +Plates: diff --git a/sts/sts_v24c_mcbm.geo.root b/sts/sts_v24c_mcbm.geo.root new file mode 100644 index 0000000000000000000000000000000000000000..895d34d426af98308dab45e762ad2602ed0008d8 GIT binary patch literal 14598 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 G$^ILhDu}EA literal 0 HcmV?d00001 -- GitLab