From 07b3b91b0f7313bb728e546d76667aad07e103dc Mon Sep 17 00:00:00 2001 From: Florian Uhlig <f.uhlig@gsi.de> Date: Fri, 3 Jul 2020 11:13:33 +0200 Subject: [PATCH] Add new macros for mCBM geometries from development branch --- .../much/create_MUCH_geometry_v20a_mcbm.C | 437 ++ .../geometry/platform/create_platform_v18a.C | 182 + .../geometry/platform/create_platform_v18c.C | 184 + .../geometry/platform/create_platform_v18d.C | 184 + .../geometry/platform/create_platform_v20a.C | 191 + macro/mcbm/geometry/psd/create_psdgeo_v20a.C | 499 ++ .../geometry/rich/create_rich_v20b_mcbm.C | 332 ++ .../geometry/rich/create_rich_v20c_mcbm.C | 332 ++ .../geometry/rich/create_rich_v20d_mcbm.C | 336 ++ macro/mcbm/geometry/sts/create_stsgeo_v20e.C | 2546 ++++++++++ .../targetbox/create_bpipe_geometry_v19g.C | 571 +++ .../targetbox/create_bpipe_geometry_v19h.C | 574 +++ .../tof/Create_TOF_Geometry_v20b_mcbm.C | 1422 ++++++ .../tof/Create_TOF_Geometry_v20c_mcbm.C | 1411 ++++++ .../tof/Create_TOF_Geometry_v20d_mcbm.C | 1417 ++++++ .../geometry/trd/Create_TRD_Geometry_v20a.C | 4116 ++++++++++++++++ .../geometry/trd/Create_TRD_Geometry_v20b.C | 4117 +++++++++++++++++ 17 files changed, 18851 insertions(+) create mode 100644 macro/mcbm/geometry/much/create_MUCH_geometry_v20a_mcbm.C create mode 100644 macro/mcbm/geometry/platform/create_platform_v18a.C create mode 100644 macro/mcbm/geometry/platform/create_platform_v18c.C create mode 100644 macro/mcbm/geometry/platform/create_platform_v18d.C create mode 100644 macro/mcbm/geometry/platform/create_platform_v20a.C create mode 100644 macro/mcbm/geometry/psd/create_psdgeo_v20a.C create mode 100644 macro/mcbm/geometry/rich/create_rich_v20b_mcbm.C create mode 100644 macro/mcbm/geometry/rich/create_rich_v20c_mcbm.C create mode 100644 macro/mcbm/geometry/rich/create_rich_v20d_mcbm.C create mode 100644 macro/mcbm/geometry/sts/create_stsgeo_v20e.C create mode 100644 macro/mcbm/geometry/targetbox/create_bpipe_geometry_v19g.C create mode 100644 macro/mcbm/geometry/targetbox/create_bpipe_geometry_v19h.C create mode 100644 macro/mcbm/geometry/tof/Create_TOF_Geometry_v20b_mcbm.C create mode 100644 macro/mcbm/geometry/tof/Create_TOF_Geometry_v20c_mcbm.C create mode 100644 macro/mcbm/geometry/tof/Create_TOF_Geometry_v20d_mcbm.C create mode 100644 macro/mcbm/geometry/trd/Create_TRD_Geometry_v20a.C create mode 100644 macro/mcbm/geometry/trd/Create_TRD_Geometry_v20b.C diff --git a/macro/mcbm/geometry/much/create_MUCH_geometry_v20a_mcbm.C b/macro/mcbm/geometry/much/create_MUCH_geometry_v20a_mcbm.C new file mode 100644 index 00000000..01185506 --- /dev/null +++ b/macro/mcbm/geometry/much/create_MUCH_geometry_v20a_mcbm.C @@ -0,0 +1,437 @@ +/*** @author Omveer Singh <omvir.ch@gmail.com> + ** @date 17 May 2020 + ** For more details see info file*/ + +#include "TSystem.h" +#include "TGeoManager.h" +#include "TGeoVolume.h" +#include "TGeoMaterial.h" +#include "TGeoMedium.h" +#include "TGeoPgon.h" +#include "TGeoMatrix.h" +#include "TGeoCompositeShape.h" +#include "TGeoXtru.h" +#include "TGeoCone.h" +#include "TGeoBBox.h" +#include "TGeoTube.h" +#include "TFile.h" +#include "TString.h" +#include "TList.h" +#include "TRandom3.h" +#include "TDatime.h" +#include "TClonesArray.h" + +#include "TObjArray.h" +#include "TFile.h" +#include "TMath.h" + +#include <iostream> +#include <fstream> +#include <cassert> +#include <stdexcept> + + +TObjArray* fStations = new TObjArray(); +CbmMuchStation *muchSt; +CbmMuchLayer *muchLy; +CbmMuchLayerSide* muchLySd; + +// Name of output file with geometry +const TString tagVersion = "_v20a"; +//const TString subVersion = "_sis100_1m_lmvm"; +const TString geoVersion = "much";// + tagVersion + subVersion; +const TString FileNameSim = geoVersion + tagVersion +"_mcbm.geo.root"; +const TString FileNameGeo = geoVersion + tagVersion + "_mcbm_geo.root"; +const TString FileNameInfo = geoVersion + tagVersion + "_mcbm.geo.info"; +const TString FileNamePar = geoVersion + tagVersion +"_mcbm.par.root"; + +// Names of the different used materials which are used to build the modules +// The materials are defined in the global media.geo file +const TString KeepingVolumeMedium = "air"; +const TString activemedium="MUCHargon"; +const TString spacermedium="MUCHnoryl"; +const TString Al = "aluminium"; //Al for cooling & support purpose +const TString copper = "copper"; +const TString g10= "G10"; + + + +// Input parameters for MUCH stations +//******************************************** + +const Int_t fNst = 1; // Number of stations + +Int_t fNlayers = 2; // Number of layers +Double_t fLayersZ0[2]={85.7,118.7}; // Layers Positions +Int_t fDetType[2]={3,3}; // Detector type +Double_t fX[2] = {7.2, 7.2}; //Placement of modules in X [cm] +Double_t fY[2] = {24.53, 24.53}; //Placement of modules in Y [cm] +Double_t fSupportLz[2]={1.,1.}; // (cooling + support) +Double_t fDriftDz=0.0035; //35 micron copper Drift +Double_t fG10Dz = 0.30; // 3 mm G10 + +Double_t fActiveLzSector[2] ={0.3, 0.3}; // Active volume thickness [cm] +Double_t fFrameLzSector[2] ={.3, .3}; // Frame thickness [cm] +Double_t fSpacerPhi = 2.0; // Spacer width in Phi [cm] +Double_t fOverlapR = 2.0; // Overlap in R direction [cm] +Double_t fSpacerR1 = 2.8; // Spacer width in R at low Z[cm] +Double_t fSpacerR2 = 3.5; // Spacer width in R at high Z[cm] + +//Size of Modules +//GEM +Double_t dy = 40.0; +Double_t dx1 = 3.75; +Double_t dx2 = 20; + +//*********************************************************** + +// some global variables +TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance +TGeoVolume* gModules_station[fNst]; // Global storage for module types + +// Forward declarations +void create_materials_from_media_file(); +TGeoVolume* CreateStations(int ist); +TGeoVolume* CreateLayers(int istn, int ily); + + +fstream infoFile; +void create_MUCH_geometry_v20a_mcbm() { + + + // ------- Open info file ----------------------------------------------- + TString infoFileName = FileNameSim; + infoFileName.ReplaceAll("root", "info"); + infoFile.open(infoFileName.Data(), fstream::out); + infoFile<< "MUCH geometry created with create_MUCH_geometry_v20a_mcbm.C" << endl << endl; + infoFile<<"Build a mMUCH setup for mCBM with 2 GEM."<<endl; + infoFile<<"10 mm thick Al plates are used for support and cooling in the GEM modules."<<endl; + infoFile<<"Drift and read-out PCBs (copper coated G10 plates) inserted for realistic material budget for both GEM and RPC modules."<<endl<<endl; + infoFile<< "No of Modules: "<<fNlayers<<" ( GEM )"<<endl; + infoFile<< "Position of Modules Z [cm]: "; + for(int i =0; i<fNlayers; i++) infoFile<<fLayersZ0[i]<<" "; + + infoFile<<endl<<endl<<"Placement of Modules:"<<endl; + infoFile<<"Module"<<"\t"<<"X [cm]"<<"\t"<<"Y [cm]"<<"\t"<<endl; + infoFile<<"----------------------"<<endl; + for(int i =0; i<fNlayers; i++)infoFile<<" "<<i+1<<"\t"<<fX[i]<<"\t"<<fY[i]<<endl; + infoFile<<"----------------------"<<endl; + infoFile<<endl<<"Al Cooling Plate Thickness [cm]: "; + for(int i =0; i<fNlayers; i++)infoFile<<fSupportLz[i]<<" "; + + infoFile<<endl<<"Active Volume Thickness [cm]: "; + for(int i =0; i<fNlayers; i++)infoFile<<fActiveLzSector[i]<<" "; + + infoFile<<endl<<endl<<endl<<" GEM Module:"<<endl; + infoFile<<" "<<2*dx1<<" cm"<<endl; + infoFile<<" ......... |"<<endl; + infoFile<<" ........... |"<<endl; + infoFile<<" ............. |"<<endl; + infoFile<<" ............... |"<<endl; + infoFile<<" ................. |"<<endl; + infoFile<<" ................... |"<<endl; + infoFile<<" ..................... |"<<endl; + infoFile<<" ....................... "<<2*dy<<" cm"<<endl; + infoFile<<" ......................... |"<<endl; + infoFile<<" ........................... |"<<endl; + infoFile<<" ............................. |"<<endl; + infoFile<<" ............................... |"<<endl; + infoFile<<" ................................. |"<<endl; + infoFile<<" ................................... |"<<endl; + infoFile<<" ..................................... |"<<endl; + infoFile<<"....................................... |"<<endl; + infoFile<<" "<<2*dx2<<" cm"<<endl; + infoFile<<endl; + + + + // Load needed material definition from media.geo file + create_materials_from_media_file(); + + // Get the GeoManager for later usage + gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom"); + gGeoMan->SetVisLevel(10); + + // Create the top volume + TGeoBBox* topbox= new TGeoBBox("", 1000., 1000., 2000.); + TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air")); + gGeoMan->SetTopVolume(top); + + TString topName = geoVersion+tagVersion+"_mcbm"; + + TGeoVolume* much = new TGeoVolumeAssembly(topName); + top->AddNode(much, 1); + + TGeoVolume *sttn = new TGeoVolumeAssembly("station"); + much->AddNode(sttn,1); + + + for (Int_t istn = 0; istn < 1; istn++) { + + Double_t stGlobalZ0 = (fLayersZ0[0] + fLayersZ0[1])/2.; + muchSt = new CbmMuchStation(istn,stGlobalZ0); + muchSt->SetRmin(0.); + muchSt->SetRmax(0.); + fStations->Add(muchSt); + + + + gModules_station[istn] = CreateStations(istn); + sttn->AddNode(gModules_station[istn],istn); + } + + gGeoMan->CloseGeometry(); + gGeoMan->CheckOverlaps(0.0001, "s"); + gGeoMan->PrintOverlaps(); + + much->Export(FileNameSim); // an alternative way of writing the much + + TFile* outfile = new TFile(FileNameSim, "UPDATE"); + TGeoTranslation* much_placement = new TGeoTranslation("much_trans", -6., 0., 0.); + much_placement->Write(); + outfile->Close(); + + outfile = new TFile(FileNameGeo,"RECREATE"); + gGeoMan->Write(); // use this if you want GeoManager format in the output + outfile->Close(); + + top->Draw("ogl"); + infoFile.close(); + + TFile *parfile = new TFile(FileNamePar,"RECREATE"); + fStations->Write("stations",1);// for geometry parameters + parfile->Close(); + +} + +void create_materials_from_media_file() +{ + // Use the FairRoot geometry interface to load the media which are already defined + FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader"); + FairGeoInterface* geoFace = geoLoad->getGeoInterface(); + TString geoPath = gSystem->Getenv("VMCWORKDIR"); + TString geoFile = geoPath + "/geometry/media.geo"; + geoFace->setMediaFile(geoFile); + geoFace->readMedia(); + + // Read the required media and create them in the GeoManager + FairGeoMedia* geoMedia = geoFace->getMedia(); + FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder(); + + FairGeoMedium* air = geoMedia->getMedium(KeepingVolumeMedium); + geoBuild->createMedium(air); + + FairGeoMedium* MUCHargon = geoMedia->getMedium(activemedium); + geoBuild->createMedium(MUCHargon); + + FairGeoMedium* MUCHnoryl = geoMedia->getMedium(spacermedium); + geoBuild->createMedium(MUCHnoryl); + + FairGeoMedium* MUCHsupport = geoMedia->getMedium(Al); + geoBuild->createMedium(MUCHsupport); + + FairGeoMedium* copperplate = geoMedia->getMedium(copper); + geoBuild->createMedium(copperplate); + + FairGeoMedium* g10plate = geoMedia->getMedium(g10); + geoBuild->createMedium(g10plate); + +} + +TGeoVolume * CreateStations(int ist){ + + TString stationName = Form("muchstation%02i",ist+1); + TGeoVolumeAssembly* station = new TGeoVolumeAssembly(stationName);//, shStation, air); + + TGeoVolume* gLayer[fNlayers+1]; + for (int ii=0;ii<fNlayers;ii++){ // 2 Layers + + Double_t sideDz = fSupportLz[ii]/2. + fActiveLzSector[ii]/2.; // distance between side's and layer's centers + + muchLy = new CbmMuchLayer(ist, ii, fLayersZ0[ii],0.); + muchSt->AddLayer(muchLy); + muchLy->GetSideF()->SetZ(fLayersZ0[ii] - sideDz); + + gLayer[ii] = CreateLayers(ist, ii); + station->AddNode(gLayer[ii],ii); + } + + return station; +} + +TGeoVolume * CreateLayers(int istn, int ily){ + + TString layerName = Form("muchstation%02ilayer%i",istn+1,ily+1); + + + TGeoVolumeAssembly* volayer = new TGeoVolumeAssembly(layerName); + + Double_t SupportDz = fSupportLz[ily]/2.; + Double_t driftDz = fActiveLzSector[ily]/2 + fDriftDz/2.; + Double_t g10Dz = driftDz + fDriftDz/2. + fG10Dz/2.; + + + Double_t moduleZ = fLayersZ0[ily]; + Double_t driftZIn = moduleZ - driftDz; + Double_t driftZOut = moduleZ + driftDz; + Double_t g10ZIn = moduleZ - g10Dz; + Double_t g10ZOut = moduleZ + g10Dz; + Double_t cool_z = g10ZIn - fG10Dz/2. - SupportDz; + + Double_t dz = fActiveLzSector[ily]/2.; // Active Volume Thickness + + Int_t Nsector=16.0; + Double_t phi0 = TMath::Pi()/Nsector; // azimuthal half widh of each module + + //define the spacer dimensions + Double_t tg = (dx2-dx1)/2/dy; + Double_t dd1 = fSpacerPhi*tg; + Double_t dd2 = fSpacerPhi*sqrt(1+tg*tg); + Double_t sdx1 = dx1+dd2-dd1; + Double_t sdx2 = dx2+dd2+dd1; + Double_t sdy1 = dy+fSpacerR1; // frame width added + Double_t sdy2 = dy+fSpacerR2; // frame width added + Double_t sdz = fFrameLzSector[ily]/2.; + + //define Additional material as realistic GEM module + Double_t dz_sD = fDriftDz/2.; //35 micron copper Drift + Double_t dz_sG = fG10Dz/2.; // 3mm G10 + Double_t sdy = sdy2; + + + Double_t pos[10]; + + Int_t iMod =0; + for (Int_t iSide=0;iSide<1;iSide++){ + muchLySd = muchLy->GetSide(iSide); + // Now start adding the GEM modules + for (Int_t iModule=0; iModule<1; iModule++){ + + Double_t phi = 0; // add 0.5 to not overlap with y-axis for left-right layer separation + Bool_t isBack = iModule%2; + Char_t cside = (isBack==1) ? 'b' : 'f'; + + // correct the x, y positions + pos[0] = fX[ily]; + pos[1] = fY[ily]; + + + + // different z positions for odd/even modules + pos[2] = moduleZ ; + pos[3] = driftZIn; + pos[4] = driftZOut; + pos[5] = g10ZIn; + pos[6] = g10ZOut; + pos[7] = cool_z; + + if(iSide!=isBack)continue; + if(iModule!=0)iMod =iModule/2; + + muchLySd = muchLy->GetSide(iSide); + + TGeoMedium* argon = gGeoMan->GetMedium(activemedium); // active medium + TGeoMedium* noryl = gGeoMan->GetMedium(spacermedium); // spacer medium + TGeoMedium* copperplate = gGeoMan->GetMedium(copper); // copper Drift medium + TGeoMedium* g10plate = gGeoMan->GetMedium(g10); // G10 medium + TGeoMedium* coolMat = gGeoMan->GetMedium(Al); + + + // Define and place the shape of the modules + TGeoTrap* shapeGem = new TGeoTrap(dz,0,0,dy,dx1,dx2,0,dy,dx1,dx2,0); + shapeGem->SetName(Form("shStation%02iLayer%i%cModule%03iActiveGemNoHole", istn, ily, cside, iModule)); + + //------------------------------------------------------Al Cooling Plate-------------------------------------------------------------------- + TGeoVolume* voActive; + TGeoTrap *coolGem; + TGeoVolume* voCool; + + coolGem = new TGeoTrap(SupportDz,0,phi,sdy2,sdx1,sdx2,0,sdy2,sdx1,sdx2,0); + coolGem->SetName(Form("shStation%02iLayer%i%cModule%03icoolGem", istn, ily, cside, iModule)); + TString CoolName = Form("muchstation%02ilayer%i%ccoolGem%03iAluminum",istn+1,ily+1,cside,iModule+1); + voCool = new TGeoVolume(CoolName,coolGem,coolMat); + voCool->SetLineColor(kYellow); + + //------------------------------------------------------Active Volume----------------------------------------------------- + //GEM + TGeoTrap* shapeActive = new TGeoTrap(dz,0,0,dy,dx1,dx2,0,dy,dx1,dx2,0); + shapeActive->SetName(Form("shStation%02iLayer%i%cModule%03iActiveNoHole", istn, ily, cside, iModule)); + TString activeName = Form("muchstation%02ilayer%i%cactive%03igasArgon",istn+1,ily+1,cside,iMod+1); + voActive = new TGeoVolume(activeName,shapeActive,argon); + voActive->SetLineColor(kGreen); + + +//---------------------------------------------------------Drift & PCB's--------------------------------------------------------------- + + TString DriftName[2], G10Name[2], AlName; + TGeoVolume *voDrift[2], *voG10[2]; + TGeoTrap *DriftGem[2], *G10Gem[2]; + + for(int iPos =0; iPos<2; iPos++){ + Char_t cpos = (iPos==0) ? 'i' : 'o'; + DriftGem[iPos] = new TGeoTrap(dz_sD,0,phi,sdy,sdx1,sdx2,0,sdy,sdx1,sdx2,0); + G10Gem[iPos] = new TGeoTrap(dz_sG,0,phi,sdy,sdx1,sdx2,0,sdy,sdx1,sdx2,0); + DriftGem[iPos]->SetName(Form("shStation%02iLayer%i%cModule%03i%cDrift", istn, ily, cside, iModule,cpos)); + DriftName[iPos] = Form("muchstation%02ilayer%i%cside%03i%ccopperDrift",istn+1,ily+1,cside,iMod+1,cpos); + G10Gem[iPos]->SetName(Form("shStation%02iLayer%i%cModule%03i%cG10", istn, ily, cside, iModule,cpos)); + G10Name[iPos] = Form("muchstation%02ilayer%i%cside%03i%cG10",istn+1,ily+1,cside,iMod+1,cpos); + voDrift[iPos] = new TGeoVolume(DriftName[iPos],DriftGem[iPos],copperplate); + voDrift[iPos]->SetLineColor(kRed); + voG10[iPos] = new TGeoVolume(G10Name[iPos],G10Gem[iPos],g10plate); + voG10[iPos]->SetLineColor(28); + } + //------------------------------------------------------------Frame----------------------------------------------------------------- + // Define the trapezoidal Frame + TGeoTrap* shapeFrame = new TGeoTrap(sdz,0,0,sdy,sdx1,sdx2,0,sdy,sdx1,sdx2,0); + shapeFrame->SetName(Form("shStation%02iLayer%i%cModule%03iFullFrameGemNoHole", istn, ily, cside, iModule)); + + + TString expression = Form("shStation%02iLayer%i%cModule%03iFullFrameGemNoHole-shStation%02iLayer%i%cModule%03iActiveGemNoHole", istn, ily, cside, iModule, istn, ily, cside, iModule); + + TGeoCompositeShape* shFrame = new TGeoCompositeShape(Form("shStation%02iLayer%i%cModule%03iFinalFrameNoHole", istn, ily, cside, iModule), expression); + TString frameName = Form("muchstation%02ilayer%i%csupport%03i",istn+1,ily+1,cside,iMod+1); + + TGeoVolume* voFrame = new TGeoVolume(frameName,shFrame,noryl); // Frame for GEM + voFrame->SetLineColor(kMagenta); + + + + //----------------------------------------------------Placement---------------------------------------------------------------------- + // Calculate the phi angle of the sector where it has to be placed + Double_t angle = 180.0-(180. / TMath::Pi() * phi0); // convert angle phi from rad to deg + + + TGeoRotation *r2 = new TGeoRotation("r2"); + //rotate in the vertical plane (per to z axis) with angle + r2->RotateZ(angle); + + + TGeoTranslation *trans[10]; + TGeoHMatrix *incline_mod[10]; + + for(int i=0; i<6; i++){ + trans[i] = new TGeoTranslation("",pos[0],pos[1],pos[i+2]); + + incline_mod[i] = new TGeoHMatrix(""); + (*incline_mod[i]) = (*trans[i]) * (*r2); + } + + volayer->AddNode(voFrame, iMod, incline_mod[0]); // add spacer + volayer->AddNode(voActive, iMod, incline_mod[0]); // add active volume + volayer->AddNode(voDrift[0], iMod, incline_mod[1]); //Drift In + volayer->AddNode(voDrift[1], iMod, incline_mod[2]); //Drift Out + volayer->AddNode(voG10[0], iMod, incline_mod[3]); //G10 In + volayer->AddNode(voG10[1], iMod, incline_mod[4]); //G10 Out + volayer->AddNode(voCool, iMod, incline_mod[5]); // Al Cooling Plate + + TVector3 Position; + Position.SetXYZ(pos[0],pos[1],pos[2]); + cout<<pos[2]<<" "<<pos[3]<<" "<<pos[4]<<" "<<pos[5]<<" "<<pos[6]<<" "<<pos[7]<<endl; +muchLySd->AddModule(new CbmMuchModuleGemRadial(fDetType[ily], istn,ily, iSide,iModule, Position,2*dx1,2*dx2,2*dy,2*dz,muchSt->GetRmin())); + + + } + } + + return volayer; +} diff --git a/macro/mcbm/geometry/platform/create_platform_v18a.C b/macro/mcbm/geometry/platform/create_platform_v18a.C new file mode 100644 index 00000000..90459290 --- /dev/null +++ b/macro/mcbm/geometry/platform/create_platform_v18a.C @@ -0,0 +1,182 @@ +/****************************************************************************** + ** Creation of beam pipe geometry in ROOT format (TGeo). + ** + ** @file create_pipegeo_v16.C + ** @author Volker Friese <v.friese@gsi.de> + ** @date 11.10.2013 + ** + ** The beam pipe is composed of carbon with a thickness of 0.5 mm. It is + ** placed directly into the cave as mother volume. + ** The pipe consists of a number of parts. Each part has a PCON + ** shape. The beam pipe inside the RICH is part of the RICH geometry; + ** the beam pipe geometry thus excludes the z range of the RICH in case + ** the latter is present in the setup. + *****************************************************************************/ + + + + +#include <iomanip> +#include <iostream> +#include "TGeoManager.h" + + +using namespace std; + +// ------------- Other global variables ----------------------------------- +// ---> TGeoManager (too lazy to write out 'Manager' all the time +TGeoManager* gGeoMan = NULL; // will be set later +// ---------------------------------------------------------------------------- + + +// ============================================================================ +// ====== Main function ===== +// ============================================================================ + +void create_platform_v18a() +{ + + // ----- Define platform parts ---------------------------------------------- + + /** For v18a (mCBM) **/ + TString geoTag = "v18a_mcbm"; + + // Double_t platform_angle = 25.; // rotation angle around y-axis + Double_t platform_angle = 19.; // rotation angle around y-axis + Double_t platX_offset = -230.; // offset to the right side along x-axis + + Double_t sizeX = 80.0; // symmetric in x + Double_t sizeY = 200.0; // without rails + Double_t sizeZ = 500.0; // short version + +// Double_t endZ = 450.0; // ends at z = 450.0 + +// /** For v16b (SIS 300) **/ +// TString geoTag = "v16b"; +// Double_t sizeX = 725.0; // symmetric in x +// Double_t sizeY = 234.0; // without rails +// Double_t sizeZ = 455.0; // long version +// Double_t endZ = 540.0; // ends at z = 450.0 + +// Double_t beamY = 570.0; // nominal beam height + Double_t beamY = 100.0; // nominal beam height + Double_t posX = - sizeX/2.; + Double_t posY = -beamY + sizeY/2.; // rest on the floor at -beamY + Double_t posZ = + sizeZ/2.; + + // -------------------------------------------------------------------------- + + + // ------- Geometry file name (output) ---------------------------------- + TString geoFileName = "platform_"; + geoFileName = geoFileName + geoTag + ".geo.root"; + // -------------------------------------------------------------------------- + + + // ------- Open info file ----------------------------------------------- + TString infoFileName = geoFileName; + infoFileName.ReplaceAll("root", "info"); + fstream infoFile; + infoFile.open(infoFileName.Data(), fstream::out); + infoFile << "Platform geometry created with create_platform_v16.C" + << std::endl << std::endl; + // -------------------------------------------------------------------------- + + + // ------- 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(); + + // ---> 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"); + +// // ---> 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"); + // -------------------------------------------------------------------------- + + + + // -------------- Create geometry and top volume ------------------------- + gGeoMan = (TGeoManager*)gROOT->FindObject("FAIRGeom"); + gGeoMan->SetName("PLATFORMgeom"); + TGeoVolume* top = new TGeoVolumeAssembly("top"); + gGeoMan->SetTopVolume(top); + TString platformName = "platform_"; + platformName += geoTag; + TGeoVolume* platform = new TGeoVolumeAssembly(platformName.Data()); + // -------------------------------------------------------------------------- + + + // ----- Create --------------------------------------------------------- + TGeoBBox* platform_base = new TGeoBBox("", sizeX /2., sizeY /2., sizeZ /2.); + TGeoVolume* platform_vol = new TGeoVolume("platform", platform_base, aluminium); + platform_vol->SetLineColor(kBlue); + platform_vol->SetTransparency(70); + + TGeoTranslation* platform_trans = new TGeoTranslation("", posX, posY, posZ); + platform->AddNode(platform_vol, 1, platform_trans); + + infoFile << "sizeX: "<< setprecision(2) << sizeX + << "sizeY: "<< setprecision(2) << sizeY + << "sizeZ: "<< setprecision(2) << sizeZ << endl; + infoFile << "posX : "<< setprecision(2) << posX + << "posY : "<< setprecision(2) << posY + << "posZ : "<< setprecision(2) << posZ << endl; + + // --------------- Finish ----------------------------------------------- + top->AddNode(platform, 1); + cout << endl << endl; + gGeoMan->CloseGeometry(); + gGeoMan->CheckOverlaps(0.001); + gGeoMan->PrintOverlaps(); + gGeoMan->Test(); + + platform->Export(geoFileName); // an alternative way of writing the platform volume + + TFile* geoFile = new TFile(geoFileName, "UPDATE"); + + // rotate the platform around y + TGeoRotation* platform_rotation = new TGeoRotation(); + platform_rotation->RotateY( platform_angle ); + // TGeoCombiTrans* platform_placement = new TGeoCombiTrans( sin( platform_angle/180.*acos(-1) ) * z1[1]/2., 0., 0., platform_rotation); + TGeoCombiTrans* platform_placement = new TGeoCombiTrans("platform_rot", platX_offset, 0., 0, platform_rotation); + + + // TGeoTranslation* platform_placement = new TGeoTranslation("platform_trans", 0., 0., 0.); + platform_placement->Write(); + geoFile->Close(); + + cout << endl; + cout << "Geometry " << top->GetName() << " written to " + << geoFileName << endl; + + top->Draw("ogl"); + + infoFile.close(); + + +} +// ============================================================================ +// ====== End of main function ===== +// ============================================================================ + diff --git a/macro/mcbm/geometry/platform/create_platform_v18c.C b/macro/mcbm/geometry/platform/create_platform_v18c.C new file mode 100644 index 00000000..795386fa --- /dev/null +++ b/macro/mcbm/geometry/platform/create_platform_v18c.C @@ -0,0 +1,184 @@ +/****************************************************************************** + ** Creation of beam pipe geometry in ROOT format (TGeo). + ** + ** @file create_pipegeo_v16.C + ** @author Volker Friese <v.friese@gsi.de> + ** @date 11.10.2013 + ** + ** The beam pipe is composed of carbon with a thickness of 0.5 mm. It is + ** placed directly into the cave as mother volume. + ** The pipe consists of a number of parts. Each part has a PCON + ** shape. The beam pipe inside the RICH is part of the RICH geometry; + ** the beam pipe geometry thus excludes the z range of the RICH in case + ** the latter is present in the setup. + *****************************************************************************/ + + + + +#include <iomanip> +#include <iostream> +#include "TGeoManager.h" + + +using namespace std; + +// ------------- Other global variables ----------------------------------- +// ---> TGeoManager (too lazy to write out 'Manager' all the time +TGeoManager* gGeoMan = NULL; // will be set later +// ---------------------------------------------------------------------------- + + +// ============================================================================ +// ====== Main function ===== +// ============================================================================ + +void create_platform_v18c() +{ + + // ----- Define platform parts ---------------------------------------------- + + /** For v18c (mCBM) **/ + TString geoTag = "v18c_mcbm"; + + // Double_t platform_angle = 25.; // rotation angle around y-axis + // Double_t platform_angle = 19.; // rotation angle around y-axis + Double_t platform_angle = 0.; // rotation angle around y-axis + // Double_t platX_offset = -230.; // offset to the right side along x-axis + Double_t platX_offset = 0.; // offset to the right side along x-axis + + Double_t sizeX = 80.0; // table width + Double_t sizeY = 80.0; // table height + Double_t sizeZ = 400.0; // table length + +// Double_t endZ = 450.0; // ends at z = 450.0 + +// /** For v16b (SIS 300) **/ +// TString geoTag = "v16b"; +// Double_t sizeX = 725.0; // symmetric in x +// Double_t sizeY = 234.0; // without rails +// Double_t sizeZ = 455.0; // long version +// Double_t endZ = 540.0; // ends at z = 450.0 + +// Double_t beamY = 570.0; // nominal beam height + Double_t beamY = 200.0; // nominal beam height + Double_t posX = 0; + Double_t posY = - beamY + sizeY/2.; // rest on the floor at -beamY + Double_t posZ = + sizeZ/2.; + + // -------------------------------------------------------------------------- + + + // ------- Geometry file name (output) ---------------------------------- + TString geoFileName = "platform_"; + geoFileName = geoFileName + geoTag + ".geo.root"; + // -------------------------------------------------------------------------- + + + // ------- Open info file ----------------------------------------------- + TString infoFileName = geoFileName; + infoFileName.ReplaceAll("root", "info"); + fstream infoFile; + infoFile.open(infoFileName.Data(), fstream::out); + infoFile << "Platform geometry created with create_platform_v16.C" + << std::endl << std::endl; + // -------------------------------------------------------------------------- + + + // ------- 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(); + +// // ---> 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"); + + // ---> 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"); + // -------------------------------------------------------------------------- + + + + // -------------- Create geometry and top volume ------------------------- + gGeoMan = (TGeoManager*)gROOT->FindObject("FAIRGeom"); + gGeoMan->SetName("PLATFORMgeom"); + TGeoVolume* top = new TGeoVolumeAssembly("top"); + gGeoMan->SetTopVolume(top); + TString platformName = "platform_"; + platformName += geoTag; + TGeoVolume* platform = new TGeoVolumeAssembly(platformName.Data()); + // -------------------------------------------------------------------------- + + + // ----- Create --------------------------------------------------------- + TGeoBBox* platform_base = new TGeoBBox("", sizeX /2., sizeY /2., sizeZ /2.); + TGeoVolume* platform_vol = new TGeoVolume("platform", platform_base, air); + platform_vol->SetLineColor(kBlue); + platform_vol->SetTransparency(70); + + TGeoTranslation* platform_trans = new TGeoTranslation("", posX, posY, posZ); + platform->AddNode(platform_vol, 1, platform_trans); + + infoFile << "sizeX: "<< setprecision(2) << sizeX + << "sizeY: "<< setprecision(2) << sizeY + << "sizeZ: "<< setprecision(2) << sizeZ << endl; + infoFile << "posX : "<< setprecision(2) << posX + << "posY : "<< setprecision(2) << posY + << "posZ : "<< setprecision(2) << posZ << endl; + + // --------------- Finish ----------------------------------------------- + top->AddNode(platform, 1); + cout << endl << endl; + gGeoMan->CloseGeometry(); + gGeoMan->CheckOverlaps(0.001); + gGeoMan->PrintOverlaps(); + gGeoMan->Test(); + + platform->Export(geoFileName); // an alternative way of writing the platform volume + + TFile* geoFile = new TFile(geoFileName, "UPDATE"); + + // rotate the platform around y + TGeoRotation* platform_rotation = new TGeoRotation(); + platform_rotation->RotateY( platform_angle ); + // TGeoCombiTrans* platform_placement = new TGeoCombiTrans( sin( platform_angle/180.*acos(-1) ) * z1[1]/2., 0., 0., platform_rotation); + TGeoCombiTrans* platform_placement = new TGeoCombiTrans("platform_rot", platX_offset, 0., 0, platform_rotation); + + + // TGeoTranslation* platform_placement = new TGeoTranslation("platform_trans", 0., 0., 0.); + platform_placement->Write(); + geoFile->Close(); + + cout << endl; + cout << "Geometry " << top->GetName() << " written to " + << geoFileName << endl; + + top->Draw("ogl"); + + infoFile.close(); + + +} +// ============================================================================ +// ====== End of main function ===== +// ============================================================================ + diff --git a/macro/mcbm/geometry/platform/create_platform_v18d.C b/macro/mcbm/geometry/platform/create_platform_v18d.C new file mode 100644 index 00000000..345a12fd --- /dev/null +++ b/macro/mcbm/geometry/platform/create_platform_v18d.C @@ -0,0 +1,184 @@ +/****************************************************************************** + ** Creation of beam pipe geometry in ROOT format (TGeo). + ** + ** @file create_pipegeo_v16.C + ** @author Volker Friese <v.friese@gsi.de> + ** @date 11.10.2013 + ** + ** The beam pipe is composed of carbon with a thickness of 0.5 mm. It is + ** placed directly into the cave as mother volume. + ** The pipe consists of a number of parts. Each part has a PCON + ** shape. The beam pipe inside the RICH is part of the RICH geometry; + ** the beam pipe geometry thus excludes the z range of the RICH in case + ** the latter is present in the setup. + *****************************************************************************/ + +// 2018.08.23 - DE - shorten the table length from 400 cm to 250 cm + + +#include <iomanip> +#include <iostream> +#include "TGeoManager.h" + + +using namespace std; + +// ------------- Other global variables ----------------------------------- +// ---> TGeoManager (too lazy to write out 'Manager' all the time +TGeoManager* gGeoMan = NULL; // will be set later +// ---------------------------------------------------------------------------- + + +// ============================================================================ +// ====== Main function ===== +// ============================================================================ + +void create_platform_v18d() +{ + + // ----- Define platform parts ---------------------------------------------- + + /** For v18d (mCBM) **/ + TString geoTag = "v18d_mcbm"; + + // Double_t platform_angle = 25.; // rotation angle around y-axis + // Double_t platform_angle = 19.; // rotation angle around y-axis + Double_t platform_angle = 0.; // rotation angle around y-axis + // Double_t platX_offset = -230.; // offset to the right side along x-axis + Double_t platX_offset = 0.; // offset to the right side along x-axis + + Double_t sizeX = 80.0; // table width + Double_t sizeY = 80.0; // table height + Double_t sizeZ = 250.0; // table length + +// Double_t endZ = 450.0; // ends at z = 450.0 + +// /** For v16b (SIS 300) **/ +// TString geoTag = "v16b"; +// Double_t sizeX = 725.0; // symmetric in x +// Double_t sizeY = 234.0; // without rails +// Double_t sizeZ = 455.0; // long version +// Double_t endZ = 540.0; // ends at z = 450.0 + +// Double_t beamY = 570.0; // nominal beam height + Double_t beamY = 200.0; // nominal beam height + Double_t posX = 0; + Double_t posY = - beamY + sizeY/2.; // rest on the floor at -beamY + Double_t posZ = + sizeZ/2.; + + // -------------------------------------------------------------------------- + + + // ------- Geometry file name (output) ---------------------------------- + TString geoFileName = "platform_"; + geoFileName = geoFileName + geoTag + ".geo.root"; + // -------------------------------------------------------------------------- + + + // ------- Open info file ----------------------------------------------- + TString infoFileName = geoFileName; + infoFileName.ReplaceAll("root", "info"); + fstream infoFile; + infoFile.open(infoFileName.Data(), fstream::out); + infoFile << "Platform geometry created with create_platform_v16.C" + << std::endl << std::endl; + // -------------------------------------------------------------------------- + + + // ------- 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(); + +// // ---> 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"); + + // ---> 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"); + // -------------------------------------------------------------------------- + + + + // -------------- Create geometry and top volume ------------------------- + gGeoMan = (TGeoManager*)gROOT->FindObject("FAIRGeom"); + gGeoMan->SetName("PLATFORMgeom"); + TGeoVolume* top = new TGeoVolumeAssembly("top"); + gGeoMan->SetTopVolume(top); + TString platformName = "platform_"; + platformName += geoTag; + TGeoVolume* platform = new TGeoVolumeAssembly(platformName.Data()); + // -------------------------------------------------------------------------- + + + // ----- Create --------------------------------------------------------- + TGeoBBox* platform_base = new TGeoBBox("", sizeX /2., sizeY /2., sizeZ /2.); + TGeoVolume* platform_vol = new TGeoVolume("platform", platform_base, air); + platform_vol->SetLineColor(kBlue); + platform_vol->SetTransparency(70); + + TGeoTranslation* platform_trans = new TGeoTranslation("", posX, posY, posZ); + platform->AddNode(platform_vol, 1, platform_trans); + + infoFile << "sizeX: "<< setprecision(2) << sizeX + << "sizeY: "<< setprecision(2) << sizeY + << "sizeZ: "<< setprecision(2) << sizeZ << endl; + infoFile << "posX : "<< setprecision(2) << posX + << "posY : "<< setprecision(2) << posY + << "posZ : "<< setprecision(2) << posZ << endl; + + // --------------- Finish ----------------------------------------------- + top->AddNode(platform, 1); + cout << endl << endl; + gGeoMan->CloseGeometry(); + gGeoMan->CheckOverlaps(0.001); + gGeoMan->PrintOverlaps(); + gGeoMan->Test(); + + platform->Export(geoFileName); // an alternative way of writing the platform volume + + TFile* geoFile = new TFile(geoFileName, "UPDATE"); + + // rotate the platform around y + TGeoRotation* platform_rotation = new TGeoRotation(); + platform_rotation->RotateY( platform_angle ); + // TGeoCombiTrans* platform_placement = new TGeoCombiTrans( sin( platform_angle/180.*acos(-1) ) * z1[1]/2., 0., 0., platform_rotation); + TGeoCombiTrans* platform_placement = new TGeoCombiTrans("platform_rot", platX_offset, 0., 0, platform_rotation); + + + // TGeoTranslation* platform_placement = new TGeoTranslation("platform_trans", 0., 0., 0.); + platform_placement->Write(); + geoFile->Close(); + + cout << endl; + cout << "Geometry " << top->GetName() << " written to " + << geoFileName << endl; + + top->Draw("ogl"); + + infoFile.close(); + + +} +// ============================================================================ +// ====== End of main function ===== +// ============================================================================ + diff --git a/macro/mcbm/geometry/platform/create_platform_v20a.C b/macro/mcbm/geometry/platform/create_platform_v20a.C new file mode 100644 index 00000000..a62d9039 --- /dev/null +++ b/macro/mcbm/geometry/platform/create_platform_v20a.C @@ -0,0 +1,191 @@ +/****************************************************************************** + ** Creation of beam pipe geometry in ROOT format (TGeo). + ** + ** @file create_pipegeo_v16.C + ** @author Volker Friese <v.friese@gsi.de> + ** @date 11.10.2013 + ** + ** The beam pipe is composed of carbon with a thickness of 0.5 mm. It is + ** placed directly into the cave as mother volume. + ** The pipe consists of a number of parts. Each part has a PCON + ** shape. The beam pipe inside the RICH is part of the RICH geometry; + ** the beam pipe geometry thus excludes the z range of the RICH in case + ** the latter is present in the setup. + *****************************************************************************/ + +// 2020.05.05 - DE - update table dimensions and position measured by Christian Sturm +// 2018.08.23 - DE - shorten the table length from 400 cm to 250 cm + +#include <iomanip> +#include <iostream> +#include "TGeoManager.h" + + +using namespace std; + +// ------------- Other global variables ----------------------------------- +// ---> TGeoManager (too lazy to write out 'Manager' all the time +TGeoManager* gGeoMan = NULL; // will be set later +// ---------------------------------------------------------------------------- + + +// ============================================================================ +// ====== Main function ===== +// ============================================================================ + +void create_platform_v20a() +{ + + // ----- Define platform parts ---------------------------------------------- + + /** For v20a (mCBM) **/ + TString geoTag = "v20a_mcbm"; + + // Double_t platform_angle = 25.; // rotation angle around y-axis + // Double_t platform_angle = 19.; // rotation angle around y-axis + Double_t platform_angle = 0.; // rotation angle around y-axis + // Double_t platX_offset = -230.; // offset to the right side along x-axis + + Double_t platX_offset = -25.1; // offset along x-axis + Double_t platY_offset = 0.0; // offset along y-axis + Double_t platZ_offset = 13.7; // offset along z-axis + + Double_t sizeX = 100.0; // table width // until 15.05.2020: 80.0; + Double_t sizeY = 98.5; // table height // until 15.05.2020: 80.0; + Double_t sizeZ = 215.5; // table length // until 15.05.2020: 250.0; + +// Double_t endZ = 450.0; // ends at z = 450.0 + +// /** For v16b (SIS 300) **/ +// TString geoTag = "v16b"; +// Double_t sizeX = 725.0; // symmetric in x +// Double_t sizeY = 234.0; // without rails +// Double_t sizeZ = 455.0; // long version +// Double_t endZ = 540.0; // ends at z = 450.0 + +// Double_t beamY = 570.0; // nominal beam height + Double_t beamY = 200.0; // nominal beam height + Double_t posX = 0; + Double_t posY = - beamY + sizeY/2.; // rest on the floor at -beamY + Double_t posZ = + sizeZ/2.; + + // -------------------------------------------------------------------------- + + + // ------- Geometry file name (output) ---------------------------------- + TString geoFileName = "platform_"; + geoFileName = geoFileName + geoTag + ".geo.root"; + // -------------------------------------------------------------------------- + + + // ------- Open info file ----------------------------------------------- + TString infoFileName = geoFileName; + infoFileName.ReplaceAll("root", "info"); + fstream infoFile; + infoFile.open(infoFileName.Data(), fstream::out); + infoFile << "Platform geometry created with create_platform_v20a.C" + << std::endl << std::endl; + // -------------------------------------------------------------------------- + + + // ------- 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(); + +// // ---> 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"); + + // ---> 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"); + // -------------------------------------------------------------------------- + + + + // -------------- Create geometry and top volume ------------------------- + gGeoMan = (TGeoManager*)gROOT->FindObject("FAIRGeom"); + gGeoMan->SetName("PLATFORMgeom"); + TGeoVolume* top = new TGeoVolumeAssembly("top"); + gGeoMan->SetTopVolume(top); + TString platformName = "platform_"; + platformName += geoTag; + TGeoVolume* platform = new TGeoVolumeAssembly(platformName.Data()); + // -------------------------------------------------------------------------- + + + // ----- Create --------------------------------------------------------- + TGeoBBox* platform_base = new TGeoBBox("", sizeX /2., sizeY /2., sizeZ /2.); + TGeoVolume* platform_vol = new TGeoVolume("platform", platform_base, air); + platform_vol->SetLineColor(kBlue); + platform_vol->SetTransparency(70); + + TGeoTranslation* platform_trans = new TGeoTranslation("", posX, posY, posZ); + platform->AddNode(platform_vol, 1, platform_trans); + + infoFile << "sizeX : "<< setprecision(2) << sizeX << " cm " << endl + << "sizeY : "<< setprecision(2) << sizeY << " cm " << endl + << "sizeZ : "<< setprecision(2) << sizeZ << " cm " << endl << endl; + + infoFile << "posX : "<< setprecision(2) << posX << " cm " << endl + << "posY : "<< setprecision(2) << posY << " cm " << endl + << "posZ : "<< setprecision(2) << posZ << " cm " << endl << endl; + + infoFile << "offsetX : "<< setprecision(2) << platX_offset << " cm " << endl + << "offsetY : "<< setprecision(2) << platY_offset << " cm " << endl + << "offsetZ : "<< setprecision(2) << platZ_offset << " cm " << endl << endl; + + // --------------- Finish ----------------------------------------------- + top->AddNode(platform, 1); + cout << endl << endl; + gGeoMan->CloseGeometry(); + gGeoMan->CheckOverlaps(0.001); + gGeoMan->PrintOverlaps(); + gGeoMan->Test(); + + platform->Export(geoFileName); // an alternative way of writing the platform volume + + TFile* geoFile = new TFile(geoFileName, "UPDATE"); + + // rotate the platform around y + TGeoRotation* platform_rotation = new TGeoRotation(); + platform_rotation->RotateY( platform_angle ); + // TGeoCombiTrans* platform_placement = new TGeoCombiTrans( sin( platform_angle/180.*acos(-1) ) * z1[1]/2., 0., 0., platform_rotation); + TGeoCombiTrans* platform_placement = new TGeoCombiTrans("platform_rot", platX_offset, platY_offset, platZ_offset, platform_rotation); + + // TGeoTranslation* platform_placement = new TGeoTranslation("platform_trans", 0., 0., 0.); + platform_placement->Write(); + geoFile->Close(); + + cout << endl; + cout << "Geometry " << top->GetName() << " written to " + << geoFileName << endl; + + top->Draw("ogl"); + + infoFile.close(); + + +} +// ============================================================================ +// ====== End of main function ===== +// ============================================================================ + diff --git a/macro/mcbm/geometry/psd/create_psdgeo_v20a.C b/macro/mcbm/geometry/psd/create_psdgeo_v20a.C new file mode 100644 index 00000000..e6788ce8 --- /dev/null +++ b/macro/mcbm/geometry/psd/create_psdgeo_v20a.C @@ -0,0 +1,499 @@ +/** @file create_psdgeo_v20a.C + ** @author Volker Friese <v.friese@gsi.de> + ** @date 16 September 2017 + ** @version 1.0 + ** + ** This macro creates a PSD geometry in ROOT format to be used as input + ** for the transport simulation. It allows to create module stacks of + ** varying sizes; the numbers of rows and columns must both be uneven. + ** The centre module as well as the edge modules are omitted. + ** The module definition is implemented in the function ConstructModule. + ** + ** The user can adjust the steering variables to the specific needs. + ** + ** 2020-05-26 - DE - v20a - move PSD upstream by 40 cm to z = 120 cm, relative to v18d + ** 2018-05-24 - DE - v18d - move PSD from 20 to 25 degrees + ** 2017-12-05 - DE - v18c - place single module very close beneath the beampipe + ** 2017-12-02 - DE - v18a - adapted mPSD, single module to mCBM setup + ** + **/ + + +using std::cout; +using std::endl; +using std::fstream; +using std::right; +using std::setw; + +// Forward declarations +TGeoVolume* ConstructModule(const char* name, Double_t moduleSize, + Int_t nLayers, fstream* info = 0); + + +// ============================================================================ +// ====== Main function ===== +// ============================================================================ + +void create_psdgeo_v20a() +{ + + // ----- Steering variables --------------------------------------------- + const char* geoTag = "v20a_mcbm"; // geometry tag + + Double_t psdX = 0.; // x position is automatically determined from psdRotY + Double_t psdY = -22.; // y position of PSD in cave + Double_t psdZ = 120.; // z position of PSD in cave (front side) + // Double_t psdZ = 160.; // z position of PSD in cave (front side) + Double_t psdRotX = 0.; // Rotation of PSD around x axis [degrees] + Double_t psdRotY = 25.; // Rotation of PSD around y axis [degrees] + Double_t moduleSize = 20.; // Module size [cm] + Int_t nModulesX = 1; // Number of modules in a row (x direction) + Int_t nModulesY = 1; // Number of modules in a row (x direction) + // -------------------------------------------------------------------------- + + + // ---- Number of modules per row/column must be uneven --------------------- + // Otherwise, the central one (to be skipped) is not defined. + if ( nModulesX % 2 != 1 || nModulesY % 2 != 1 ) { + cout << "Error: number of modules per row and column must be uneven! " + << nModulesX << " " << nModulesY << endl; + return; + } + // -------------------------------------------------------------------------- + + + // ------- Open info file ----------------------------------------------- + TString infoFileName = "psd_"; + infoFileName = infoFileName + geoTag + ".geo.info"; + fstream infoFile; + infoFile.open(infoFileName.Data(), fstream::out); + infoFile << "PSD geometry " << geoTag << " created with create_psdgeo.C" + << endl << endl; + infoFile << "Number of modules: " << nModulesX << " x " << nModulesY << endl; + infoFile << "Module size: " << moduleSize << " cm x " << moduleSize << " cm" + << endl; + infoFile << "PSD translation in cave: (" << psdX << ", " << psdY << ", " + << psdZ << ") cm" << endl; + infoFile << "PSD rotation around y axis: " << psdRotY << " degrees" + << endl << endl; + // -------------------------------------------------------------------------- + + + // ------- Load media from media file ----------------------------------- + cout << endl << "==> Reading media..." << endl; + 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(); + // -------------------------------------------------------------------------- + + + // ------ Create the required media from the media file ---------------- + 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 = gGeoManager->GetMedium("air"); + if ( ! air ) Fatal("Main", "Medium air not found"); + cout << "Created medium: air" << endl; + + // ---> Iron + FairGeoMedium* mIron = geoMedia->getMedium("iron"); + if ( ! mIron ) Fatal("Main", "FairMedium iron not found"); + geoBuild->createMedium(mIron); + TGeoMedium* iron = gGeoManager->GetMedium("iron"); + if ( ! iron ) Fatal("Main", "Medium iron not found"); + cout << "Created medium: iron" << endl; + + // ---> Lead + FairGeoMedium* mLead = geoMedia->getMedium("lead"); + if ( ! mIron ) Fatal("Main", "FairMedium lead not found"); + geoBuild->createMedium(mLead); + TGeoMedium* lead = gGeoManager->GetMedium("lead"); + if ( ! lead ) Fatal("Main", "Medium iron not found"); + cout << "Created medium: lead" << endl; + + // ---> Tyvek + FairGeoMedium* mTyvek = geoMedia->getMedium("PsdTyvek"); + if ( ! mTyvek ) Fatal("Main", "FairMedium PsdTyvek not found"); + geoBuild->createMedium(mTyvek); + TGeoMedium* tyvek = gGeoManager->GetMedium("PsdTyvek"); + if ( ! tyvek ) Fatal("Main", "Medium PsdTyvek not found"); + cout << "Created medium: PsdTyvek" << endl; + + // ---> Scintillator + FairGeoMedium* mScint = geoMedia->getMedium("PsdScint"); + if ( ! mScint ) Fatal("Main", "FairMedium PsdScint not found"); + geoBuild->createMedium(mScint); + TGeoMedium* scint = gGeoManager->GetMedium("PsdScint"); + if ( ! scint ) Fatal("Main", "Medium PsdScint not found"); + cout << "Created medium: PsdScint" << endl; + + // ---> Fibres + FairGeoMedium* mFibre = geoMedia->getMedium("PsdFibre"); + if ( ! mFibre ) Fatal("Main", "FairMedium PsdFibre not found"); + geoBuild->createMedium(mFibre); + TGeoMedium* fibre = gGeoManager->GetMedium("PsdFibre"); + if ( ! fibre ) Fatal("Main", "Medium PsdFibre not found"); + cout << "Created medium: PsdFibre" << endl; + + // ---> Medium for PSD volume + TGeoMedium* psdMedium = air; + // -------------------------------------------------------------------------- + + + // -------------- Create geometry and top volume ------------------------- + cout << endl << "==> Set top volume..." << endl; + gGeoManager->SetName("PSDgeom"); + TGeoVolume* top = new TGeoVolumeAssembly("TOP"); + gGeoManager->SetTopVolume(top); + // -------------------------------------------------------------------------- + + + // ----- Create the PSD modules ----------------------------------------- + cout << endl; + TGeoVolume* module2060 = ConstructModule("module2060", 20., 60, &infoFile); + // -------------------------------------------------------------------------- + + + // --------------- Create PSD volume ------------------------------------ + cout << endl; + cout << "===> Creating PSD...." << endl; + + // --- Determine size of PSD box (half-lengths) + Double_t psdSizeX = 0.5 * nModulesX * moduleSize; + Double_t psdSizeY = 0.5 * nModulesY * moduleSize; + TGeoBBox* shape = dynamic_cast<TGeoBBox*>(module2060->GetShape()); + Double_t psdSizeZ = shape->GetDZ(); + + TString psdName = "psd_"; + psdName += geoTag; + TGeoVolume* psd = gGeoManager->MakeBox(psdName, psdMedium, psdSizeX, + psdSizeY, psdSizeZ); + cout << "Module array is " << nModulesX << " x " << nModulesY + << endl; + cout << "PSD size is " << 2. * psdSizeX << " cm x " << 2. * psdSizeY + << " cm x " << 2. * psdSizeZ << " cm" << endl; + infoFile << endl << "PSD size is " << 2. * psdSizeX << " cm x " + << 2. * psdSizeY << " cm x " << 2. * psdSizeZ << " cm" << endl; + // -------------------------------------------------------------------------- + + + // ----- Place modules into the system volume --------------------------- + Double_t xModCurrent = -0.5 * ( nModulesX + 1 ) * moduleSize; + + Int_t nModules = 0; + for (Int_t iModX = 0; iModX < nModulesX; iModX++) { + xModCurrent += moduleSize; + Double_t yModCurrent = -0.5 * ( nModulesY + 1 ) * moduleSize; + for (Int_t iModY = 0; iModY < nModulesY; iModY++) { + yModCurrent += moduleSize; + +// // Skip edge modules +// if ( ( iModX == 0 || iModX == nModulesX - 1 ) && +// ( iModY == 0 || iModY == nModulesY - 1 ) ) continue; +// +// // Skip centre module (only for uneven number of modules) +// if ( iModX == (nModulesX - 1) / 2 && iModY == (nModulesY - 1) / 2 ) +// continue; + + // Node number and name (convention) + Int_t iNode = 100 * iModX + iModY; + + // Position of module inside PSD + TGeoTranslation* trans = new TGeoTranslation(xModCurrent, yModCurrent, 0.); + + psd->AddNode(module2060, iNode, trans); + cout << "Adding module " << setw(5) << right << iNode << " at x = " + << setw(6) << right << xModCurrent << " cm , y = " + << setw(6) << right << yModCurrent << " cm" << endl; + nModules++; + + } //# modules in y direction + } //# modules in x direction + cout << "PSD contains " << nModules << " modules." << endl; + infoFile << "PSD contains " << nModules << " modules." << endl; + // -------------------------------------------------------------------------- + + + + // ----- Place PSD in top node (cave) ------------------------------------- + TGeoRotation* psdRot = new TGeoRotation(); + // psdRot->RotateY(psdRotY); + + // DEDE start + psdZ = psdZ + psdSizeZ; + + // calculate mPSD x-position + psdX = psdZ * tan (psdRotY * acos(-1) / 180); + cout << "psdX at " << psdRotY << " degree angle: x= " << psdX << " cm" << endl; + + // rotate around x axis + psdRotX = atan( psdY / sqrt( psdX*psdX + psdZ*psdZ ) ) * 180 / acos(-1); + psdRot->RotateX(-psdRotX); + + cout << "angle around x: " << psdRotX << " deg" << endl; + cout << "y " << psdY << " t " << sqrt( psdX*psdX + psdZ*psdZ ) << " cm" << endl; + + // rotate around y axis + // psdRotY = atan( psdX / psdZ ) * 180 / acos(-1); // psdX is already calculated accordingly + psdRot->RotateY(psdRotY); + + cout << "angle around y: " << psdRotY << " deg" << endl; + cout << "x " << psdX << " y " << psdY << " cm" << endl; + + cout << endl; + // DEDE stop + + // TGeoCombiTrans* psdTrans = new TGeoCombiTrans(psdX, psdY, psdZ + psdSizeZ, psdRot); + TGeoCombiTrans* psdTrans = new TGeoCombiTrans(psdX, psdY, psdZ, psdRot); + top->AddNode(psd, 0, psdTrans); + cout << endl << "==> PSD position in cave: " << endl; + psdTrans->Print(); + // -------------------------------------------------------------------------- + + + // ----- Close and check geometry --------------------------------------- + cout << endl << "==> Closing geometry..." << endl; + gGeoManager->CloseGeometry(); + gGeoManager->CheckGeometryFull(); + cout << endl; + gGeoManager->CheckOverlaps(0.0001, "s"); + // -------------------------------------------------------------------------- + + + // ----- Write PSD volume and placement matrix to geometry file --------- + cout << endl; + TString geoFileName = "psd_"; + geoFileName = geoFileName + geoTag + ".geo.root"; + psd->Export(geoFileName); + TFile* geoFile = new TFile(geoFileName, "UPDATE"); + psdTrans->Write(); + cout << endl; + cout << "==> Geometry " << psd->GetName() << " written to " + << geoFileName << endl; + cout << "==> Info written to " << infoFileName << endl; + geoFile->Close(); + infoFile.close(); + // -------------------------------------------------------------------------- + + + // ----- Write entire TGeoManager to file ------------------------------- + TString geoManFileName = "psd_"; + geoManFileName = geoManFileName + geoTag + ".geoman.root"; + TFile* geoManFile = new TFile(geoManFileName, "RECREATE"); + gGeoManager->Write(); + geoManFile->Close(); + cout << "==> TGeoManager " << gGeoManager->GetName() << " written to " + << geoManFileName << endl << endl << endl; + // -------------------------------------------------------------------------- + + + // ---- Display geometry ------------------------------------------------ + gGeoManager->SetVisLevel(5); // Scintillator level + top->Draw("ogl"); + // -------------------------------------------------------------------------- + +} +// End of main function +/** ======================================================================= **/ + + + + + + +/** ======================================================================= **/ +TGeoVolume* ConstructModule(const char* name, Double_t sizeXY, + Int_t nLayers, fstream* info) { + + // The module consists of nLayers of scintillators covered with Tyvek. + // Between each two scintillators, there is a lead layer (total nLayers -1). + // At the top, there is a gap to stretch the light fibres. This is modelled + // by a volume made of the same material as the scintillator (but inactive). + // The arrangement is surrounded by iron. At the front and at the back, + // there is a thick iron layer (the back one acting as first absorber) + // for constructional reasons. + + cout << "===> Creating Module " << name << ", size " << sizeXY + << " cm with " << nLayers << " layers...." << endl; + + // ----- Constructional parameters ---------------------------- + Double_t leadD = 1.60; // Thickness of lead layer + Double_t scintD = 0.40; // Thickness of scintillator layer + Double_t tyvekD = 0.02; // Thickness of Tyvek wrapper around scintillator + Double_t boxDx = 0.15; // Thickness of iron box lateral + Double_t boxDy = 0.05; // Thickness of iron box top/bottom + Double_t boxDz = 2.00; // Thickness of iron box front/back + Double_t chanDy = 0.20; // Height of fibre channel + Double_t chanDistL = 0.50; // Distance of channel from left edge of lead + Double_t chanDistR = 2.00; // Distance of channel from right edge of lead + // ------------------------------------------------------------------------ + + + // ----- Info to file ------------------------------------------------- + if ( info ) { + (*info) << "Parameters of module " << name << ": " << endl; + (*info) << "Size: " << sizeXY << " cm x " << sizeXY << " cm" << endl; + (*info) << "Number of layers: " << nLayers << endl; + (*info) << "Thickness of lead layers: " << leadD << " cm" << endl; + (*info) << "Thickness of scintillators: " << scintD << " cm" << endl; + (*info) << "Thickness of Tyvek wrap: " << tyvekD << " cm" << endl; + (*info) << "Thickness of iron box: (" << boxDx << " / " << boxDy + << " / " << boxDz << ") cm" << endl; + (*info) << "Height of fibre channel: " << chanDy << " cm" << endl; + (*info) << "Distance of channel from edges: left " << chanDistL + << " cm, right " << chanDistR << " cm" << endl; + } + // ------------------------------------------------------------------------ + + + // ----- Get required media ------------------------------------------- + TGeoMedium* medAir = gGeoManager->GetMedium("air"); // PSD + if ( ! medAir ) Fatal("ConstructModule", "Medium air not found"); + TGeoMedium* medIron = gGeoManager->GetMedium("iron"); // Box + if ( ! medIron ) Fatal("ConstructModule", "Medium iron not found"); + TGeoMedium* medLead = gGeoManager->GetMedium("lead"); // Lead layers + if ( ! medLead ) Fatal("ConstructModule", "Medium lead not found"); + TGeoMedium* medTyvek = gGeoManager->GetMedium("PsdTyvek"); // Tyvek layers + if ( ! medTyvek ) Fatal("ConstructModule", "Medium PsdTyvek not found"); + TGeoMedium* medScint = gGeoManager->GetMedium("PsdScint"); // Scintillator + if ( ! medScint ) Fatal("ConstructModule", "Medium PsdScint not found"); + TGeoMedium* medFibre = gGeoManager->GetMedium("PsdFibre"); // Fibres + if ( ! medFibre ) Fatal("ConstructModule", "Medium PsdFibre not found"); + // ------------------------------------------------------------------------ + + + + // ----- Create module volume ----------------------------------------- + // Module length: nLayers of scintillators, nLayers - 1 of lead + // plus the iron box front and back. + // Material is iron. + Double_t moduleLength = 2. * boxDz + + nLayers * ( scintD + 2. * tyvekD ) + + ( nLayers - 1 ) * leadD; + TGeoVolume* module = gGeoManager->MakeBox(name, medIron, 0.5 * sizeXY, + 0.5 * sizeXY, 0.5 * moduleLength); + module->SetLineColor(kRed); + module->Print(); + cout << endl; + // ------------------------------------------------------------------------ + + + // ----- Lead filler -------------------------------------------------- + // The lead filler represents all lead absorber layers. + // The Tyvek/scintillator layers and the fibre channel will be placed + // inside. + // Dimensions are half-lengths. + Double_t leadLx = 0.5 * sizeXY - boxDx; + Double_t leadLy = 0.5 * sizeXY - boxDy; + Double_t leadLz = 0.5 * moduleLength - boxDz; + TGeoVolume* lead = gGeoManager->MakeBox("lead", medLead, + leadLx, leadLy, leadLz); + lead->SetLineColor(kBlue); + // ------------------------------------------------------------------------ + + + // ----- Fibre channel ------------------------------------------------ + // This volume represents the air gap at the top of the volume hosting the + // light guide fibres. The material is the same as for the scintillators + // (but inactive). + // The (half-)width of the channel is defined by the distances from the + // lead edges. + Double_t chanLx = leadLx - 0.5 * chanDistL - 0.5 * chanDistR; + if ( chanLx < 0. ) { + cout << "Error: lead volume is not large enough to host fibre channel!" + << endl; + cout << "Lead width: " << 2. * leadLx << ", distance from left edge " + << chanDistL << ", distance from right edge " << chanDistR + << endl; + return 0; + } + Double_t chanLy = 0.5 * chanDy; + Double_t chanLz = leadLz; + TGeoVolume* channel = gGeoManager->MakeBox("channel", medFibre, + chanLx, chanLy, chanLz); + channel->SetLineColor(kMagenta); + // ------------------------------------------------------------------------ + + + // ---- Positioning of the fibre channel ------------------------------ + // The channel extends from chanDistL from the left edge of the lead filler + // to chanDistR from its right edge (seen from the front). It is top-aligned + // with the lead filler. + Double_t chanShiftX = 0.5 * ( chanDistL - chanDistR ); + Double_t chanShiftY = leadLy - 0.5 * chanDy; + // ------------------------------------------------------------------------ + + + // ----- Tyvek layer -------------------------------------------------- + // The scintillator will be placed inside this, leaving only the thin + // Tyvek as a wrapper. Since these layers will be placed in the lead filler, + // there has to be a cut-out for the fibre channel. + Double_t tyvekLz = 0.5 * scintD + tyvekD; // half-length + TGeoBBox* tyv1 = new TGeoBBox("psdTyv1", leadLx, leadLy, tyvekLz); + TGeoBBox* tyv2 = new TGeoBBox("psdTyv2", chanLx, chanLy, tyvekLz); + TGeoTranslation* trans1 = new TGeoTranslation("tPsd1", + chanShiftX, chanShiftY, 0.); + trans1->RegisterYourself(); + TGeoCompositeShape* tyvekShape = new TGeoCompositeShape("psdTyv1-psdTyv2:tPsd1"); + TGeoVolume* tyvek = new TGeoVolume("tyvek", tyvekShape, medTyvek); + tyvek->SetLineColor(kGreen); + // ------------------------------------------------------------------------ + + + // ----- Scintillator layer ------------------------------------------- + // The scintillator layer is embedded (as daughter) into the Tyvek layer. + // It is also a box minus the cut-out for the fibres. The cut-out is + // slightly smaller than for the Tyvek volume. + Double_t scintLx = leadLx - tyvekD; + Double_t scintLy = leadLy - tyvekD; + Double_t scintLz = 0.5 * scintD; + TGeoBBox* sci1 = new TGeoBBox("sci1", scintLx, scintLy, scintLz); + Double_t cutLx = chanLx; + Double_t cutLy = chanLy - tyvekD; + Double_t cutLz = scintLz; + TGeoBBox* sci2 = new TGeoBBox("sci2", cutLx, cutLy, cutLz); + Double_t cutShiftX = chanShiftX; + Double_t cutShiftY = scintLy - cutLy; + TGeoTranslation* trans2 = new TGeoTranslation("tPsd2", cutShiftX, cutShiftY, 0.); + trans2->RegisterYourself(); + TGeoCompositeShape* scintShape = new TGeoCompositeShape("scintShape", "sci1-sci2:tPsd2"); + TGeoVolume* scint = new TGeoVolume("scint", scintShape, medScint); + scint->SetLineColor(kBlack); + // ------------------------------------------------------------------------ + + + // ----- Place volumes ------------------------------------------------ + + // ---> Scintillator into Tyvek + tyvek->AddNode(scint, 0); + + // ---> Fibre channel into lead filler + lead->AddNode(channel, 0, trans1); + + // ---> Tyvek layers into lead + Double_t zFirst = 0.; + Double_t zLast = 0.; + for (Int_t iLayer = 0; iLayer < nLayers; iLayer++) { + Double_t zPos = -1. * leadLz + iLayer * leadD + (2. * iLayer + 1.) * tyvekLz; + if ( iLayer == 0 ) zFirst = zPos; + if ( iLayer == nLayers - 1) zLast = zPos; + lead->AddNode(tyvek, iLayer, new TGeoTranslation(0., 0., zPos)); + } + cout << module->GetName() << ": Positioned " << nLayers << " Tyvek layers; first at z = " << zFirst + << ", last at z = " << zLast << endl; + + // ---> Lead into module + module->AddNode(lead, 0); + // ------------------------------------------------------------------------ + + return module; +} +/** ======================================================================= **/ + diff --git a/macro/mcbm/geometry/rich/create_rich_v20b_mcbm.C b/macro/mcbm/geometry/rich/create_rich_v20b_mcbm.C new file mode 100644 index 00000000..97517c17 --- /dev/null +++ b/macro/mcbm/geometry/rich/create_rich_v20b_mcbm.C @@ -0,0 +1,332 @@ +#include <iostream> +//#include "FairGeoMedium.h" +//#include "FairGeoBuilder.h" +//#include "FairGeoMedia.h" +#include "TGeoVolume.h" +#include "TGeoManager.h" + +using namespace std; + +// Changelog + +// 2020-05-06 - v20b - AW - changed positioning to center on 25° line (without Window) +// 2020-04-02 - v19a - FU - same as v19c but with exported geometry in output file +// 2019-11-28 - v19c - DE - move mRICH +12+7 cm in x direction (same as mTOF v19b) for the Nov 2019 run +// 2017-11-17 - v18d - DE - add aerogel as radiator to the mRICH module +// 2017-11-12 - v18c - DE - push mRICH downstream to z=355 cm for long setup +// 2017-07-19 - v18b - DE - add one level to the geometry hierarchy +// 2017-07-15 - v18b - DE - arrange 4x mRICH detectors in the setup and tilt towards target + + +void create_rich_v20b_mcbm() +{ + gSystem->Load("libGeom"); + + TString geoFileName= "rich_v20b_mcbm.geo.root"; + TString topNodeName= "rich_v20b_mcbm"; + + 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(); + TGeoManager* gGeoMan = gGeoManager; + + FairGeoMedia* geoMedia = geoFace->getMedia(); + FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder(); + + //Media + FairGeoMedium* mAluminium = geoMedia->getMedium("aluminium"); + if (mAluminium == NULL) Fatal("Main", "FairMedium aluminium not found"); + geoBuild->createMedium(mAluminium); + TGeoMedium* medAl = gGeoMan->GetMedium("aluminium"); + if (medAl == NULL) Fatal("Main", "Medium vacuum not found"); + + FairGeoMedium* mKapton = geoMedia->getMedium("kapton"); + if (mKapton == NULL) Fatal("Main", "FairMedium kapton not found"); + geoBuild->createMedium(mKapton); + TGeoMedium* medKapton = gGeoMan->GetMedium("kapton"); + if (medKapton == NULL) Fatal("Main", "Medium kapton not found"); + + FairGeoMedium* mAir = geoMedia->getMedium("air"); + if (mAir == NULL) Fatal("Main", "FairMedium air not found"); + geoBuild->createMedium(mAir); + TGeoMedium* medAir = gGeoMan->GetMedium("air"); + if (medAir == NULL) Fatal("Main", "Medium air not found"); + + FairGeoMedium* mPmtGlas = geoMedia->getMedium("PMTglass"); + if (mPmtGlas == NULL) Fatal("Main", "FairMedium vacuum not found"); + geoBuild->createMedium(mPmtGlas); + TGeoMedium* medPmtGlas = gGeoMan->GetMedium("PMTglass"); + if (medPmtGlas == NULL) Fatal("Main", "Medium vacuum not found"); + + FairGeoMedium* mNitrogen = geoMedia->getMedium("RICHgas_N2_dis"); + if (mNitrogen == NULL) Fatal("Main", "FairMedium RICHgas_N2_dis not found"); + geoBuild->createMedium(mNitrogen); + TGeoMedium* medNitrogen = gGeoMan->GetMedium("RICHgas_N2_dis"); + if (medNitrogen == NULL) Fatal("Main", "Medium RICHgas_N2_dis not found"); + + FairGeoMedium* mPMT = geoMedia->getMedium("CsI"); + if (mPMT == NULL) Fatal("Main", "FairMedium CsI not found"); + geoBuild->createMedium(mPMT); + TGeoMedium* medCsI = gGeoMan->GetMedium("CsI"); + if (medCsI == NULL) Fatal("Main", "Medium CsI not found"); + + FairGeoMedium* mElectronic = geoMedia->getMedium("air"); + if (mElectronic == NULL) Fatal("Main", "FairMedium air not found"); + geoBuild->createMedium(mElectronic); + TGeoMedium* medElectronic = gGeoMan->GetMedium("air"); + if (medElectronic == NULL) Fatal("Main", "Medium air not found"); + + FairGeoMedium* mAerogel = geoMedia->getMedium("aerogel"); + if (mAerogel == NULL) Fatal("Main", "FairMedium aerogel not found"); + geoBuild->createMedium(mAerogel); + TGeoMedium* medAerogel = gGeoMan->GetMedium("aerogel"); + if (medAerogel == NULL) Fatal("Main", "Medium aerogel not found"); + + + //Dimensions of the RICH prototype [cm] + + const Double_t ItemToKapton = 1.85; + + // Box + const Double_t boxThickness = 0.3; + const Double_t boxBackThickness = 1.; + const Double_t boxFrontThickness = 0.3; + const Double_t boxXLen = 38.2; + const Double_t boxYLen= 59.7; + const Double_t boxZLen = 25. + boxBackThickness - ItemToKapton; + const Bool_t isRotate90DegZ = false; + + // PMT + // PMT specs https://www.hamamatsu.com/resources/pdf/etd/H12700_TPMH1348E.pdf + const Double_t pmtNofPixels = 8; + const Double_t pmtSize = 5.2; + const Double_t pmtSizeHalf = pmtSize / 2.; + const Double_t pmtSensitiveSize = 4.85; + const Double_t pmtPixelSize = 0.6;//pmtSensitiveSize / pmtNofPixels; + const Double_t pmtPixelSizeHalf = pmtPixelSize / 2.; + const Double_t pmtOuterPixelSize = 0.625;//pmtSensitiveSize / pmtNofPixels; + const Double_t pmtOuterPixelSizeHalf = pmtOuterPixelSize / 2.; + const Double_t pmtGap = 0.1; + const Double_t pmtGapHalf = pmtGap / 2.; + const Double_t pmtMatrixGap = 0.1; + const Double_t pmtPixelThickness = 0.1; + const Double_t pmtWindowThickness = 0.00;//0.15 + Double_t pmtWindowPixelDistance = 0.0; + if (pmtWindowThickness > 0.0) pmtWindowPixelDistance = 0.0; + const Double_t pmtThickness = pmtPixelThickness + pmtWindowThickness + pmtWindowPixelDistance; + const Double_t pmtZPadding = 3.871; + const Double_t pmtXShift = 2.5; + + // Electronics + const Double_t elecLength = 10.; + const Double_t elecWidth = 3. * pmtSize; + const Double_t elecHeight = 2. * pmtSize; + + // Aerogel Box + const Double_t aerogelXLen = 20.; + const Double_t aerogelYLen = 20.; + const Double_t aerogelZLen = 3.; + const Double_t aerogelPmtDistance = 10.; + const Double_t aerogelGap = 0.1; + + // Imaginary sensitive plane + Bool_t isIncludeSensPlane = false; + const Double_t sensPlaneSize = 200.; + const Double_t sensPlaneBoxDistance = 1.; + + //Global positioning + const Double_t boxFrontToTarget = 327. + ItemToKapton + boxZLen/2; + + // Create the top volume + TGeoVolume *top = new TGeoVolumeAssembly("top"); + gGeoMan->SetTopVolume(top); + + // Rich assembly + TGeoVolume* rich = new TGeoVolumeAssembly(topNodeName); + top->AddNode(rich, 1); + + // Al box + TGeoRotation* rotBox = new TGeoRotation("rotBox", 0., 0., 0.); + TGeoCombiTrans* trBox = NULL; + if ( isRotate90DegZ ) { + rotBox->RotateZ(90.); + rotBox->RotateY(0.955);//Tilting of Rich + trBox = new TGeoCombiTrans(0, -pmtXShift-(pmtSize + pmtGap + 1), boxFrontToTarget, rotBox); + } else { + rotBox->RotateX(0.955);//Tilting of Rich + // Nov 2019 run + //trBox = new TGeoCombiTrans(-pmtXShift-(pmtSize + pmtGap + 1)+12.+7., 0, boxFrontToTarget, rotBox); + // Mar2020 + trBox = new TGeoCombiTrans(-pmtXShift-(pmtSize + pmtGap + 1)+6.3, 0, boxFrontToTarget, rotBox); + } + TGeoVolume *boxVol = gGeoMan->MakeBox("box", medAl, boxXLen / 2., boxYLen / 2., boxZLen / 2.); +// rich->AddNode(boxVol, 1, trBox); + rich->AddNode(boxVol, 1); + + // Gas + TGeoVolume *gasVol = gGeoMan->MakeBox("Gas", medNitrogen, boxXLen / 2. - boxThickness, boxYLen / 2. - boxThickness, + ((boxZLen - boxBackThickness - boxFrontThickness) / 2. )); + TGeoTranslation* trGas = new TGeoTranslation(0., 0., (-(boxBackThickness - boxFrontThickness)/2.)); + boxVol->AddNode(gasVol, 1, trGas); + + // Front plane from kapton + TGeoVolume *kaptonVol = gGeoMan->MakeBox("kapton", medKapton, boxXLen / 2. - boxThickness, boxYLen / 2. - boxThickness, boxFrontThickness / 2.); + TGeoTranslation* trKapton = new TGeoTranslation(0., 0., -(boxZLen - boxFrontThickness)/2.); + boxVol->AddNode(kaptonVol, 1, trKapton); + + + // Aerogel + TGeoVolume *aerogelVol = gGeoMan->MakeBox("aerogel", medAerogel, aerogelXLen/2., aerogelYLen/2., aerogelZLen/2.); + Double_t aerogelZ = boxZLen / 2. - boxBackThickness - pmtZPadding - aerogelPmtDistance - aerogelZLen / 2.; + TGeoTranslation* trAerogel1 = new TGeoTranslation(pmtXShift, (aerogelYLen + aerogelGap)/2., aerogelZ); + TGeoTranslation* trAerogel2 = new TGeoTranslation(pmtXShift, -(aerogelYLen + aerogelGap)/2., aerogelZ); + gasVol->AddNode(aerogelVol, 1, trAerogel1); + gasVol->AddNode(aerogelVol, 2, trAerogel2); + + // PMT + TGeoTranslation *trPmt1 = new TGeoTranslation(pmtSizeHalf + pmtGapHalf, -pmtSize - pmtGap, 0.); // Bottom Right + TGeoTranslation *trPmt2 = new TGeoTranslation(pmtSizeHalf + pmtGapHalf,0., 0.); // Middle Right + TGeoTranslation *trPmt3 = new TGeoTranslation(pmtSizeHalf + pmtGapHalf, pmtSize + pmtGap, 0.); // Top Right + TGeoTranslation *trPmt4 = new TGeoTranslation(-pmtSizeHalf - pmtGapHalf, -pmtSize - pmtGap, 0.); // Bottom Left + TGeoTranslation *trPmt5 = new TGeoTranslation(-pmtSizeHalf - pmtGapHalf, 0., 0.); // Middle Left + TGeoTranslation *trPmt6 = new TGeoTranslation( -pmtSizeHalf - pmtGapHalf, pmtSize + pmtGap, 0.); // Top Left + + TGeoVolume *pmtContVol = new TGeoVolumeAssembly("pmt_cont_vol"); + TGeoVolume *pmtVol = new TGeoVolumeAssembly("pmt_vol_0"); + TGeoVolume *pmtVol_180 = new TGeoVolumeAssembly("pmt_vol_1"); + TGeoVolume *pmtPixelVol = gGeoMan->MakeBox("pmt_pixel", medCsI, pmtPixelSize/2., pmtPixelSize/2., pmtPixelThickness / 2.); + TGeoVolume *pmtPixelVol_outer_outer = gGeoMan->MakeBox("pmt_pixel", medCsI, pmtOuterPixelSize/2., pmtOuterPixelSize/2., pmtPixelThickness / 2.); + TGeoVolume *pmtPixelVol_inner_outer = gGeoMan->MakeBox("pmt_pixel", medCsI, pmtPixelSize/2., pmtOuterPixelSize/2., pmtPixelThickness / 2.); + TGeoVolume *pmtPixelVol_outer_inner = gGeoMan->MakeBox("pmt_pixel", medCsI, pmtOuterPixelSize/2., pmtPixelSize/2., pmtPixelThickness / 2.); + TGeoVolume *pmtWindow = gGeoMan->MakeBox("pmt_Window", medPmtGlas, pmtSizeHalf, pmtSizeHalf, pmtWindowThickness / 2.); + + pmtContVol->AddNode(pmtVol_180, 1, trPmt1); // To Power Module // Bottom Right + pmtContVol->AddNode(pmtVol, 2, trPmt2); // Middle // Middle Right + pmtContVol->AddNode(pmtVol, 3, trPmt3); // To Combiner // Top Right + pmtContVol->AddNode(pmtVol_180, 4, trPmt4); // To Power Module // Bottom Left + pmtContVol->AddNode(pmtVol, 5, trPmt5); // Middle // Middle Left + pmtContVol->AddNode(pmtVol, 6, trPmt6); // To Combiner // Top Left + + Int_t halfPmtNofPixels = pmtNofPixels / 2; + for(Int_t i = 0; i < pmtNofPixels; i++) { + for(Int_t j = 0; j < pmtNofPixels; j++) { + //check outer Pixels + + Double_t x = 0.; + Double_t y = 0.; + bool x_outer = false; + bool y_outer = false; + + if (i==0){ + x = -(halfPmtNofPixels - 1) * pmtPixelSize - pmtOuterPixelSizeHalf; + x_outer = true; + } else if (i==(pmtNofPixels-1)){ + x = (halfPmtNofPixels - 1) * pmtPixelSize + pmtOuterPixelSizeHalf; + x_outer = true; + } else if (i < halfPmtNofPixels){ + x = -((halfPmtNofPixels - 1)-i) * pmtPixelSize - pmtPixelSizeHalf; + x_outer = false; + } else { + x = (i-halfPmtNofPixels) * pmtPixelSize + pmtPixelSizeHalf; + x_outer = false; + } + + + if (j==0){ + y = -(halfPmtNofPixels - 1) * pmtPixelSize - pmtOuterPixelSizeHalf; + y_outer = true; + } else if (j==(pmtNofPixels-1)){ + y = (halfPmtNofPixels - 1) * pmtPixelSize + pmtOuterPixelSizeHalf; + y_outer = true; + } else if (j < halfPmtNofPixels){ + y = -((halfPmtNofPixels - 1)-j) * pmtPixelSize - pmtPixelSizeHalf; + y_outer = false; + } else { + y = (j-halfPmtNofPixels) * pmtPixelSize + pmtPixelSizeHalf; + y_outer = false; + } + //Double_t x = (i - (halfPmtNofPixels - 1)) * pmtPixelSize - pmtPixelSizeHalf; + + //Double_t y = (j - (halfPmtNofPixels - 1)) * pmtPixelSize - pmtPixelSizeHalf; + TGeoTranslation *trij = new TGeoTranslation(x, y, -pmtPixelThickness/2. + pmtThickness/2.); + + //normal rotated PMT (HV connector at lower side) + uint uid = 18 - ((j%4)/2)*16-(j%2)+2*i+(1-(j/4))*100; + + //180?? rotated PMT + uint uid_180 = 15 + ((j%4)/2)*16+(j%2)-2*i+(1-(j/4))*100; + if (x_outer == true && y_outer == true){ + pmtVol->AddNode(pmtPixelVol_outer_outer, uid, trij); + pmtVol_180->AddNode(pmtPixelVol_outer_outer, uid_180, trij); + } else if (x_outer == true && y_outer == false) { + pmtVol->AddNode(pmtPixelVol_outer_inner, uid, trij); + pmtVol_180->AddNode(pmtPixelVol_outer_inner, uid_180, trij); + } else if (x_outer == false && y_outer == true) { + pmtVol->AddNode(pmtPixelVol_inner_outer, uid, trij); + pmtVol_180->AddNode(pmtPixelVol_inner_outer, uid_180, trij); + } else { + pmtVol->AddNode(pmtPixelVol, uid, trij); + pmtVol_180->AddNode(pmtPixelVol, uid_180, trij); + } + } + } + + TGeoTranslation *trWndw = new TGeoTranslation(0., 0., +pmtWindowThickness/2. - pmtThickness/2.); + if (pmtWindowThickness > 0.0) { + pmtVol->AddNode(pmtWindow, 1, trWndw); + pmtVol_180->AddNode(pmtWindow, 1, trWndw); + } + + // + Double_t pmtContXLen = 2 * (pmtSize + pmtGap); + Double_t pmtContYLen = 3 * (pmtSize + pmtGap); + TGeoTranslation *trPmtCont1 = new TGeoTranslation(-pmtContXLen/2., pmtContYLen, 0.); //Top Left + TGeoTranslation *trPmtCont2 = new TGeoTranslation(-pmtContXLen/2., 0., 0.); //Middle Left + TGeoTranslation *trPmtCont3 = new TGeoTranslation(-pmtContXLen/2., - pmtContYLen, 0.); //Bottom Left + TGeoTranslation *trPmtCont4 = new TGeoTranslation(pmtContXLen/2., pmtContYLen, 0.); // + TGeoTranslation *trPmtCont5 = new TGeoTranslation(pmtContXLen/2., 0., 0.); // + TGeoTranslation *trPmtCont6 = new TGeoTranslation(pmtContXLen/2., -pmtContYLen, 0.); // + + TGeoVolume *pmtPlaneVol = new TGeoVolumeAssembly("pmt_plane"); + pmtPlaneVol->AddNode(pmtContVol, 00, trPmtCont1); // Id gives the Address 0x7**0 of the top left DiRICH in a BP (X|Y) + pmtPlaneVol->AddNode(pmtContVol, 03, trPmtCont2); + pmtPlaneVol->AddNode(pmtContVol, 06, trPmtCont3); + pmtPlaneVol->AddNode(pmtContVol, 20, trPmtCont4); + pmtPlaneVol->AddNode(pmtContVol, 23, trPmtCont5); + pmtPlaneVol->AddNode(pmtContVol, 26, trPmtCont6); + + TGeoTranslation *trPmtPlane = new TGeoTranslation( pmtXShift, 0., boxZLen / 2. - boxBackThickness - pmtZPadding + (pmtThickness / 2.)); + gasVol->AddNode(pmtPlaneVol, 1, trPmtPlane); + + + gGeoMan->CheckOverlaps(); + gGeoMan->PrintOverlaps(); + + //Draw + pmtPixelVol->SetLineColor(kYellow+4); + aerogelVol->SetLineColor(kCyan); + aerogelVol->SetTransparency(70); + gasVol->SetLineColor(kGreen); + gasVol->SetTransparency(60); + kaptonVol->SetLineColor(kBlue); + kaptonVol->SetTransparency(70); + + + //gGeoMan->SetTopVisible(); + //boxVol->SetVisibility(true); + + // boxVol->Draw("ogl"); + //top->Draw("ogl"); + gGeoMan->SetVisLevel(7);//7 + + rich->Export(geoFileName); // an alternative way of writing the trd volume + TFile* geoFile = new TFile(geoFileName, "UPDATE"); + trBox->Write(); + cout << endl << "Geometry exported to " << geoFileName << endl; + geoFile->Close(); + +} diff --git a/macro/mcbm/geometry/rich/create_rich_v20c_mcbm.C b/macro/mcbm/geometry/rich/create_rich_v20c_mcbm.C new file mode 100644 index 00000000..b92ef0c0 --- /dev/null +++ b/macro/mcbm/geometry/rich/create_rich_v20c_mcbm.C @@ -0,0 +1,332 @@ +#include <iostream> +//#include "FairGeoMedium.h" +//#include "FairGeoBuilder.h" +//#include "FairGeoMedia.h" +#include "TGeoVolume.h" +#include "TGeoManager.h" + +using namespace std; + +// Changelog + +// 2020-05-06 - v20b - AW - changed positioning to center on 25° line (with Window) +// 2020-04-02 - v19a - FU - same as v19c but with exported geometry in output file +// 2019-11-28 - v19c - DE - move mRICH +12+7 cm in x direction (same as mTOF v19b) for the Nov 2019 run +// 2017-11-17 - v18d - DE - add aerogel as radiator to the mRICH module +// 2017-11-12 - v18c - DE - push mRICH downstream to z=355 cm for long setup +// 2017-07-19 - v18b - DE - add one level to the geometry hierarchy +// 2017-07-15 - v18b - DE - arrange 4x mRICH detectors in the setup and tilt towards target + + +void create_rich_v20c_mcbm() +{ + gSystem->Load("libGeom"); + + TString geoFileName= "rich_v20c_mcbm.geo.root"; + TString topNodeName= "rich_v20c_mcbm"; + + 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(); + TGeoManager* gGeoMan = gGeoManager; + + FairGeoMedia* geoMedia = geoFace->getMedia(); + FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder(); + + //Media + FairGeoMedium* mAluminium = geoMedia->getMedium("aluminium"); + if (mAluminium == NULL) Fatal("Main", "FairMedium aluminium not found"); + geoBuild->createMedium(mAluminium); + TGeoMedium* medAl = gGeoMan->GetMedium("aluminium"); + if (medAl == NULL) Fatal("Main", "Medium vacuum not found"); + + FairGeoMedium* mKapton = geoMedia->getMedium("kapton"); + if (mKapton == NULL) Fatal("Main", "FairMedium kapton not found"); + geoBuild->createMedium(mKapton); + TGeoMedium* medKapton = gGeoMan->GetMedium("kapton"); + if (medKapton == NULL) Fatal("Main", "Medium kapton not found"); + + FairGeoMedium* mAir = geoMedia->getMedium("air"); + if (mAir == NULL) Fatal("Main", "FairMedium air not found"); + geoBuild->createMedium(mAir); + TGeoMedium* medAir = gGeoMan->GetMedium("air"); + if (medAir == NULL) Fatal("Main", "Medium air not found"); + + FairGeoMedium* mPmtGlas = geoMedia->getMedium("PMTglass"); + if (mPmtGlas == NULL) Fatal("Main", "FairMedium vacuum not found"); + geoBuild->createMedium(mPmtGlas); + TGeoMedium* medPmtGlas = gGeoMan->GetMedium("PMTglass"); + if (medPmtGlas == NULL) Fatal("Main", "Medium vacuum not found"); + + FairGeoMedium* mNitrogen = geoMedia->getMedium("RICHgas_N2_dis"); + if (mNitrogen == NULL) Fatal("Main", "FairMedium RICHgas_N2_dis not found"); + geoBuild->createMedium(mNitrogen); + TGeoMedium* medNitrogen = gGeoMan->GetMedium("RICHgas_N2_dis"); + if (medNitrogen == NULL) Fatal("Main", "Medium RICHgas_N2_dis not found"); + + FairGeoMedium* mPMT = geoMedia->getMedium("CsI"); + if (mPMT == NULL) Fatal("Main", "FairMedium CsI not found"); + geoBuild->createMedium(mPMT); + TGeoMedium* medCsI = gGeoMan->GetMedium("CsI"); + if (medCsI == NULL) Fatal("Main", "Medium CsI not found"); + + FairGeoMedium* mElectronic = geoMedia->getMedium("air"); + if (mElectronic == NULL) Fatal("Main", "FairMedium air not found"); + geoBuild->createMedium(mElectronic); + TGeoMedium* medElectronic = gGeoMan->GetMedium("air"); + if (medElectronic == NULL) Fatal("Main", "Medium air not found"); + + FairGeoMedium* mAerogel = geoMedia->getMedium("aerogel"); + if (mAerogel == NULL) Fatal("Main", "FairMedium aerogel not found"); + geoBuild->createMedium(mAerogel); + TGeoMedium* medAerogel = gGeoMan->GetMedium("aerogel"); + if (medAerogel == NULL) Fatal("Main", "Medium aerogel not found"); + + + //Dimensions of the RICH prototype [cm] + + const Double_t ItemToKapton = 1.85; + + // Box + const Double_t boxThickness = 0.3; + const Double_t boxBackThickness = 1.; + const Double_t boxFrontThickness = 0.3; + const Double_t boxXLen = 38.2; + const Double_t boxYLen= 59.7; + const Double_t boxZLen = 25. + boxBackThickness - ItemToKapton; + const Bool_t isRotate90DegZ = false; + + // PMT + // PMT specs https://www.hamamatsu.com/resources/pdf/etd/H12700_TPMH1348E.pdf + const Double_t pmtNofPixels = 8; + const Double_t pmtSize = 5.2; + const Double_t pmtSizeHalf = pmtSize / 2.; + const Double_t pmtSensitiveSize = 4.85; + const Double_t pmtPixelSize = 0.6;//pmtSensitiveSize / pmtNofPixels; + const Double_t pmtPixelSizeHalf = pmtPixelSize / 2.; + const Double_t pmtOuterPixelSize = 0.625;//pmtSensitiveSize / pmtNofPixels; + const Double_t pmtOuterPixelSizeHalf = pmtOuterPixelSize / 2.; + const Double_t pmtGap = 0.1; + const Double_t pmtGapHalf = pmtGap / 2.; + const Double_t pmtMatrixGap = 0.1; + const Double_t pmtPixelThickness = 0.1; + const Double_t pmtWindowThickness = 0.15; + Double_t pmtWindowPixelDistance = 0.0; + if (pmtWindowThickness > 0.0) pmtWindowPixelDistance = 0.0; + const Double_t pmtThickness = pmtPixelThickness + pmtWindowThickness + pmtWindowPixelDistance; + const Double_t pmtZPadding = 3.871; + const Double_t pmtXShift = 2.5; + + // Electronics + const Double_t elecLength = 10.; + const Double_t elecWidth = 3. * pmtSize; + const Double_t elecHeight = 2. * pmtSize; + + // Aerogel Box + const Double_t aerogelXLen = 20.; + const Double_t aerogelYLen = 20.; + const Double_t aerogelZLen = 3.; + const Double_t aerogelPmtDistance = 10.; + const Double_t aerogelGap = 0.1; + + // Imaginary sensitive plane + Bool_t isIncludeSensPlane = false; + const Double_t sensPlaneSize = 200.; + const Double_t sensPlaneBoxDistance = 1.; + + //Global positioning + const Double_t boxFrontToTarget = 327. + ItemToKapton + boxZLen/2; + + // Create the top volume + TGeoVolume *top = new TGeoVolumeAssembly("top"); + gGeoMan->SetTopVolume(top); + + // Rich assembly + TGeoVolume* rich = new TGeoVolumeAssembly(topNodeName); + top->AddNode(rich, 1); + + // Al box + TGeoRotation* rotBox = new TGeoRotation("rotBox", 0., 0., 0.); + TGeoCombiTrans* trBox = NULL; + if ( isRotate90DegZ ) { + rotBox->RotateZ(90.); + rotBox->RotateY(0.955);//Tilting of Rich + trBox = new TGeoCombiTrans(0, -pmtXShift-(pmtSize + pmtGap + 1), boxFrontToTarget, rotBox); + } else { + rotBox->RotateX(0.955);//Tilting of Rich + // Nov 2019 run + //trBox = new TGeoCombiTrans(-pmtXShift-(pmtSize + pmtGap + 1)+12.+7., 0, boxFrontToTarget, rotBox); + // Mar2020 + trBox = new TGeoCombiTrans(-pmtXShift-(pmtSize + pmtGap + 1)+6.3, 0, boxFrontToTarget, rotBox); + } + TGeoVolume *boxVol = gGeoMan->MakeBox("box", medAl, boxXLen / 2., boxYLen / 2., boxZLen / 2.); +// rich->AddNode(boxVol, 1, trBox); + rich->AddNode(boxVol, 1); + + // Gas + TGeoVolume *gasVol = gGeoMan->MakeBox("Gas", medNitrogen, boxXLen / 2. - boxThickness, boxYLen / 2. - boxThickness, + ((boxZLen - boxBackThickness - boxFrontThickness) / 2. )); + TGeoTranslation* trGas = new TGeoTranslation(0., 0., (-(boxBackThickness - boxFrontThickness)/2.)); + boxVol->AddNode(gasVol, 1, trGas); + + // Front plane from kapton + TGeoVolume *kaptonVol = gGeoMan->MakeBox("kapton", medKapton, boxXLen / 2. - boxThickness, boxYLen / 2. - boxThickness, boxFrontThickness / 2.); + TGeoTranslation* trKapton = new TGeoTranslation(0., 0., -(boxZLen - boxFrontThickness)/2.); + boxVol->AddNode(kaptonVol, 1, trKapton); + + + // Aerogel + TGeoVolume *aerogelVol = gGeoMan->MakeBox("aerogel", medAerogel, aerogelXLen/2., aerogelYLen/2., aerogelZLen/2.); + Double_t aerogelZ = boxZLen / 2. - boxBackThickness - pmtZPadding - aerogelPmtDistance - aerogelZLen / 2.; + TGeoTranslation* trAerogel1 = new TGeoTranslation(pmtXShift, (aerogelYLen + aerogelGap)/2., aerogelZ); + TGeoTranslation* trAerogel2 = new TGeoTranslation(pmtXShift, -(aerogelYLen + aerogelGap)/2., aerogelZ); + gasVol->AddNode(aerogelVol, 1, trAerogel1); + gasVol->AddNode(aerogelVol, 2, trAerogel2); + + // PMT + TGeoTranslation *trPmt1 = new TGeoTranslation(pmtSizeHalf + pmtGapHalf, -pmtSize - pmtGap, 0.); // Bottom Right + TGeoTranslation *trPmt2 = new TGeoTranslation(pmtSizeHalf + pmtGapHalf,0., 0.); // Middle Right + TGeoTranslation *trPmt3 = new TGeoTranslation(pmtSizeHalf + pmtGapHalf, pmtSize + pmtGap, 0.); // Top Right + TGeoTranslation *trPmt4 = new TGeoTranslation(-pmtSizeHalf - pmtGapHalf, -pmtSize - pmtGap, 0.); // Bottom Left + TGeoTranslation *trPmt5 = new TGeoTranslation(-pmtSizeHalf - pmtGapHalf, 0., 0.); // Middle Left + TGeoTranslation *trPmt6 = new TGeoTranslation( -pmtSizeHalf - pmtGapHalf, pmtSize + pmtGap, 0.); // Top Left + + TGeoVolume *pmtContVol = new TGeoVolumeAssembly("pmt_cont_vol"); + TGeoVolume *pmtVol = new TGeoVolumeAssembly("pmt_vol_0"); + TGeoVolume *pmtVol_180 = new TGeoVolumeAssembly("pmt_vol_1"); + TGeoVolume *pmtPixelVol = gGeoMan->MakeBox("pmt_pixel", medCsI, pmtPixelSize/2., pmtPixelSize/2., pmtPixelThickness / 2.); + TGeoVolume *pmtPixelVol_outer_outer = gGeoMan->MakeBox("pmt_pixel", medCsI, pmtOuterPixelSize/2., pmtOuterPixelSize/2., pmtPixelThickness / 2.); + TGeoVolume *pmtPixelVol_inner_outer = gGeoMan->MakeBox("pmt_pixel", medCsI, pmtPixelSize/2., pmtOuterPixelSize/2., pmtPixelThickness / 2.); + TGeoVolume *pmtPixelVol_outer_inner = gGeoMan->MakeBox("pmt_pixel", medCsI, pmtOuterPixelSize/2., pmtPixelSize/2., pmtPixelThickness / 2.); + TGeoVolume *pmtWindow = gGeoMan->MakeBox("pmt_Window", medPmtGlas, pmtSizeHalf, pmtSizeHalf, pmtWindowThickness / 2.); + + pmtContVol->AddNode(pmtVol_180, 1, trPmt1); // To Power Module // Bottom Right + pmtContVol->AddNode(pmtVol, 2, trPmt2); // Middle // Middle Right + pmtContVol->AddNode(pmtVol, 3, trPmt3); // To Combiner // Top Right + pmtContVol->AddNode(pmtVol_180, 4, trPmt4); // To Power Module // Bottom Left + pmtContVol->AddNode(pmtVol, 5, trPmt5); // Middle // Middle Left + pmtContVol->AddNode(pmtVol, 6, trPmt6); // To Combiner // Top Left + + Int_t halfPmtNofPixels = pmtNofPixels / 2; + for(Int_t i = 0; i < pmtNofPixels; i++) { + for(Int_t j = 0; j < pmtNofPixels; j++) { + //check outer Pixels + + Double_t x = 0.; + Double_t y = 0.; + bool x_outer = false; + bool y_outer = false; + + if (i==0){ + x = -(halfPmtNofPixels - 1) * pmtPixelSize - pmtOuterPixelSizeHalf; + x_outer = true; + } else if (i==(pmtNofPixels-1)){ + x = (halfPmtNofPixels - 1) * pmtPixelSize + pmtOuterPixelSizeHalf; + x_outer = true; + } else if (i < halfPmtNofPixels){ + x = -((halfPmtNofPixels - 1)-i) * pmtPixelSize - pmtPixelSizeHalf; + x_outer = false; + } else { + x = (i-halfPmtNofPixels) * pmtPixelSize + pmtPixelSizeHalf; + x_outer = false; + } + + + if (j==0){ + y = -(halfPmtNofPixels - 1) * pmtPixelSize - pmtOuterPixelSizeHalf; + y_outer = true; + } else if (j==(pmtNofPixels-1)){ + y = (halfPmtNofPixels - 1) * pmtPixelSize + pmtOuterPixelSizeHalf; + y_outer = true; + } else if (j < halfPmtNofPixels){ + y = -((halfPmtNofPixels - 1)-j) * pmtPixelSize - pmtPixelSizeHalf; + y_outer = false; + } else { + y = (j-halfPmtNofPixels) * pmtPixelSize + pmtPixelSizeHalf; + y_outer = false; + } + //Double_t x = (i - (halfPmtNofPixels - 1)) * pmtPixelSize - pmtPixelSizeHalf; + + //Double_t y = (j - (halfPmtNofPixels - 1)) * pmtPixelSize - pmtPixelSizeHalf; + TGeoTranslation *trij = new TGeoTranslation(x, y, -pmtPixelThickness/2. + pmtThickness/2.); + + //normal rotated PMT (HV connector at lower side) + uint uid = 18 - ((j%4)/2)*16-(j%2)+2*i+(1-(j/4))*100; + + //180?? rotated PMT + uint uid_180 = 15 + ((j%4)/2)*16+(j%2)-2*i+(1-(j/4))*100; + if (x_outer == true && y_outer == true){ + pmtVol->AddNode(pmtPixelVol_outer_outer, uid, trij); + pmtVol_180->AddNode(pmtPixelVol_outer_outer, uid_180, trij); + } else if (x_outer == true && y_outer == false) { + pmtVol->AddNode(pmtPixelVol_outer_inner, uid, trij); + pmtVol_180->AddNode(pmtPixelVol_outer_inner, uid_180, trij); + } else if (x_outer == false && y_outer == true) { + pmtVol->AddNode(pmtPixelVol_inner_outer, uid, trij); + pmtVol_180->AddNode(pmtPixelVol_inner_outer, uid_180, trij); + } else { + pmtVol->AddNode(pmtPixelVol, uid, trij); + pmtVol_180->AddNode(pmtPixelVol, uid_180, trij); + } + } + } + + TGeoTranslation *trWndw = new TGeoTranslation(0., 0., +pmtWindowThickness/2. - pmtThickness/2.); + if (pmtWindowThickness > 0.0) { + pmtVol->AddNode(pmtWindow, 1, trWndw); + pmtVol_180->AddNode(pmtWindow, 1, trWndw); + } + + // + Double_t pmtContXLen = 2 * (pmtSize + pmtGap); + Double_t pmtContYLen = 3 * (pmtSize + pmtGap); + TGeoTranslation *trPmtCont1 = new TGeoTranslation(-pmtContXLen/2., pmtContYLen, 0.); //Top Left + TGeoTranslation *trPmtCont2 = new TGeoTranslation(-pmtContXLen/2., 0., 0.); //Middle Left + TGeoTranslation *trPmtCont3 = new TGeoTranslation(-pmtContXLen/2., - pmtContYLen, 0.); //Bottom Left + TGeoTranslation *trPmtCont4 = new TGeoTranslation(pmtContXLen/2., pmtContYLen, 0.); // + TGeoTranslation *trPmtCont5 = new TGeoTranslation(pmtContXLen/2., 0., 0.); // + TGeoTranslation *trPmtCont6 = new TGeoTranslation(pmtContXLen/2., -pmtContYLen, 0.); // + + TGeoVolume *pmtPlaneVol = new TGeoVolumeAssembly("pmt_plane"); + pmtPlaneVol->AddNode(pmtContVol, 00, trPmtCont1); // Id gives the Address 0x7**0 of the top left DiRICH in a BP (X|Y) + pmtPlaneVol->AddNode(pmtContVol, 03, trPmtCont2); + pmtPlaneVol->AddNode(pmtContVol, 06, trPmtCont3); + pmtPlaneVol->AddNode(pmtContVol, 20, trPmtCont4); + pmtPlaneVol->AddNode(pmtContVol, 23, trPmtCont5); + pmtPlaneVol->AddNode(pmtContVol, 26, trPmtCont6); + + TGeoTranslation *trPmtPlane = new TGeoTranslation( pmtXShift, 0., boxZLen / 2. - boxBackThickness - pmtZPadding + (pmtThickness / 2.)); + gasVol->AddNode(pmtPlaneVol, 1, trPmtPlane); + + + gGeoMan->CheckOverlaps(); + gGeoMan->PrintOverlaps(); + + //Draw + pmtPixelVol->SetLineColor(kYellow+4); + aerogelVol->SetLineColor(kCyan); + aerogelVol->SetTransparency(70); + gasVol->SetLineColor(kGreen); + gasVol->SetTransparency(60); + kaptonVol->SetLineColor(kBlue); + kaptonVol->SetTransparency(70); + + + //gGeoMan->SetTopVisible(); + //boxVol->SetVisibility(true); + + // boxVol->Draw("ogl"); + //top->Draw("ogl"); + gGeoMan->SetVisLevel(7);//7 + + rich->Export(geoFileName); // an alternative way of writing the trd volume + TFile* geoFile = new TFile(geoFileName, "UPDATE"); + trBox->Write(); + cout << endl << "Geometry exported to " << geoFileName << endl; + geoFile->Close(); + +} diff --git a/macro/mcbm/geometry/rich/create_rich_v20d_mcbm.C b/macro/mcbm/geometry/rich/create_rich_v20d_mcbm.C new file mode 100644 index 00000000..7165542f --- /dev/null +++ b/macro/mcbm/geometry/rich/create_rich_v20d_mcbm.C @@ -0,0 +1,336 @@ +#include <iostream> +//#include "FairGeoMedium.h" +//#include "FairGeoBuilder.h" +//#include "FairGeoMedia.h" +#include "TGeoVolume.h" +#include "TGeoManager.h" + +using namespace std; + +// Changelog + +// 2020-05-25 - v20d - AW - Move mRICH by +7.2cm in Z accordingly to the mTOF movement from rev 16441 +// 2020-05-20 - v20d - AW - changed positioning to +2.5cm to 25°line (nearer to beam axis) (from Analysis) +// 2020-05-06 - v20b - AW - changed positioning to center on 25° line (without Window) +// 2020-04-02 - v19a - FU - same as v19c but with exported geometry in output file +// 2019-11-28 - v19c - DE - move mRICH +12+7 cm in x direction (same as mTOF v19b) for the Nov 2019 run +// 2017-11-17 - v18d - DE - add aerogel as radiator to the mRICH module +// 2017-11-12 - v18c - DE - push mRICH downstream to z=355 cm for long setup +// 2017-07-19 - v18b - DE - add one level to the geometry hierarchy +// 2017-07-15 - v18b - DE - arrange 4x mRICH detectors in the setup and tilt towards target + + +void create_rich_v20d_mcbm() +{ + gSystem->Load("libGeom"); + + TString geoFileName= "rich_v20d_mcbm.geo.root"; + TString topNodeName= "rich_v20d_mcbm"; + + Double_t XOffset = 2.5; + + 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(); + TGeoManager* gGeoMan = gGeoManager; + + FairGeoMedia* geoMedia = geoFace->getMedia(); + FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder(); + + //Media + FairGeoMedium* mAluminium = geoMedia->getMedium("aluminium"); + if (mAluminium == NULL) Fatal("Main", "FairMedium aluminium not found"); + geoBuild->createMedium(mAluminium); + TGeoMedium* medAl = gGeoMan->GetMedium("aluminium"); + if (medAl == NULL) Fatal("Main", "Medium vacuum not found"); + + FairGeoMedium* mKapton = geoMedia->getMedium("kapton"); + if (mKapton == NULL) Fatal("Main", "FairMedium kapton not found"); + geoBuild->createMedium(mKapton); + TGeoMedium* medKapton = gGeoMan->GetMedium("kapton"); + if (medKapton == NULL) Fatal("Main", "Medium kapton not found"); + + FairGeoMedium* mAir = geoMedia->getMedium("air"); + if (mAir == NULL) Fatal("Main", "FairMedium air not found"); + geoBuild->createMedium(mAir); + TGeoMedium* medAir = gGeoMan->GetMedium("air"); + if (medAir == NULL) Fatal("Main", "Medium air not found"); + + FairGeoMedium* mPmtGlas = geoMedia->getMedium("PMTglass"); + if (mPmtGlas == NULL) Fatal("Main", "FairMedium vacuum not found"); + geoBuild->createMedium(mPmtGlas); + TGeoMedium* medPmtGlas = gGeoMan->GetMedium("PMTglass"); + if (medPmtGlas == NULL) Fatal("Main", "Medium vacuum not found"); + + FairGeoMedium* mNitrogen = geoMedia->getMedium("RICHgas_N2_dis"); + if (mNitrogen == NULL) Fatal("Main", "FairMedium RICHgas_N2_dis not found"); + geoBuild->createMedium(mNitrogen); + TGeoMedium* medNitrogen = gGeoMan->GetMedium("RICHgas_N2_dis"); + if (medNitrogen == NULL) Fatal("Main", "Medium RICHgas_N2_dis not found"); + + FairGeoMedium* mPMT = geoMedia->getMedium("CsI"); + if (mPMT == NULL) Fatal("Main", "FairMedium CsI not found"); + geoBuild->createMedium(mPMT); + TGeoMedium* medCsI = gGeoMan->GetMedium("CsI"); + if (medCsI == NULL) Fatal("Main", "Medium CsI not found"); + + FairGeoMedium* mElectronic = geoMedia->getMedium("air"); + if (mElectronic == NULL) Fatal("Main", "FairMedium air not found"); + geoBuild->createMedium(mElectronic); + TGeoMedium* medElectronic = gGeoMan->GetMedium("air"); + if (medElectronic == NULL) Fatal("Main", "Medium air not found"); + + FairGeoMedium* mAerogel = geoMedia->getMedium("aerogel"); + if (mAerogel == NULL) Fatal("Main", "FairMedium aerogel not found"); + geoBuild->createMedium(mAerogel); + TGeoMedium* medAerogel = gGeoMan->GetMedium("aerogel"); + if (medAerogel == NULL) Fatal("Main", "Medium aerogel not found"); + + + //Dimensions of the RICH prototype [cm] + + const Double_t ItemToKapton = 1.85; + + // Box + const Double_t boxThickness = 0.3; + const Double_t boxBackThickness = 1.; + const Double_t boxFrontThickness = 0.3; + const Double_t boxXLen = 38.2; + const Double_t boxYLen= 59.7; + const Double_t boxZLen = 25. + boxBackThickness - ItemToKapton; + const Bool_t isRotate90DegZ = false; + + // PMT + // PMT specs https://www.hamamatsu.com/resources/pdf/etd/H12700_TPMH1348E.pdf + const Double_t pmtNofPixels = 8; + const Double_t pmtSize = 5.2; + const Double_t pmtSizeHalf = pmtSize / 2.; + const Double_t pmtSensitiveSize = 4.85; + const Double_t pmtPixelSize = 0.6;//pmtSensitiveSize / pmtNofPixels; + const Double_t pmtPixelSizeHalf = pmtPixelSize / 2.; + const Double_t pmtOuterPixelSize = 0.625;//pmtSensitiveSize / pmtNofPixels; + const Double_t pmtOuterPixelSizeHalf = pmtOuterPixelSize / 2.; + const Double_t pmtGap = 0.1; + const Double_t pmtGapHalf = pmtGap / 2.; + const Double_t pmtMatrixGap = 0.1; + const Double_t pmtPixelThickness = 0.1; + const Double_t pmtWindowThickness = 0.00;//0.15 + Double_t pmtWindowPixelDistance = 0.0; + if (pmtWindowThickness > 0.0) pmtWindowPixelDistance = 0.0; + const Double_t pmtThickness = pmtPixelThickness + pmtWindowThickness + pmtWindowPixelDistance; + const Double_t pmtZPadding = 3.871; + const Double_t pmtXShift = 2.5; + + // Electronics + const Double_t elecLength = 10.; + const Double_t elecWidth = 3. * pmtSize; + const Double_t elecHeight = 2. * pmtSize; + + // Aerogel Box + const Double_t aerogelXLen = 20.; + const Double_t aerogelYLen = 20.; + const Double_t aerogelZLen = 3.; + const Double_t aerogelPmtDistance = 10.; + const Double_t aerogelGap = 0.1; + + // Imaginary sensitive plane + Bool_t isIncludeSensPlane = false; + const Double_t sensPlaneSize = 200.; + const Double_t sensPlaneBoxDistance = 1.; + + //Global positioning + const Double_t boxFrontToTarget = 334.2 + ItemToKapton + boxZLen/2; + + // Create the top volume + TGeoVolume *top = new TGeoVolumeAssembly("top"); + gGeoMan->SetTopVolume(top); + + // Rich assembly + TGeoVolume* rich = new TGeoVolumeAssembly(topNodeName); + top->AddNode(rich, 1); + + // Al box + TGeoRotation* rotBox = new TGeoRotation("rotBox", 0., 0., 0.); + TGeoCombiTrans* trBox = NULL; + if ( isRotate90DegZ ) { + rotBox->RotateZ(90.); + rotBox->RotateY(0.955);//Tilting of Rich + trBox = new TGeoCombiTrans(0, -pmtXShift-(pmtSize + pmtGap + 1), boxFrontToTarget, rotBox); + } else { + rotBox->RotateX(0.955);//Tilting of Rich + // Nov 2019 run + //trBox = new TGeoCombiTrans(-pmtXShift-(pmtSize + pmtGap + 1)+12.+7., 0, boxFrontToTarget, rotBox); + // Mar2020 + trBox = new TGeoCombiTrans(-pmtXShift-(pmtSize + pmtGap + 1)+6.3 + XOffset, 0, boxFrontToTarget, rotBox); + } + TGeoVolume *boxVol = gGeoMan->MakeBox("box", medAl, boxXLen / 2., boxYLen / 2., boxZLen / 2.); +// rich->AddNode(boxVol, 1, trBox); + rich->AddNode(boxVol, 1); + + // Gas + TGeoVolume *gasVol = gGeoMan->MakeBox("Gas", medNitrogen, boxXLen / 2. - boxThickness, boxYLen / 2. - boxThickness, + ((boxZLen - boxBackThickness - boxFrontThickness) / 2. )); + TGeoTranslation* trGas = new TGeoTranslation(0., 0., (-(boxBackThickness - boxFrontThickness)/2.)); + boxVol->AddNode(gasVol, 1, trGas); + + // Front plane from kapton + TGeoVolume *kaptonVol = gGeoMan->MakeBox("kapton", medKapton, boxXLen / 2. - boxThickness, boxYLen / 2. - boxThickness, boxFrontThickness / 2.); + TGeoTranslation* trKapton = new TGeoTranslation(0., 0., -(boxZLen - boxFrontThickness)/2.); + boxVol->AddNode(kaptonVol, 1, trKapton); + + + // Aerogel + TGeoVolume *aerogelVol = gGeoMan->MakeBox("aerogel", medAerogel, aerogelXLen/2., aerogelYLen/2., aerogelZLen/2.); + Double_t aerogelZ = boxZLen / 2. - boxBackThickness - pmtZPadding - aerogelPmtDistance - aerogelZLen / 2.; + TGeoTranslation* trAerogel1 = new TGeoTranslation(pmtXShift, (aerogelYLen + aerogelGap)/2., aerogelZ); + TGeoTranslation* trAerogel2 = new TGeoTranslation(pmtXShift, -(aerogelYLen + aerogelGap)/2., aerogelZ); + gasVol->AddNode(aerogelVol, 1, trAerogel1); + gasVol->AddNode(aerogelVol, 2, trAerogel2); + + // PMT + TGeoTranslation *trPmt1 = new TGeoTranslation(pmtSizeHalf + pmtGapHalf, -pmtSize - pmtGap, 0.); // Bottom Right + TGeoTranslation *trPmt2 = new TGeoTranslation(pmtSizeHalf + pmtGapHalf,0., 0.); // Middle Right + TGeoTranslation *trPmt3 = new TGeoTranslation(pmtSizeHalf + pmtGapHalf, pmtSize + pmtGap, 0.); // Top Right + TGeoTranslation *trPmt4 = new TGeoTranslation(-pmtSizeHalf - pmtGapHalf, -pmtSize - pmtGap, 0.); // Bottom Left + TGeoTranslation *trPmt5 = new TGeoTranslation(-pmtSizeHalf - pmtGapHalf, 0., 0.); // Middle Left + TGeoTranslation *trPmt6 = new TGeoTranslation( -pmtSizeHalf - pmtGapHalf, pmtSize + pmtGap, 0.); // Top Left + + TGeoVolume *pmtContVol = new TGeoVolumeAssembly("pmt_cont_vol"); + TGeoVolume *pmtVol = new TGeoVolumeAssembly("pmt_vol_0"); + TGeoVolume *pmtVol_180 = new TGeoVolumeAssembly("pmt_vol_1"); + TGeoVolume *pmtPixelVol = gGeoMan->MakeBox("pmt_pixel", medCsI, pmtPixelSize/2., pmtPixelSize/2., pmtPixelThickness / 2.); + TGeoVolume *pmtPixelVol_outer_outer = gGeoMan->MakeBox("pmt_pixel", medCsI, pmtOuterPixelSize/2., pmtOuterPixelSize/2., pmtPixelThickness / 2.); + TGeoVolume *pmtPixelVol_inner_outer = gGeoMan->MakeBox("pmt_pixel", medCsI, pmtPixelSize/2., pmtOuterPixelSize/2., pmtPixelThickness / 2.); + TGeoVolume *pmtPixelVol_outer_inner = gGeoMan->MakeBox("pmt_pixel", medCsI, pmtOuterPixelSize/2., pmtPixelSize/2., pmtPixelThickness / 2.); + TGeoVolume *pmtWindow = gGeoMan->MakeBox("pmt_Window", medPmtGlas, pmtSizeHalf, pmtSizeHalf, pmtWindowThickness / 2.); + + pmtContVol->AddNode(pmtVol_180, 1, trPmt1); // To Power Module // Bottom Right + pmtContVol->AddNode(pmtVol, 2, trPmt2); // Middle // Middle Right + pmtContVol->AddNode(pmtVol, 3, trPmt3); // To Combiner // Top Right + pmtContVol->AddNode(pmtVol_180, 4, trPmt4); // To Power Module // Bottom Left + pmtContVol->AddNode(pmtVol, 5, trPmt5); // Middle // Middle Left + pmtContVol->AddNode(pmtVol, 6, trPmt6); // To Combiner // Top Left + + Int_t halfPmtNofPixels = pmtNofPixels / 2; + for(Int_t i = 0; i < pmtNofPixels; i++) { + for(Int_t j = 0; j < pmtNofPixels; j++) { + //check outer Pixels + + Double_t x = 0.; + Double_t y = 0.; + bool x_outer = false; + bool y_outer = false; + + if (i==0){ + x = -(halfPmtNofPixels - 1) * pmtPixelSize - pmtOuterPixelSizeHalf; + x_outer = true; + } else if (i==(pmtNofPixels-1)){ + x = (halfPmtNofPixels - 1) * pmtPixelSize + pmtOuterPixelSizeHalf; + x_outer = true; + } else if (i < halfPmtNofPixels){ + x = -((halfPmtNofPixels - 1)-i) * pmtPixelSize - pmtPixelSizeHalf; + x_outer = false; + } else { + x = (i-halfPmtNofPixels) * pmtPixelSize + pmtPixelSizeHalf; + x_outer = false; + } + + + if (j==0){ + y = -(halfPmtNofPixels - 1) * pmtPixelSize - pmtOuterPixelSizeHalf; + y_outer = true; + } else if (j==(pmtNofPixels-1)){ + y = (halfPmtNofPixels - 1) * pmtPixelSize + pmtOuterPixelSizeHalf; + y_outer = true; + } else if (j < halfPmtNofPixels){ + y = -((halfPmtNofPixels - 1)-j) * pmtPixelSize - pmtPixelSizeHalf; + y_outer = false; + } else { + y = (j-halfPmtNofPixels) * pmtPixelSize + pmtPixelSizeHalf; + y_outer = false; + } + //Double_t x = (i - (halfPmtNofPixels - 1)) * pmtPixelSize - pmtPixelSizeHalf; + + //Double_t y = (j - (halfPmtNofPixels - 1)) * pmtPixelSize - pmtPixelSizeHalf; + TGeoTranslation *trij = new TGeoTranslation(x, y, -pmtPixelThickness/2. + pmtThickness/2.); + + //normal rotated PMT (HV connector at lower side) + uint uid = 18 - ((j%4)/2)*16-(j%2)+2*i+(1-(j/4))*100; + + //180?? rotated PMT + uint uid_180 = 15 + ((j%4)/2)*16+(j%2)-2*i+(1-(j/4))*100; + if (x_outer == true && y_outer == true){ + pmtVol->AddNode(pmtPixelVol_outer_outer, uid, trij); + pmtVol_180->AddNode(pmtPixelVol_outer_outer, uid_180, trij); + } else if (x_outer == true && y_outer == false) { + pmtVol->AddNode(pmtPixelVol_outer_inner, uid, trij); + pmtVol_180->AddNode(pmtPixelVol_outer_inner, uid_180, trij); + } else if (x_outer == false && y_outer == true) { + pmtVol->AddNode(pmtPixelVol_inner_outer, uid, trij); + pmtVol_180->AddNode(pmtPixelVol_inner_outer, uid_180, trij); + } else { + pmtVol->AddNode(pmtPixelVol, uid, trij); + pmtVol_180->AddNode(pmtPixelVol, uid_180, trij); + } + } + } + + TGeoTranslation *trWndw = new TGeoTranslation(0., 0., +pmtWindowThickness/2. - pmtThickness/2.); + if (pmtWindowThickness > 0.0) { + pmtVol->AddNode(pmtWindow, 1, trWndw); + pmtVol_180->AddNode(pmtWindow, 1, trWndw); + } + + // + Double_t pmtContXLen = 2 * (pmtSize + pmtGap); + Double_t pmtContYLen = 3 * (pmtSize + pmtGap); + TGeoTranslation *trPmtCont1 = new TGeoTranslation(-pmtContXLen/2., pmtContYLen, 0.); //Top Left + TGeoTranslation *trPmtCont2 = new TGeoTranslation(-pmtContXLen/2., 0., 0.); //Middle Left + TGeoTranslation *trPmtCont3 = new TGeoTranslation(-pmtContXLen/2., - pmtContYLen, 0.); //Bottom Left + TGeoTranslation *trPmtCont4 = new TGeoTranslation(pmtContXLen/2., pmtContYLen, 0.); // + TGeoTranslation *trPmtCont5 = new TGeoTranslation(pmtContXLen/2., 0., 0.); // + TGeoTranslation *trPmtCont6 = new TGeoTranslation(pmtContXLen/2., -pmtContYLen, 0.); // + + TGeoVolume *pmtPlaneVol = new TGeoVolumeAssembly("pmt_plane"); + pmtPlaneVol->AddNode(pmtContVol, 00, trPmtCont1); // Id gives the Address 0x7**0 of the top left DiRICH in a BP (X|Y) + pmtPlaneVol->AddNode(pmtContVol, 03, trPmtCont2); + pmtPlaneVol->AddNode(pmtContVol, 06, trPmtCont3); + pmtPlaneVol->AddNode(pmtContVol, 20, trPmtCont4); + pmtPlaneVol->AddNode(pmtContVol, 23, trPmtCont5); + pmtPlaneVol->AddNode(pmtContVol, 26, trPmtCont6); + + TGeoTranslation *trPmtPlane = new TGeoTranslation( pmtXShift, 0., boxZLen / 2. - boxBackThickness - pmtZPadding + (pmtThickness / 2.)); + gasVol->AddNode(pmtPlaneVol, 1, trPmtPlane); + + + gGeoMan->CheckOverlaps(); + gGeoMan->PrintOverlaps(); + + //Draw + pmtPixelVol->SetLineColor(kYellow+4); + aerogelVol->SetLineColor(kCyan); + aerogelVol->SetTransparency(70); + gasVol->SetLineColor(kGreen); + gasVol->SetTransparency(60); + kaptonVol->SetLineColor(kBlue); + kaptonVol->SetTransparency(70); + + + //gGeoMan->SetTopVisible(); + //boxVol->SetVisibility(true); + + // boxVol->Draw("ogl"); + //top->Draw("ogl"); + gGeoMan->SetVisLevel(7);//7 + + rich->Export(geoFileName); // an alternative way of writing the trd volume + TFile* geoFile = new TFile(geoFileName, "UPDATE"); + trBox->Write(); + cout << endl << "Geometry exported to " << geoFileName << endl; + geoFile->Close(); + +} diff --git a/macro/mcbm/geometry/sts/create_stsgeo_v20e.C b/macro/mcbm/geometry/sts/create_stsgeo_v20e.C new file mode 100644 index 00000000..c256dd24 --- /dev/null +++ b/macro/mcbm/geometry/sts/create_stsgeo_v20e.C @@ -0,0 +1,2546 @@ +/****************************************************************************** + ** Creation of STS geometry in ROOT format (TGeo). + ** + ** @file create_stsgeo_v20e.C + ** @author Volker Friese <v.friese@gsi.de> + ** @since 15 June 2012 + ** @date 09.05.2014 + ** @author Tomas Balog <T.Balog@gsi.de> + ** + ** 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 <iomanip> +#include <iostream> +#include "TGeoManager.h" + +#include "TGeoCompositeShape.h" +#include "TGeoPara.h" +#include "TGeoTube.h" +#include "TGeoCone.h" + + +// ------------- 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 + +// ---> 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.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 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_v20e(const char* geoTag="v20e_mcbm") +{ + + // ------- Geometry file name (output) ---------------------------------- + TString geoFileName = "sts_"; + geoFileName = geoFileName + geoTag + ".geo.root"; + // -------------------------------------------------------------------------- + + + // ------- 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_v20e.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 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"); + + // ---> 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.}; + Float_t statPos[8] = {28., 42., 50., 60., 70., 80., 90., 100.}; + // 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 = 2; + ladderTypes[0] = 9; + ladderTypes[1] = 9; + TGeoVolume* station01 = ConstructStation(0, nLadders, ladderTypes, rHole); + + if (gkConstructCones) { + // upstream + TGeoRotation* coneRot11 = new TGeoRotation; + coneRot11->RotateZ(90); + coneRot11->RotateY(180); + // TGeoCombiTrans* conePosRot11 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.3-gkLadderGapZ/2., coneRot11); + TGeoCombiTrans* conePosRot11 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.305-gkLadderGapZ/2., coneRot11); + station01->AddNode(coneSmallVolum, 1, conePosRot11); + + // downstream + TGeoRotation* coneRot12 = new TGeoRotation; + coneRot12->RotateZ(90); + // TGeoCombiTrans* conePosRot12 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.3+gkLadderGapZ/2., coneRot12); + TGeoCombiTrans* conePosRot12 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.305+gkLadderGapZ/2., coneRot12); + station01->AddNode(coneSmallVolum, 2, conePosRot12); + + station01->GetShape()->ComputeBBox(); + } + + 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; + ladderTypes[0] = 10; + ladderTypes[1] = 10; + ladderTypes[2] = 11; // triple ladder + TGeoVolume* station02 = ConstructStation(1, nLadders, ladderTypes, rHole); + + if (gkConstructCones) { + // upstream + TGeoRotation* coneRot21 = new TGeoRotation; + coneRot21->RotateZ(-90); + coneRot21->RotateY(180); + // TGeoCombiTrans* conePosRot21 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.3-gkLadderGapZ/2., coneRot21); + TGeoCombiTrans* conePosRot21 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.305-gkLadderGapZ/2., coneRot21); + station02->AddNode(coneSmallVolum, 1, conePosRot21); + + // downstream + TGeoRotation* coneRot22 = new TGeoRotation; + coneRot22->RotateZ(-90); + // TGeoCombiTrans* conePosRot22 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.3+gkLadderGapZ/2., coneRot22); + TGeoCombiTrans* conePosRot22 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.305+gkLadderGapZ/2., coneRot22); + station02->AddNode(coneSmallVolum, 2, conePosRot22); + + station02->GetShape()->ComputeBBox(); + } + + 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 = 12; +// ladderTypes[0] = 14; // 34; // 8; +// ladderTypes[1] = 13; // 33; // 7; +// ladderTypes[2] = 12; // 32; // 6; +// ladderTypes[3] = 12; // 32; // 6; +// ladderTypes[4] = 12; // 32; // 6; +// ladderTypes[5] = 3; // 31; // 22; // 5; +// ladderTypes[6] = 3; // 31; // 22; // 5; +// ladderTypes[7] = 12; // 32; // 6; +// ladderTypes[8] = 12; // 32; // 6; +// ladderTypes[9] = 12; // 32; // 6; +// ladderTypes[10] = 13; // 33; // 7; +// ladderTypes[11] = 14; // 34; // 8; +// TGeoVolume* station03 = ConstructStation(2, nLadders, ladderTypes, rHole); +// +// if (gkConstructCones) { +// // upstream +// TGeoRotation* coneRot31 = new TGeoRotation; +// coneRot31->RotateZ(90); +// coneRot31->RotateY(180); +// // TGeoCombiTrans* conePosRot31 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.3-gkLadderGapZ/2., coneRot31); +// TGeoCombiTrans* conePosRot31 = new TGeoCombiTrans(name+"conePosRot2", 0., 0., -coneDz-0.285-gkLadderGapZ/2., coneRot31); +// station03->AddNode(coneBigVolum, 1, conePosRot31); +// +// // downstream +// TGeoRotation* coneRot32 = new TGeoRotation; +// coneRot32->RotateZ(90); +// // TGeoCombiTrans* conePosRot32 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.3+gkLadderGapZ/2., coneRot32); +// TGeoCombiTrans* conePosRot32 = new TGeoCombiTrans(name+"conePosRot1", 0., 0., coneDz+0.285+gkLadderGapZ/2., coneRot32); +// station03->AddNode(coneBigVolum, 2, conePosRot32); +// +// station03->GetShape()->ComputeBBox(); +// } +// +// 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 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 = 2; // 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[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(); + } + cout << endl; + CheckVolume(sts); + // -------------------------------------------------------------------------- + + + + + // --------------- Finish ----------------------------------------------- + TGeoTranslation* stsTrans = new TGeoTranslation(0., 0., stsPosZ); + 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"); + top->Write(); + cout << endl; + cout << "Geometry " << top->GetName() << " written to " + << geoFileName << endl; + geoFile->Close(); + + TString geoFileName_ = "sts_"; + geoFileName_ = geoFileName_ + geoTag + "_geo.root"; + + geoFile = new TFile(geoFileName_, "RECREATE"); + gGeoMan->Write(); // use this is you want GeoManager format in the output + geoFile->Close(); + + TString geoFileName__ = "sts_"; + geoFileName_ = geoFileName__ + geoTag + "-geo.root"; + sts->Export(geoFileName_); + + geoFile = new TFile(geoFileName_, "UPDATE"); + stsTrans->Write(); + geoFile->Close(); + + top->Draw("ogl"); + gGeoManager->SetVisLevel(6); + + infoFile.close(); + +} +// ============================================================================ +// ====== 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; +} +/** ======================================================================= **/ + + + + +/** =========================================================================== + ** 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 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 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 12: 10 sectors, type 5 4 3 3 3 3 3 3 4 5 + nSectors = 5; + sectorTypes[0] = 3; + sectorTypes[1] = 3; + sectorTypes[2] = 3; + sectorTypes[3] = 4; + sectorTypes[4] = 5; + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + ladderY = 2. * shape->GetDY(); + halfLadderU = ConstructHalfLadder(12, "HalfLadder12u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(12, "HalfLadder12d", nSectors, sectorTypes, 'r'); + shape = (TGeoBBox*) halfLadderU->GetShape(); + ConstructLadder(12, halfLadderU, halfLadderD, shiftZ); + nLadders++; + + + // --- Ladder 13: 8 sectors, type 5 4 3 3 3 3 4 5 + nSectors = 4; + sectorTypes[0] = 3; + sectorTypes[1] = 3; + sectorTypes[2] = 4; + sectorTypes[3] = 5; + s0name = Form("Sector%02d", sectorTypes[0]); + s0vol = gGeoMan->GetVolume(s0name); + shape = (TGeoBBox*) s0vol->GetShape(); + shiftZ = 2. * shape->GetDZ() + gkSectorGapZ; + halfLadderU = ConstructHalfLadder(13, "HalfLadder13u", nSectors, sectorTypes, 'l'); + halfLadderD = ConstructHalfLadder(13, "HalfLadder13d", nSectors, sectorTypes, 'r'); + ConstructLadder(13, 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 + ladderY -= Double_t(nSectors-1) * gkSectorOverlapY; + // --- Add gaps in z direction + ladderZ += Double_t(nSectors-1) * gkSectorGapZ; + + + // --- Create and place modules + 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 + 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(); + yPosSect += 0.5 * sectorY - gkSectorOverlapY; + 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; + +// 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 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 == 10) && (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/macro/mcbm/geometry/targetbox/create_bpipe_geometry_v19g.C b/macro/mcbm/geometry/targetbox/create_bpipe_geometry_v19g.C new file mode 100644 index 00000000..08ce5601 --- /dev/null +++ b/macro/mcbm/geometry/targetbox/create_bpipe_geometry_v19g.C @@ -0,0 +1,571 @@ +/****************************************************************************** + ** Creation of beam pipe geometry in ROOT format (TGeo). + ** + ** @file create_bpipe_geometry_v19g.C + ** @author David Emschermann <d.emschermann@gsi.de> + ** @author Andrey Chernogorov <a.chernogorov@gsi.de> + ** @date 19.07.2016 + ** + ** mCBM + ** pipe v19g - based on v19f, without vacuum inside + ** pipe v19f - reproduce v19e in a single piece as originally in v19b + ** pipe v19e - extend the downstream end of the pipe to the beam dump for 2021 + ** pipe v19d - create two separate volumes, one with the targetbox the + ** other one with the pipe + ** pipe v19b - build target box from CAD design + ** pipe v19a - adapt dimensions of beampipe to technical drawings + ** pipe v18g - rotate 2-diameter beampipe v18f to 25 degrees + ** pipe v18f - increase pipe length from 3.00 m to 4.00 m + ** pipe v18f - reduce diameter of first 50 cm of beampipe to avoid collision with mSTS + ** pipe v18e - rotate cylindrical pipe around the vertical (y) axis by 20 degrees + ** pipe v18d - rotate cylindrical pipe around the vertical (y) axis by 25 degrees + ** + ** SIS-100 + ** pipe v16c_1e - is a pipe for the STS up to the interface to RICH at z = 1700 mm + ** with a (blue) flange at the downstream end of the STS box + ** + ** The beam pipe is composed of carbon with a fixed wall thickness of 0.5 or 1.0 mm. + ** It is placed directly into the cave as mother volume. The beam pipe consists of + ** few sections up to the RICH section (1700-3700mm), which is part of the RICH geometry. + ** Each section has a PCON shape (including windows). + ** The STS section is composed of cylinder D(z=220-410mm)=34mm and cone (z=410-1183mm). + ** All sections of the beam pipe with conical shape have half opening angle 2.5deg. + *****************************************************************************/ + +// dimensions from z = -38.0 cm to z = +59.8 cm +// dimensions of core [-29.9 cm .. +15.2 cm] +// dimensions of sections -38.0 cm | + 7.7 + 0.4 + 45.1 + 0.6 + 44.0 | +59.8 cm + +// naming scheme +// main elements - flanges +// pipe10 - pipe11 +// pipe20 - pipe21, 22, 23, 24, 25 +// pipe30 - pipe31 + + +#include <iomanip> +#include <iostream> +#include "TGeoManager.h" + +#include "TGeoPcon.h" +#include "TGeoTube.h" + +using namespace std; + +const Bool_t IncludeVacuum = false; // true; // true, if vacuum to be placed inside the pipe + +// ------------- Steering variables ----------------------------------- +// ---> Beam pipe material name +TString pipeMediumName = "iron"; // "carbon"; // "beryllium"; // "aluminium"; +// ---------------------------------------------------------------------------- + + +// ------------- Other global variables ----------------------------------- +// ---> Macro name to info file +TString macroname = "create_bpipe_geometry_v19g.C"; +// ---> Geometry file name (output) +TString rootFileName = "pipe_v19g_mcbm.geo.root"; +// ---> Geometry name +TString pipeName = "pipe_v19g"; +// ---------------------------------------------------------------------------- + +TGeoVolume* MakeCutPipe(Int_t ipart, TGeoMedium *medium, + Double_t rmin, Double_t rmax, Double_t dz, + Double_t angle1, Double_t angle2, + Double_t nlo1, Double_t nlo2, Double_t nlo3, + Double_t nhi1, Double_t nhi2, Double_t nhi3); + +//TGeoVolume* MakePipe(Int_t iPart, Int_t nSects, Double_t* z, Double_t* rin, +// Double_t* rout, TGeoMedium* medium, fstream* infoFile); +// +//TGeoVolume* MakeVacuum(Int_t iPart, Int_t nSects, Double_t* z, Double_t* rin, +// Double_t* rout, TGeoMedium* medium, fstream* infoFile); + +// ============================================================================ +// ====== Main function ===== +// ============================================================================ + +void create_bpipe_geometry_v19g() +{ + // ----- Define beam pipe sections -------------------------------------- + /** For v19g: **/ + TString pipe1name = "pipe1 - straight miniCBM beampipe"; + + // start and stop angles of beampipe + +// Double_t angle1 = 180; // lower half +// Double_t angle2 = 0; // lower half +// +// Double_t angle1 = 190; // open cut @ -x +// Double_t angle2 = 170; // open cut @ -x + + Double_t angle1 = 0; // closed + Double_t angle2 = 360; // closed + + Double_t nlow[3]; + nlow[0] = 0; + nlow[1] = 0; + nlow[2] = -1; + + Double_t theta = 25.*TMath::Pi()/180.; + Double_t phi = 180.*TMath::Pi()/180.; + + Double_t nhi[3]; + nhi[0] = TMath::Sin(theta)*TMath::Cos(phi); + nhi[1] = TMath::Sin(theta)*TMath::Sin(phi); + nhi[2] = TMath::Cos(theta); + + Double_t pipe_angle = 25.; // rotation angle around y-axis + + // tan (acos(-1)/180 * 2.5) * 30 cm = 1.310 cm + + cout << "1 - lx: " << nlow[0] << " ly: " << nlow[1] << " lz: " << nlow[2] << endl; + cout << "2 - hx: " << nhi[0] << " hy: " << nhi[1] << " hz: " << nhi[2] << endl; + + // end of thin beampipe in reality: 610 mm downstream of target + + // -------------------------------------------------------------------------- + + + // ------- Open info file ----------------------------------------------- + TString infoFileName = rootFileName; + infoFileName.ReplaceAll("root", "info"); + fstream infoFile; + fstream infoFileEmpty; + infoFile.open(infoFileName.Data(), fstream::out); + infoFile << "SIS-18 mCBM beam pipe geometry created with " + macroname << endl; + infoFile << "Introducing the target chamber derived from CAD drawings." << endl << endl; + // infoFile << "It ends at z=610 mm downstream of the target." << endl << endl; + infoFile << "The beam pipe is composed of iron with a varying wall thickness." << endl << endl; + infoFile << "Material: " << pipeMediumName << endl; + // -------------------------------------------------------------------------- + + + // ------- 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(); + TGeoManager* gGeoMan = gGeoManager; + // -------------------------------------------------------------------------- + + + + // ----------------- Get and create the required media ----------------- + FairGeoMedia* geoMedia = geoFace->getMedia(); + FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder(); + + // ---> pipe medium + FairGeoMedium* fPipeMedium = geoMedia->getMedium(pipeMediumName.Data()); + TString fairError = "FairMedium " + pipeMediumName + " not found"; + if ( ! fPipeMedium ) Fatal("Main", "%s", fairError.Data()); + geoBuild->createMedium(fPipeMedium); + TGeoMedium* pipeMedium = gGeoMan->GetMedium(pipeMediumName.Data()); + TString geoError = "Medium " + pipeMediumName + " not found"; + if ( ! pipeMedium ) Fatal("Main", "%s", geoError.Data()); + + // ---> iron + FairGeoMedium* mIron = geoMedia->getMedium("iron"); + if ( ! mIron ) Fatal("Main", "FairMedium iron not found"); + geoBuild->createMedium(mIron); + TGeoMedium* iron = gGeoMan->GetMedium("iron"); + if ( ! iron ) Fatal("Main", "Medium iron not found"); + +// // ---> lead +// FairGeoMedium* mLead = geoMedia->getMedium("lead"); +// if ( ! mLead ) Fatal("Main", "FairMedium lead not found"); +// geoBuild->createMedium(mLead); +// TGeoMedium* lead = gGeoMan->GetMedium("lead"); +// if ( ! lead ) Fatal("Main", "Medium lead 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"); + + // ---> vacuum + FairGeoMedium* mVacuum = geoMedia->getMedium("vacuum"); + if ( ! mVacuum ) Fatal("Main", "FairMedium vacuum not found"); + geoBuild->createMedium(mVacuum); + TGeoMedium* vacuum = gGeoMan->GetMedium("vacuum"); + if ( ! vacuum ) Fatal("Main", "Medium vacuum not found"); + // -------------------------------------------------------------------------- + + + + // -------------- Create geometry and top volume ------------------------- + gGeoMan = (TGeoManager*)gROOT->FindObject("FAIRGeom"); + gGeoMan->SetName("PIPEgeom"); + TGeoVolume* top = new TGeoVolumeAssembly("TOP"); + gGeoMan->SetTopVolume(top); + TGeoVolume* pipe = new TGeoVolumeAssembly(pipeName.Data()); + // -------------------------------------------------------------------------- + + + // ----- Create sections ------------------------------------------------- + Int_t i = 0; + + // Aussendurchmesser 35.56 cm + // Wanddicke 0.3 cm + // Laenge 45.1 cm + // Offset 29.9 cm + + Double_t rmax20 = 35.56/2.; + Double_t rmin20 = rmax20 - 0.3; + Double_t length20 = 45.1; + Double_t offset20 = 29.9; + + TGeoVolume *vpipe20 = gGeoManager->MakeCtub("pipe20", pipeMedium, rmin20, rmax20, length20/2., angle1, angle2, nlow[0], nlow[1], nlow[2], nhi[0], nhi[1], nhi[2]); + TGeoTranslation* tra20 = new TGeoTranslation("tra20", 0, 0, -offset20 +length20/2.); + vpipe20->SetLineColor(kBlue); + pipe->AddNode(vpipe20, 1, tra20); + + TGeoVolume *vvacu20 = gGeoManager->MakeCtub("vacu20", vacuum, 0, rmin20, length20/2., angle1, angle2, nlow[0], nlow[1], nlow[2], nhi[0], nhi[1], nhi[2]); + vvacu20->SetLineColor(kYellow); + vvacu20->SetTransparency(50); + if(IncludeVacuum) + pipe->AddNode(vvacu20, 1, tra20); + + // upstream cover + Double_t rmax21 = rmax20; + Double_t rmin21 = 15.9 /2.; + Double_t length21 = 0.4; + + TGeoVolume *vwall21 = gGeoManager->MakeCtub("wall21", pipeMedium, rmin21, rmax21, length21/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + TGeoTranslation* tra21 = new TGeoTranslation("tra21", 0, 0, -offset20 -length21/2.); + vwall21->SetLineColor(kBlue); + pipe->AddNode(vwall21, 1, tra21); + +//======================================================================================= + + // downstream cover with cutout + Double_t rmax22 = rmax20; + Double_t rmin22 = 5.4 /2.; + Double_t length22 = 0.6 / cos(25.*acos(-1.)/180.); // compensate for 25 degree rotation + + TGeoCtub *cdown = new TGeoCtub(rmin22, rmax22, length22/2., angle1, angle2, + -nhi[0],-nhi[1],-nhi[2], nhi[0], nhi[1], nhi[2]); + cdown->SetName("O"); // shapes need names too + + TGeoBBox *box22 = new TGeoBBox(11.5/2., 10.0/2., 2.0/2.); + box22->SetName("A"); // shapes need names too + + TGeoTranslation* tcut1 = new TGeoTranslation("tcut1", -10.0, 0., 0.); + tcut1->RegisterYourself(); + + Double_t fthick22 = 0.6; + TGeoBBox *frame22 = new TGeoBBox(13.9/2., 12.4/2., fthick22/2.); + frame22->SetName("F"); // shapes need names too + + TGeoTranslation* tfra1 = new TGeoTranslation("tfra1", -10.0, 0., fthick22-0.0001); // 0.0001 avoids optical error + tfra1->RegisterYourself(); + + // kapton foil frame dimensions - inner dimensions - frame width + // x/y/z - 13.9/12.4/0.6 cm - 11.5/10.0 cm - 1.2 cm + + // corner of pipe at + // x = -2.70 + // z = 14.54 = tan(25.*acos(-1.)/180.) * -5.4/2. + 15.8 + + // corner of frame towards beampipe + // x = -3.74 + // z = 14.06 + // distance = sqrt( 1.04 * 1.04 + 0.48 * 0.48 ) = 1.14 cm + + // rotate clockwise + TGeoRotation* rot22 = new TGeoRotation(); + rot22->RotateY(-25.); + TGeoCombiTrans* frot22 = new TGeoCombiTrans("frot22", 0, 0, 0, rot22); + frot22->RegisterYourself(); + + // rotate counter clockwise + TGeoRotation* back22 = new TGeoRotation(); + back22->RotateY(+25.); + TGeoCombiTrans* brot22 = new TGeoCombiTrans("brot22", 0, 0, 0, back22); + brot22->RegisterYourself(); + + // TGeoCombiTrans* tcut = new TGeoCombiTrans("tcut", + // cos(25.*acos(-1.)/180.) * -10.0, 0., sin(25.*acos(-1.)/180.) * -10.0, rot22); + // tcut->RegisterYourself(); + + // cutout inner border at: + // x : cos(25.*acos(-1.)/180.) * -4.25 : x = -3.852 cm + // z : sin(25.*acos(-1.)/180.) * -4.25 + 15.2 + 0.3 : z = 13.704 cm + + // cutout outer border at: + // x : cos(25.*acos(-1.)/180.) * -15.75 : x = -14.274 cm + // z : sin(25.*acos(-1.)/180.) * -15.75 + 15.2 + 0.3 : z = 8.843 cm + + // TGeoCompositeShape *compsha = new TGeoCompositeShape("compsha", "O - A:tcut"); + // TGeoVolume *vpipe22 = new TGeoVolume("wall22", compsha, pipeMedium); + // TGeoTranslation* tra22 = new TGeoTranslation("tra22", 0, 0, -offset20 +length20 +length22/2.); + + TGeoCompositeShape *compsha = new TGeoCompositeShape("compsha", "O:brot22 + F:tfra1 - A:tcut1"); + TGeoVolume *vpipe22 = new TGeoVolume("wall22", compsha, pipeMedium); + TGeoCombiTrans* tra22 = new TGeoCombiTrans("tra22", 0, 0, -offset20 +length20 +length22/2., rot22); + vpipe22->SetLineColor(kBlue); + pipe->AddNode(vpipe22, 1, tra22); + +//======================================================================================= + + // vertical tubes + Double_t height23 = 28.0 - 17.8; + TGeoRotation* rot23 = new TGeoRotation(); + rot23->RotateX(90.); + + // target tube + TGeoVolume *tube23 = gGeoManager->MakeTube("shaft23", pipeMedium, 10.4/2., 10.8/2., height23/2.); + TGeoCombiTrans* tra23 = new TGeoCombiTrans("tra23", 0, 28.0-height23/2., 0, rot23); + tube23->SetLineColor(kBlue); + pipe->AddNode(tube23, 1, tra23); + + // diamond tube + TGeoVolume *tube24 = gGeoManager->MakeTube("shaft24", pipeMedium, 10.4/2., 10.8/2., height23/2.); + TGeoCombiTrans* tra24 = new TGeoCombiTrans("tra24", 0, 28.0-height23/2., -20.0, rot23); + tube24->SetLineColor(kBlue); + pipe->AddNode(tube24, 1, tra24); + +//======================================================================================= + + // upstream pipe + Double_t rmax10 = 15.9 /2.; + Double_t rmin10 = rmax10 - 0.2; + Double_t length10 = 7.7 + length21; + + TGeoVolume *vpipe10 = gGeoManager->MakeCtub("pipe10", pipeMedium, rmin10, rmax10, length10/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + TGeoTranslation* tra10 = new TGeoTranslation("tra10", 0, 0, -offset20 -length10/2.); + vpipe10->SetLineColor(kBlue); + pipe->AddNode(vpipe10, 1, tra10); + + TGeoVolume *vvacu10 = gGeoManager->MakeCtub("vacu10", vacuum, 0, rmin10, length10/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + vvacu10->SetLineColor(kYellow); + if(IncludeVacuum) + pipe->AddNode(vvacu10, 1, tra10); + + // upstream flange + // size of flange + // Diameter 19.9 cm + // Thickness 1.8 cm + + Double_t rmax11 = 19.9 /2.; + Double_t rmin11 = rmax10; + Double_t length11 = 1.8; + + TGeoVolume *vfla11 = gGeoManager->MakeCtub("flange11", pipeMedium, rmin11, rmax11, length11/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + TGeoTranslation* tra11 = new TGeoTranslation("tra11", 0, 0, -offset20-length10+length11/2.); + vfla11->SetLineColor(kBlue); + pipe->AddNode(vfla11, 1, tra11); + +//======================================================================================= + + // Laenge 44.0 cm + // Durchmesser 5.4 cm + // Wanddicke 0.2 cm + + // downstream pipe + Double_t rmax30 = 5.4 /2.; + Double_t rmin30 = rmax30-0.2; + Double_t length30 = 44.0+0.6; + + TGeoVolume *vpipe30 = gGeoManager->MakeCtub("pipe30", pipeMedium, rmin30, rmax30, length30/2., angle1, angle2, -nhi[0],-nhi[1],-nhi[2],-nlow[0],-nlow[1],-nlow[2]); + TGeoTranslation* tra30 = new TGeoTranslation("tra30", 0, 0, -offset20 +length20 +length30/2.); + vpipe30->SetLineColor(kBlue); + pipe->AddNode(vpipe30, 1, tra30); + + TGeoVolume *vvacu30 = gGeoManager->MakeCtub("vacu30", vacuum, 0, rmin30, length30/2., angle1, angle2, -nhi[0],-nhi[1],-nhi[2],-nlow[0],-nlow[1],-nlow[2]); + vvacu30->SetLineColor(kYellow); + if(IncludeVacuum) + pipe->AddNode(vvacu30, 1, tra30); + + // size of flange + // Thickness 1.8 cm + // Diameter 11.4 cm + + Double_t rmax40 = 11.4 /2.; + Double_t rmin40 = rmax30; + Double_t length40 = 1.8; + + // downstream flange + TGeoVolume *vfla31 = gGeoManager->MakeCtub("flange31", pipeMedium, rmin40, rmax40, length40/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + TGeoTranslation* fla31 = new TGeoTranslation("fla31", 0, 0, -offset20 +length20 +length30 -length40/2.); + vfla31->SetLineColor(kBlue); + pipe->AddNode(vfla31, 1, fla31); + +//======================================================================================= + + // Laenge 300.0 cm + // Durchmesser 10.0 cm + // Wanddicke 0.2 cm + + // downstream pipe + Double_t rmax50 = 10.0 /2.; + Double_t rmin50 = rmax50-0.2; + Double_t length50 = 300.0; // 44.0; + + // 2nd downstream flange + TGeoVolume *vfla32 = gGeoManager->MakeCtub("flange32", pipeMedium, rmax50, rmax40, length40/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + TGeoTranslation* fla32 = new TGeoTranslation("fla32", 0., 0., -offset20 +length20 +length30 +length40/2.); + // TGeoTranslation* fla32 = new TGeoTranslation("fla32", 0., 0., -offset20 +length20 +length30 +length40/2. + 20.); + vfla32->SetLineColor(kRed); + pipe->AddNode(vfla32, 1, fla32); + + TGeoVolume *vpipe50 = gGeoManager->MakeCtub("pipe50", pipeMedium, rmin50, rmax50, length50/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + TGeoTranslation* fla50 = new TGeoTranslation("fla50", 0., 0., -offset20 +length20 +length30 +length50/2.); + // TGeoTranslation* fla50 = new TGeoTranslation("fla50", 0., 0., -offset20 +length20 +length30 +length50/2. + 20.); + vpipe50->SetLineColor(kRed); + pipe->AddNode(vpipe50, 1, fla50); + + TGeoVolume *vvacu50 = gGeoManager->MakeCtub("vacu50", vacuum, 0, rmin50, length50/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + vvacu50->SetLineColor(kYellow); + if(IncludeVacuum) + pipe->AddNode(vvacu50, 1, fla50); + + +//======================================================================================= + +// infoFile << endl << "Beam pipe section: " << pipe1name << endl; +// infoFile << setw(2) << "i" << setw(10) << "Z,mm" << setw(10) << "Rin,mm" << setw(10) << "Rout,mm" << setw(10) << "h,mm" << endl; +// TGeoVolume* pipe1 = MakePipe (1, nSects1, z1, rin1, rout1, pipeMedium, &infoFile); +// pipe1->SetLineColor(kYellow); +// // pipe1->SetLineColor(kGray); +// pipe->AddNode(pipe1, 0); +// +// TGeoVolume* pipevac1 = MakeVacuum(1, nSects01, z01, rin01, rout01, vacuum, &infoFile); +// pipevac1->SetLineColor(kCyan); +// pipe->AddNode(pipevac1, 0); + + // ----- End -------------------------------------------------- + + // --------------- Finish ----------------------------------------------- + top->AddNode(pipe, 1); + cout << endl << endl; + gGeoMan->CloseGeometry(); + gGeoManager->SetNsegments(80); + gGeoMan->CheckOverlaps(0.0001); + gGeoMan->PrintOverlaps(); + gGeoMan->Test(); + + pipe->Export(rootFileName); + + // TFile* rootFile = new TFile(rootFileName, "RECREATE"); + // top->Write(); + + TFile* rootFile = new TFile(rootFileName, "UPDATE"); + + // rotate the PIPE around y + TGeoRotation* pipe_rotation = new TGeoRotation(); + pipe_rotation->RotateY( pipe_angle ); + // TGeoCombiTrans* pipe_placement = new TGeoCombiTrans( sin( pipe_angle/180.*acos(-1) ) * z1[1]/2., 0., 0., pipe_rotation); + TGeoCombiTrans* pipe_placement = new TGeoCombiTrans("pipe_rot", 0., 0., 0, pipe_rotation); + pipe_placement->Write(); + + rootFile->Close(); + + cout << endl; + cout << "Geometry " << top->GetName() << " written to " + << rootFileName << endl; + + infoFile.close(); + + // visualize it with ray tracing, OGL/X3D viewer + //top->Raytrace(); + top->Draw("ogl"); + //top->Draw("x3d"); + + +} +// ============================================================================ +// ====== End of main function ===== +// ============================================================================ + + +//// ===== Make the beam pipe volume ========================================= +//TGeoPcon* MakeShape(Int_t nSects, char* name, Double_t* z, Double_t* rin, +// Double_t* rout, fstream* infoFile) { +// +// // ---> Shape +// TGeoPcon* shape = new TGeoPcon(name, 0., 360., nSects); +// for (Int_t iSect = 0; iSect < nSects; iSect++) { +// shape->DefineSection(iSect, z[iSect]/10., rin[iSect]/10., rout[iSect]/10.); // mm->cm +// *infoFile << setw(2) << iSect+1 +// << setw(10) << fixed << setprecision(2) << z[iSect] +// << setw(10) << fixed << setprecision(2) << rin[iSect] +// << setw(10) << fixed << setprecision(2) << rout[iSect] +// << setw(10) << fixed << setprecision(2) << rout[iSect]-rin[iSect] << endl; +// } +// +// return shape; +// +//} +// ============================================================================ + + + +// ===== Make the beam pipe volume ========================================= +TGeoVolume* MakeCutPipe(Int_t ipart, TGeoMedium *medium, + Double_t rmin, Double_t rmax, Double_t dz, + Double_t angle1, Double_t angle2, + Double_t nlo1, Double_t nlo2, Double_t nlo3, + Double_t nhi1, Double_t nhi2, Double_t nhi3) { + + // ---> Shape + TString volName = Form("part%i", ipart); + TGeoCtub* shape = new TGeoCtub(volName.Data(), rmin, rmax, dz, angle1, angle2, nlo1, nlo2, nlo3, nhi1, nhi2, nhi3); + + // ---> Volume + TGeoVolume* pipe = new TGeoVolume(volName.Data(), shape, medium); + + return pipe; +} +// ============================================================================ + + + +// // ===== Make the beam pipe volume ========================================= +// TGeoVolume* MakePipe(Int_t iPart, Int_t nSects, Double_t* z, Double_t* rin, +// Double_t* rout, TGeoMedium* medium, fstream* infoFile) { +// +// // ---> Shape +// TString volName = Form("pipe%i", iPart); +// TGeoPcon* shape = new TGeoPcon(volName.Data(), 0., 360., nSects); +// for (Int_t iSect = 0; iSect < nSects; iSect++) { +// shape->DefineSection(iSect, z[iSect]/10., rin[iSect]/10., rout[iSect]/10.); // mm->cm +// *infoFile << setw(2) << iSect+1 +// << setw(10) << fixed << setprecision(2) << z[iSect] +// << setw(10) << fixed << setprecision(2) << rin[iSect] +// << setw(10) << fixed << setprecision(2) << rout[iSect] +// << setw(10) << fixed << setprecision(2) << rout[iSect]-rin[iSect] << endl; +// } +// +// // ---> Volume +// TGeoVolume* pipe = new TGeoVolume(volName.Data(), shape, medium); +// +// return pipe; +// +// } +// // ============================================================================ +// +// +// +// // ===== Make the volume for the vacuum inside the beam pipe ============== +// TGeoVolume* MakeVacuum(Int_t iPart, Int_t nSects, Double_t* z, Double_t* rin, +// Double_t* rout, TGeoMedium* medium, fstream* infoFile) { +// +// // ---> Shape +// TString volName = Form("pipevac%i", iPart); +// TGeoPcon* shape = new TGeoPcon(volName.Data(), 0., 360., nSects); +// for (Int_t iSect = 0; iSect < nSects; iSect++) { +// shape->DefineSection(iSect, z[iSect]/10., rin[iSect]/10., rout[iSect]/10.); // mm->cm +// } +// +// // ---> Volume +// TGeoVolume* pipevac = new TGeoVolume(volName.Data(), shape, medium); +// +// return pipevac; +// +// } +// // ============================================================================ diff --git a/macro/mcbm/geometry/targetbox/create_bpipe_geometry_v19h.C b/macro/mcbm/geometry/targetbox/create_bpipe_geometry_v19h.C new file mode 100644 index 00000000..1712928e --- /dev/null +++ b/macro/mcbm/geometry/targetbox/create_bpipe_geometry_v19h.C @@ -0,0 +1,574 @@ +/****************************************************************************** + ** Creation of beam pipe geometry in ROOT format (TGeo). + ** + ** @file create_bpipe_geometry_v19h.C + ** @author David Emschermann <d.emschermann@gsi.de> + ** @author Andrey Chernogorov <a.chernogorov@gsi.de> + ** @date 19.07.2016 + ** + ** mCBM + ** pipe v19h - based on v19g, removing the downstream plate and window of the targetbox + ** pipe v19g - based on v19f, without vacuum inside + ** pipe v19f - reproduce v19e in a single piece as originally in v19b + ** pipe v19e - extend the downstream end of the pipe to the beam dump for 2021 + ** pipe v19d - create two separate volumes, one with the targetbox the + ** other one with the pipe + ** pipe v19b - build target box from CAD design + ** pipe v19a - adapt dimensions of beampipe to technical drawings + ** pipe v18g - rotate 2-diameter beampipe v18f to 25 degrees + ** pipe v18f - increase pipe length from 3.00 m to 4.00 m + ** pipe v18f - reduce diameter of first 50 cm of beampipe to avoid collision with mSTS + ** pipe v18e - rotate cylindrical pipe around the vertical (y) axis by 20 degrees + ** pipe v18d - rotate cylindrical pipe around the vertical (y) axis by 25 degrees + ** + ** SIS-100 + ** pipe v16c_1e - is a pipe for the STS up to the interface to RICH at z = 1700 mm + ** with a (blue) flange at the downstream end of the STS box + ** + ** The beam pipe is composed of carbon with a fixed wall thickness of 0.5 or 1.0 mm. + ** It is placed directly into the cave as mother volume. The beam pipe consists of + ** few sections up to the RICH section (1700-3700mm), which is part of the RICH geometry. + ** Each section has a PCON shape (including windows). + ** The STS section is composed of cylinder D(z=220-410mm)=34mm and cone (z=410-1183mm). + ** All sections of the beam pipe with conical shape have half opening angle 2.5deg. + *****************************************************************************/ + +// dimensions from z = -38.0 cm to z = +59.8 cm +// dimensions of core [-29.9 cm .. +15.2 cm] +// dimensions of sections -38.0 cm | + 7.7 + 0.4 + 45.1 + 0.6 + 44.0 | +59.8 cm + +// naming scheme +// main elements - flanges +// pipe10 - pipe11 +// pipe20 - pipe21, 22, 23, 24, 25 +// pipe30 - pipe31 + + +#include <iomanip> +#include <iostream> +#include "TGeoManager.h" + +#include "TGeoPcon.h" +#include "TGeoTube.h" + +using namespace std; + +const Bool_t IncludeVacuum = false; // true; // true, if vacuum to be placed inside the pipe +const Bool_t IncludeDownstreamCover = false; // true; // true, if downstream cover with cutout to be placed + +// ------------- Steering variables ----------------------------------- +// ---> Beam pipe material name +TString pipeMediumName = "iron"; // "carbon"; // "beryllium"; // "aluminium"; +// ---------------------------------------------------------------------------- + + +// ------------- Other global variables ----------------------------------- +// ---> Macro name to info file +TString macroname = "create_bpipe_geometry_v19h.C"; +// ---> Geometry file name (output) +TString rootFileName = "pipe_v19h_mcbm.geo.root"; +// ---> Geometry name +TString pipeName = "pipe_v19h"; +// ---------------------------------------------------------------------------- + +TGeoVolume* MakeCutPipe(Int_t ipart, TGeoMedium *medium, + Double_t rmin, Double_t rmax, Double_t dz, + Double_t angle1, Double_t angle2, + Double_t nlo1, Double_t nlo2, Double_t nlo3, + Double_t nhi1, Double_t nhi2, Double_t nhi3); + +//TGeoVolume* MakePipe(Int_t iPart, Int_t nSects, Double_t* z, Double_t* rin, +// Double_t* rout, TGeoMedium* medium, fstream* infoFile); +// +//TGeoVolume* MakeVacuum(Int_t iPart, Int_t nSects, Double_t* z, Double_t* rin, +// Double_t* rout, TGeoMedium* medium, fstream* infoFile); + +// ============================================================================ +// ====== Main function ===== +// ============================================================================ + +void create_bpipe_geometry_v19h() +{ + // ----- Define beam pipe sections -------------------------------------- + /** For v19h: **/ + TString pipe1name = "pipe1 - straight miniCBM beampipe"; + + // start and stop angles of beampipe + +// Double_t angle1 = 180; // lower half +// Double_t angle2 = 0; // lower half +// +// Double_t angle1 = 190; // open cut @ -x +// Double_t angle2 = 170; // open cut @ -x + + Double_t angle1 = 0; // closed + Double_t angle2 = 360; // closed + + Double_t nlow[3]; + nlow[0] = 0; + nlow[1] = 0; + nlow[2] = -1; + + Double_t theta = 25.*TMath::Pi()/180.; + Double_t phi = 180.*TMath::Pi()/180.; + + Double_t nhi[3]; + nhi[0] = TMath::Sin(theta)*TMath::Cos(phi); + nhi[1] = TMath::Sin(theta)*TMath::Sin(phi); + nhi[2] = TMath::Cos(theta); + + Double_t pipe_angle = 25.; // rotation angle around y-axis + + // tan (acos(-1)/180 * 2.5) * 30 cm = 1.310 cm + + cout << "1 - lx: " << nlow[0] << " ly: " << nlow[1] << " lz: " << nlow[2] << endl; + cout << "2 - hx: " << nhi[0] << " hy: " << nhi[1] << " hz: " << nhi[2] << endl; + + // end of thin beampipe in reality: 610 mm downstream of target + + // -------------------------------------------------------------------------- + + + // ------- Open info file ----------------------------------------------- + TString infoFileName = rootFileName; + infoFileName.ReplaceAll("root", "info"); + fstream infoFile; + fstream infoFileEmpty; + infoFile.open(infoFileName.Data(), fstream::out); + infoFile << "SIS-18 mCBM beam pipe geometry created with " + macroname << endl; + infoFile << "Introducing the target chamber derived from CAD drawings." << endl << endl; + // infoFile << "It ends at z=610 mm downstream of the target." << endl << endl; + infoFile << "The beam pipe is composed of iron with a varying wall thickness." << endl << endl; + infoFile << "Material: " << pipeMediumName << endl; + // -------------------------------------------------------------------------- + + + // ------- 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(); + TGeoManager* gGeoMan = gGeoManager; + // -------------------------------------------------------------------------- + + + + // ----------------- Get and create the required media ----------------- + FairGeoMedia* geoMedia = geoFace->getMedia(); + FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder(); + + // ---> pipe medium + FairGeoMedium* fPipeMedium = geoMedia->getMedium(pipeMediumName.Data()); + TString fairError = "FairMedium " + pipeMediumName + " not found"; + if ( ! fPipeMedium ) Fatal("Main", "%s", fairError.Data()); + geoBuild->createMedium(fPipeMedium); + TGeoMedium* pipeMedium = gGeoMan->GetMedium(pipeMediumName.Data()); + TString geoError = "Medium " + pipeMediumName + " not found"; + if ( ! pipeMedium ) Fatal("Main", "%s", geoError.Data()); + + // ---> iron + FairGeoMedium* mIron = geoMedia->getMedium("iron"); + if ( ! mIron ) Fatal("Main", "FairMedium iron not found"); + geoBuild->createMedium(mIron); + TGeoMedium* iron = gGeoMan->GetMedium("iron"); + if ( ! iron ) Fatal("Main", "Medium iron not found"); + +// // ---> lead +// FairGeoMedium* mLead = geoMedia->getMedium("lead"); +// if ( ! mLead ) Fatal("Main", "FairMedium lead not found"); +// geoBuild->createMedium(mLead); +// TGeoMedium* lead = gGeoMan->GetMedium("lead"); +// if ( ! lead ) Fatal("Main", "Medium lead 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"); + + // ---> vacuum + FairGeoMedium* mVacuum = geoMedia->getMedium("vacuum"); + if ( ! mVacuum ) Fatal("Main", "FairMedium vacuum not found"); + geoBuild->createMedium(mVacuum); + TGeoMedium* vacuum = gGeoMan->GetMedium("vacuum"); + if ( ! vacuum ) Fatal("Main", "Medium vacuum not found"); + // -------------------------------------------------------------------------- + + + + // -------------- Create geometry and top volume ------------------------- + gGeoMan = (TGeoManager*)gROOT->FindObject("FAIRGeom"); + gGeoMan->SetName("PIPEgeom"); + TGeoVolume* top = new TGeoVolumeAssembly("TOP"); + gGeoMan->SetTopVolume(top); + TGeoVolume* pipe = new TGeoVolumeAssembly(pipeName.Data()); + // -------------------------------------------------------------------------- + + + // ----- Create sections ------------------------------------------------- + Int_t i = 0; + + // Aussendurchmesser 35.56 cm + // Wanddicke 0.3 cm + // Laenge 45.1 cm + // Offset 29.9 cm + + Double_t rmax20 = 35.56/2.; + Double_t rmin20 = rmax20 - 0.3; + Double_t length20 = 45.1; + Double_t offset20 = 29.9; + + TGeoVolume *vpipe20 = gGeoManager->MakeCtub("pipe20", pipeMedium, rmin20, rmax20, length20/2., angle1, angle2, nlow[0], nlow[1], nlow[2], nhi[0], nhi[1], nhi[2]); + TGeoTranslation* tra20 = new TGeoTranslation("tra20", 0, 0, -offset20 +length20/2.); + vpipe20->SetLineColor(kBlue); + pipe->AddNode(vpipe20, 1, tra20); + + TGeoVolume *vvacu20 = gGeoManager->MakeCtub("vacu20", vacuum, 0, rmin20, length20/2., angle1, angle2, nlow[0], nlow[1], nlow[2], nhi[0], nhi[1], nhi[2]); + vvacu20->SetLineColor(kYellow); + vvacu20->SetTransparency(50); + if(IncludeVacuum) + pipe->AddNode(vvacu20, 1, tra20); + + // upstream cover + Double_t rmax21 = rmax20; + Double_t rmin21 = 15.9 /2.; + Double_t length21 = 0.4; + + TGeoVolume *vwall21 = gGeoManager->MakeCtub("wall21", pipeMedium, rmin21, rmax21, length21/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + TGeoTranslation* tra21 = new TGeoTranslation("tra21", 0, 0, -offset20 -length21/2.); + vwall21->SetLineColor(kBlue); + pipe->AddNode(vwall21, 1, tra21); + +//======================================================================================= + + // downstream cover with cutout + Double_t rmax22 = rmax20; + Double_t rmin22 = 5.4 /2.; + Double_t length22 = 0.6 / cos(25.*acos(-1.)/180.); // compensate for 25 degree rotation + + TGeoCtub *cdown = new TGeoCtub(rmin22, rmax22, length22/2., angle1, angle2, + -nhi[0],-nhi[1],-nhi[2], nhi[0], nhi[1], nhi[2]); + cdown->SetName("O"); // shapes need names too + + TGeoBBox *box22 = new TGeoBBox(11.5/2., 10.0/2., 2.0/2.); + box22->SetName("A"); // shapes need names too + + TGeoTranslation* tcut1 = new TGeoTranslation("tcut1", -10.0, 0., 0.); + tcut1->RegisterYourself(); + + Double_t fthick22 = 0.6; + TGeoBBox *frame22 = new TGeoBBox(13.9/2., 12.4/2., fthick22/2.); + frame22->SetName("F"); // shapes need names too + + TGeoTranslation* tfra1 = new TGeoTranslation("tfra1", -10.0, 0., fthick22-0.0001); // 0.0001 avoids optical error + tfra1->RegisterYourself(); + + // kapton foil frame dimensions - inner dimensions - frame width + // x/y/z - 13.9/12.4/0.6 cm - 11.5/10.0 cm - 1.2 cm + + // corner of pipe at + // x = -2.70 + // z = 14.54 = tan(25.*acos(-1.)/180.) * -5.4/2. + 15.8 + + // corner of frame towards beampipe + // x = -3.74 + // z = 14.06 + // distance = sqrt( 1.04 * 1.04 + 0.48 * 0.48 ) = 1.14 cm + + // rotate clockwise + TGeoRotation* rot22 = new TGeoRotation(); + rot22->RotateY(-25.); + TGeoCombiTrans* frot22 = new TGeoCombiTrans("frot22", 0, 0, 0, rot22); + frot22->RegisterYourself(); + + // rotate counter clockwise + TGeoRotation* back22 = new TGeoRotation(); + back22->RotateY(+25.); + TGeoCombiTrans* brot22 = new TGeoCombiTrans("brot22", 0, 0, 0, back22); + brot22->RegisterYourself(); + + // TGeoCombiTrans* tcut = new TGeoCombiTrans("tcut", + // cos(25.*acos(-1.)/180.) * -10.0, 0., sin(25.*acos(-1.)/180.) * -10.0, rot22); + // tcut->RegisterYourself(); + + // cutout inner border at: + // x : cos(25.*acos(-1.)/180.) * -4.25 : x = -3.852 cm + // z : sin(25.*acos(-1.)/180.) * -4.25 + 15.2 + 0.3 : z = 13.704 cm + + // cutout outer border at: + // x : cos(25.*acos(-1.)/180.) * -15.75 : x = -14.274 cm + // z : sin(25.*acos(-1.)/180.) * -15.75 + 15.2 + 0.3 : z = 8.843 cm + + // TGeoCompositeShape *compsha = new TGeoCompositeShape("compsha", "O - A:tcut"); + // TGeoVolume *vpipe22 = new TGeoVolume("wall22", compsha, pipeMedium); + // TGeoTranslation* tra22 = new TGeoTranslation("tra22", 0, 0, -offset20 +length20 +length22/2.); + + TGeoCompositeShape *compsha = new TGeoCompositeShape("compsha", "O:brot22 + F:tfra1 - A:tcut1"); + TGeoVolume *vpipe22 = new TGeoVolume("wall22", compsha, pipeMedium); + TGeoCombiTrans* tra22 = new TGeoCombiTrans("tra22", 0, 0, -offset20 +length20 +length22/2., rot22); + vpipe22->SetLineColor(kBlue); + if(IncludeDownstreamCover) + pipe->AddNode(vpipe22, 1, tra22); + +//======================================================================================= + + // vertical tubes + Double_t height23 = 28.0 - 17.8; + TGeoRotation* rot23 = new TGeoRotation(); + rot23->RotateX(90.); + + // target tube + TGeoVolume *tube23 = gGeoManager->MakeTube("shaft23", pipeMedium, 10.4/2., 10.8/2., height23/2.); + TGeoCombiTrans* tra23 = new TGeoCombiTrans("tra23", 0, 28.0-height23/2., 0, rot23); + tube23->SetLineColor(kBlue); + pipe->AddNode(tube23, 1, tra23); + + // diamond tube + TGeoVolume *tube24 = gGeoManager->MakeTube("shaft24", pipeMedium, 10.4/2., 10.8/2., height23/2.); + TGeoCombiTrans* tra24 = new TGeoCombiTrans("tra24", 0, 28.0-height23/2., -20.0, rot23); + tube24->SetLineColor(kBlue); + pipe->AddNode(tube24, 1, tra24); + +//======================================================================================= + + // upstream pipe + Double_t rmax10 = 15.9 /2.; + Double_t rmin10 = rmax10 - 0.2; + Double_t length10 = 7.7 + length21; + + TGeoVolume *vpipe10 = gGeoManager->MakeCtub("pipe10", pipeMedium, rmin10, rmax10, length10/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + TGeoTranslation* tra10 = new TGeoTranslation("tra10", 0, 0, -offset20 -length10/2.); + vpipe10->SetLineColor(kBlue); + pipe->AddNode(vpipe10, 1, tra10); + + TGeoVolume *vvacu10 = gGeoManager->MakeCtub("vacu10", vacuum, 0, rmin10, length10/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + vvacu10->SetLineColor(kYellow); + if(IncludeVacuum) + pipe->AddNode(vvacu10, 1, tra10); + + // upstream flange + // size of flange + // Diameter 19.9 cm + // Thickness 1.8 cm + + Double_t rmax11 = 19.9 /2.; + Double_t rmin11 = rmax10; + Double_t length11 = 1.8; + + TGeoVolume *vfla11 = gGeoManager->MakeCtub("flange11", pipeMedium, rmin11, rmax11, length11/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + TGeoTranslation* tra11 = new TGeoTranslation("tra11", 0, 0, -offset20-length10+length11/2.); + vfla11->SetLineColor(kBlue); + pipe->AddNode(vfla11, 1, tra11); + +//======================================================================================= + + // Laenge 44.0 cm + // Durchmesser 5.4 cm + // Wanddicke 0.2 cm + + // downstream pipe + Double_t rmax30 = 5.4 /2.; + Double_t rmin30 = rmax30-0.2; + Double_t length30 = 44.0+0.6; + + TGeoVolume *vpipe30 = gGeoManager->MakeCtub("pipe30", pipeMedium, rmin30, rmax30, length30/2., angle1, angle2, -nhi[0],-nhi[1],-nhi[2],-nlow[0],-nlow[1],-nlow[2]); + TGeoTranslation* tra30 = new TGeoTranslation("tra30", 0, 0, -offset20 +length20 +length30/2.); + vpipe30->SetLineColor(kBlue); + pipe->AddNode(vpipe30, 1, tra30); + + TGeoVolume *vvacu30 = gGeoManager->MakeCtub("vacu30", vacuum, 0, rmin30, length30/2., angle1, angle2, -nhi[0],-nhi[1],-nhi[2],-nlow[0],-nlow[1],-nlow[2]); + vvacu30->SetLineColor(kYellow); + if(IncludeVacuum) + pipe->AddNode(vvacu30, 1, tra30); + + // size of flange + // Thickness 1.8 cm + // Diameter 11.4 cm + + Double_t rmax40 = 11.4 /2.; + Double_t rmin40 = rmax30; + Double_t length40 = 1.8; + + // downstream flange + TGeoVolume *vfla31 = gGeoManager->MakeCtub("flange31", pipeMedium, rmin40, rmax40, length40/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + TGeoTranslation* fla31 = new TGeoTranslation("fla31", 0, 0, -offset20 +length20 +length30 -length40/2.); + vfla31->SetLineColor(kBlue); + pipe->AddNode(vfla31, 1, fla31); + +//======================================================================================= + + // Laenge 300.0 cm + // Durchmesser 10.0 cm + // Wanddicke 0.2 cm + + // downstream pipe + Double_t rmax50 = 10.0 /2.; + Double_t rmin50 = rmax50-0.2; + Double_t length50 = 300.0; // 44.0; + + // 2nd downstream flange + TGeoVolume *vfla32 = gGeoManager->MakeCtub("flange32", pipeMedium, rmax50, rmax40, length40/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + TGeoTranslation* fla32 = new TGeoTranslation("fla32", 0., 0., -offset20 +length20 +length30 +length40/2.); + // TGeoTranslation* fla32 = new TGeoTranslation("fla32", 0., 0., -offset20 +length20 +length30 +length40/2. + 20.); + vfla32->SetLineColor(kRed); + pipe->AddNode(vfla32, 1, fla32); + + TGeoVolume *vpipe50 = gGeoManager->MakeCtub("pipe50", pipeMedium, rmin50, rmax50, length50/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + TGeoTranslation* fla50 = new TGeoTranslation("fla50", 0., 0., -offset20 +length20 +length30 +length50/2.); + // TGeoTranslation* fla50 = new TGeoTranslation("fla50", 0., 0., -offset20 +length20 +length30 +length50/2. + 20.); + vpipe50->SetLineColor(kRed); + pipe->AddNode(vpipe50, 1, fla50); + + TGeoVolume *vvacu50 = gGeoManager->MakeCtub("vacu50", vacuum, 0, rmin50, length50/2., angle1, angle2, 0, 0,-1, 0, 0, 1); + vvacu50->SetLineColor(kYellow); + if(IncludeVacuum) + pipe->AddNode(vvacu50, 1, fla50); + + +//======================================================================================= + +// infoFile << endl << "Beam pipe section: " << pipe1name << endl; +// infoFile << setw(2) << "i" << setw(10) << "Z,mm" << setw(10) << "Rin,mm" << setw(10) << "Rout,mm" << setw(10) << "h,mm" << endl; +// TGeoVolume* pipe1 = MakePipe (1, nSects1, z1, rin1, rout1, pipeMedium, &infoFile); +// pipe1->SetLineColor(kYellow); +// // pipe1->SetLineColor(kGray); +// pipe->AddNode(pipe1, 0); +// +// TGeoVolume* pipevac1 = MakeVacuum(1, nSects01, z01, rin01, rout01, vacuum, &infoFile); +// pipevac1->SetLineColor(kCyan); +// pipe->AddNode(pipevac1, 0); + + // ----- End -------------------------------------------------- + + // --------------- Finish ----------------------------------------------- + top->AddNode(pipe, 1); + cout << endl << endl; + gGeoMan->CloseGeometry(); + gGeoManager->SetNsegments(80); + gGeoMan->CheckOverlaps(0.0001); + gGeoMan->PrintOverlaps(); + gGeoMan->Test(); + + pipe->Export(rootFileName); + + // TFile* rootFile = new TFile(rootFileName, "RECREATE"); + // top->Write(); + + TFile* rootFile = new TFile(rootFileName, "UPDATE"); + + // rotate the PIPE around y + TGeoRotation* pipe_rotation = new TGeoRotation(); + pipe_rotation->RotateY( pipe_angle ); + // TGeoCombiTrans* pipe_placement = new TGeoCombiTrans( sin( pipe_angle/180.*acos(-1) ) * z1[1]/2., 0., 0., pipe_rotation); + TGeoCombiTrans* pipe_placement = new TGeoCombiTrans("pipe_rot", 0., 0., 0, pipe_rotation); + pipe_placement->Write(); + + rootFile->Close(); + + cout << endl; + cout << "Geometry " << top->GetName() << " written to " + << rootFileName << endl; + + infoFile.close(); + + // visualize it with ray tracing, OGL/X3D viewer + //top->Raytrace(); + top->Draw("ogl"); + //top->Draw("x3d"); + + +} +// ============================================================================ +// ====== End of main function ===== +// ============================================================================ + + +//// ===== Make the beam pipe volume ========================================= +//TGeoPcon* MakeShape(Int_t nSects, char* name, Double_t* z, Double_t* rin, +// Double_t* rout, fstream* infoFile) { +// +// // ---> Shape +// TGeoPcon* shape = new TGeoPcon(name, 0., 360., nSects); +// for (Int_t iSect = 0; iSect < nSects; iSect++) { +// shape->DefineSection(iSect, z[iSect]/10., rin[iSect]/10., rout[iSect]/10.); // mm->cm +// *infoFile << setw(2) << iSect+1 +// << setw(10) << fixed << setprecision(2) << z[iSect] +// << setw(10) << fixed << setprecision(2) << rin[iSect] +// << setw(10) << fixed << setprecision(2) << rout[iSect] +// << setw(10) << fixed << setprecision(2) << rout[iSect]-rin[iSect] << endl; +// } +// +// return shape; +// +//} +// ============================================================================ + + + +// ===== Make the beam pipe volume ========================================= +TGeoVolume* MakeCutPipe(Int_t ipart, TGeoMedium *medium, + Double_t rmin, Double_t rmax, Double_t dz, + Double_t angle1, Double_t angle2, + Double_t nlo1, Double_t nlo2, Double_t nlo3, + Double_t nhi1, Double_t nhi2, Double_t nhi3) { + + // ---> Shape + TString volName = Form("part%i", ipart); + TGeoCtub* shape = new TGeoCtub(volName.Data(), rmin, rmax, dz, angle1, angle2, nlo1, nlo2, nlo3, nhi1, nhi2, nhi3); + + // ---> Volume + TGeoVolume* pipe = new TGeoVolume(volName.Data(), shape, medium); + + return pipe; +} +// ============================================================================ + + + +// // ===== Make the beam pipe volume ========================================= +// TGeoVolume* MakePipe(Int_t iPart, Int_t nSects, Double_t* z, Double_t* rin, +// Double_t* rout, TGeoMedium* medium, fstream* infoFile) { +// +// // ---> Shape +// TString volName = Form("pipe%i", iPart); +// TGeoPcon* shape = new TGeoPcon(volName.Data(), 0., 360., nSects); +// for (Int_t iSect = 0; iSect < nSects; iSect++) { +// shape->DefineSection(iSect, z[iSect]/10., rin[iSect]/10., rout[iSect]/10.); // mm->cm +// *infoFile << setw(2) << iSect+1 +// << setw(10) << fixed << setprecision(2) << z[iSect] +// << setw(10) << fixed << setprecision(2) << rin[iSect] +// << setw(10) << fixed << setprecision(2) << rout[iSect] +// << setw(10) << fixed << setprecision(2) << rout[iSect]-rin[iSect] << endl; +// } +// +// // ---> Volume +// TGeoVolume* pipe = new TGeoVolume(volName.Data(), shape, medium); +// +// return pipe; +// +// } +// // ============================================================================ +// +// +// +// // ===== Make the volume for the vacuum inside the beam pipe ============== +// TGeoVolume* MakeVacuum(Int_t iPart, Int_t nSects, Double_t* z, Double_t* rin, +// Double_t* rout, TGeoMedium* medium, fstream* infoFile) { +// +// // ---> Shape +// TString volName = Form("pipevac%i", iPart); +// TGeoPcon* shape = new TGeoPcon(volName.Data(), 0., 360., nSects); +// for (Int_t iSect = 0; iSect < nSects; iSect++) { +// shape->DefineSection(iSect, z[iSect]/10., rin[iSect]/10., rout[iSect]/10.); // mm->cm +// } +// +// // ---> Volume +// TGeoVolume* pipevac = new TGeoVolume(volName.Data(), shape, medium); +// +// return pipevac; +// +// } +// // ============================================================================ diff --git a/macro/mcbm/geometry/tof/Create_TOF_Geometry_v20b_mcbm.C b/macro/mcbm/geometry/tof/Create_TOF_Geometry_v20b_mcbm.C new file mode 100644 index 00000000..ba107335 --- /dev/null +++ b/macro/mcbm/geometry/tof/Create_TOF_Geometry_v20b_mcbm.C @@ -0,0 +1,1422 @@ +/// +/// \file Create_TOF_Geometry_v20b_mcbm.C +/// \brief Generates TOF geometry in Root format. +/// + +// Changelog +// +// 2020-04-14 - v20b - NH - swapped double stack layer 2 with STAR2 moodule, buc kept as dummy +// 2020-04-01 - v20a - NH - move mTOF +20 cm in x direction for the Mar 2020 run +// 2019-11-28 - v19b - DE - move mTOF +12 cm in x direction for the Nov 2019 run +// 2019-07-31 - v19a - DE - this TOF March 2019 geometry is also known as v18m +// 2017-11-03 - v18i - DE - shift mTOF to z=298 cm for acceptance matching with mSTS +// 2017-10-06 - v18h - DE - put v18f into vertical position to fit into the mCBM cave +// 2017-07-15 - v18g - DE - swap the z-position of TOF modules: 2 in the front, 3 in the back +// 2017-07-14 - v18f - DE - reduce vertical gap between TOF modules to fix the gap between modules 1-2 and 4-5 +// 2017-05-17 - v18e - DE - rotate electronics away from beam, shift 16 cm away from beam along x-axis +// 2017-05-17 - v18d - DE - change geometry name to v18d + +// in root all sizes are given in cm + +#include "TSystem.h" +#include "TGeoManager.h" +#include "TGeoVolume.h" +#include "TGeoMaterial.h" +#include "TGeoMedium.h" +#include "TGeoPgon.h" +#include "TGeoMatrix.h" +#include "TGeoCompositeShape.h" +#include "TFile.h" +#include "TString.h" +#include "TList.h" +#include "TROOT.h" +#include "TMath.h" + +#include <iostream> + +// Name of geometry version and output file +const TString geoVersion = "tof_v20b_mcbm"; // do not change +const TString geoVersionStand = geoVersion + "Stand"; +// +const TString fileTag = "tof_v20b"; +const TString FileNameSim = fileTag + "_mcbm.geo.root"; +const TString FileNameGeo = fileTag + "_mcbm_geo.root"; +const TString FileNameInfo = fileTag + "_mcbm.geo.info"; + +// TOF_Z_Front corresponds to front cover of outer super module towers +const Float_t TOF_Z_Front_Stand = 247.2; // = z=298 mCBM@SIS18 +const Float_t TOF_Z_Front = 0; // = z=298 mCBM@SIS18 +//const Float_t TOF_Z_Front = 130; // = z=225 mCBM@SIS18 +//const Float_t TOF_Z_Front = 250; // SIS 100 hadron +//const Float_t TOF_Z_Front = 450; // SIS 100 hadron +//const Float_t TOF_Z_Front = 600; // SIS 100 electron +//const Float_t TOF_Z_Front = 650; // SIS 100 muon +//const Float_t TOF_Z_Front = 880; // SIS 300 electron +//const Float_t TOF_Z_Front = 1020; // SIS 300 muon +// +//const Float_t TOF_Z_Front = 951.5; // Wall_Z_Position = 1050 cm + + +// Names of the different used materials which are used to build the modules +// The materials are defined in the global media.geo file +const TString KeepingVolumeMedium = "air"; +const TString BoxVolumeMedium = "aluminium"; +const TString NoActivGasMedium = "RPCgas_noact"; +const TString ActivGasMedium = "RPCgas"; +const TString GlasMedium = "RPCglass"; +const TString ElectronicsMedium = "carbon"; + +// Counters: +// 0 MRPC3a +// 1 MRPC3b +// 2 +// 3 +// 4 Diamond +// +// 6 Buc 2019 +// 7 CERN 20gap +// 8 Ceramic Pad +const Int_t NumberOfDifferentCounterTypes = 9; +const Float_t Glass_X[NumberOfDifferentCounterTypes] = {32. , 52., 32., 32., 0.2, 32., 28.8, 20., 2.4}; +const Float_t Glass_Y[NumberOfDifferentCounterTypes] = {26.9, 53., 20., 10., 0.2, 10., 6., 20., 2.4}; +const Float_t Glass_Z[NumberOfDifferentCounterTypes] = {0.1, 0.1,0.1, 0.1,0.01 ,0.1,0.1, 0.1, 0.1}; + +const Float_t GasGap_X[NumberOfDifferentCounterTypes] = {32. , 52., 32., 32., 0.2, 32., 28.8, 20., 2.4}; +const Float_t GasGap_Y[NumberOfDifferentCounterTypes] = {26.9, 53., 20., 10., 0.2, 10., 6., 20., 2.4}; +const Float_t GasGap_Z[NumberOfDifferentCounterTypes] = {0.025,0.025,0.025,0.025,0.01,0.02,0.02,0.02,0.025}; + +const Int_t NumberOfGaps[NumberOfDifferentCounterTypes] = {8,8,8,8,1,8,10,20,4}; +//const Int_t NumberOfGaps[NumberOfDifferentCounterTypes] = {1,1,1,1}; //deb +const Int_t NumberOfReadoutStrips[NumberOfDifferentCounterTypes] = {32,32,32,32,8,32,32,20,1}; +//const Int_t NumberOfReadoutStrips[NumberOfDifferentCounterTypes] = {1,1,1,1}; //deb + +const Float_t SingleStackStartPosition_Z[NumberOfDifferentCounterTypes] = {-0.6,-0.6,-0.6,-0.6,-0.1,-0.6,-0.6,-0.6,-1.}; + +const Float_t Electronics_X[NumberOfDifferentCounterTypes] = {34.0,53.0,32.0,32.,0.3,0.1, 28.8,20.,0.1}; +const Float_t Electronics_Y[NumberOfDifferentCounterTypes] = { 5.0, 5.0, 1.0, 1.,0.1,0.1,1.0,1.0,0.1}; +const Float_t Electronics_Z[NumberOfDifferentCounterTypes] = { 0.3, 0.3, 0.3, 0.3,0.1,0.1,0.1,0.1,0.1}; + +const Int_t NofModuleTypes = 10; +// 5 Diamond +// 6 Buc +// 7 CERN 20 gap +// 8 Ceramic +// 9 Star2 +// Aluminum box for all module types +const Float_t Module_Size_X[NofModuleTypes] = {180.,180.,180.,180.,180.,5., 40., 30., 22.5, 100.}; +const Float_t Module_Size_Y[NofModuleTypes] = { 49., 49., 74., 28., 18., 5., 12., 30., 11., 49.}; +const Float_t Module_Over_Y[NofModuleTypes] = {11.5,11.5,11., 4.5, 4.5, 0., 0., 0., 0., 0.}; +const Float_t Module_Size_Z[NofModuleTypes] = {11., 11., 13., 11., 11., 1., 12., 6., 6.2, 11.2}; +const Float_t Module_Thick_Alu_X_left = 0.1; +const Float_t Module_Thick_Alu_X_right = 1.0; +const Float_t Module_Thick_Alu_Y = 0.1; +const Float_t Module_Thick_Alu_Z = 0.1; + +// Distance to the center of the TOF wall [cm]; +const Float_t Wall_Z_Position = 400.; +const Float_t MeanTheta = 0.; + +//Type of Counter for module +const Int_t CounterTypeInModule[NofModuleTypes] = {0, 0, 1, 2, 3, 4, 6, 7, 8, 0}; +const Int_t NCounterInModule[NofModuleTypes] = {5, 5, 3, 5, 5, 1, 2, 1, 8, 2}; + +// Placement of the counter inside the module +const Float_t CounterXStartPosition[NofModuleTypes] = {-60.0, -66.0, -56.0,-60.0,-60.0, 0.0, 0., 0., -7., 0.}; +const Float_t CounterXDistance[NofModuleTypes] = {30.0, 32.0, 51.0, 30.0, 30.0, 0.0, 0., 0., 2., 0.}; +const Float_t CounterYStartPosition[NofModuleTypes] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0., 0., -4., -1.3, 0.}; +const Float_t CounterYDistance[NofModuleTypes] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0., 0., 8., 0., 0.}; +const Float_t CounterZDistance[NofModuleTypes] = {-2.5, 0.0, 0.0, 2.5, 2.5, 0., 6., 0., 0.1, 4.}; +const Float_t CounterZStartPosition[NofModuleTypes] = {0.0, 0.0, 0.0, 0.0, 0.0, 0., -3., 0., 0.0, -2.}; +const Float_t CounterRotationAngle[NofModuleTypes] = {0., 8.7, 7.0, 0., 0., 0., 0., 0., 0., 0.}; + +// Pole (support structure) +const Int_t MaxNumberOfPoles=20; +Float_t Pole_ZPos[MaxNumberOfPoles]; +Float_t Pole_Col[MaxNumberOfPoles]; +Int_t NumberOfPoles=0; + +const Float_t Pole_Size_X = 20.; +const Float_t Pole_Size_Y = 300.; +const Float_t Pole_Size_Z = 10.; +const Float_t Pole_Thick_X = 5.; +const Float_t Pole_Thick_Y = 5.; +const Float_t Pole_Thick_Z = 5.; + +// Bars (support structure) +const Float_t Bar_Size_X = 20.; +const Float_t Bar_Size_Y = 20.; +Float_t Bar_Size_Z = 100.; + +const Int_t MaxNumberOfBars=20; +Float_t Bar_ZPos[MaxNumberOfBars]; +Float_t Bar_XPos[MaxNumberOfBars]; +Int_t NumberOfBars=0; + +const Float_t ChamberOverlap=40; +const Float_t DxColl=158.0; //Module_Size_X-ChamberOverlap; +//const Float_t Pole_Offset=Module_Size_X/2.+Pole_Size_X/2.; +const Float_t Pole_Offset=90.0+Pole_Size_X/2.; + +// Position for module placement +const Float_t Inner_Module_First_Y_Position=16.; +const Float_t Inner_Module_Last_Y_Position=480.; +const Float_t Inner_Module_X_Offset=0.; // centered position in x/y +//const Float_t Inner_Module_X_Offset=18; // shift by 16 cm in x +const Int_t Inner_Module_NTypes = 3; +const Float_t Inner_Module_Types[Inner_Module_NTypes] = {4.,3.,0.}; +//const Float_t Inner_Module_Number[Inner_Module_NTypes] = {2.,2.,6.}; //V13_3a +const Float_t Inner_Module_Number[Inner_Module_NTypes] = {2.,2.,1.}; //V13_3a +//const Float_t Inner_Module_Number[Inner_Module_NTypes] = {0.,0.,0.}; //debugging + +const Float_t InnerSide_Module_X_Offset=51.; +const Float_t InnerSide_Module_NTypes = 1; +const Float_t InnerSide_Module_Types[Inner_Module_NTypes] = {5.}; +const Float_t InnerSide_Module_Number[Inner_Module_NTypes] = {2.}; //v13_3a +//const Float_t InnerSide_Module_Number[Inner_Module_NTypes] = {0.}; //debug + +const Float_t Outer_Module_First_Y_Position=0.; +const Float_t Outer_Module_Last_Y_Position=480.; +const Float_t Outer_Module_X_Offset=3.; +const Int_t Outer_Module_Col = 4; +const Int_t Outer_Module_NTypes = 2; +const Float_t Outer_Module_Types [Outer_Module_NTypes][Outer_Module_Col] = {1.,1.,1.,1., 2.,2.,2.,2.}; +const Float_t Outer_Module_Number[Outer_Module_NTypes][Outer_Module_Col] = {9.,9.,2.,0., 0.,0.,3.,4.};//V13_3a +//const Float_t Outer_Module_Number[Outer_Module_NTypes][Outer_Module_Col] = {1.,1.,0.,0., 0.,0.,0.,0.};//debug + +const Float_t Star2_First_Z_Position=TOF_Z_Front + 16.5; +const Float_t Star2_Delta_Z_Position=0.; +const Float_t Star2_First_Y_Position=32.; // +const Float_t Star2_Delta_Y_Position=0.; // +const Float_t Star2_rotate_Z=-90.; +const Int_t Star2_NTypes = 1; +const Float_t Star2_Types[Star2_NTypes] = {9.}; +const Float_t Star2_Number[Star2_NTypes] = {1.}; //debugging, V16b +const Float_t Star2_X_Offset[Star2_NTypes]={51.}; //{62.}; + +const Float_t Buc_First_Z_Position=TOF_Z_Front + 50.; +const Float_t Buc_Delta_Z_Position=0.; +const Float_t Buc_First_Y_Position=-32.5; // +const Float_t Buc_Delta_Y_Position=0.; // +const Float_t Buc_rotate_Z=180.; +const Int_t Buc_NTypes = 1; +const Float_t Buc_Types[Buc_NTypes] = {6.}; +const Float_t Buc_Number[Buc_NTypes] = {1.}; //debugging, V16b +const Float_t Buc_X_Offset[Buc_NTypes]={53.5}; + +const Int_t Cer_NTypes = 3; +const Float_t Cer_Z_Position[Cer_NTypes]={(float)(TOF_Z_Front+13.2),(float)(TOF_Z_Front+45.),(float)(TOF_Z_Front+45.)}; +const Float_t Cer_X_Position[Cer_NTypes]={0.,49.8,49.8}; +const Float_t Cer_Y_Position[Cer_NTypes]={-1.,5.,5.}; +const Float_t Cer_rotate_Z[Cer_NTypes]={0.,0.,0.}; +const Float_t Cer_Types[Cer_NTypes] = {5.,8.,8.}; +const Float_t Cer_Number[Cer_NTypes] = {1.,1.,1.}; //V16b + +const Float_t CERN_Z_Position=TOF_Z_Front+50; // 20 gap +const Float_t CERN_First_Y_Position=36.; +const Float_t CERN_X_Offset=46.; //65.5; +const Float_t CERN_rotate_Z=90.; +const Int_t CERN_NTypes = 1; +const Float_t CERN_Types[CERN_NTypes] = {7.}; // this is the SmType! +const Float_t CERN_Number[CERN_NTypes] = {1.}; // evtl. double for split signals + +// some global variables +TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance +TGeoVolume* gModules[NofModuleTypes]; // Global storage for module types +TGeoVolume* gCounter[NumberOfDifferentCounterTypes]; +TGeoVolume* gPole; +TGeoVolume* gBar[MaxNumberOfBars]; + +const Float_t Dia_Z_Position=-0.2-TOF_Z_Front_Stand; +const Float_t Dia_First_Y_Position=0.; +const Float_t Dia_X_Offset=0.; +const Float_t Dia_rotate_Z=0.; +const Int_t Dia_NTypes = 1; +const Float_t Dia_Types[Dia_NTypes] = {5.}; +const Float_t Dia_Number[Dia_NTypes] = {1.}; + +Float_t Last_Size_Y=0.; +Float_t Last_Over_Y=0.; + +// Forward declarations +void create_materials_from_media_file(); +TGeoVolume* create_counter(Int_t); +TGeoVolume* create_new_counter(Int_t); +TGeoVolume* create_tof_module(Int_t); +TGeoVolume* create_new_tof_module(Int_t); +TGeoVolume* create_tof_pole(); +TGeoVolume* create_tof_bar(); +void position_tof_poles(Int_t); +void position_tof_bars(Int_t); +void position_inner_tof_modules(Int_t); +void position_side_tof_modules(Int_t); +void position_outer_tof_modules(Int_t); +void position_Dia(Int_t); +void position_Star2(Int_t); +void position_Buc(Int_t); +void position_cer_modules(Int_t); +void position_CERN(Int_t); +void dump_info_file(); + + +void Create_TOF_Geometry_v20b_mcbm() { + + // Load needed material definition from media.geo file + create_materials_from_media_file(); + + // Get the GeoManager for later usage + gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom"); + gGeoMan->SetVisLevel(5); // 2 = super modules + gGeoMan->SetVisOption(0); + + // Create the top volume + /* + TGeoBBox* topbox= new TGeoBBox("", 1000., 1000., 1000.); + TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air")); + gGeoMan->SetTopVolume(top); + */ + + TGeoVolume* top = new TGeoVolumeAssembly("TOP"); + gGeoMan->SetTopVolume(top); + + TGeoRotation* tof_rotation = new TGeoRotation(); + tof_rotation->RotateY( 0. ); // angle with respect to beam axis + //tof_rotation->RotateZ( 0 ); // electronics on 9 o'clock position = +x + // tof_rotation->RotateZ( 0 ); // electronics on 9 o'clock position = +x + // tof_rotation->RotateZ( 90 ); // electronics on 12 o'clock position (top) + // tof_rotation->RotateZ( 180 ); // electronics on 3 o'clock position = -x + // tof_rotation->RotateZ( 270 ); // electronics on 6 o'clock position (bottom) + + TGeoVolume* tof = new TGeoVolumeAssembly(geoVersion); +// top->AddNode(tof, 1, tof_rotation); + top->AddNode(tof,1); + + TGeoVolume* tofstand = new TGeoVolumeAssembly(geoVersionStand); + // Mar 2020 run + TGeoTranslation* stand_trans = new TGeoTranslation("", 0., 0., TOF_Z_Front_Stand); + // Nov 2019 run + // TGeoTranslation* stand_trans = new TGeoTranslation("", 12., 0., TOF_Z_Front_Stand); + // TGeoTranslation* stand_trans = new TGeoTranslation("", 0., 0., TOF_Z_Front_Stand); + TGeoRotation* stand_rot = new TGeoRotation(); + stand_rot->RotateY(-2.7); + TGeoCombiTrans* stand_combi_trans = new TGeoCombiTrans(*stand_trans, *stand_rot); + //tof->AddNode(tofstand, 1, stand_combi_trans); + tof->AddNode(tofstand,1); + + for(Int_t counterType = 0; counterType < NumberOfDifferentCounterTypes; counterType++) { + gCounter[counterType] = create_new_counter(counterType); + } + + for(Int_t moduleType = 0; moduleType < NofModuleTypes; moduleType++) { + gModules[moduleType] = create_new_tof_module(moduleType); + gModules[moduleType]->SetVisContainers(1); + } + + // no pole + // gPole = create_tof_pole(); + + // position_side_tof_modules(1); // keep order !! + // position_inner_tof_modules(2); + position_inner_tof_modules(3); + position_Dia(1); + position_Star2(1); + // position_cer_modules(3); + // position_CERN(1); + position_Buc(1); + + cout << "Outer Types "<<Outer_Module_Types[0][0]<<", "<<Outer_Module_Types[1][0] + <<", col=1: "<<Outer_Module_Types[0][1]<<", "<<Outer_Module_Types[1][1] + <<endl; + cout << "Outer Number "<<Outer_Module_Number[0][0]<<", "<<Outer_Module_Number[1][0] + <<", col=1: "<<Outer_Module_Number[0][1]<<", "<<Outer_Module_Number[1][1] + <<endl; + // position_outer_tof_modules(4); + // position_tof_poles(0); + // position_tof_bars(0); + + gGeoMan->CloseGeometry(); + gGeoMan->CheckOverlaps(0.001); + gGeoMan->PrintOverlaps(); + gGeoMan->CheckOverlaps(0.001,"s"); + gGeoMan->PrintOverlaps(); + gGeoMan->Test(); + + tof->Export(FileNameSim); + TFile* geoFile = new TFile(FileNameSim, "UPDATE"); + stand_combi_trans->Write(); + geoFile->Close(); + +/* + TFile* outfile1 = new TFile(FileNameSim,"RECREATE"); + top->Write(); + //gGeoMan->Write(); + outfile1->Close(); +*/ + //tof->RemoveNode((TGeoNode*)tofstand); + //top->AddNode(tof, 1, tof_rotation); + //tof->ReplaceNode((TGeoNode*)tofstand, 0, stand_combi_trans); + /* + CbmTransport run; + run.SetGeoFileName(FileNameGeo); + run.LoadSetup("setup_mcbm_tof_2020"); + run.SetField(new CbmFieldConst()); +*/ + //top->Export(FileNameGeo); + + TFile* outfile2 = new TFile(FileNameGeo,"RECREATE"); + gGeoMan->Write(); + outfile2->Close(); + + dump_info_file(); + + top->SetVisContainers(1); + gGeoMan->SetVisLevel(5); + top->Draw("ogl"); + //top->Draw(); + //gModules[0]->Draw("ogl"); + // gModules[0]->Draw(""); + gModules[0]->SetVisContainers(1); + // gModules[1]->Draw(""); + gModules[1]->SetVisContainers(1); + //gModules[5]->Draw(""); + // top->Raytrace(); + +} + +void create_materials_from_media_file() +{ + // Use the FairRoot geometry interface to load the media which are already defined + FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader"); + FairGeoInterface* geoFace = geoLoad->getGeoInterface(); + TString geoPath = gSystem->Getenv("VMCWORKDIR"); + TString geoFile = geoPath + "/geometry/media.geo"; + geoFace->setMediaFile(geoFile); + geoFace->readMedia(); + + // Read the required media and create them in the GeoManager + FairGeoMedia* geoMedia = geoFace->getMedia(); + FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder(); + + FairGeoMedium* air = geoMedia->getMedium("air"); + FairGeoMedium* aluminium = geoMedia->getMedium("aluminium"); + FairGeoMedium* RPCgas = geoMedia->getMedium("RPCgas"); + FairGeoMedium* RPCgas_noact = geoMedia->getMedium("RPCgas_noact"); + FairGeoMedium* RPCglass = geoMedia->getMedium("RPCglass"); + FairGeoMedium* carbon = geoMedia->getMedium("carbon"); + + // include check if all media are found + + geoBuild->createMedium(air); + geoBuild->createMedium(aluminium); + geoBuild->createMedium(RPCgas); + geoBuild->createMedium(RPCgas_noact); + geoBuild->createMedium(RPCglass); + geoBuild->createMedium(carbon); +} + +TGeoVolume* create_counter(Int_t modType) +{ + + //glass + Float_t gdx=Glass_X[modType]; + Float_t gdy=Glass_Y[modType]; + Float_t gdz=Glass_Z[modType]; + + //gas gap + Int_t nstrips=NumberOfReadoutStrips[modType]; + Int_t ngaps=NumberOfGaps[modType]; + + + Float_t ggdx=GasGap_X[modType]; + Float_t ggdy=GasGap_Y[modType]; + Float_t ggdz=GasGap_Z[modType]; + Float_t gsdx=ggdx/float(nstrips); + + //single stack + Float_t dzpos=gdz+ggdz; + Float_t startzpos=SingleStackStartPosition_Z[modType]; + + // electronics + //pcb dimensions + Float_t dxe=Electronics_X[modType]; + Float_t dye=Electronics_Y[modType]; + Float_t dze=Electronics_Z[modType]; + Float_t yele=(gdy+0.1)/2.+dye/2.; + + // needed materials + TGeoMedium* glassPlateVolMed = gGeoMan->GetMedium(GlasMedium); + TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); + TGeoMedium* activeGasVolMed = gGeoMan->GetMedium(ActivGasMedium); + TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsMedium); + + // Single glass plate + TGeoBBox* glass_plate = new TGeoBBox("", gdx/2., gdy/2., gdz/2.); + TGeoVolume* glass_plate_vol = + new TGeoVolume("tof_glass", glass_plate, glassPlateVolMed); + glass_plate_vol->SetLineColor(kMagenta); // set line color for the glass plate + glass_plate_vol->SetTransparency(20); // set transparency for the TOF + TGeoTranslation* glass_plate_trans + = new TGeoTranslation("", 0., 0., 0.); + + // Single gas gap + TGeoBBox* gas_gap = new TGeoBBox("", ggdx/2., ggdy/2., ggdz/2.); + //TGeoVolume* gas_gap_vol = + //new TGeoVolume("tof_gas_gap", gas_gap, noActiveGasVolMed); + TGeoVolume* gas_gap_vol = + new TGeoVolume("tof_gas_active", gas_gap, activeGasVolMed); + gas_gap_vol->Divide("Strip",1,nstrips,-ggdx/2.,0); + + gas_gap_vol->SetLineColor(kRed); // set line color for the gas gap + gas_gap_vol->SetTransparency(70); // set transparency for the TOF + TGeoTranslation* gas_gap_trans + = new TGeoTranslation("", 0., 0., (gdz+ggdz)/2.); + + + // Single subdivided active gas gap + /* + TGeoBBox* gas_active = new TGeoBBox("", gsdx/2., ggdy/2., ggdz/2.); + TGeoVolume* gas_active_vol = + new TGeoVolume("tof_gas_active", gas_active, activeGasVolMed); + gas_active_vol->SetLineColor(kBlack); // set line color for the gas gap + gas_active_vol->SetTransparency(70); // set transparency for the TOF + */ + + // Add glass plate, inactive gas gap and active gas gaps to a single stack + TGeoVolume* single_stack = new TGeoVolumeAssembly("single_stack"); + single_stack->AddNode(glass_plate_vol, 0, glass_plate_trans); + single_stack->AddNode(gas_gap_vol, 0, gas_gap_trans); + + /* + for (Int_t l=0; l<nstrips; l++){ + TGeoTranslation* gas_active_trans + = new TGeoTranslation("", -ggdx/2+(l+0.5)*gsdx, 0., 0.); + gas_gap_vol->AddNode(gas_active_vol, l, gas_active_trans); + // single_stack->AddNode(gas_active_vol, l, gas_active_trans); + } + */ + + // Add 8 single stacks + one glass plate at the e09.750nd to a multi stack + TGeoVolume* multi_stack = new TGeoVolumeAssembly("multi_stack"); + Int_t l; + for (l=0; l<ngaps; l++){ + TGeoTranslation* single_stack_trans + = new TGeoTranslation("", 0., 0., startzpos + l*dzpos); + multi_stack->AddNode(single_stack, l, single_stack_trans); + } + TGeoTranslation* single_glass_back_trans + = new TGeoTranslation("", 0., 0., startzpos + ngaps*dzpos); + multi_stack->AddNode(glass_plate_vol, l, single_glass_back_trans); + + // Add electronics above and below the glass stack to build a complete counter + TGeoVolume* counter = new TGeoVolumeAssembly("counter"); + TGeoTranslation* multi_stack_trans + = new TGeoTranslation("", 0., 0., 0.); + counter->AddNode(multi_stack, l, multi_stack_trans); + + TGeoBBox* pcb = new TGeoBBox("", dxe/2., dye/2., dze/2.); + TGeoVolume* pcb_vol = + new TGeoVolume("pcb", pcb, electronicsVolMed); + pcb_vol->SetLineColor(kCyan); // set line color for the gas gap + pcb_vol->SetTransparency(10); // set transparency for the TOF + for (Int_t l=0; l<2; l++){ + yele *= -1.; + TGeoTranslation* pcb_trans + = new TGeoTranslation("", 0., yele, 0.); + counter->AddNode(pcb_vol, l, pcb_trans); + } + + return counter; + +} + +TGeoVolume* create_new_counter(Int_t modType) +{ + + //glass + Float_t gdx=Glass_X[modType]; + Float_t gdy=Glass_Y[modType]; + Float_t gdz=Glass_Z[modType]; + + //gas gap + Int_t nstrips=NumberOfReadoutStrips[modType]; + Int_t ngaps=NumberOfGaps[modType]; + + + Float_t ggdx=GasGap_X[modType]; + Float_t ggdy=GasGap_Y[modType]; + Float_t ggdz=GasGap_Z[modType]; + Float_t gsdx=ggdx/(Float_t)(nstrips); + + // electronics + //pcb dimensions + Float_t dxe=Electronics_X[modType]; + Float_t dye=Electronics_Y[modType]; + Float_t dze=Electronics_Z[modType]; + Float_t yele=gdy/2.+dye/2.; + + // counter size (calculate from glas, gap and electronics sizes) + Float_t cdx = TMath::Max(gdx, ggdx); + cdx = TMath::Max(cdx, dxe)+ 0.2; + Float_t cdy = TMath::Max(gdy, ggdy) + 2*dye + 0.2; + Float_t cdz = ngaps * ggdz + (ngaps+1) * gdz + 0.2; // ngaps * (gdz+ggdz) + gdz + 0.2; // ok + + //calculate thickness and first position in counter of single stack + Float_t dzpos = gdz+ggdz; + Float_t startzposglas= -ngaps * (gdz + ggdz) /2.; // -cdz/2.+0.1+gdz/2.; // ok // (-cdz+gdz)/2.; // not ok + Float_t startzposgas = startzposglas + gdz/2. + ggdz/2.; // -cdz/2.+0.1+gdz +ggdz/2.; // ok + + + // needed materials + TGeoMedium* glassPlateVolMed = gGeoMan->GetMedium(GlasMedium); + TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); + TGeoMedium* activeGasVolMed = gGeoMan->GetMedium(ActivGasMedium); + TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsMedium); + + + // define counter volume + TGeoBBox* counter_box = new TGeoBBox("", cdx/2., cdy/2., cdz/2.); + TGeoVolume* counter = + new TGeoVolume("counter", counter_box, noActiveGasVolMed); + counter->SetLineColor(kRed); // set line color for the counter + counter->SetTransparency(70); // set transparency for the TOF + + // define single glass plate volume + TGeoBBox* glass_plate = new TGeoBBox("", gdx/2., gdy/2., gdz/2.); + TGeoVolume* glass_plate_vol = + new TGeoVolume("tof_glass", glass_plate, glassPlateVolMed); + glass_plate_vol->SetLineColor(kMagenta); // set line color for the glass plate + glass_plate_vol->SetTransparency(20); // set transparency for the TOF + // define single gas gap volume + TGeoBBox* gas_gap = new TGeoBBox("", ggdx/2., ggdy/2., ggdz/2.); + TGeoVolume* gas_gap_vol = + new TGeoVolume("Gap", gas_gap, activeGasVolMed); + gas_gap_vol->Divide("Cell",1,nstrips,-ggdx/2.,0); + gas_gap_vol->SetLineColor(kRed); // set line color for the gas gap + gas_gap_vol->SetTransparency(99); // set transparency for the TOF + + // place 8 gas gaps and 9 glas plates in the counter + for( Int_t igap = 0; igap <= ngaps; igap++) { + // place (ngaps+1) glass plates + Float_t zpos_glas = startzposglas + igap*dzpos; + TGeoTranslation* glass_plate_trans + = new TGeoTranslation("", 0., 0., zpos_glas); + counter->AddNode(glass_plate_vol, igap, glass_plate_trans); + // place ngaps gas gaps + if (igap < ngaps) + { + Float_t zpos_gas = startzposgas + igap*dzpos; + TGeoTranslation* gas_gap_trans + = new TGeoTranslation("", 0., 0., zpos_gas); + counter->AddNode(gas_gap_vol, igap, gas_gap_trans); + } +// cout <<"Zpos(Glas): "<< zpos_glas << endl; +// cout <<"Zpos(Gas): "<< zpos_gas << endl; + } + + // create and place the electronics above and below the glas stack + TGeoBBox* pcb = new TGeoBBox("", dxe/2., dye/2., dze/2.); + TGeoVolume* pcb_vol = + new TGeoVolume("pcb", pcb, electronicsVolMed); + pcb_vol->SetLineColor(kYellow); // kCyan); // set line color for electronics + pcb_vol->SetTransparency(10); // set transparency for the TOF + for (Int_t l=0; l<2; l++){ + yele *= -1.; + TGeoTranslation* pcb_trans + = new TGeoTranslation("", 0., yele, 0.); + counter->AddNode(pcb_vol, l, pcb_trans); + } + + + return counter; + +} + +TGeoVolume* create_tof_module(Int_t modType) +{ + Int_t cType = CounterTypeInModule[modType]; + Float_t dx=Module_Size_X[modType]; + Float_t dy=Module_Size_Y[modType]; + Float_t dz=Module_Size_Z[modType]; + Float_t width_aluxl=Module_Thick_Alu_X_left; + Float_t width_aluxr=Module_Thick_Alu_X_right; + Float_t width_aluy=Module_Thick_Alu_Y; + Float_t width_aluz=Module_Thick_Alu_Z; + + Float_t shift_gas_box = (Module_Thick_Alu_X_right - Module_Thick_Alu_X_left)/2; + + Float_t dxpos=CounterXDistance[modType]; + Float_t startxpos=CounterXStartPosition[modType]; + Float_t dzoff=CounterZDistance[modType]; + Float_t rotangle=CounterRotationAngle[modType]; + + TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium); + TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); + + TString moduleName = Form("module_%d", modType); + TGeoVolume* module = new TGeoVolumeAssembly(moduleName); + + TGeoBBox* alu_box = new TGeoBBox("", dx/2., dy/2., dz/2.); + TGeoVolume* alu_box_vol = + new TGeoVolume("alu_box", alu_box, boxVolMed); + alu_box_vol->SetLineColor(kGreen); // set line color for the alu box + alu_box_vol->SetTransparency(20); // set transparency for the TOF + TGeoTranslation* alu_box_trans + = new TGeoTranslation("", 0., 0., 0.); + module->AddNode(alu_box_vol, 0, alu_box_trans); + + TGeoBBox* gas_box = new TGeoBBox("", (dx-(width_aluxl+width_aluxr))/2., (dy-2*width_aluy)/2., (dz-2*width_aluz)/2.); + TGeoVolume* gas_box_vol = + new TGeoVolume("gas_box", gas_box, noActiveGasVolMed); + gas_box_vol->SetLineColor(kYellow); // set line color for the gas box + gas_box_vol->SetTransparency(70); // set transparency for the TOF + TGeoTranslation* gas_box_trans + = new TGeoTranslation("", shift_gas_box, 0., 0.); + alu_box_vol->AddNode(gas_box_vol, 0, gas_box_trans); + + for (Int_t j=0; j<5; j++){ //loop over counters (modules) + Float_t zpos; + if (0 == modType) { + zpos = dzoff *=-1; + } else { + zpos = 0.; + } + //cout << "counter z position " << zpos << endl; + TGeoTranslation* counter_trans + = new TGeoTranslation("", startxpos+ j*dxpos , 0.0 , zpos); + + TGeoRotation* counter_rot = new TGeoRotation(); + counter_rot->RotateY(rotangle); + TGeoCombiTrans* counter_combi_trans = new TGeoCombiTrans(*counter_trans, *counter_rot); + gas_box_vol->AddNode(gCounter[cType], j, counter_combi_trans); + } + + return module; +} + +TGeoVolume* create_new_tof_module(Int_t modType) +{ + Int_t cType = CounterTypeInModule[modType]; + Float_t dx=Module_Size_X[modType]; + Float_t dy=Module_Size_Y[modType]; + Float_t dz=Module_Size_Z[modType]; + Float_t width_aluxl=Module_Thick_Alu_X_left; + Float_t width_aluxr=Module_Thick_Alu_X_right; + Float_t width_aluy=Module_Thick_Alu_Y; + Float_t width_aluz=Module_Thick_Alu_Z; + + Float_t shift_gas_box = (Module_Thick_Alu_X_right - Module_Thick_Alu_X_left)/2; + + Float_t dxpos=CounterXDistance[modType]; + Float_t startxpos=CounterXStartPosition[modType]; + Float_t dypos=CounterYDistance[modType]; + Float_t startypos=CounterYStartPosition[modType]; + Float_t dzoff=CounterZDistance[modType]; + Float_t rotangle=CounterRotationAngle[modType]; + + TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium); + TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); + + TString moduleName = Form("module_%d", modType); + + TGeoBBox* module_box = new TGeoBBox("", dx/2., dy/2., dz/2.); + TGeoVolume* module = + new TGeoVolume(moduleName, module_box, boxVolMed); + module->SetLineColor(kGreen); // set line color for the alu box + module->SetTransparency(20); // set transparency for the TOF + + TGeoBBox* gas_box = new TGeoBBox("", (dx-(width_aluxl+width_aluxr))/2., (dy-2*width_aluy)/2., (dz-2*width_aluz)/2.); + TGeoVolume* gas_box_vol = + new TGeoVolume("gas_box", gas_box, noActiveGasVolMed); + gas_box_vol->SetLineColor(kBlue); // set line color for the alu box + gas_box_vol->SetTransparency(50); // set transparency for the TOF + TGeoTranslation* gas_box_trans + = new TGeoTranslation("", shift_gas_box, 0., 0.); + module->AddNode(gas_box_vol, 0, gas_box_trans); + + for (Int_t j=0; j< NCounterInModule[modType]; j++){ //loop over counters (modules) + //for (Int_t j=0; j< 1; j++){ //loop over counters (modules) + Float_t xpos,ypos,zpos; + if (0 == modType || 3 == modType || 4 == modType || 5 == modType) { + zpos = dzoff *=-1; + } else { + zpos = CounterZStartPosition[modType]+j*dzoff; + } + //cout << "counter z position " << zpos << endl; + xpos=startxpos + j*dxpos; + ypos=startypos + j*dypos; + + TGeoTranslation* counter_trans + = new TGeoTranslation("", xpos , ypos , zpos); + + TGeoRotation* counter_rot = new TGeoRotation(); + counter_rot->RotateY(rotangle); + TGeoCombiTrans* counter_combi_trans = new TGeoCombiTrans(*counter_trans, *counter_rot); + gas_box_vol->AddNode(gCounter[cType], j, counter_combi_trans); + } + + return module; +} + + +TGeoVolume* create_tof_pole() +{ + // needed materials + TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium); + TGeoMedium* airVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + + Float_t dx=Pole_Size_X; + Float_t dy=Pole_Size_Y; + Float_t dz=Pole_Size_Z; + Float_t width_alux=Pole_Thick_X; + Float_t width_aluy=Pole_Thick_Y; + Float_t width_aluz=Pole_Thick_Z; + + TGeoVolume* pole = new TGeoVolumeAssembly("Pole"); + TGeoBBox* pole_alu_box = new TGeoBBox("", dx/2., dy/2., dz/2.); + TGeoVolume* pole_alu_vol = + new TGeoVolume("pole_alu", pole_alu_box, boxVolMed); + pole_alu_vol->SetLineColor(kGreen); // set line color for the alu box + pole_alu_vol->SetTransparency(20); // set transparency for the TOF + TGeoTranslation* pole_alu_trans + = new TGeoTranslation("", 0., 0., 0.); + pole->AddNode(pole_alu_vol, 0, pole_alu_trans); + + Float_t air_dx = dx/2. - width_alux; + Float_t air_dy = dy/2. - width_aluy; + Float_t air_dz = dz/2. - width_aluz; + + // cout << "My pole." << endl; + if (air_dx <= 0.) + cout << "ERROR - No air volume in pole X, size: "<< air_dx << endl; + if (air_dy <= 0.) + cout << "ERROR - No air volume in pole Y, size: "<< air_dy << endl; + if (air_dz <= 0.) + cout << "ERROR - No air volume in pole Z, size: "<< air_dz << endl; + + if ((air_dx > 0.) && (air_dy > 0.) && (air_dz > 0.)) // crate air volume only, if larger than zero + { + TGeoBBox* pole_air_box = new TGeoBBox("", air_dx, air_dy, air_dz); + // TGeoBBox* pole_air_box = new TGeoBBox("", dx/2.-width_alux, dy/2.-width_aluy, dz/2.-width_aluz); + TGeoVolume* pole_air_vol = + new TGeoVolume("pole_air", pole_air_box, airVolMed); + pole_air_vol->SetLineColor(kYellow); // set line color for the alu box + pole_air_vol->SetTransparency(70); // set transparency for the TOF + TGeoTranslation* pole_air_trans + = new TGeoTranslation("", 0., 0., 0.); + pole_alu_vol->AddNode(pole_air_vol, 0, pole_air_trans); + } + else + cout << "Skipping pole_air_vol, no thickness: " << air_dx << " " << air_dy << " " << air_dz << endl; + + return pole; +} + +TGeoVolume* create_tof_bar(Float_t dx, Float_t dy, Float_t dz) +{ + // needed materials + TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium); + TGeoMedium* airVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + + Float_t width_alux=Pole_Thick_X; + Float_t width_aluy=Pole_Thick_Y; + Float_t width_aluz=Pole_Thick_Z; + + TGeoVolume* bar = new TGeoVolumeAssembly("Bar"); + TGeoBBox* bar_alu_box = new TGeoBBox("", dx/2., dy/2., dz/2.); + TGeoVolume* bar_alu_vol = + new TGeoVolume("bar_alu", bar_alu_box, boxVolMed); + bar_alu_vol->SetLineColor(kGreen); // set line color for the alu box + bar_alu_vol->SetTransparency(20); // set transparency for the TOF + TGeoTranslation* bar_alu_trans + = new TGeoTranslation("", 0., 0., 0.); + bar->AddNode(bar_alu_vol, 0, bar_alu_trans); + + TGeoBBox* bar_air_box = new TGeoBBox("", dx/2.-width_alux, dy/2.-width_aluy, dz/2.-width_aluz); + TGeoVolume* bar_air_vol = + new TGeoVolume("bar_air", bar_air_box, airVolMed); + bar_air_vol->SetLineColor(kYellow); // set line color for the alu box + bar_air_vol->SetTransparency(70); // set transparency for the TOF + TGeoTranslation* bar_air_trans + = new TGeoTranslation("", 0., 0., 0.); + bar_alu_vol->AddNode(bar_air_vol, 0, bar_air_trans); + + return bar; +} + +void position_tof_poles(Int_t modType) +{ + + TGeoTranslation* pole_trans=NULL; + + Int_t numPoles=0; + for (Int_t i=0; i<NumberOfPoles; i++){ + if(i<2) { + pole_trans + = new TGeoTranslation("", -Pole_Offset+2.0, 0., Pole_ZPos[i]); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gPole, numPoles, pole_trans); + numPoles++; + }else{ + Float_t xPos=Pole_Offset+Pole_Size_X/2.+Pole_Col[i]*DxColl; + Float_t zPos=Pole_ZPos[i]; + pole_trans + = new TGeoTranslation("", xPos, 0., zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gPole, numPoles, pole_trans); + numPoles++; + + pole_trans + = new TGeoTranslation("", -xPos, 0., zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gPole, numPoles, pole_trans); + numPoles++; + } + cout << " Position Pole "<< numPoles<<" at z="<< Pole_ZPos[i] << endl; + } +} + +void position_tof_bars(Int_t modType) +{ + + TGeoTranslation* bar_trans=NULL; + + Int_t numBars=0; + Int_t i; + Float_t xPos; + Float_t yPos; + Float_t zPos; + + for (i=0; i<NumberOfBars; i++){ + + xPos=Bar_XPos[i]; + zPos=Bar_ZPos[i]; + yPos=Pole_Size_Y/2.+Bar_Size_Y/2.; + + bar_trans = new TGeoTranslation("", xPos, yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + bar_trans = new TGeoTranslation("", xPos,-yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + bar_trans = new TGeoTranslation("", -xPos, yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + bar_trans = new TGeoTranslation("", -xPos, -yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + } + cout << " Position Bar "<< numBars<<" at z="<< Bar_ZPos[i] << endl; + + // horizontal frame bars + i = NumberOfBars; + NumberOfBars++; + // no bar + // gBar[i]=create_tof_bar(2.*xPos+Pole_Size_X,Bar_Size_Y,Bar_Size_Y); + + zPos = Pole_ZPos[0]+Pole_Size_Z/2.; + bar_trans = new TGeoTranslation("", 0., yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + bar_trans = new TGeoTranslation("", 0., -yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + +} + +void position_inner_tof_modules(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + + // Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1; + Float_t yPos=Inner_Module_First_Y_Position; + Int_t ii=0; + Float_t xPos = Inner_Module_X_Offset; + Float_t zPos = Wall_Z_Position; + + Pole_ZPos[NumberOfPoles] = zPos; + Pole_Col[NumberOfPoles] = 0; + NumberOfPoles++; + + Float_t DzPos =0.; + for (Int_t j=0; j<modNType; j++){ + if (Module_Size_Z[j]>DzPos){ + DzPos = Module_Size_Z[j]; + } + } + Pole_ZPos[NumberOfPoles]=zPos+DzPos; + Pole_Col[NumberOfPoles] = 0; + NumberOfPoles++; + + // for (Int_t j=0; j<modNType; j++){ + // for (Int_t j=1; j<modNType; j++){ + Int_t modType; + Int_t modNum; + for (Int_t j=2; j<modNType; j++){ // place only M4 type modules (modNType == 2) + //DEDE + modType = Inner_Module_Types[j]; + modNum = 0; + // for(Int_t i=0; i<Inner_Module_Number[j]; i++) { + // for(Int_t i=0; i<1; i++) { // place 1x2 modules in the top and same in the bottom + for(Int_t i=0; i<2; i++) { // place 2x2 modules in the top and same in the bottom + ii++; + cout << "Inner ii "<<ii<<" Last "<<Last_Size_Y<<", "<<Last_Over_Y<<endl; + Float_t DeltaY=Module_Size_Y[modType]+Last_Size_Y-2.*(Module_Over_Y[modType]+Last_Over_Y); + // DeltaY = 1.5; + cout << "DeltaY " << DeltaY << endl; + yPos += DeltaY; + Last_Size_Y=Module_Size_Y[modType]; + Last_Over_Y=Module_Over_Y[modType]; + cout <<"Position Inner Module "<<i<<" of "<<Inner_Module_Number[j]<<" Type "<<modType + <<" at Y = "<<yPos<<" Ysize = "<<Module_Size_Y[modType] + <<" DeltaY = "<<DeltaY<<endl; + +/// module_trans = new TGeoTranslation("", xPos, yPos, zPos); +/// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); +/// modNum++; +/// module_trans = new TGeoTranslation("", xPos, -yPos, zPos); +/// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); +/// modNum++; +// // if (ii>0) { +// if (ii>1) { +// module_trans +// = new TGeoTranslation("", xPos, yPos-DeltaY/2, zPos+Module_Size_Z[modType]); +// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); +// modNum++; +// module_trans +// = new TGeoTranslation("", xPos, -(yPos-DeltaY/2), zPos+Module_Size_Z[modType]); +// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); +// modNum++; +// } + } + } + // module_trans = new TGeoTranslation("", xPos, -49-3, zPos); + + // Mar2019 setup + const Int_t NModules=5; + xPos=0.; + yPos=0.; + zPos=TOF_Z_Front; + const Double_t ModDx[NModules]= { 0., 0., 0., 49.8, 49.8}; + //const Double_t ModDx[NModules]= { 1.5, 0., -1.5, 49.8, 55.8}; + const Double_t ModDy[NModules]= { 0., 0., 0., 0., 0. }; + const Double_t ModDz[NModules]= { 0., 16.5, 34., 0., 34.}; + const Double_t ModAng[NModules]={-90.,-90.,-90., -90.,-90.0}; + TGeoRotation* module_rot = NULL; + TGeoCombiTrans* module_combi_trans = NULL; + + for (Int_t iMod=0; iMod<NModules; iMod++) { + module_trans = new TGeoTranslation("", xPos+ModDx[iMod], yPos+ModDy[iMod], zPos+ModDz[iMod]); + module_rot = new TGeoRotation(); + module_rot->RotateZ(ModAng[iMod]); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + } + + + /* + module_trans = new TGeoTranslation("", xPos, 0, zPos+16.5); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + // module_trans = new TGeoTranslation("", xPos, 49+3, zPos); + module_trans = new TGeoTranslation("", xPos, 0, zPos+16.5+17.5); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + // module_trans = new TGeoTranslation("", xPos,-26, zPos+Module_Size_Z[modType]); + module_trans = new TGeoTranslation("", xPos, -49.8, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + // module_trans = new TGeoTranslation("", xPos, 26, zPos+Module_Size_Z[modType]); + module_trans = new TGeoTranslation("", xPos, -49.8, zPos+16.5); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + */ +} + + +void position_Dia(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(Dia_rotate_Z); + TGeoCombiTrans* module_combi_trans = NULL; + + // Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1; + Float_t yPos=Dia_First_Y_Position; + Int_t ii=0; + Float_t xPos = Dia_X_Offset; + Float_t zPos = Dia_Z_Position; + + Int_t modNum = 0; + for (Int_t j=0; j<modNType; j++){ + Int_t modType= Dia_Types[j]; + for(Int_t i=0; i<Dia_Number[j]; i++) { + ii++; + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + } + } +} + +void position_Star2(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(Star2_rotate_Z); + TGeoCombiTrans* module_combi_trans = NULL; + + Float_t yPos = Star2_First_Y_Position; + Float_t zPos = Star2_First_Z_Position; + Int_t ii=0; + + Int_t modNum = 0; + for (Int_t j=0; j<modNType; j++){ + Int_t modType= Star2_Types[j]; + Float_t xPos = Star2_X_Offset[j]; + for(Int_t i=0; i<Star2_Number[j]; i++) { + ii++; + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + yPos += Star2_Delta_Y_Position; + zPos += Star2_Delta_Z_Position; + } + + } +} + +void position_Buc(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(Buc_rotate_Z); + TGeoCombiTrans* module_combi_trans = NULL; + + Float_t yPos = Buc_First_Y_Position; + Float_t zPos = Buc_First_Z_Position; + Int_t ii=0; + + Int_t modNum = 0; + for (Int_t j=0; j<modNType; j++){ + Int_t modType= Buc_Types[j]; + Float_t xPos = Buc_X_Offset[j]; + for(Int_t i=0; i<Buc_Number[j]; i++) { + ii++; + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + yPos += Buc_Delta_Y_Position; + zPos += Buc_Delta_Z_Position; + } + } +} + +void position_cer_modules(Int_t modNType) +{ + Int_t ii=0; + Int_t modNum = 0; + for (Int_t j=1; j<modNType; j++){ + Int_t modType= Cer_Types[j]; + Float_t xPos = Cer_X_Position[j]; + Float_t yPos = Cer_Y_Position[j]; + Float_t zPos = Cer_Z_Position[j]; + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(Form("Cer%d",j),Cer_rotate_Z[j],-MeanTheta,0.); + // module_rot->RotateZ(Cer_rotate_Z[j]); + TGeoCombiTrans* module_combi_trans = NULL; + + for(Int_t i=0; i<Cer_Number[j]; i++) { + ii++; + cout <<"Position Ceramic Module "<<i<<" of "<<Cer_Number[j]<<" Type "<<modType + <<" at X = "<<xPos + <<", Y = "<<yPos + <<", Z = "<<zPos + <<endl; + // Front staggered module (Top if pair), top + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + // modNum++; + } + } +} + +void position_CERN(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(CERN_rotate_Z); + TGeoCombiTrans* module_combi_trans = NULL; + + // Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1; + Float_t yPos=CERN_First_Y_Position; + Int_t ii=0; + Float_t xPos = CERN_X_Offset; + Float_t zPos = CERN_Z_Position; + + for (Int_t j=0; j<modNType; j++){ + Int_t modType= CERN_Types[j]; + Int_t modNum = 0; + for(Int_t i=0; i<CERN_Number[j]; i++) { + ii++; + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + } + } +} + +void position_side_tof_modules(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(180.); + TGeoCombiTrans* module_combi_trans = NULL; + + // Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1; + Float_t yPos=0.; //Inner_Module_First_Y_Position; + Int_t ii=0; + for (Int_t j=0; j<modNType; j++){ + Int_t modType= InnerSide_Module_Types[j]; + Int_t modNum = 0; + for(Int_t i=0; i<InnerSide_Module_Number[j]; i++) { + ii++; + cout << "InnerSide ii "<<ii<<" Last "<<Last_Size_Y<<","<<Last_Over_Y<<endl; + Float_t DeltaY=Module_Size_Y[modType]+Last_Size_Y-2.*(Module_Over_Y[modType]+Last_Over_Y); + if (ii>1){yPos += DeltaY;} + Last_Size_Y=Module_Size_Y[modType]; + Last_Over_Y=Module_Over_Y[modType]; + Float_t xPos = InnerSide_Module_X_Offset; + Float_t zPos = Wall_Z_Position; + cout <<"Position InnerSide Module "<<i<<" of "<<InnerSide_Module_Number[j]<<" Type "<<modType + <<" at Y = "<<yPos<<" Ysize = "<<Module_Size_Y[modType] + <<" DeltaY = "<<DeltaY<<endl; + + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + module_trans + = new TGeoTranslation("", -xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + + if (ii>1) { + module_trans + = new TGeoTranslation("", xPos, -yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + module_trans + = new TGeoTranslation("", -xPos, -yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + + module_trans + = new TGeoTranslation("", xPos, yPos-DeltaY/2, zPos+Module_Size_Z[modType]); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + module_trans + = new TGeoTranslation("", -xPos, yPos-DeltaY/2, zPos+Module_Size_Z[modType]); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + + module_trans + = new TGeoTranslation("", xPos, -(yPos-DeltaY/2), zPos+Module_Size_Z[modType]); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + module_trans + = new TGeoTranslation("", -xPos,-(yPos-DeltaY/2), zPos+Module_Size_Z[modType]); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + + } + } + } +} + +void position_outer_tof_modules(Int_t nCol) //modType, Int_t col1, Int_t col2) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(180.); + TGeoCombiTrans* module_combi_trans = NULL; + + // Int_t numModules=(Int_t)( (Outer_Module_Last_Y_Position-Outer_Module_First_Y_Position)/Module_Size_Y[modType])+1; + + Int_t modNum[NofModuleTypes]; + for (Int_t k=0; k<NofModuleTypes; k++){ + modNum[k]=0; + } + + Float_t zPos = Wall_Z_Position; + for(Int_t j=0; j<nCol; j++){ + Float_t xPos = Outer_Module_X_Offset + ((j+1)*DxColl); + Last_Size_Y=0.; + Last_Over_Y=0.; + Float_t yPos = 0.; + Int_t ii=0; + Float_t DzPos =0.; + for(Int_t k=0; k<Outer_Module_NTypes; k++){ + Int_t modType= Outer_Module_Types[k][j]; + if(Module_Size_Z[modType]>DzPos){ + if(Outer_Module_Number[k][j]>0){ + DzPos = Module_Size_Z[modType]; + } + } + } + + zPos -= 2.*DzPos; //((j+1)*2*Module_Size_Z[modType]); + + Pole_ZPos[NumberOfPoles] = zPos; + Pole_Col[NumberOfPoles] = j+1; + NumberOfPoles++; + Pole_ZPos[NumberOfPoles] = zPos+DzPos; + Pole_Col[NumberOfPoles] = j+1; + NumberOfPoles++; + //if (j+1==nCol) { + if (1) { + Pole_ZPos[NumberOfPoles] = Pole_ZPos[0]; + Pole_Col[NumberOfPoles] = j+1; + NumberOfPoles++; + + Bar_Size_Z = Pole_ZPos[0] - zPos; + gBar[NumberOfBars] = create_tof_bar(Bar_Size_X, Bar_Size_Y, Bar_Size_Z); + Bar_ZPos[NumberOfBars] = zPos+Bar_Size_Z/2.-Pole_Size_Z/2.; + Bar_XPos[NumberOfBars] = xPos + Pole_Offset; + NumberOfBars++; + } + + for (Int_t k=0; k<Outer_Module_NTypes; k++) { + Int_t modType = Outer_Module_Types[k][j]; + Int_t numModules = Outer_Module_Number[k][j]; + + cout <<" Outer: position "<<numModules<<" of type "<<modType<<" in col "<<j + <<" at z = "<<zPos<<", DzPos = "<<DzPos<<endl; + for(Int_t i=0; i<numModules; i++) { + ii++; + cout << "Outer ii "<<ii<<" Last "<<Last_Size_Y<<","<<Last_Over_Y<<endl; + Float_t DeltaY=Module_Size_Y[modType]+Last_Size_Y-2.*(Module_Over_Y[modType]+Last_Over_Y); + if (ii>1){yPos += DeltaY;} + Last_Size_Y=Module_Size_Y[modType]; + Last_Over_Y=Module_Over_Y[modType]; + cout <<"Position Outer Module "<<i<<" of "<<Outer_Module_Number[k][j]<<" Type "<<modType + <<"(#"<<modNum[modType]<<") "<<" at Y = "<<yPos<<" Ysize = "<<Module_Size_Y[modType] + <<" DeltaY = "<<DeltaY<<endl; + + module_trans = new TGeoTranslation("", xPos, yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans); + modNum[modType]++; + + module_trans = new TGeoTranslation("", -xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans); + modNum[modType]++; + + if (ii>1) { + module_trans + = new TGeoTranslation("", xPos, -yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans); + modNum[modType]++; + module_trans + = new TGeoTranslation("", -xPos, -yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans); + modNum[modType]++; + + // second layer + module_trans + = new TGeoTranslation("", xPos, yPos-DeltaY/2., zPos+DzPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans); + modNum[modType]++; + module_trans + = new TGeoTranslation("", -xPos, yPos-DeltaY/2., zPos+DzPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans); + modNum[modType]++; + + module_trans + = new TGeoTranslation("", xPos, -(yPos-DeltaY/2.), zPos+DzPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans); + modNum[modType]++; + module_trans + = new TGeoTranslation("", -xPos, -(yPos-DeltaY/2.), zPos+DzPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans); + modNum[modType]++; + + } + } + } + } +} + + +void dump_info_file() +{ + TDatime datetime; // used to get timestamp + + printf("writing info file: %s\n", FileNameInfo.Data()); + + FILE *ifile; + ifile = fopen(FileNameInfo.Data(),"w"); + + if (ifile == NULL) + { + printf("error opening %s\n", FileNameInfo.Data()); + exit(1); + } + + fprintf(ifile,"#\n## %s information file\n#\n\n", geoVersion.Data()); + + fprintf(ifile,"# created %d\n\n", datetime.GetDate()); + + fprintf(ifile,"# TOF setup\n"); + if (TOF_Z_Front == 450) + fprintf(ifile,"SIS 100 hadron setup\n"); + if (TOF_Z_Front == 600) + fprintf(ifile,"SIS 100 electron\n"); + if (TOF_Z_Front == 650) + fprintf(ifile,"SIS 100 muon\n"); + if (TOF_Z_Front == 880) + fprintf(ifile,"SIS 300 electron\n"); + if (TOF_Z_Front == 1020) + fprintf(ifile,"SIS 300 muon\n"); + fprintf(ifile,"\n"); + + const Float_t TOF_Z_Back = Wall_Z_Position + 1.5 * Module_Size_Z[0]; // back of TOF wall + + fprintf(ifile,"# envelope\n"); + // Show extension of TRD + fprintf(ifile,"%7.2f cm start of TOF (z)\n", TOF_Z_Front); + fprintf(ifile,"%7.2f cm end of TOF (z)\n", TOF_Z_Back); + fprintf(ifile,"\n"); + + // Layer thickness + fprintf(ifile,"# central tower position\n"); + fprintf(ifile,"%7.2f cm center of staggered, front RPC cell at x=0\n", Wall_Z_Position); + fprintf(ifile,"\n"); + + fclose(ifile); +} diff --git a/macro/mcbm/geometry/tof/Create_TOF_Geometry_v20c_mcbm.C b/macro/mcbm/geometry/tof/Create_TOF_Geometry_v20c_mcbm.C new file mode 100644 index 00000000..8662c286 --- /dev/null +++ b/macro/mcbm/geometry/tof/Create_TOF_Geometry_v20c_mcbm.C @@ -0,0 +1,1411 @@ +/// +/// \file Create_TOF_Geometry_v20b_mcbm.C +/// \brief Generates TOF geometry in Root format. +/// + +// Changelog +// +// 2020-04-14 - v20b - NH - swapped double stack layer 2 with STAR2 moodule, buc kept as dummy +// 2020-04-01 - v20a - NH - move mTOF +20 cm in x direction for the Mar 2020 run +// 2019-11-28 - v19b - DE - move mTOF +12 cm in x direction for the Nov 2019 run +// 2019-07-31 - v19a - DE - this TOF March 2019 geometry is also known as v18m +// 2017-11-03 - v18i - DE - shift mTOF to z=298 cm for acceptance matching with mSTS +// 2017-10-06 - v18h - DE - put v18f into vertical position to fit into the mCBM cave +// 2017-07-15 - v18g - DE - swap the z-position of TOF modules: 2 in the front, 3 in the back +// 2017-07-14 - v18f - DE - reduce vertical gap between TOF modules to fix the gap between modules 1-2 and 4-5 +// 2017-05-17 - v18e - DE - rotate electronics away from beam, shift 16 cm away from beam along x-axis +// 2017-05-17 - v18d - DE - change geometry name to v18d + +// in root all sizes are given in cm + +#include "TSystem.h" +#include "TGeoManager.h" +#include "TGeoVolume.h" +#include "TGeoMaterial.h" +#include "TGeoMedium.h" +#include "TGeoPgon.h" +#include "TGeoMatrix.h" +#include "TGeoCompositeShape.h" +#include "TFile.h" +#include "TString.h" +#include "TList.h" +#include "TROOT.h" +#include "TMath.h" + +#include <iostream> + +// Name of geometry version and output file +const TString geoVersion = "tof_v20c_mcbm"; // do not change +const TString geoVersionStand = geoVersion + "Stand"; +// +const TString fileTag = "tof_v20c"; +const TString FileNameSim = fileTag + "_mcbm.geo.root"; +const TString FileNameGeo = fileTag + "_mcbm_geo.root"; +const TString FileNameInfo = fileTag + "_mcbm.geo.info"; + +// TOF_Z_Front corresponds to front cover of outer super module towers +const Float_t TOF_Z_Front_Stand = 250.; // = z=298 mCBM@SIS18 +const Float_t TOF_Z_Front = 0; // = z=298 mCBM@SIS18 +//const Float_t TOF_Z_Front = 130; // = z=225 mCBM@SIS18 +//const Float_t TOF_Z_Front = 250; // SIS 100 hadron +//const Float_t TOF_Z_Front = 450; // SIS 100 hadron +//const Float_t TOF_Z_Front = 600; // SIS 100 electron +//const Float_t TOF_Z_Front = 650; // SIS 100 muon +//const Float_t TOF_Z_Front = 880; // SIS 300 electron +//const Float_t TOF_Z_Front = 1020; // SIS 300 muon +// +//const Float_t TOF_Z_Front = 951.5; // Wall_Z_Position = 1050 cm + + +// Names of the different used materials which are used to build the modules +// The materials are defined in the global media.geo file +const TString KeepingVolumeMedium = "air"; +const TString BoxVolumeMedium = "aluminium"; +const TString NoActivGasMedium = "RPCgas_noact"; +const TString ActivGasMedium = "RPCgas"; +const TString GlasMedium = "RPCglass"; +const TString ElectronicsMedium = "carbon"; + +// Counters: +// 0 MRPC3a +// 1 MRPC3b +// 2 +// 3 +// 4 Diamond +// +// 6 Buc 2019 +// 7 CERN 20gap +// 8 Ceramic Pad +const Int_t NumberOfDifferentCounterTypes = 9; +const Float_t Glass_X[NumberOfDifferentCounterTypes] = {32. , 52., 32., 32., 0.2, 32., 28.8, 20., 2.4}; +const Float_t Glass_Y[NumberOfDifferentCounterTypes] = {26.9, 53., 20., 10., 0.2, 10., 6., 20., 2.4}; +const Float_t Glass_Z[NumberOfDifferentCounterTypes] = {0.1, 0.1,0.1, 0.1,0.01 ,0.1,0.1, 0.1, 0.1}; + +const Float_t GasGap_X[NumberOfDifferentCounterTypes] = {32. , 52., 32., 32., 0.2, 32., 28.8, 20., 2.4}; +const Float_t GasGap_Y[NumberOfDifferentCounterTypes] = {26.9, 53., 20., 10., 0.2, 10., 6., 20., 2.4}; +const Float_t GasGap_Z[NumberOfDifferentCounterTypes] = {0.025,0.025,0.025,0.025,0.01,0.02,0.02,0.02,0.025}; + +const Int_t NumberOfGaps[NumberOfDifferentCounterTypes] = {8,8,8,8,1,8,10,20,4}; +//const Int_t NumberOfGaps[NumberOfDifferentCounterTypes] = {1,1,1,1}; //deb +const Int_t NumberOfReadoutStrips[NumberOfDifferentCounterTypes] = {32,32,32,32,8,32,32,20,1}; +//const Int_t NumberOfReadoutStrips[NumberOfDifferentCounterTypes] = {1,1,1,1}; //deb + +const Float_t SingleStackStartPosition_Z[NumberOfDifferentCounterTypes] = {-0.6,-0.6,-0.6,-0.6,-0.1,-0.6,-0.6,-0.6,-1.}; + +const Float_t Electronics_X[NumberOfDifferentCounterTypes] = {34.0,53.0,32.0,32.,0.3,0.1, 28.8,20.,0.1}; +const Float_t Electronics_Y[NumberOfDifferentCounterTypes] = { 5.0, 5.0, 1.0, 1.,0.1,0.1,1.0,1.0,0.1}; +const Float_t Electronics_Z[NumberOfDifferentCounterTypes] = { 0.3, 0.3, 0.3, 0.3,0.1,0.1,0.1,0.1,0.1}; + +const Int_t NofModuleTypes = 10; +// 5 Diamond +// 6 Buc +// 7 CERN 20 gap +// 8 Ceramic +// 9 Star2 +// Aluminum box for all module types +const Float_t Module_Size_X[NofModuleTypes] = {180.,180.,180.,180.,180.,5., 40., 30., 22.5, 100.}; +const Float_t Module_Size_Y[NofModuleTypes] = { 49., 49., 74., 28., 18., 5., 12., 30., 11., 49.}; +const Float_t Module_Over_Y[NofModuleTypes] = {11.5,11.5,11., 4.5, 4.5, 0., 0., 0., 0., 0.}; +const Float_t Module_Size_Z[NofModuleTypes] = {11., 11., 13., 11., 11., 1., 12., 6., 6.2, 11.2}; +const Float_t Module_Thick_Alu_X_left = 0.1; +const Float_t Module_Thick_Alu_X_right = 1.0; +const Float_t Module_Thick_Alu_Y = 0.1; +const Float_t Module_Thick_Alu_Z = 0.1; + +// Distance to the center of the TOF wall [cm]; +const Float_t Wall_Z_Position = 400.; +const Float_t MeanTheta = 0.; + +//Type of Counter for module +const Int_t CounterTypeInModule[NofModuleTypes] = {0, 0, 1, 2, 3, 4, 6, 7, 8, 0}; +const Int_t NCounterInModule[NofModuleTypes] = {5, 5, 3, 5, 5, 1, 2, 1, 8, 2}; + +// Placement of the counter inside the module +const Float_t CounterXStartPosition[NofModuleTypes] = {-60.0, -66.0, -56.0,-60.0,-60.0, 0.0, 0., 0., -7., 0.}; +const Float_t CounterXDistance[NofModuleTypes] = {30.0, 32.0, 51.0, 30.0, 30.0, 0.0, 0., 0., 2., 0.}; +const Float_t CounterYStartPosition[NofModuleTypes] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0., 0., -4., -1.3, 0.}; +const Float_t CounterYDistance[NofModuleTypes] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0., 0., 8., 0., 0.}; +const Float_t CounterZDistance[NofModuleTypes] = {-2.5, 0.0, 0.0, 2.5, 2.5, 0., 6., 0., 0.1, 4.}; +const Float_t CounterZStartPosition[NofModuleTypes] = {0.0, 0.0, 0.0, 0.0, 0.0, 0., -3., 0., 0.0, -2.}; +const Float_t CounterRotationAngle[NofModuleTypes] = {0., 8.7, 7.0, 0., 0., 0., 0., 0., 0., 0.}; + +// Pole (support structure) +const Int_t MaxNumberOfPoles=20; +Float_t Pole_ZPos[MaxNumberOfPoles]; +Float_t Pole_Col[MaxNumberOfPoles]; +Int_t NumberOfPoles=0; + +const Float_t Pole_Size_X = 20.; +const Float_t Pole_Size_Y = 300.; +const Float_t Pole_Size_Z = 10.; +const Float_t Pole_Thick_X = 5.; +const Float_t Pole_Thick_Y = 5.; +const Float_t Pole_Thick_Z = 5.; + +// Bars (support structure) +const Float_t Bar_Size_X = 20.; +const Float_t Bar_Size_Y = 20.; +Float_t Bar_Size_Z = 100.; + +const Int_t MaxNumberOfBars=20; +Float_t Bar_ZPos[MaxNumberOfBars]; +Float_t Bar_XPos[MaxNumberOfBars]; +Int_t NumberOfBars=0; + +const Float_t ChamberOverlap=40; +const Float_t DxColl=158.0; //Module_Size_X-ChamberOverlap; +//const Float_t Pole_Offset=Module_Size_X/2.+Pole_Size_X/2.; +const Float_t Pole_Offset=90.0+Pole_Size_X/2.; + +// Position for module placement +const Float_t Inner_Module_First_Y_Position=16.; +const Float_t Inner_Module_Last_Y_Position=480.; +const Float_t Inner_Module_X_Offset=0.; // centered position in x/y +//const Float_t Inner_Module_X_Offset=18; // shift by 16 cm in x +const Int_t Inner_Module_NTypes = 3; +const Float_t Inner_Module_Types[Inner_Module_NTypes] = {4.,3.,0.}; +//const Float_t Inner_Module_Number[Inner_Module_NTypes] = {2.,2.,6.}; //V13_3a +const Float_t Inner_Module_Number[Inner_Module_NTypes] = {2.,2.,1.}; //V13_3a +//const Float_t Inner_Module_Number[Inner_Module_NTypes] = {0.,0.,0.}; //debugging + +const Float_t InnerSide_Module_X_Offset=51.; +const Float_t InnerSide_Module_NTypes = 1; +const Float_t InnerSide_Module_Types[Inner_Module_NTypes] = {5.}; +const Float_t InnerSide_Module_Number[Inner_Module_NTypes] = {2.}; //v13_3a +//const Float_t InnerSide_Module_Number[Inner_Module_NTypes] = {0.}; //debug + +const Float_t Outer_Module_First_Y_Position=0.; +const Float_t Outer_Module_Last_Y_Position=480.; +const Float_t Outer_Module_X_Offset=3.; +const Int_t Outer_Module_Col = 4; +const Int_t Outer_Module_NTypes = 2; +const Float_t Outer_Module_Types [Outer_Module_NTypes][Outer_Module_Col] = {1.,1.,1.,1., 2.,2.,2.,2.}; +const Float_t Outer_Module_Number[Outer_Module_NTypes][Outer_Module_Col] = {9.,9.,2.,0., 0.,0.,3.,4.};//V13_3a +//const Float_t Outer_Module_Number[Outer_Module_NTypes][Outer_Module_Col] = {1.,1.,0.,0., 0.,0.,0.,0.};//debug + +const Float_t Star2_First_Z_Position=TOF_Z_Front + 16.5; +const Float_t Star2_Delta_Z_Position=0.; +const Float_t Star2_First_Y_Position=32.; // +const Float_t Star2_Delta_Y_Position=0.; // +const Float_t Star2_rotate_Z=-90.; +const Int_t Star2_NTypes = 1; +const Float_t Star2_Types[Star2_NTypes] = {9.}; +const Float_t Star2_Number[Star2_NTypes] = {1.}; //debugging, V16b +const Float_t Star2_X_Offset[Star2_NTypes]={51.}; //{62.}; + +const Float_t Buc_First_Z_Position=TOF_Z_Front + 50.; +const Float_t Buc_Delta_Z_Position=0.; +const Float_t Buc_First_Y_Position=-32.5; // +const Float_t Buc_Delta_Y_Position=0.; // +const Float_t Buc_rotate_Z=180.; +const Int_t Buc_NTypes = 1; +const Float_t Buc_Types[Buc_NTypes] = {6.}; +const Float_t Buc_Number[Buc_NTypes] = {1.}; //debugging, V16b +const Float_t Buc_X_Offset[Buc_NTypes]={53.5}; + +const Int_t Cer_NTypes = 3; +const Float_t Cer_Z_Position[Cer_NTypes]={(float)(TOF_Z_Front+13.2),(float)(TOF_Z_Front+45.),(float)(TOF_Z_Front+45.)}; +const Float_t Cer_X_Position[Cer_NTypes]={0.,49.8,49.8}; +const Float_t Cer_Y_Position[Cer_NTypes]={-1.,5.,5.}; +const Float_t Cer_rotate_Z[Cer_NTypes]={0.,0.,0.}; +const Float_t Cer_Types[Cer_NTypes] = {5.,8.,8.}; +const Float_t Cer_Number[Cer_NTypes] = {1.,1.,1.}; //V16b + +const Float_t CERN_Z_Position=TOF_Z_Front+50; // 20 gap +const Float_t CERN_First_Y_Position=36.; +const Float_t CERN_X_Offset=46.; //65.5; +const Float_t CERN_rotate_Z=90.; +const Int_t CERN_NTypes = 1; +const Float_t CERN_Types[CERN_NTypes] = {7.}; // this is the SmType! +const Float_t CERN_Number[CERN_NTypes] = {1.}; // evtl. double for split signals + +// some global variables +TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance +TGeoVolume* gModules[NofModuleTypes]; // Global storage for module types +TGeoVolume* gCounter[NumberOfDifferentCounterTypes]; +TGeoVolume* gPole; +TGeoVolume* gBar[MaxNumberOfBars]; + +const Float_t Dia_Z_Position=-0.5-TOF_Z_Front_Stand; +const Float_t Dia_First_Y_Position=0.; +const Float_t Dia_X_Offset=3.; +const Float_t Dia_rotate_Z=0.; +const Int_t Dia_NTypes = 1; +const Float_t Dia_Types[Dia_NTypes] = {5.}; +const Float_t Dia_Number[Dia_NTypes] = {1.}; + +Float_t Last_Size_Y=0.; +Float_t Last_Over_Y=0.; + +// Forward declarations +void create_materials_from_media_file(); +TGeoVolume* create_counter(Int_t); +TGeoVolume* create_new_counter(Int_t); +TGeoVolume* create_tof_module(Int_t); +TGeoVolume* create_new_tof_module(Int_t); +TGeoVolume* create_tof_pole(); +TGeoVolume* create_tof_bar(); +void position_tof_poles(Int_t); +void position_tof_bars(Int_t); +void position_inner_tof_modules(Int_t); +void position_side_tof_modules(Int_t); +void position_outer_tof_modules(Int_t); +void position_Dia(Int_t); +void position_Star2(Int_t); +void position_Buc(Int_t); +void position_cer_modules(Int_t); +void position_CERN(Int_t); +void dump_info_file(); + + +void Create_TOF_Geometry_v20c_mcbm() { + + // Load needed material definition from media.geo file + create_materials_from_media_file(); + + // Get the GeoManager for later usage + gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom"); + gGeoMan->SetVisLevel(5); // 2 = super modules + gGeoMan->SetVisOption(0); + + // Create the top volume + /* + TGeoBBox* topbox= new TGeoBBox("", 1000., 1000., 1000.); + TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air")); + gGeoMan->SetTopVolume(top); + */ + + TGeoVolume* top = new TGeoVolumeAssembly("TOP"); + gGeoMan->SetTopVolume(top); + + TGeoRotation* tof_rotation = new TGeoRotation(); + tof_rotation->RotateY( 0. ); // angle with respect to beam axis + //tof_rotation->RotateZ( 0 ); // electronics on 9 o'clock position = +x + // tof_rotation->RotateZ( 0 ); // electronics on 9 o'clock position = +x + // tof_rotation->RotateZ( 90 ); // electronics on 12 o'clock position (top) + // tof_rotation->RotateZ( 180 ); // electronics on 3 o'clock position = -x + // tof_rotation->RotateZ( 270 ); // electronics on 6 o'clock position (bottom) + + TGeoVolume* tof = new TGeoVolumeAssembly(geoVersion); +// top->AddNode(tof, 1, tof_rotation); + top->AddNode(tof,1); + + TGeoVolume* tofstand = new TGeoVolumeAssembly(geoVersionStand); + // Mar 2020 run + TGeoTranslation* stand_trans = new TGeoTranslation("", 0., 0., TOF_Z_Front_Stand); + // Nov 2019 run + // TGeoTranslation* stand_trans = new TGeoTranslation("", 12., 0., TOF_Z_Front_Stand); + // TGeoTranslation* stand_trans = new TGeoTranslation("", 0., 0., TOF_Z_Front_Stand); + TGeoRotation* stand_rot = new TGeoRotation(); + stand_rot->RotateY(0.0); + TGeoCombiTrans* stand_combi_trans = new TGeoCombiTrans(*stand_trans, *stand_rot); + // tof->AddNode(tofstand, 1, stand_combi_trans); + tof->AddNode(tofstand,1); + + for(Int_t counterType = 0; counterType < NumberOfDifferentCounterTypes; counterType++) { + gCounter[counterType] = create_new_counter(counterType); + } + + for(Int_t moduleType = 0; moduleType < NofModuleTypes; moduleType++) { + gModules[moduleType] = create_new_tof_module(moduleType); + gModules[moduleType]->SetVisContainers(1); + } + + // no pole + // gPole = create_tof_pole(); + + // position_side_tof_modules(1); // keep order !! + // position_inner_tof_modules(2); + position_inner_tof_modules(3); + position_Dia(1); + // position_Star2(1); + // position_cer_modules(3); + // position_CERN(1); + // position_Buc(1); + + cout << "Outer Types "<<Outer_Module_Types[0][0]<<", "<<Outer_Module_Types[1][0] + <<", col=1: "<<Outer_Module_Types[0][1]<<", "<<Outer_Module_Types[1][1] + <<endl; + cout << "Outer Number "<<Outer_Module_Number[0][0]<<", "<<Outer_Module_Number[1][0] + <<", col=1: "<<Outer_Module_Number[0][1]<<", "<<Outer_Module_Number[1][1] + <<endl; + // position_outer_tof_modules(4); + // position_tof_poles(0); + // position_tof_bars(0); + + gGeoMan->CloseGeometry(); + gGeoMan->CheckOverlaps(0.001); + gGeoMan->PrintOverlaps(); + gGeoMan->CheckOverlaps(0.001,"s"); + gGeoMan->PrintOverlaps(); + gGeoMan->Test(); + + tof->Export(FileNameSim); + TFile* geoFile = new TFile(FileNameSim, "UPDATE"); + stand_combi_trans->Write(); + geoFile->Close(); + +/* + TFile* outfile1 = new TFile(FileNameSim,"RECREATE"); + top->Write(); + //gGeoMan->Write(); + outfile1->Close(); +*/ + TFile* outfile2 = new TFile(FileNameGeo,"RECREATE"); + gGeoMan->Write(); + outfile2->Close(); + + dump_info_file(); + + top->SetVisContainers(1); + gGeoMan->SetVisLevel(5); + top->Draw("ogl"); + //top->Draw(); + //gModules[0]->Draw("ogl"); + // gModules[0]->Draw(""); + gModules[0]->SetVisContainers(1); + // gModules[1]->Draw(""); + gModules[1]->SetVisContainers(1); + //gModules[5]->Draw(""); + // top->Raytrace(); + +} + +void create_materials_from_media_file() +{ + // Use the FairRoot geometry interface to load the media which are already defined + FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader"); + FairGeoInterface* geoFace = geoLoad->getGeoInterface(); + TString geoPath = gSystem->Getenv("VMCWORKDIR"); + TString geoFile = geoPath + "/geometry/media.geo"; + geoFace->setMediaFile(geoFile); + geoFace->readMedia(); + + // Read the required media and create them in the GeoManager + FairGeoMedia* geoMedia = geoFace->getMedia(); + FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder(); + + FairGeoMedium* air = geoMedia->getMedium("air"); + FairGeoMedium* aluminium = geoMedia->getMedium("aluminium"); + FairGeoMedium* RPCgas = geoMedia->getMedium("RPCgas"); + FairGeoMedium* RPCgas_noact = geoMedia->getMedium("RPCgas_noact"); + FairGeoMedium* RPCglass = geoMedia->getMedium("RPCglass"); + FairGeoMedium* carbon = geoMedia->getMedium("carbon"); + + // include check if all media are found + + geoBuild->createMedium(air); + geoBuild->createMedium(aluminium); + geoBuild->createMedium(RPCgas); + geoBuild->createMedium(RPCgas_noact); + geoBuild->createMedium(RPCglass); + geoBuild->createMedium(carbon); +} + +TGeoVolume* create_counter(Int_t modType) +{ + + //glass + Float_t gdx=Glass_X[modType]; + Float_t gdy=Glass_Y[modType]; + Float_t gdz=Glass_Z[modType]; + + //gas gap + Int_t nstrips=NumberOfReadoutStrips[modType]; + Int_t ngaps=NumberOfGaps[modType]; + + + Float_t ggdx=GasGap_X[modType]; + Float_t ggdy=GasGap_Y[modType]; + Float_t ggdz=GasGap_Z[modType]; + Float_t gsdx=ggdx/float(nstrips); + + //single stack + Float_t dzpos=gdz+ggdz; + Float_t startzpos=SingleStackStartPosition_Z[modType]; + + // electronics + //pcb dimensions + Float_t dxe=Electronics_X[modType]; + Float_t dye=Electronics_Y[modType]; + Float_t dze=Electronics_Z[modType]; + Float_t yele=(gdy+0.1)/2.+dye/2.; + + // needed materials + TGeoMedium* glassPlateVolMed = gGeoMan->GetMedium(GlasMedium); + TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); + TGeoMedium* activeGasVolMed = gGeoMan->GetMedium(ActivGasMedium); + TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsMedium); + + // Single glass plate + TGeoBBox* glass_plate = new TGeoBBox("", gdx/2., gdy/2., gdz/2.); + TGeoVolume* glass_plate_vol = + new TGeoVolume("tof_glass", glass_plate, glassPlateVolMed); + glass_plate_vol->SetLineColor(kMagenta); // set line color for the glass plate + glass_plate_vol->SetTransparency(20); // set transparency for the TOF + TGeoTranslation* glass_plate_trans + = new TGeoTranslation("", 0., 0., 0.); + + // Single gas gap + TGeoBBox* gas_gap = new TGeoBBox("", ggdx/2., ggdy/2., ggdz/2.); + //TGeoVolume* gas_gap_vol = + //new TGeoVolume("tof_gas_gap", gas_gap, noActiveGasVolMed); + TGeoVolume* gas_gap_vol = + new TGeoVolume("tof_gas_active", gas_gap, activeGasVolMed); + gas_gap_vol->Divide("Strip",1,nstrips,-ggdx/2.,0); + + gas_gap_vol->SetLineColor(kRed); // set line color for the gas gap + gas_gap_vol->SetTransparency(70); // set transparency for the TOF + TGeoTranslation* gas_gap_trans + = new TGeoTranslation("", 0., 0., (gdz+ggdz)/2.); + + + // Single subdivided active gas gap + /* + TGeoBBox* gas_active = new TGeoBBox("", gsdx/2., ggdy/2., ggdz/2.); + TGeoVolume* gas_active_vol = + new TGeoVolume("tof_gas_active", gas_active, activeGasVolMed); + gas_active_vol->SetLineColor(kBlack); // set line color for the gas gap + gas_active_vol->SetTransparency(70); // set transparency for the TOF + */ + + // Add glass plate, inactive gas gap and active gas gaps to a single stack + TGeoVolume* single_stack = new TGeoVolumeAssembly("single_stack"); + single_stack->AddNode(glass_plate_vol, 0, glass_plate_trans); + single_stack->AddNode(gas_gap_vol, 0, gas_gap_trans); + + /* + for (Int_t l=0; l<nstrips; l++){ + TGeoTranslation* gas_active_trans + = new TGeoTranslation("", -ggdx/2+(l+0.5)*gsdx, 0., 0.); + gas_gap_vol->AddNode(gas_active_vol, l, gas_active_trans); + // single_stack->AddNode(gas_active_vol, l, gas_active_trans); + } + */ + + // Add 8 single stacks + one glass plate at the e09.750nd to a multi stack + TGeoVolume* multi_stack = new TGeoVolumeAssembly("multi_stack"); + Int_t l; + for (l=0; l<ngaps; l++){ + TGeoTranslation* single_stack_trans + = new TGeoTranslation("", 0., 0., startzpos + l*dzpos); + multi_stack->AddNode(single_stack, l, single_stack_trans); + } + TGeoTranslation* single_glass_back_trans + = new TGeoTranslation("", 0., 0., startzpos + ngaps*dzpos); + multi_stack->AddNode(glass_plate_vol, l, single_glass_back_trans); + + // Add electronics above and below the glass stack to build a complete counter + TGeoVolume* counter = new TGeoVolumeAssembly("counter"); + TGeoTranslation* multi_stack_trans + = new TGeoTranslation("", 0., 0., 0.); + counter->AddNode(multi_stack, l, multi_stack_trans); + + TGeoBBox* pcb = new TGeoBBox("", dxe/2., dye/2., dze/2.); + TGeoVolume* pcb_vol = + new TGeoVolume("pcb", pcb, electronicsVolMed); + pcb_vol->SetLineColor(kCyan); // set line color for the gas gap + pcb_vol->SetTransparency(10); // set transparency for the TOF + for (Int_t l=0; l<2; l++){ + yele *= -1.; + TGeoTranslation* pcb_trans + = new TGeoTranslation("", 0., yele, 0.); + counter->AddNode(pcb_vol, l, pcb_trans); + } + + return counter; + +} + +TGeoVolume* create_new_counter(Int_t modType) +{ + + //glass + Float_t gdx=Glass_X[modType]; + Float_t gdy=Glass_Y[modType]; + Float_t gdz=Glass_Z[modType]; + + //gas gap + Int_t nstrips=NumberOfReadoutStrips[modType]; + Int_t ngaps=NumberOfGaps[modType]; + + + Float_t ggdx=GasGap_X[modType]; + Float_t ggdy=GasGap_Y[modType]; + Float_t ggdz=GasGap_Z[modType]; + Float_t gsdx=ggdx/(Float_t)(nstrips); + + // electronics + //pcb dimensions + Float_t dxe=Electronics_X[modType]; + Float_t dye=Electronics_Y[modType]; + Float_t dze=Electronics_Z[modType]; + Float_t yele=gdy/2.+dye/2.; + + // counter size (calculate from glas, gap and electronics sizes) + Float_t cdx = TMath::Max(gdx, ggdx); + cdx = TMath::Max(cdx, dxe)+ 0.2; + Float_t cdy = TMath::Max(gdy, ggdy) + 2*dye + 0.2; + Float_t cdz = ngaps * ggdz + (ngaps+1) * gdz + 0.2; // ngaps * (gdz+ggdz) + gdz + 0.2; // ok + + //calculate thickness and first position in counter of single stack + Float_t dzpos = gdz+ggdz; + Float_t startzposglas= -ngaps * (gdz + ggdz) /2.; // -cdz/2.+0.1+gdz/2.; // ok // (-cdz+gdz)/2.; // not ok + Float_t startzposgas = startzposglas + gdz/2. + ggdz/2.; // -cdz/2.+0.1+gdz +ggdz/2.; // ok + + + // needed materials + TGeoMedium* glassPlateVolMed = gGeoMan->GetMedium(GlasMedium); + TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); + TGeoMedium* activeGasVolMed = gGeoMan->GetMedium(ActivGasMedium); + TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsMedium); + + + // define counter volume + TGeoBBox* counter_box = new TGeoBBox("", cdx/2., cdy/2., cdz/2.); + TGeoVolume* counter = + new TGeoVolume("counter", counter_box, noActiveGasVolMed); + counter->SetLineColor(kRed); // set line color for the counter + counter->SetTransparency(70); // set transparency for the TOF + + // define single glass plate volume + TGeoBBox* glass_plate = new TGeoBBox("", gdx/2., gdy/2., gdz/2.); + TGeoVolume* glass_plate_vol = + new TGeoVolume("tof_glass", glass_plate, glassPlateVolMed); + glass_plate_vol->SetLineColor(kMagenta); // set line color for the glass plate + glass_plate_vol->SetTransparency(20); // set transparency for the TOF + // define single gas gap volume + TGeoBBox* gas_gap = new TGeoBBox("", ggdx/2., ggdy/2., ggdz/2.); + TGeoVolume* gas_gap_vol = + new TGeoVolume("Gap", gas_gap, activeGasVolMed); + gas_gap_vol->Divide("Cell",1,nstrips,-ggdx/2.,0); + gas_gap_vol->SetLineColor(kRed); // set line color for the gas gap + gas_gap_vol->SetTransparency(99); // set transparency for the TOF + + // place 8 gas gaps and 9 glas plates in the counter + for( Int_t igap = 0; igap <= ngaps; igap++) { + // place (ngaps+1) glass plates + Float_t zpos_glas = startzposglas + igap*dzpos; + TGeoTranslation* glass_plate_trans + = new TGeoTranslation("", 0., 0., zpos_glas); + counter->AddNode(glass_plate_vol, igap, glass_plate_trans); + // place ngaps gas gaps + if (igap < ngaps) + { + Float_t zpos_gas = startzposgas + igap*dzpos; + TGeoTranslation* gas_gap_trans + = new TGeoTranslation("", 0., 0., zpos_gas); + counter->AddNode(gas_gap_vol, igap, gas_gap_trans); + } +// cout <<"Zpos(Glas): "<< zpos_glas << endl; +// cout <<"Zpos(Gas): "<< zpos_gas << endl; + } + + // create and place the electronics above and below the glas stack + TGeoBBox* pcb = new TGeoBBox("", dxe/2., dye/2., dze/2.); + TGeoVolume* pcb_vol = + new TGeoVolume("pcb", pcb, electronicsVolMed); + pcb_vol->SetLineColor(kYellow); // kCyan); // set line color for electronics + pcb_vol->SetTransparency(10); // set transparency for the TOF + for (Int_t l=0; l<2; l++){ + yele *= -1.; + TGeoTranslation* pcb_trans + = new TGeoTranslation("", 0., yele, 0.); + counter->AddNode(pcb_vol, l, pcb_trans); + } + + + return counter; + +} + +TGeoVolume* create_tof_module(Int_t modType) +{ + Int_t cType = CounterTypeInModule[modType]; + Float_t dx=Module_Size_X[modType]; + Float_t dy=Module_Size_Y[modType]; + Float_t dz=Module_Size_Z[modType]; + Float_t width_aluxl=Module_Thick_Alu_X_left; + Float_t width_aluxr=Module_Thick_Alu_X_right; + Float_t width_aluy=Module_Thick_Alu_Y; + Float_t width_aluz=Module_Thick_Alu_Z; + + Float_t shift_gas_box = (Module_Thick_Alu_X_right - Module_Thick_Alu_X_left)/2; + + Float_t dxpos=CounterXDistance[modType]; + Float_t startxpos=CounterXStartPosition[modType]; + Float_t dzoff=CounterZDistance[modType]; + Float_t rotangle=CounterRotationAngle[modType]; + + TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium); + TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); + + TString moduleName = Form("module_%d", modType); + TGeoVolume* module = new TGeoVolumeAssembly(moduleName); + + TGeoBBox* alu_box = new TGeoBBox("", dx/2., dy/2., dz/2.); + TGeoVolume* alu_box_vol = + new TGeoVolume("alu_box", alu_box, boxVolMed); + alu_box_vol->SetLineColor(kGreen); // set line color for the alu box + alu_box_vol->SetTransparency(20); // set transparency for the TOF + TGeoTranslation* alu_box_trans + = new TGeoTranslation("", 0., 0., 0.); + module->AddNode(alu_box_vol, 0, alu_box_trans); + + TGeoBBox* gas_box = new TGeoBBox("", (dx-(width_aluxl+width_aluxr))/2., (dy-2*width_aluy)/2., (dz-2*width_aluz)/2.); + TGeoVolume* gas_box_vol = + new TGeoVolume("gas_box", gas_box, noActiveGasVolMed); + gas_box_vol->SetLineColor(kYellow); // set line color for the gas box + gas_box_vol->SetTransparency(70); // set transparency for the TOF + TGeoTranslation* gas_box_trans + = new TGeoTranslation("", shift_gas_box, 0., 0.); + alu_box_vol->AddNode(gas_box_vol, 0, gas_box_trans); + + for (Int_t j=0; j<5; j++){ //loop over counters (modules) + Float_t zpos; + if (0 == modType) { + zpos = dzoff *=-1; + } else { + zpos = 0.; + } + //cout << "counter z position " << zpos << endl; + TGeoTranslation* counter_trans + = new TGeoTranslation("", startxpos+ j*dxpos , 0.0 , zpos); + + TGeoRotation* counter_rot = new TGeoRotation(); + counter_rot->RotateY(rotangle); + TGeoCombiTrans* counter_combi_trans = new TGeoCombiTrans(*counter_trans, *counter_rot); + gas_box_vol->AddNode(gCounter[cType], j, counter_combi_trans); + } + + return module; +} + +TGeoVolume* create_new_tof_module(Int_t modType) +{ + Int_t cType = CounterTypeInModule[modType]; + Float_t dx=Module_Size_X[modType]; + Float_t dy=Module_Size_Y[modType]; + Float_t dz=Module_Size_Z[modType]; + Float_t width_aluxl=Module_Thick_Alu_X_left; + Float_t width_aluxr=Module_Thick_Alu_X_right; + Float_t width_aluy=Module_Thick_Alu_Y; + Float_t width_aluz=Module_Thick_Alu_Z; + + Float_t shift_gas_box = (Module_Thick_Alu_X_right - Module_Thick_Alu_X_left)/2; + + Float_t dxpos=CounterXDistance[modType]; + Float_t startxpos=CounterXStartPosition[modType]; + Float_t dypos=CounterYDistance[modType]; + Float_t startypos=CounterYStartPosition[modType]; + Float_t dzoff=CounterZDistance[modType]; + Float_t rotangle=CounterRotationAngle[modType]; + + TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium); + TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); + + TString moduleName = Form("module_%d", modType); + + TGeoBBox* module_box = new TGeoBBox("", dx/2., dy/2., dz/2.); + TGeoVolume* module = + new TGeoVolume(moduleName, module_box, boxVolMed); + module->SetLineColor(kGreen); // set line color for the alu box + module->SetTransparency(20); // set transparency for the TOF + + TGeoBBox* gas_box = new TGeoBBox("", (dx-(width_aluxl+width_aluxr))/2., (dy-2*width_aluy)/2., (dz-2*width_aluz)/2.); + TGeoVolume* gas_box_vol = + new TGeoVolume("gas_box", gas_box, noActiveGasVolMed); + gas_box_vol->SetLineColor(kBlue); // set line color for the alu box + gas_box_vol->SetTransparency(50); // set transparency for the TOF + TGeoTranslation* gas_box_trans + = new TGeoTranslation("", shift_gas_box, 0., 0.); + module->AddNode(gas_box_vol, 0, gas_box_trans); + + for (Int_t j=0; j< NCounterInModule[modType]; j++){ //loop over counters (modules) + //for (Int_t j=0; j< 1; j++){ //loop over counters (modules) + Float_t xpos,ypos,zpos; + if (0 == modType || 3 == modType || 4 == modType || 5 == modType) { + zpos = dzoff *=-1; + } else { + zpos = CounterZStartPosition[modType]+j*dzoff; + } + //cout << "counter z position " << zpos << endl; + xpos=startxpos + j*dxpos; + ypos=startypos + j*dypos; + + TGeoTranslation* counter_trans + = new TGeoTranslation("", xpos , ypos , zpos); + + TGeoRotation* counter_rot = new TGeoRotation(); + counter_rot->RotateY(rotangle); + TGeoCombiTrans* counter_combi_trans = new TGeoCombiTrans(*counter_trans, *counter_rot); + gas_box_vol->AddNode(gCounter[cType], j, counter_combi_trans); + } + + return module; +} + + +TGeoVolume* create_tof_pole() +{ + // needed materials + TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium); + TGeoMedium* airVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + + Float_t dx=Pole_Size_X; + Float_t dy=Pole_Size_Y; + Float_t dz=Pole_Size_Z; + Float_t width_alux=Pole_Thick_X; + Float_t width_aluy=Pole_Thick_Y; + Float_t width_aluz=Pole_Thick_Z; + + TGeoVolume* pole = new TGeoVolumeAssembly("Pole"); + TGeoBBox* pole_alu_box = new TGeoBBox("", dx/2., dy/2., dz/2.); + TGeoVolume* pole_alu_vol = + new TGeoVolume("pole_alu", pole_alu_box, boxVolMed); + pole_alu_vol->SetLineColor(kGreen); // set line color for the alu box + pole_alu_vol->SetTransparency(20); // set transparency for the TOF + TGeoTranslation* pole_alu_trans + = new TGeoTranslation("", 0., 0., 0.); + pole->AddNode(pole_alu_vol, 0, pole_alu_trans); + + Float_t air_dx = dx/2. - width_alux; + Float_t air_dy = dy/2. - width_aluy; + Float_t air_dz = dz/2. - width_aluz; + + // cout << "My pole." << endl; + if (air_dx <= 0.) + cout << "ERROR - No air volume in pole X, size: "<< air_dx << endl; + if (air_dy <= 0.) + cout << "ERROR - No air volume in pole Y, size: "<< air_dy << endl; + if (air_dz <= 0.) + cout << "ERROR - No air volume in pole Z, size: "<< air_dz << endl; + + if ((air_dx > 0.) && (air_dy > 0.) && (air_dz > 0.)) // crate air volume only, if larger than zero + { + TGeoBBox* pole_air_box = new TGeoBBox("", air_dx, air_dy, air_dz); + // TGeoBBox* pole_air_box = new TGeoBBox("", dx/2.-width_alux, dy/2.-width_aluy, dz/2.-width_aluz); + TGeoVolume* pole_air_vol = + new TGeoVolume("pole_air", pole_air_box, airVolMed); + pole_air_vol->SetLineColor(kYellow); // set line color for the alu box + pole_air_vol->SetTransparency(70); // set transparency for the TOF + TGeoTranslation* pole_air_trans + = new TGeoTranslation("", 0., 0., 0.); + pole_alu_vol->AddNode(pole_air_vol, 0, pole_air_trans); + } + else + cout << "Skipping pole_air_vol, no thickness: " << air_dx << " " << air_dy << " " << air_dz << endl; + + return pole; +} + +TGeoVolume* create_tof_bar(Float_t dx, Float_t dy, Float_t dz) +{ + // needed materials + TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium); + TGeoMedium* airVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + + Float_t width_alux=Pole_Thick_X; + Float_t width_aluy=Pole_Thick_Y; + Float_t width_aluz=Pole_Thick_Z; + + TGeoVolume* bar = new TGeoVolumeAssembly("Bar"); + TGeoBBox* bar_alu_box = new TGeoBBox("", dx/2., dy/2., dz/2.); + TGeoVolume* bar_alu_vol = + new TGeoVolume("bar_alu", bar_alu_box, boxVolMed); + bar_alu_vol->SetLineColor(kGreen); // set line color for the alu box + bar_alu_vol->SetTransparency(20); // set transparency for the TOF + TGeoTranslation* bar_alu_trans + = new TGeoTranslation("", 0., 0., 0.); + bar->AddNode(bar_alu_vol, 0, bar_alu_trans); + + TGeoBBox* bar_air_box = new TGeoBBox("", dx/2.-width_alux, dy/2.-width_aluy, dz/2.-width_aluz); + TGeoVolume* bar_air_vol = + new TGeoVolume("bar_air", bar_air_box, airVolMed); + bar_air_vol->SetLineColor(kYellow); // set line color for the alu box + bar_air_vol->SetTransparency(70); // set transparency for the TOF + TGeoTranslation* bar_air_trans + = new TGeoTranslation("", 0., 0., 0.); + bar_alu_vol->AddNode(bar_air_vol, 0, bar_air_trans); + + return bar; +} + +void position_tof_poles(Int_t modType) +{ + + TGeoTranslation* pole_trans=NULL; + + Int_t numPoles=0; + for (Int_t i=0; i<NumberOfPoles; i++){ + if(i<2) { + pole_trans + = new TGeoTranslation("", -Pole_Offset+2.0, 0., Pole_ZPos[i]); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gPole, numPoles, pole_trans); + numPoles++; + }else{ + Float_t xPos=Pole_Offset+Pole_Size_X/2.+Pole_Col[i]*DxColl; + Float_t zPos=Pole_ZPos[i]; + pole_trans + = new TGeoTranslation("", xPos, 0., zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gPole, numPoles, pole_trans); + numPoles++; + + pole_trans + = new TGeoTranslation("", -xPos, 0., zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gPole, numPoles, pole_trans); + numPoles++; + } + cout << " Position Pole "<< numPoles<<" at z="<< Pole_ZPos[i] << endl; + } +} + +void position_tof_bars(Int_t modType) +{ + + TGeoTranslation* bar_trans=NULL; + + Int_t numBars=0; + Int_t i; + Float_t xPos; + Float_t yPos; + Float_t zPos; + + for (i=0; i<NumberOfBars; i++){ + + xPos=Bar_XPos[i]; + zPos=Bar_ZPos[i]; + yPos=Pole_Size_Y/2.+Bar_Size_Y/2.; + + bar_trans = new TGeoTranslation("", xPos, yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + bar_trans = new TGeoTranslation("", xPos,-yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + bar_trans = new TGeoTranslation("", -xPos, yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + bar_trans = new TGeoTranslation("", -xPos, -yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + } + cout << " Position Bar "<< numBars<<" at z="<< Bar_ZPos[i] << endl; + + // horizontal frame bars + i = NumberOfBars; + NumberOfBars++; + // no bar + // gBar[i]=create_tof_bar(2.*xPos+Pole_Size_X,Bar_Size_Y,Bar_Size_Y); + + zPos = Pole_ZPos[0]+Pole_Size_Z/2.; + bar_trans = new TGeoTranslation("", 0., yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + bar_trans = new TGeoTranslation("", 0., -yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + +} + +void position_inner_tof_modules(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + + // Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1; + Float_t yPos=Inner_Module_First_Y_Position; + Int_t ii=0; + Float_t xPos = Inner_Module_X_Offset; + Float_t zPos = Wall_Z_Position; + + Pole_ZPos[NumberOfPoles] = zPos; + Pole_Col[NumberOfPoles] = 0; + NumberOfPoles++; + + Float_t DzPos =0.; + for (Int_t j=0; j<modNType; j++){ + if (Module_Size_Z[j]>DzPos){ + DzPos = Module_Size_Z[j]; + } + } + Pole_ZPos[NumberOfPoles]=zPos+DzPos; + Pole_Col[NumberOfPoles] = 0; + NumberOfPoles++; + + // for (Int_t j=0; j<modNType; j++){ + // for (Int_t j=1; j<modNType; j++){ + Int_t modType; + Int_t modNum; + for (Int_t j=2; j<modNType; j++){ // place only M4 type modules (modNType == 2) + //DEDE + modType = Inner_Module_Types[j]; + modNum = 0; + // for(Int_t i=0; i<Inner_Module_Number[j]; i++) { + // for(Int_t i=0; i<1; i++) { // place 1x2 modules in the top and same in the bottom + for(Int_t i=0; i<2; i++) { // place 2x2 modules in the top and same in the bottom + ii++; + cout << "Inner ii "<<ii<<" Last "<<Last_Size_Y<<", "<<Last_Over_Y<<endl; + Float_t DeltaY=Module_Size_Y[modType]+Last_Size_Y-2.*(Module_Over_Y[modType]+Last_Over_Y); + // DeltaY = 1.5; + cout << "DeltaY " << DeltaY << endl; + yPos += DeltaY; + Last_Size_Y=Module_Size_Y[modType]; + Last_Over_Y=Module_Over_Y[modType]; + cout <<"Position Inner Module "<<i<<" of "<<Inner_Module_Number[j]<<" Type "<<modType + <<" at Y = "<<yPos<<" Ysize = "<<Module_Size_Y[modType] + <<" DeltaY = "<<DeltaY<<endl; + +/// module_trans = new TGeoTranslation("", xPos, yPos, zPos); +/// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); +/// modNum++; +/// module_trans = new TGeoTranslation("", xPos, -yPos, zPos); +/// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); +/// modNum++; +// // if (ii>0) { +// if (ii>1) { +// module_trans +// = new TGeoTranslation("", xPos, yPos-DeltaY/2, zPos+Module_Size_Z[modType]); +// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); +// modNum++; +// module_trans +// = new TGeoTranslation("", xPos, -(yPos-DeltaY/2), zPos+Module_Size_Z[modType]); +// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); +// modNum++; +// } + } + } + // module_trans = new TGeoTranslation("", xPos, -49-3, zPos); + + // Mar2019 setup + const Int_t NModules=5; + xPos=0.; + yPos=0.; + zPos=TOF_Z_Front; + const Double_t ModDx[NModules]= { -50., 0., 50., -25., 25.0}; + //const Double_t ModDx[NModules]= { 1.5, 0., -1.5, 49.8, 55.8}; + const Double_t ModDy[NModules]= { 0., 0., 0., 0., 0. }; + const Double_t ModDz[NModules]= { 0., 0, 0, 16.5, 16.5 }; + const Double_t ModAng[NModules]={-90.,-90.,-90., -90.,-90.0}; + TGeoRotation* module_rot = NULL; + TGeoCombiTrans* module_combi_trans = NULL; + + for (Int_t iMod=0; iMod<NModules; iMod++) { + module_trans = new TGeoTranslation("", xPos+ModDx[iMod], yPos+ModDy[iMod], zPos+ModDz[iMod]); + module_rot = new TGeoRotation(); + module_rot->RotateZ(ModAng[iMod]); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + } + + + /* + module_trans = new TGeoTranslation("", xPos, 0, zPos+16.5); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + // module_trans = new TGeoTranslation("", xPos, 49+3, zPos); + module_trans = new TGeoTranslation("", xPos, 0, zPos+16.5+17.5); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + // module_trans = new TGeoTranslation("", xPos,-26, zPos+Module_Size_Z[modType]); + module_trans = new TGeoTranslation("", xPos, -49.8, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + // module_trans = new TGeoTranslation("", xPos, 26, zPos+Module_Size_Z[modType]); + module_trans = new TGeoTranslation("", xPos, -49.8, zPos+16.5); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + */ +} + + +void position_Dia(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(Dia_rotate_Z); + TGeoCombiTrans* module_combi_trans = NULL; + + // Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1; + Float_t yPos=Dia_First_Y_Position; + Int_t ii=0; + Float_t xPos = Dia_X_Offset; + Float_t zPos = Dia_Z_Position; + + Int_t modNum = 0; + for (Int_t j=0; j<modNType; j++){ + Int_t modType= Dia_Types[j]; + for(Int_t i=0; i<Dia_Number[j]; i++) { + ii++; + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + } + } +} + +void position_Star2(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(Star2_rotate_Z); + TGeoCombiTrans* module_combi_trans = NULL; + + Float_t yPos = Star2_First_Y_Position; + Float_t zPos = Star2_First_Z_Position; + Int_t ii=0; + + Int_t modNum = 0; + for (Int_t j=0; j<modNType; j++){ + Int_t modType= Star2_Types[j]; + Float_t xPos = Star2_X_Offset[j]; + for(Int_t i=0; i<Star2_Number[j]; i++) { + ii++; + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + yPos += Star2_Delta_Y_Position; + zPos += Star2_Delta_Z_Position; + } + + } +} + +void position_Buc(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(Buc_rotate_Z); + TGeoCombiTrans* module_combi_trans = NULL; + + Float_t yPos = Buc_First_Y_Position; + Float_t zPos = Buc_First_Z_Position; + Int_t ii=0; + + Int_t modNum = 0; + for (Int_t j=0; j<modNType; j++){ + Int_t modType= Buc_Types[j]; + Float_t xPos = Buc_X_Offset[j]; + for(Int_t i=0; i<Buc_Number[j]; i++) { + ii++; + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + yPos += Buc_Delta_Y_Position; + zPos += Buc_Delta_Z_Position; + } + } +} + +void position_cer_modules(Int_t modNType) +{ + Int_t ii=0; + Int_t modNum = 0; + for (Int_t j=1; j<modNType; j++){ + Int_t modType= Cer_Types[j]; + Float_t xPos = Cer_X_Position[j]; + Float_t yPos = Cer_Y_Position[j]; + Float_t zPos = Cer_Z_Position[j]; + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(Form("Cer%d",j),Cer_rotate_Z[j],-MeanTheta,0.); + // module_rot->RotateZ(Cer_rotate_Z[j]); + TGeoCombiTrans* module_combi_trans = NULL; + + for(Int_t i=0; i<Cer_Number[j]; i++) { + ii++; + cout <<"Position Ceramic Module "<<i<<" of "<<Cer_Number[j]<<" Type "<<modType + <<" at X = "<<xPos + <<", Y = "<<yPos + <<", Z = "<<zPos + <<endl; + // Front staggered module (Top if pair), top + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + // modNum++; + } + } +} + +void position_CERN(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(CERN_rotate_Z); + TGeoCombiTrans* module_combi_trans = NULL; + + // Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1; + Float_t yPos=CERN_First_Y_Position; + Int_t ii=0; + Float_t xPos = CERN_X_Offset; + Float_t zPos = CERN_Z_Position; + + for (Int_t j=0; j<modNType; j++){ + Int_t modType= CERN_Types[j]; + Int_t modNum = 0; + for(Int_t i=0; i<CERN_Number[j]; i++) { + ii++; + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + } + } +} + +void position_side_tof_modules(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(180.); + TGeoCombiTrans* module_combi_trans = NULL; + + // Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1; + Float_t yPos=0.; //Inner_Module_First_Y_Position; + Int_t ii=0; + for (Int_t j=0; j<modNType; j++){ + Int_t modType= InnerSide_Module_Types[j]; + Int_t modNum = 0; + for(Int_t i=0; i<InnerSide_Module_Number[j]; i++) { + ii++; + cout << "InnerSide ii "<<ii<<" Last "<<Last_Size_Y<<","<<Last_Over_Y<<endl; + Float_t DeltaY=Module_Size_Y[modType]+Last_Size_Y-2.*(Module_Over_Y[modType]+Last_Over_Y); + if (ii>1){yPos += DeltaY;} + Last_Size_Y=Module_Size_Y[modType]; + Last_Over_Y=Module_Over_Y[modType]; + Float_t xPos = InnerSide_Module_X_Offset; + Float_t zPos = Wall_Z_Position; + cout <<"Position InnerSide Module "<<i<<" of "<<InnerSide_Module_Number[j]<<" Type "<<modType + <<" at Y = "<<yPos<<" Ysize = "<<Module_Size_Y[modType] + <<" DeltaY = "<<DeltaY<<endl; + + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + module_trans + = new TGeoTranslation("", -xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + + if (ii>1) { + module_trans + = new TGeoTranslation("", xPos, -yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + module_trans + = new TGeoTranslation("", -xPos, -yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + + module_trans + = new TGeoTranslation("", xPos, yPos-DeltaY/2, zPos+Module_Size_Z[modType]); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + module_trans + = new TGeoTranslation("", -xPos, yPos-DeltaY/2, zPos+Module_Size_Z[modType]); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + + module_trans + = new TGeoTranslation("", xPos, -(yPos-DeltaY/2), zPos+Module_Size_Z[modType]); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + module_trans + = new TGeoTranslation("", -xPos,-(yPos-DeltaY/2), zPos+Module_Size_Z[modType]); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + + } + } + } +} + +void position_outer_tof_modules(Int_t nCol) //modType, Int_t col1, Int_t col2) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(180.); + TGeoCombiTrans* module_combi_trans = NULL; + + // Int_t numModules=(Int_t)( (Outer_Module_Last_Y_Position-Outer_Module_First_Y_Position)/Module_Size_Y[modType])+1; + + Int_t modNum[NofModuleTypes]; + for (Int_t k=0; k<NofModuleTypes; k++){ + modNum[k]=0; + } + + Float_t zPos = Wall_Z_Position; + for(Int_t j=0; j<nCol; j++){ + Float_t xPos = Outer_Module_X_Offset + ((j+1)*DxColl); + Last_Size_Y=0.; + Last_Over_Y=0.; + Float_t yPos = 0.; + Int_t ii=0; + Float_t DzPos =0.; + for(Int_t k=0; k<Outer_Module_NTypes; k++){ + Int_t modType= Outer_Module_Types[k][j]; + if(Module_Size_Z[modType]>DzPos){ + if(Outer_Module_Number[k][j]>0){ + DzPos = Module_Size_Z[modType]; + } + } + } + + zPos -= 2.*DzPos; //((j+1)*2*Module_Size_Z[modType]); + + Pole_ZPos[NumberOfPoles] = zPos; + Pole_Col[NumberOfPoles] = j+1; + NumberOfPoles++; + Pole_ZPos[NumberOfPoles] = zPos+DzPos; + Pole_Col[NumberOfPoles] = j+1; + NumberOfPoles++; + //if (j+1==nCol) { + if (1) { + Pole_ZPos[NumberOfPoles] = Pole_ZPos[0]; + Pole_Col[NumberOfPoles] = j+1; + NumberOfPoles++; + + Bar_Size_Z = Pole_ZPos[0] - zPos; + gBar[NumberOfBars] = create_tof_bar(Bar_Size_X, Bar_Size_Y, Bar_Size_Z); + Bar_ZPos[NumberOfBars] = zPos+Bar_Size_Z/2.-Pole_Size_Z/2.; + Bar_XPos[NumberOfBars] = xPos + Pole_Offset; + NumberOfBars++; + } + + for (Int_t k=0; k<Outer_Module_NTypes; k++) { + Int_t modType = Outer_Module_Types[k][j]; + Int_t numModules = Outer_Module_Number[k][j]; + + cout <<" Outer: position "<<numModules<<" of type "<<modType<<" in col "<<j + <<" at z = "<<zPos<<", DzPos = "<<DzPos<<endl; + for(Int_t i=0; i<numModules; i++) { + ii++; + cout << "Outer ii "<<ii<<" Last "<<Last_Size_Y<<","<<Last_Over_Y<<endl; + Float_t DeltaY=Module_Size_Y[modType]+Last_Size_Y-2.*(Module_Over_Y[modType]+Last_Over_Y); + if (ii>1){yPos += DeltaY;} + Last_Size_Y=Module_Size_Y[modType]; + Last_Over_Y=Module_Over_Y[modType]; + cout <<"Position Outer Module "<<i<<" of "<<Outer_Module_Number[k][j]<<" Type "<<modType + <<"(#"<<modNum[modType]<<") "<<" at Y = "<<yPos<<" Ysize = "<<Module_Size_Y[modType] + <<" DeltaY = "<<DeltaY<<endl; + + module_trans = new TGeoTranslation("", xPos, yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans); + modNum[modType]++; + + module_trans = new TGeoTranslation("", -xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans); + modNum[modType]++; + + if (ii>1) { + module_trans + = new TGeoTranslation("", xPos, -yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans); + modNum[modType]++; + module_trans + = new TGeoTranslation("", -xPos, -yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans); + modNum[modType]++; + + // second layer + module_trans + = new TGeoTranslation("", xPos, yPos-DeltaY/2., zPos+DzPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans); + modNum[modType]++; + module_trans + = new TGeoTranslation("", -xPos, yPos-DeltaY/2., zPos+DzPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans); + modNum[modType]++; + + module_trans + = new TGeoTranslation("", xPos, -(yPos-DeltaY/2.), zPos+DzPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans); + modNum[modType]++; + module_trans + = new TGeoTranslation("", -xPos, -(yPos-DeltaY/2.), zPos+DzPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans); + modNum[modType]++; + + } + } + } + } +} + + +void dump_info_file() +{ + TDatime datetime; // used to get timestamp + + printf("writing info file: %s\n", FileNameInfo.Data()); + + FILE *ifile; + ifile = fopen(FileNameInfo.Data(),"w"); + + if (ifile == NULL) + { + printf("error opening %s\n", FileNameInfo.Data()); + exit(1); + } + + fprintf(ifile,"#\n## %s information file\n#\n\n", geoVersion.Data()); + + fprintf(ifile,"# created %d\n\n", datetime.GetDate()); + + fprintf(ifile,"# TOF setup\n"); + if (TOF_Z_Front == 450) + fprintf(ifile,"SIS 100 hadron setup\n"); + if (TOF_Z_Front == 600) + fprintf(ifile,"SIS 100 electron\n"); + if (TOF_Z_Front == 650) + fprintf(ifile,"SIS 100 muon\n"); + if (TOF_Z_Front == 880) + fprintf(ifile,"SIS 300 electron\n"); + if (TOF_Z_Front == 1020) + fprintf(ifile,"SIS 300 muon\n"); + fprintf(ifile,"\n"); + + const Float_t TOF_Z_Back = Wall_Z_Position + 1.5 * Module_Size_Z[0]; // back of TOF wall + + fprintf(ifile,"# envelope\n"); + // Show extension of TRD + fprintf(ifile,"%7.2f cm start of TOF (z)\n", TOF_Z_Front); + fprintf(ifile,"%7.2f cm end of TOF (z)\n", TOF_Z_Back); + fprintf(ifile,"\n"); + + // Layer thickness + fprintf(ifile,"# central tower position\n"); + fprintf(ifile,"%7.2f cm center of staggered, front RPC cell at x=0\n", Wall_Z_Position); + fprintf(ifile,"\n"); + + fclose(ifile); +} diff --git a/macro/mcbm/geometry/tof/Create_TOF_Geometry_v20d_mcbm.C b/macro/mcbm/geometry/tof/Create_TOF_Geometry_v20d_mcbm.C new file mode 100644 index 00000000..b299771c --- /dev/null +++ b/macro/mcbm/geometry/tof/Create_TOF_Geometry_v20d_mcbm.C @@ -0,0 +1,1417 @@ +/// +/// \file Create_TOF_Geometry_v20b_mcbm.C +/// \brief Generates TOF geometry in Root format. +/// + +// Changelog +// +// 2020-04-14 - v20b - NH - swapped double stack layer 2 with STAR2 moodule, buc kept as dummy +// 2020-04-01 - v20a - NH - move mTOF +20 cm in x direction for the Mar 2020 run +// 2019-11-28 - v19b - DE - move mTOF +12 cm in x direction for the Nov 2019 run +// 2019-07-31 - v19a - DE - this TOF March 2019 geometry is also known as v18m +// 2017-11-03 - v18i - DE - shift mTOF to z=298 cm for acceptance matching with mSTS +// 2017-10-06 - v18h - DE - put v18f into vertical position to fit into the mCBM cave +// 2017-07-15 - v18g - DE - swap the z-position of TOF modules: 2 in the front, 3 in the back +// 2017-07-14 - v18f - DE - reduce vertical gap between TOF modules to fix the gap between modules 1-2 and 4-5 +// 2017-05-17 - v18e - DE - rotate electronics away from beam, shift 16 cm away from beam along x-axis +// 2017-05-17 - v18d - DE - change geometry name to v18d + +// in root all sizes are given in cm + +#include "TSystem.h" +#include "TGeoManager.h" +#include "TGeoVolume.h" +#include "TGeoMaterial.h" +#include "TGeoMedium.h" +#include "TGeoPgon.h" +#include "TGeoMatrix.h" +#include "TGeoCompositeShape.h" +#include "TFile.h" +#include "TString.h" +#include "TList.h" +#include "TROOT.h" +#include "TMath.h" + +#include <iostream> + +// Name of geometry version and output file +const TString geoVersion = "tof_v20d_mcbm"; // do not change +const TString geoVersionStand = geoVersion + "Stand"; +// +const TString fileTag = "tof_v20d"; +const TString FileNameSim = fileTag + "_mcbm.geo.root"; +const TString FileNameGeo = fileTag + "_mcbm_geo.root"; +const TString FileNameInfo = fileTag + "_mcbm.geo.info"; + +// TOF_Z_Front corresponds to front cover of outer super module towers +const Float_t TOF_Z_Front_Stand = 250.; // = z=298 mCBM@SIS18 +const Float_t TOF_Z_Front = 0; // = z=298 mCBM@SIS18 +//const Float_t TOF_Z_Front = 130; // = z=225 mCBM@SIS18 +//const Float_t TOF_Z_Front = 250; // SIS 100 hadron +//const Float_t TOF_Z_Front = 450; // SIS 100 hadron +//const Float_t TOF_Z_Front = 600; // SIS 100 electron +//const Float_t TOF_Z_Front = 650; // SIS 100 muon +//const Float_t TOF_Z_Front = 880; // SIS 300 electron +//const Float_t TOF_Z_Front = 1020; // SIS 300 muon +// +//const Float_t TOF_Z_Front = 951.5; // Wall_Z_Position = 1050 cm + + +// Names of the different used materials which are used to build the modules +// The materials are defined in the global media.geo file +const TString KeepingVolumeMedium = "air"; +const TString BoxVolumeMedium = "aluminium"; +const TString NoActivGasMedium = "RPCgas_noact"; +const TString ActivGasMedium = "RPCgas"; +const TString GlasMedium = "RPCglass"; +const TString ElectronicsMedium = "carbon"; + +// Counters: +// 0 MRPC3a +// 1 MRPC3b +// 2 +// 3 +// 4 Diamond +// +// 6 Buc 2019 +// 7 CERN 20gap +// 8 Ceramic Pad +const Int_t NumberOfDifferentCounterTypes = 9; +const Float_t Glass_X[NumberOfDifferentCounterTypes] = {32. , 32., 32., 32., 0.2, 32., 28.8, 20., 2.4}; +const Float_t Glass_Y[NumberOfDifferentCounterTypes] = {26.9, 53., 20., 10., 0.2, 10., 6., 20., 2.4}; +const Float_t Glass_Z[NumberOfDifferentCounterTypes] = {0.1, 0.1,0.1, 0.1,0.01 ,0.1,0.1, 0.1, 0.1}; + +const Float_t GasGap_X[NumberOfDifferentCounterTypes] = {32. , 32., 32., 32., 0.2, 32., 28.8, 20., 2.4}; +const Float_t GasGap_Y[NumberOfDifferentCounterTypes] = {26.9, 53., 20., 10., 0.2, 10., 6., 20., 2.4}; +const Float_t GasGap_Z[NumberOfDifferentCounterTypes] = {0.025,0.025,0.025,0.025,0.01,0.02,0.02,0.02,0.025}; + +const Int_t NumberOfGaps[NumberOfDifferentCounterTypes] = {8,8,8,8,1,8,10,20,4}; +//const Int_t NumberOfGaps[NumberOfDifferentCounterTypes] = {1,1,1,1}; //deb +const Int_t NumberOfReadoutStrips[NumberOfDifferentCounterTypes] = {32,32,32,32,8,32,32,20,1}; +//const Int_t NumberOfReadoutStrips[NumberOfDifferentCounterTypes] = {1,1,1,1}; //deb + +const Float_t SingleStackStartPosition_Z[NumberOfDifferentCounterTypes] = {-0.6,-0.6,-0.6,-0.6,-0.1,-0.6,-0.6,-0.6,-1.}; + +const Float_t Electronics_X[NumberOfDifferentCounterTypes] = {34.0,34.0,32.0,32.,0.3,0.1, 28.8,20.,0.1}; +const Float_t Electronics_Y[NumberOfDifferentCounterTypes] = { 5.0, 5.0, 1.0, 1.,0.1,0.1,1.0,1.0,0.1}; +const Float_t Electronics_Z[NumberOfDifferentCounterTypes] = { 0.3, 0.3, 0.3, 0.3,0.1,0.1,0.1,0.1,0.1}; + +const Int_t NofModuleTypes = 10; +// 5 Diamond +// 6 Buc +// 7 CERN 20 gap +// 8 Ceramic +// 9 Star2 +// Aluminum box for all module types +const Float_t Module_Size_X[NofModuleTypes] = {180.,180.,180.,180.,180.,5., 40., 30., 22.5, 100.}; +const Float_t Module_Size_Y[NofModuleTypes] = { 49., 49., 74., 28., 18., 5., 12., 30., 11., 49.}; +const Float_t Module_Over_Y[NofModuleTypes] = {11.5,11.5,11., 4.5, 4.5, 0., 0., 0., 0., 0.}; +const Float_t Module_Size_Z[NofModuleTypes] = {11., 11., 11., 11., 11., 1., 12., 6., 6.2, 11.2}; +const Float_t Module_Thick_Alu_X_left = 0.1; +const Float_t Module_Thick_Alu_X_right = 1.0; +const Float_t Module_Thick_Alu_Y = 0.1; +const Float_t Module_Thick_Alu_Z = 0.1; + +// Distance to the center of the TOF wall [cm]; +const Float_t Wall_Z_Position = 400.; +const Float_t MeanTheta = 0.; + +//Type of Counter for module +const Int_t CounterTypeInModule[NofModuleTypes] = {0, 0, 1, 2, 3, 4, 6, 7, 8, 0}; +const Int_t NCounterInModule[NofModuleTypes] = {5, 5, 5, 5, 5, 1, 2, 1, 8, 2}; + +// Placement of the counter inside the module +const Float_t CounterXStartPosition[NofModuleTypes] = {-60.0, -66.0, -60.0,-60.0,-60.0, 0.0, 0., 0., -7., 0.}; +const Float_t CounterXDistance[NofModuleTypes] = {30.0, 32.0, 30.0, 30.0, 30.0, 0.0, 0., 0., 2., 0.}; +const Float_t CounterYStartPosition[NofModuleTypes] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0., 0., -4., -1.3, 0.}; +const Float_t CounterYDistance[NofModuleTypes] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0., 0., 8., 0., 0.}; +const Float_t CounterZDistance[NofModuleTypes] = {-2.5, 0.0, 0.0, 2.5, 2.5, 0., 6., 0., 0.1, 4.}; +const Float_t CounterZStartPosition[NofModuleTypes] = {0.0, 0.0, 0.0, 0.0, 0.0, 0., -3., 0., 0.0, -2.}; +const Float_t CounterRotationAngle[NofModuleTypes] = {0., 8.7, 10.0, 0., 0., 0., 0., 0., 0., 0.}; + +// Pole (support structure) +const Int_t MaxNumberOfPoles=20; +Float_t Pole_ZPos[MaxNumberOfPoles]; +Float_t Pole_Col[MaxNumberOfPoles]; +Int_t NumberOfPoles=0; + +const Float_t Pole_Size_X = 20.; +const Float_t Pole_Size_Y = 300.; +const Float_t Pole_Size_Z = 10.; +const Float_t Pole_Thick_X = 5.; +const Float_t Pole_Thick_Y = 5.; +const Float_t Pole_Thick_Z = 5.; + +// Bars (support structure) +const Float_t Bar_Size_X = 20.; +const Float_t Bar_Size_Y = 20.; +Float_t Bar_Size_Z = 100.; + +const Int_t MaxNumberOfBars=20; +Float_t Bar_ZPos[MaxNumberOfBars]; +Float_t Bar_XPos[MaxNumberOfBars]; +Int_t NumberOfBars=0; + +const Float_t ChamberOverlap=40; +const Float_t DxColl=158.0; //Module_Size_X-ChamberOverlap; +//const Float_t Pole_Offset=Module_Size_X/2.+Pole_Size_X/2.; +const Float_t Pole_Offset=90.0+Pole_Size_X/2.; + +// Position for module placement +const Float_t Inner_Module_First_Y_Position=16.; +const Float_t Inner_Module_Last_Y_Position=480.; +const Float_t Inner_Module_X_Offset=0.; // centered position in x/y +//const Float_t Inner_Module_X_Offset=18; // shift by 16 cm in x +const Int_t Inner_Module_NTypes = 3; +const Float_t Inner_Module_Types[Inner_Module_NTypes] = {4.,3.,0.}; +//const Float_t Inner_Module_Number[Inner_Module_NTypes] = {2.,2.,6.}; //V13_3a +const Float_t Inner_Module_Number[Inner_Module_NTypes] = {2.,2.,1.}; //V13_3a +//const Float_t Inner_Module_Number[Inner_Module_NTypes] = {0.,0.,0.}; //debugging + +const Float_t InnerSide_Module_X_Offset=51.; +const Float_t InnerSide_Module_NTypes = 1; +const Float_t InnerSide_Module_Types[Inner_Module_NTypes] = {5.}; +const Float_t InnerSide_Module_Number[Inner_Module_NTypes] = {2.}; //v13_3a +//const Float_t InnerSide_Module_Number[Inner_Module_NTypes] = {0.}; //debug + +const Float_t Outer_Module_First_Y_Position=0.; +const Float_t Outer_Module_Last_Y_Position=480.; +const Float_t Outer_Module_X_Offset=3.; +const Int_t Outer_Module_Col = 4; +const Int_t Outer_Module_NTypes = 2; +const Float_t Outer_Module_Types [Outer_Module_NTypes][Outer_Module_Col] = {1.,1.,1.,1., 2.,2.,2.,2.}; +const Float_t Outer_Module_Number[Outer_Module_NTypes][Outer_Module_Col] = {9.,9.,2.,0., 0.,0.,3.,4.};//V13_3a +//const Float_t Outer_Module_Number[Outer_Module_NTypes][Outer_Module_Col] = {1.,1.,0.,0., 0.,0.,0.,0.};//debug + +const Float_t Star2_First_Z_Position=TOF_Z_Front + 16.5; +const Float_t Star2_Delta_Z_Position=0.; +const Float_t Star2_First_Y_Position=32.; // +const Float_t Star2_Delta_Y_Position=0.; // +const Float_t Star2_rotate_Z=-90.; +const Int_t Star2_NTypes = 1; +const Float_t Star2_Types[Star2_NTypes] = {9.}; +const Float_t Star2_Number[Star2_NTypes] = {1.}; //debugging, V16b +const Float_t Star2_X_Offset[Star2_NTypes]={51.}; //{62.}; + +const Float_t Buc_First_Z_Position=TOF_Z_Front + 50.; +const Float_t Buc_Delta_Z_Position=0.; +const Float_t Buc_First_Y_Position=-32.5; // +const Float_t Buc_Delta_Y_Position=0.; // +const Float_t Buc_rotate_Z=180.; +const Int_t Buc_NTypes = 1; +const Float_t Buc_Types[Buc_NTypes] = {6.}; +const Float_t Buc_Number[Buc_NTypes] = {1.}; //debugging, V16b +const Float_t Buc_X_Offset[Buc_NTypes]={53.5}; + +const Int_t Cer_NTypes = 3; +const Float_t Cer_Z_Position[Cer_NTypes]={(float)(TOF_Z_Front+13.2),(float)(TOF_Z_Front+45.),(float)(TOF_Z_Front+45.)}; +const Float_t Cer_X_Position[Cer_NTypes]={0.,49.8,49.8}; +const Float_t Cer_Y_Position[Cer_NTypes]={-1.,5.,5.}; +const Float_t Cer_rotate_Z[Cer_NTypes]={0.,0.,0.}; +const Float_t Cer_Types[Cer_NTypes] = {5.,8.,8.}; +const Float_t Cer_Number[Cer_NTypes] = {1.,1.,1.}; //V16b + +const Float_t CERN_Z_Position=TOF_Z_Front+50; // 20 gap +const Float_t CERN_First_Y_Position=36.; +const Float_t CERN_X_Offset=46.; //65.5; +const Float_t CERN_rotate_Z=90.; +const Int_t CERN_NTypes = 1; +const Float_t CERN_Types[CERN_NTypes] = {7.}; // this is the SmType! +const Float_t CERN_Number[CERN_NTypes] = {1.}; // evtl. double for split signals + +// some global variables +TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance +TGeoVolume* gModules[NofModuleTypes]; // Global storage for module types +TGeoVolume* gCounter[NumberOfDifferentCounterTypes]; +TGeoVolume* gPole; +TGeoVolume* gBar[MaxNumberOfBars]; + +const Float_t Dia_Z_Position=-0.5-TOF_Z_Front_Stand; +const Float_t Dia_First_Y_Position=0.; +const Float_t Dia_X_Offset=3.; +const Float_t Dia_rotate_Z=0.; +const Int_t Dia_NTypes = 1; +const Float_t Dia_Types[Dia_NTypes] = {5.}; +const Float_t Dia_Number[Dia_NTypes] = {1.}; + +Float_t Last_Size_Y=0.; +Float_t Last_Over_Y=0.; + +// Forward declarations +void create_materials_from_media_file(); +TGeoVolume* create_counter(Int_t); +TGeoVolume* create_new_counter(Int_t); +TGeoVolume* create_tof_module(Int_t); +TGeoVolume* create_new_tof_module(Int_t); +TGeoVolume* create_tof_pole(); +TGeoVolume* create_tof_bar(); +void position_tof_poles(Int_t); +void position_tof_bars(Int_t); +void position_inner_tof_modules(Int_t); +void position_side_tof_modules(Int_t); +void position_outer_tof_modules(Int_t); +void position_Dia(Int_t); +void position_Star2(Int_t); +void position_Buc(Int_t); +void position_cer_modules(Int_t); +void position_CERN(Int_t); +void dump_info_file(); + + +void Create_TOF_Geometry_v20d_mcbm() { + + // Load needed material definition from media.geo file + create_materials_from_media_file(); + + // Get the GeoManager for later usage + gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom"); + gGeoMan->SetVisLevel(5); // 2 = super modules + gGeoMan->SetVisOption(0); + + // Create the top volume + /* + TGeoBBox* topbox= new TGeoBBox("", 1000., 1000., 1000.); + TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air")); + gGeoMan->SetTopVolume(top); + */ + + TGeoVolume* top = new TGeoVolumeAssembly("TOP"); + gGeoMan->SetTopVolume(top); + + TGeoRotation* tof_rotation = new TGeoRotation(); + tof_rotation->RotateY( 0. ); // angle with respect to beam axis + //tof_rotation->RotateZ( 0 ); // electronics on 9 o'clock position = +x + // tof_rotation->RotateZ( 0 ); // electronics on 9 o'clock position = +x + // tof_rotation->RotateZ( 90 ); // electronics on 12 o'clock position (top) + // tof_rotation->RotateZ( 180 ); // electronics on 3 o'clock position = -x + // tof_rotation->RotateZ( 270 ); // electronics on 6 o'clock position (bottom) + + TGeoVolume* tof = new TGeoVolumeAssembly(geoVersion); +// top->AddNode(tof, 1, tof_rotation); + top->AddNode(tof,1); + + TGeoVolume* tofstand = new TGeoVolumeAssembly(geoVersionStand); + // Mar 2020 run + TGeoTranslation* stand_trans = new TGeoTranslation("", 0., 0., TOF_Z_Front_Stand); + // Nov 2019 run + // TGeoTranslation* stand_trans = new TGeoTranslation("", 12., 0., TOF_Z_Front_Stand); + // TGeoTranslation* stand_trans = new TGeoTranslation("", 0., 0., TOF_Z_Front_Stand); + TGeoRotation* stand_rot = new TGeoRotation(); + stand_rot->RotateY(0.0); + TGeoCombiTrans* stand_combi_trans = new TGeoCombiTrans(*stand_trans, *stand_rot); + // tof->AddNode(tofstand, 1, stand_combi_trans); + tof->AddNode(tofstand,1); + + for(Int_t counterType = 0; counterType < NumberOfDifferentCounterTypes; counterType++) { + gCounter[counterType] = create_new_counter(counterType); + } + + for(Int_t moduleType = 0; moduleType < NofModuleTypes; moduleType++) { + gModules[moduleType] = create_new_tof_module(moduleType); + gModules[moduleType]->SetVisContainers(1); + } + + // no pole + // gPole = create_tof_pole(); + + // position_side_tof_modules(1); // keep order !! + // position_inner_tof_modules(2); + position_inner_tof_modules(3); + position_Dia(1); + // position_Star2(1); + // position_cer_modules(3); + // position_CERN(1); + // position_Buc(1); + + cout << "Outer Types "<<Outer_Module_Types[0][0]<<", "<<Outer_Module_Types[1][0] + <<", col=1: "<<Outer_Module_Types[0][1]<<", "<<Outer_Module_Types[1][1] + <<endl; + cout << "Outer Number "<<Outer_Module_Number[0][0]<<", "<<Outer_Module_Number[1][0] + <<", col=1: "<<Outer_Module_Number[0][1]<<", "<<Outer_Module_Number[1][1] + <<endl; + // position_outer_tof_modules(4); + // position_tof_poles(0); + // position_tof_bars(0); + + gGeoMan->CloseGeometry(); + gGeoMan->CheckOverlaps(0.001); + gGeoMan->PrintOverlaps(); + gGeoMan->CheckOverlaps(0.001,"s"); + gGeoMan->PrintOverlaps(); + gGeoMan->Test(); + + tof->Export(FileNameSim); + TFile* geoFile = new TFile(FileNameSim, "UPDATE"); + stand_combi_trans->Write(); + geoFile->Close(); + +/* + TFile* outfile1 = new TFile(FileNameSim,"RECREATE"); + top->Write(); + //gGeoMan->Write(); + outfile1->Close(); +*/ + TFile* outfile2 = new TFile(FileNameGeo,"RECREATE"); + gGeoMan->Write(); + outfile2->Close(); + + dump_info_file(); + + top->SetVisContainers(1); + gGeoMan->SetVisLevel(5); + top->Draw("ogl"); + //top->Draw(); + //gModules[0]->Draw("ogl"); + // gModules[0]->Draw(""); + gModules[0]->SetVisContainers(1); + // gModules[1]->Draw(""); + gModules[1]->SetVisContainers(1); + //gModules[5]->Draw(""); + // top->Raytrace(); + +} + +void create_materials_from_media_file() +{ + // Use the FairRoot geometry interface to load the media which are already defined + FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader"); + FairGeoInterface* geoFace = geoLoad->getGeoInterface(); + TString geoPath = gSystem->Getenv("VMCWORKDIR"); + TString geoFile = geoPath + "/geometry/media.geo"; + geoFace->setMediaFile(geoFile); + geoFace->readMedia(); + + // Read the required media and create them in the GeoManager + FairGeoMedia* geoMedia = geoFace->getMedia(); + FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder(); + + FairGeoMedium* air = geoMedia->getMedium("air"); + FairGeoMedium* aluminium = geoMedia->getMedium("aluminium"); + FairGeoMedium* RPCgas = geoMedia->getMedium("RPCgas"); + FairGeoMedium* RPCgas_noact = geoMedia->getMedium("RPCgas_noact"); + FairGeoMedium* RPCglass = geoMedia->getMedium("RPCglass"); + FairGeoMedium* carbon = geoMedia->getMedium("carbon"); + + // include check if all media are found + + geoBuild->createMedium(air); + geoBuild->createMedium(aluminium); + geoBuild->createMedium(RPCgas); + geoBuild->createMedium(RPCgas_noact); + geoBuild->createMedium(RPCglass); + geoBuild->createMedium(carbon); +} + +TGeoVolume* create_counter(Int_t modType) +{ + + //glass + Float_t gdx=Glass_X[modType]; + Float_t gdy=Glass_Y[modType]; + Float_t gdz=Glass_Z[modType]; + + //gas gap + Int_t nstrips=NumberOfReadoutStrips[modType]; + Int_t ngaps=NumberOfGaps[modType]; + + + Float_t ggdx=GasGap_X[modType]; + Float_t ggdy=GasGap_Y[modType]; + Float_t ggdz=GasGap_Z[modType]; + Float_t gsdx=ggdx/float(nstrips); + + //single stack + Float_t dzpos=gdz+ggdz; + Float_t startzpos=SingleStackStartPosition_Z[modType]; + + // electronics + //pcb dimensions + Float_t dxe=Electronics_X[modType]; + Float_t dye=Electronics_Y[modType]; + Float_t dze=Electronics_Z[modType]; + Float_t yele=(gdy+0.1)/2.+dye/2.; + + // needed materials + TGeoMedium* glassPlateVolMed = gGeoMan->GetMedium(GlasMedium); + TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); + TGeoMedium* activeGasVolMed = gGeoMan->GetMedium(ActivGasMedium); + TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsMedium); + + // Single glass plate + TGeoBBox* glass_plate = new TGeoBBox("", gdx/2., gdy/2., gdz/2.); + TGeoVolume* glass_plate_vol = + new TGeoVolume("tof_glass", glass_plate, glassPlateVolMed); + glass_plate_vol->SetLineColor(kMagenta); // set line color for the glass plate + glass_plate_vol->SetTransparency(20); // set transparency for the TOF + TGeoTranslation* glass_plate_trans + = new TGeoTranslation("", 0., 0., 0.); + + // Single gas gap + TGeoBBox* gas_gap = new TGeoBBox("", ggdx/2., ggdy/2., ggdz/2.); + //TGeoVolume* gas_gap_vol = + //new TGeoVolume("tof_gas_gap", gas_gap, noActiveGasVolMed); + TGeoVolume* gas_gap_vol = + new TGeoVolume("tof_gas_active", gas_gap, activeGasVolMed); + gas_gap_vol->Divide("Strip",1,nstrips,-ggdx/2.,0); + + gas_gap_vol->SetLineColor(kRed); // set line color for the gas gap + gas_gap_vol->SetTransparency(70); // set transparency for the TOF + TGeoTranslation* gas_gap_trans + = new TGeoTranslation("", 0., 0., (gdz+ggdz)/2.); + + + // Single subdivided active gas gap + /* + TGeoBBox* gas_active = new TGeoBBox("", gsdx/2., ggdy/2., ggdz/2.); + TGeoVolume* gas_active_vol = + new TGeoVolume("tof_gas_active", gas_active, activeGasVolMed); + gas_active_vol->SetLineColor(kBlack); // set line color for the gas gap + gas_active_vol->SetTransparency(70); // set transparency for the TOF + */ + + // Add glass plate, inactive gas gap and active gas gaps to a single stack + TGeoVolume* single_stack = new TGeoVolumeAssembly("single_stack"); + single_stack->AddNode(glass_plate_vol, 0, glass_plate_trans); + single_stack->AddNode(gas_gap_vol, 0, gas_gap_trans); + + /* + for (Int_t l=0; l<nstrips; l++){ + TGeoTranslation* gas_active_trans + = new TGeoTranslation("", -ggdx/2+(l+0.5)*gsdx, 0., 0.); + gas_gap_vol->AddNode(gas_active_vol, l, gas_active_trans); + // single_stack->AddNode(gas_active_vol, l, gas_active_trans); + } + */ + + // Add 8 single stacks + one glass plate at the e09.750nd to a multi stack + TGeoVolume* multi_stack = new TGeoVolumeAssembly("multi_stack"); + Int_t l; + for (l=0; l<ngaps; l++){ + TGeoTranslation* single_stack_trans + = new TGeoTranslation("", 0., 0., startzpos + l*dzpos); + multi_stack->AddNode(single_stack, l, single_stack_trans); + } + TGeoTranslation* single_glass_back_trans + = new TGeoTranslation("", 0., 0., startzpos + ngaps*dzpos); + multi_stack->AddNode(glass_plate_vol, l, single_glass_back_trans); + + // Add electronics above and below the glass stack to build a complete counter + TGeoVolume* counter = new TGeoVolumeAssembly("counter"); + TGeoTranslation* multi_stack_trans + = new TGeoTranslation("", 0., 0., 0.); + counter->AddNode(multi_stack, l, multi_stack_trans); + + TGeoBBox* pcb = new TGeoBBox("", dxe/2., dye/2., dze/2.); + TGeoVolume* pcb_vol = + new TGeoVolume("pcb", pcb, electronicsVolMed); + pcb_vol->SetLineColor(kCyan); // set line color for the gas gap + pcb_vol->SetTransparency(10); // set transparency for the TOF + for (Int_t l=0; l<2; l++){ + yele *= -1.; + TGeoTranslation* pcb_trans + = new TGeoTranslation("", 0., yele, 0.); + counter->AddNode(pcb_vol, l, pcb_trans); + } + + return counter; + +} + +TGeoVolume* create_new_counter(Int_t modType) +{ + + //glass + Float_t gdx=Glass_X[modType]; + Float_t gdy=Glass_Y[modType]; + Float_t gdz=Glass_Z[modType]; + + //gas gap + Int_t nstrips=NumberOfReadoutStrips[modType]; + Int_t ngaps=NumberOfGaps[modType]; + + + Float_t ggdx=GasGap_X[modType]; + Float_t ggdy=GasGap_Y[modType]; + Float_t ggdz=GasGap_Z[modType]; + Float_t gsdx=ggdx/(Float_t)(nstrips); + + // electronics + //pcb dimensions + Float_t dxe=Electronics_X[modType]; + Float_t dye=Electronics_Y[modType]; + Float_t dze=Electronics_Z[modType]; + Float_t yele=gdy/2.+dye/2.; + + // counter size (calculate from glas, gap and electronics sizes) + Float_t cdx = TMath::Max(gdx, ggdx); + cdx = TMath::Max(cdx, dxe)+ 0.2; + Float_t cdy = TMath::Max(gdy, ggdy) + 2*dye + 0.2; + Float_t cdz = ngaps * ggdz + (ngaps+1) * gdz + 0.2; // ngaps * (gdz+ggdz) + gdz + 0.2; // ok + + //calculate thickness and first position in counter of single stack + Float_t dzpos = gdz+ggdz; + Float_t startzposglas= -ngaps * (gdz + ggdz) /2.; // -cdz/2.+0.1+gdz/2.; // ok // (-cdz+gdz)/2.; // not ok + Float_t startzposgas = startzposglas + gdz/2. + ggdz/2.; // -cdz/2.+0.1+gdz +ggdz/2.; // ok + + + // needed materials + TGeoMedium* glassPlateVolMed = gGeoMan->GetMedium(GlasMedium); + TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); + TGeoMedium* activeGasVolMed = gGeoMan->GetMedium(ActivGasMedium); + TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsMedium); + + + // define counter volume + TGeoBBox* counter_box = new TGeoBBox("", cdx/2., cdy/2., cdz/2.); + TGeoVolume* counter = + new TGeoVolume("counter", counter_box, noActiveGasVolMed); + counter->SetLineColor(kRed); // set line color for the counter + counter->SetTransparency(70); // set transparency for the TOF + + // define single glass plate volume + TGeoBBox* glass_plate = new TGeoBBox("", gdx/2., gdy/2., gdz/2.); + TGeoVolume* glass_plate_vol = + new TGeoVolume("tof_glass", glass_plate, glassPlateVolMed); + glass_plate_vol->SetLineColor(kMagenta); // set line color for the glass plate + glass_plate_vol->SetTransparency(20); // set transparency for the TOF + // define single gas gap volume + TGeoBBox* gas_gap = new TGeoBBox("", ggdx/2., ggdy/2., ggdz/2.); + TGeoVolume* gas_gap_vol = + new TGeoVolume("Gap", gas_gap, activeGasVolMed); + gas_gap_vol->Divide("Cell",1,nstrips,-ggdx/2.,0); + gas_gap_vol->SetLineColor(kRed); // set line color for the gas gap + gas_gap_vol->SetTransparency(99); // set transparency for the TOF + + // place 8 gas gaps and 9 glas plates in the counter + for( Int_t igap = 0; igap <= ngaps; igap++) { + // place (ngaps+1) glass plates + Float_t zpos_glas = startzposglas + igap*dzpos; + TGeoTranslation* glass_plate_trans + = new TGeoTranslation("", 0., 0., zpos_glas); + counter->AddNode(glass_plate_vol, igap, glass_plate_trans); + // place ngaps gas gaps + if (igap < ngaps) + { + Float_t zpos_gas = startzposgas + igap*dzpos; + TGeoTranslation* gas_gap_trans + = new TGeoTranslation("", 0., 0., zpos_gas); + counter->AddNode(gas_gap_vol, igap, gas_gap_trans); + } +// cout <<"Zpos(Glas): "<< zpos_glas << endl; +// cout <<"Zpos(Gas): "<< zpos_gas << endl; + } + + // create and place the electronics above and below the glas stack + TGeoBBox* pcb = new TGeoBBox("", dxe/2., dye/2., dze/2.); + TGeoVolume* pcb_vol = + new TGeoVolume("pcb", pcb, electronicsVolMed); + pcb_vol->SetLineColor(kYellow); // kCyan); // set line color for electronics + pcb_vol->SetTransparency(10); // set transparency for the TOF + for (Int_t l=0; l<2; l++){ + yele *= -1.; + TGeoTranslation* pcb_trans + = new TGeoTranslation("", 0., yele, 0.); + counter->AddNode(pcb_vol, l, pcb_trans); + } + + + return counter; + +} + +TGeoVolume* create_tof_module(Int_t modType) +{ + Int_t cType = CounterTypeInModule[modType]; + Float_t dx=Module_Size_X[modType]; + Float_t dy=Module_Size_Y[modType]; + Float_t dz=Module_Size_Z[modType]; + Float_t width_aluxl=Module_Thick_Alu_X_left; + Float_t width_aluxr=Module_Thick_Alu_X_right; + Float_t width_aluy=Module_Thick_Alu_Y; + Float_t width_aluz=Module_Thick_Alu_Z; + + Float_t shift_gas_box = (Module_Thick_Alu_X_right - Module_Thick_Alu_X_left)/2; + + Float_t dxpos=CounterXDistance[modType]; + Float_t startxpos=CounterXStartPosition[modType]; + Float_t dzoff=CounterZDistance[modType]; + Float_t rotangle=CounterRotationAngle[modType]; + + TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium); + TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); + + TString moduleName = Form("module_%d", modType); + TGeoVolume* module = new TGeoVolumeAssembly(moduleName); + + TGeoBBox* alu_box = new TGeoBBox("", dx/2., dy/2., dz/2.); + TGeoVolume* alu_box_vol = + new TGeoVolume("alu_box", alu_box, boxVolMed); + alu_box_vol->SetLineColor(kGreen); // set line color for the alu box + alu_box_vol->SetTransparency(20); // set transparency for the TOF + TGeoTranslation* alu_box_trans + = new TGeoTranslation("", 0., 0., 0.); + module->AddNode(alu_box_vol, 0, alu_box_trans); + + TGeoBBox* gas_box = new TGeoBBox("", (dx-(width_aluxl+width_aluxr))/2., (dy-2*width_aluy)/2., (dz-2*width_aluz)/2.); + TGeoVolume* gas_box_vol = + new TGeoVolume("gas_box", gas_box, noActiveGasVolMed); + gas_box_vol->SetLineColor(kYellow); // set line color for the gas box + gas_box_vol->SetTransparency(70); // set transparency for the TOF + TGeoTranslation* gas_box_trans + = new TGeoTranslation("", shift_gas_box, 0., 0.); + alu_box_vol->AddNode(gas_box_vol, 0, gas_box_trans); + + for (Int_t j=0; j<5; j++){ //loop over counters (modules) + Float_t zpos; + if (0 == modType) { + zpos = dzoff *=-1; + } else { + zpos = 0.; + } + //cout << "counter z position " << zpos << endl; + TGeoTranslation* counter_trans + = new TGeoTranslation("", startxpos+ j*dxpos , 0.0 , zpos); + + TGeoRotation* counter_rot = new TGeoRotation(); + counter_rot->RotateY(rotangle); + TGeoCombiTrans* counter_combi_trans = new TGeoCombiTrans(*counter_trans, *counter_rot); + gas_box_vol->AddNode(gCounter[cType], j, counter_combi_trans); + } + + return module; +} + +TGeoVolume* create_new_tof_module(Int_t modType) +{ + Int_t cType = CounterTypeInModule[modType]; + Float_t dx=Module_Size_X[modType]; + Float_t dy=Module_Size_Y[modType]; + Float_t dz=Module_Size_Z[modType]; + Float_t width_aluxl=Module_Thick_Alu_X_left; + Float_t width_aluxr=Module_Thick_Alu_X_right; + Float_t width_aluy=Module_Thick_Alu_Y; + Float_t width_aluz=Module_Thick_Alu_Z; + + Float_t shift_gas_box = (Module_Thick_Alu_X_right - Module_Thick_Alu_X_left)/2; + + Float_t dxpos=CounterXDistance[modType]; + Float_t startxpos=CounterXStartPosition[modType]; + Float_t dypos=CounterYDistance[modType]; + Float_t startypos=CounterYStartPosition[modType]; + Float_t dzoff=CounterZDistance[modType]; + Float_t rotangle=CounterRotationAngle[modType]; + + TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium); + TGeoMedium* noActiveGasVolMed = gGeoMan->GetMedium(NoActivGasMedium); + + TString moduleName = Form("module_%d", modType); + + TGeoBBox* module_box = new TGeoBBox("", dx/2., dy/2., dz/2.); + TGeoVolume* module = + new TGeoVolume(moduleName, module_box, boxVolMed); + module->SetLineColor(kGreen); // set line color for the alu box + module->SetTransparency(20); // set transparency for the TOF + + TGeoBBox* gas_box = new TGeoBBox("", (dx-(width_aluxl+width_aluxr))/2., (dy-2*width_aluy)/2., (dz-2*width_aluz)/2.); + TGeoVolume* gas_box_vol = + new TGeoVolume("gas_box", gas_box, noActiveGasVolMed); + gas_box_vol->SetLineColor(kBlue); // set line color for the alu box + gas_box_vol->SetTransparency(50); // set transparency for the TOF + TGeoTranslation* gas_box_trans + = new TGeoTranslation("", shift_gas_box, 0., 0.); + module->AddNode(gas_box_vol, 0, gas_box_trans); + + for (Int_t j=0; j< NCounterInModule[modType]; j++){ //loop over counters (modules) + //for (Int_t j=0; j< 1; j++){ //loop over counters (modules) + Float_t xpos,ypos,zpos; + if (0 == modType || 3 == modType || 4 == modType || 5 == modType) { + zpos = dzoff *=-1; + } else { + zpos = CounterZStartPosition[modType]+j*dzoff; + } + //cout << "counter z position " << zpos << endl; + xpos=startxpos + j*dxpos; + ypos=startypos + j*dypos; + + TGeoTranslation* counter_trans + = new TGeoTranslation("", xpos , ypos , zpos); + + TGeoRotation* counter_rot = new TGeoRotation(); + counter_rot->RotateY(rotangle); + TGeoCombiTrans* counter_combi_trans = new TGeoCombiTrans(*counter_trans, *counter_rot); + gas_box_vol->AddNode(gCounter[cType], j, counter_combi_trans); + } + + return module; +} + + +TGeoVolume* create_tof_pole() +{ + // needed materials + TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium); + TGeoMedium* airVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + + Float_t dx=Pole_Size_X; + Float_t dy=Pole_Size_Y; + Float_t dz=Pole_Size_Z; + Float_t width_alux=Pole_Thick_X; + Float_t width_aluy=Pole_Thick_Y; + Float_t width_aluz=Pole_Thick_Z; + + TGeoVolume* pole = new TGeoVolumeAssembly("Pole"); + TGeoBBox* pole_alu_box = new TGeoBBox("", dx/2., dy/2., dz/2.); + TGeoVolume* pole_alu_vol = + new TGeoVolume("pole_alu", pole_alu_box, boxVolMed); + pole_alu_vol->SetLineColor(kGreen); // set line color for the alu box + pole_alu_vol->SetTransparency(20); // set transparency for the TOF + TGeoTranslation* pole_alu_trans + = new TGeoTranslation("", 0., 0., 0.); + pole->AddNode(pole_alu_vol, 0, pole_alu_trans); + + Float_t air_dx = dx/2. - width_alux; + Float_t air_dy = dy/2. - width_aluy; + Float_t air_dz = dz/2. - width_aluz; + + // cout << "My pole." << endl; + if (air_dx <= 0.) + cout << "ERROR - No air volume in pole X, size: "<< air_dx << endl; + if (air_dy <= 0.) + cout << "ERROR - No air volume in pole Y, size: "<< air_dy << endl; + if (air_dz <= 0.) + cout << "ERROR - No air volume in pole Z, size: "<< air_dz << endl; + + if ((air_dx > 0.) && (air_dy > 0.) && (air_dz > 0.)) // crate air volume only, if larger than zero + { + TGeoBBox* pole_air_box = new TGeoBBox("", air_dx, air_dy, air_dz); + // TGeoBBox* pole_air_box = new TGeoBBox("", dx/2.-width_alux, dy/2.-width_aluy, dz/2.-width_aluz); + TGeoVolume* pole_air_vol = + new TGeoVolume("pole_air", pole_air_box, airVolMed); + pole_air_vol->SetLineColor(kYellow); // set line color for the alu box + pole_air_vol->SetTransparency(70); // set transparency for the TOF + TGeoTranslation* pole_air_trans + = new TGeoTranslation("", 0., 0., 0.); + pole_alu_vol->AddNode(pole_air_vol, 0, pole_air_trans); + } + else + cout << "Skipping pole_air_vol, no thickness: " << air_dx << " " << air_dy << " " << air_dz << endl; + + return pole; +} + +TGeoVolume* create_tof_bar(Float_t dx, Float_t dy, Float_t dz) +{ + // needed materials + TGeoMedium* boxVolMed = gGeoMan->GetMedium(BoxVolumeMedium); + TGeoMedium* airVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + + Float_t width_alux=Pole_Thick_X; + Float_t width_aluy=Pole_Thick_Y; + Float_t width_aluz=Pole_Thick_Z; + + TGeoVolume* bar = new TGeoVolumeAssembly("Bar"); + TGeoBBox* bar_alu_box = new TGeoBBox("", dx/2., dy/2., dz/2.); + TGeoVolume* bar_alu_vol = + new TGeoVolume("bar_alu", bar_alu_box, boxVolMed); + bar_alu_vol->SetLineColor(kGreen); // set line color for the alu box + bar_alu_vol->SetTransparency(20); // set transparency for the TOF + TGeoTranslation* bar_alu_trans + = new TGeoTranslation("", 0., 0., 0.); + bar->AddNode(bar_alu_vol, 0, bar_alu_trans); + + TGeoBBox* bar_air_box = new TGeoBBox("", dx/2.-width_alux, dy/2.-width_aluy, dz/2.-width_aluz); + TGeoVolume* bar_air_vol = + new TGeoVolume("bar_air", bar_air_box, airVolMed); + bar_air_vol->SetLineColor(kYellow); // set line color for the alu box + bar_air_vol->SetTransparency(70); // set transparency for the TOF + TGeoTranslation* bar_air_trans + = new TGeoTranslation("", 0., 0., 0.); + bar_alu_vol->AddNode(bar_air_vol, 0, bar_air_trans); + + return bar; +} + +void position_tof_poles(Int_t modType) +{ + + TGeoTranslation* pole_trans=NULL; + + Int_t numPoles=0; + for (Int_t i=0; i<NumberOfPoles; i++){ + if(i<2) { + pole_trans + = new TGeoTranslation("", -Pole_Offset+2.0, 0., Pole_ZPos[i]); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gPole, numPoles, pole_trans); + numPoles++; + }else{ + Float_t xPos=Pole_Offset+Pole_Size_X/2.+Pole_Col[i]*DxColl; + Float_t zPos=Pole_ZPos[i]; + pole_trans + = new TGeoTranslation("", xPos, 0., zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gPole, numPoles, pole_trans); + numPoles++; + + pole_trans + = new TGeoTranslation("", -xPos, 0., zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gPole, numPoles, pole_trans); + numPoles++; + } + cout << " Position Pole "<< numPoles<<" at z="<< Pole_ZPos[i] << endl; + } +} + +void position_tof_bars(Int_t modType) +{ + + TGeoTranslation* bar_trans=NULL; + + Int_t numBars=0; + Int_t i; + Float_t xPos; + Float_t yPos; + Float_t zPos; + + for (i=0; i<NumberOfBars; i++){ + + xPos=Bar_XPos[i]; + zPos=Bar_ZPos[i]; + yPos=Pole_Size_Y/2.+Bar_Size_Y/2.; + + bar_trans = new TGeoTranslation("", xPos, yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + bar_trans = new TGeoTranslation("", xPos,-yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + bar_trans = new TGeoTranslation("", -xPos, yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + bar_trans = new TGeoTranslation("", -xPos, -yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + } + cout << " Position Bar "<< numBars<<" at z="<< Bar_ZPos[i] << endl; + + // horizontal frame bars + i = NumberOfBars; + NumberOfBars++; + // no bar + // gBar[i]=create_tof_bar(2.*xPos+Pole_Size_X,Bar_Size_Y,Bar_Size_Y); + + zPos = Pole_ZPos[0]+Pole_Size_Z/2.; + bar_trans = new TGeoTranslation("", 0., yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + + bar_trans = new TGeoTranslation("", 0., -yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gBar[i], numBars, bar_trans); + numBars++; + +} + +void position_inner_tof_modules(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + + // Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1; + Float_t yPos=Inner_Module_First_Y_Position; + Int_t ii=0; + Float_t xPos = Inner_Module_X_Offset; + Float_t zPos = Wall_Z_Position; + + Pole_ZPos[NumberOfPoles] = zPos; + Pole_Col[NumberOfPoles] = 0; + NumberOfPoles++; + + Float_t DzPos =0.; + for (Int_t j=0; j<modNType; j++){ + if (Module_Size_Z[j]>DzPos){ + DzPos = Module_Size_Z[j]; + } + } + Pole_ZPos[NumberOfPoles]=zPos+DzPos; + Pole_Col[NumberOfPoles] = 0; + NumberOfPoles++; + + // for (Int_t j=0; j<modNType; j++){ + // for (Int_t j=1; j<modNType; j++){ + Int_t modType; + Int_t modNum; + for (Int_t j=2; j<modNType; j++){ // place only M4 type modules (modNType == 2) + //DEDE + modType = Inner_Module_Types[j]; + modNum = 0; + // for(Int_t i=0; i<Inner_Module_Number[j]; i++) { + // for(Int_t i=0; i<1; i++) { // place 1x2 modules in the top and same in the bottom + for(Int_t i=0; i<2; i++) { // place 2x2 modules in the top and same in the bottom + ii++; + cout << "Inner ii "<<ii<<" Last "<<Last_Size_Y<<", "<<Last_Over_Y<<endl; + Float_t DeltaY=Module_Size_Y[modType]+Last_Size_Y-2.*(Module_Over_Y[modType]+Last_Over_Y); + // DeltaY = 1.5; + cout << "DeltaY " << DeltaY << endl; + yPos += DeltaY; + Last_Size_Y=Module_Size_Y[modType]; + Last_Over_Y=Module_Over_Y[modType]; + cout <<"Position Inner Module "<<i<<" of "<<Inner_Module_Number[j]<<" Type "<<modType + <<" at Y = "<<yPos<<" Ysize = "<<Module_Size_Y[modType] + <<" DeltaY = "<<DeltaY<<endl; + +/// module_trans = new TGeoTranslation("", xPos, yPos, zPos); +/// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); +/// modNum++; +/// module_trans = new TGeoTranslation("", xPos, -yPos, zPos); +/// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); +/// modNum++; +// // if (ii>0) { +// if (ii>1) { +// module_trans +// = new TGeoTranslation("", xPos, yPos-DeltaY/2, zPos+Module_Size_Z[modType]); +// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); +// modNum++; +// module_trans +// = new TGeoTranslation("", xPos, -(yPos-DeltaY/2), zPos+Module_Size_Z[modType]); +// gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); +// modNum++; +// } + } + } + // module_trans = new TGeoTranslation("", xPos, -49-3, zPos); + + // Mar2019 setup + const Int_t NModules=8; + xPos=0.; + yPos=0.; + zPos=TOF_Z_Front; + const Double_t ModDx[NModules]= { -50., 0., 50., -25., 25.0, -37.5, 37.5, 0.0}; + //const Double_t ModDx[NModules]= { 1.5, 0., -1.5, 49.8, 55.8}; + const Double_t ModDy[NModules]= { 0., 0., 0., 0., 0. , 0., 0., 0.}; + const Double_t ModDz[NModules]= { 0., 0, 0, 16.5, 16.5 , 33., 33., 49.5}; + const Double_t ModAng[NModules]={-90.,-90.,-90., -90.,-90.0,-90.0,-90.0,-90.0}; + TGeoRotation* module_rot = NULL; + TGeoCombiTrans* module_combi_trans = NULL; + + for (Int_t iMod=0; iMod<NModules; iMod++) { + module_trans = new TGeoTranslation("", xPos+ModDx[iMod], yPos+ModDy[iMod], zPos+ModDz[iMod]); + module_rot = new TGeoRotation(); + module_rot->RotateZ(ModAng[iMod]); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + if (iMod<5){ + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[0], modNum, module_combi_trans); + } + else + { + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[2], modNum, module_combi_trans); + } + modNum++; + } + + + /* + module_trans = new TGeoTranslation("", xPos, 0, zPos+16.5); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + // module_trans = new TGeoTranslation("", xPos, 49+3, zPos); + module_trans = new TGeoTranslation("", xPos, 0, zPos+16.5+17.5); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + // module_trans = new TGeoTranslation("", xPos,-26, zPos+Module_Size_Z[modType]); + module_trans = new TGeoTranslation("", xPos, -49.8, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + // module_trans = new TGeoTranslation("", xPos, 26, zPos+Module_Size_Z[modType]); + module_trans = new TGeoTranslation("", xPos, -49.8, zPos+16.5); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + */ +} + + +void position_Dia(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(Dia_rotate_Z); + TGeoCombiTrans* module_combi_trans = NULL; + + // Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1; + Float_t yPos=Dia_First_Y_Position; + Int_t ii=0; + Float_t xPos = Dia_X_Offset; + Float_t zPos = Dia_Z_Position; + + Int_t modNum = 0; + for (Int_t j=0; j<modNType; j++){ + Int_t modType= Dia_Types[j]; + for(Int_t i=0; i<Dia_Number[j]; i++) { + ii++; + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + } + } +} + +void position_Star2(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(Star2_rotate_Z); + TGeoCombiTrans* module_combi_trans = NULL; + + Float_t yPos = Star2_First_Y_Position; + Float_t zPos = Star2_First_Z_Position; + Int_t ii=0; + + Int_t modNum = 0; + for (Int_t j=0; j<modNType; j++){ + Int_t modType= Star2_Types[j]; + Float_t xPos = Star2_X_Offset[j]; + for(Int_t i=0; i<Star2_Number[j]; i++) { + ii++; + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + yPos += Star2_Delta_Y_Position; + zPos += Star2_Delta_Z_Position; + } + + } +} + +void position_Buc(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(Buc_rotate_Z); + TGeoCombiTrans* module_combi_trans = NULL; + + Float_t yPos = Buc_First_Y_Position; + Float_t zPos = Buc_First_Z_Position; + Int_t ii=0; + + Int_t modNum = 0; + for (Int_t j=0; j<modNType; j++){ + Int_t modType= Buc_Types[j]; + Float_t xPos = Buc_X_Offset[j]; + for(Int_t i=0; i<Buc_Number[j]; i++) { + ii++; + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + yPos += Buc_Delta_Y_Position; + zPos += Buc_Delta_Z_Position; + } + } +} + +void position_cer_modules(Int_t modNType) +{ + Int_t ii=0; + Int_t modNum = 0; + for (Int_t j=1; j<modNType; j++){ + Int_t modType= Cer_Types[j]; + Float_t xPos = Cer_X_Position[j]; + Float_t yPos = Cer_Y_Position[j]; + Float_t zPos = Cer_Z_Position[j]; + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(Form("Cer%d",j),Cer_rotate_Z[j],-MeanTheta,0.); + // module_rot->RotateZ(Cer_rotate_Z[j]); + TGeoCombiTrans* module_combi_trans = NULL; + + for(Int_t i=0; i<Cer_Number[j]; i++) { + ii++; + cout <<"Position Ceramic Module "<<i<<" of "<<Cer_Number[j]<<" Type "<<modType + <<" at X = "<<xPos + <<", Y = "<<yPos + <<", Z = "<<zPos + <<endl; + // Front staggered module (Top if pair), top + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + // modNum++; + } + } +} + +void position_CERN(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(CERN_rotate_Z); + TGeoCombiTrans* module_combi_trans = NULL; + + // Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1; + Float_t yPos=CERN_First_Y_Position; + Int_t ii=0; + Float_t xPos = CERN_X_Offset; + Float_t zPos = CERN_Z_Position; + + for (Int_t j=0; j<modNType; j++){ + Int_t modType= CERN_Types[j]; + Int_t modNum = 0; + for(Int_t i=0; i<CERN_Number[j]; i++) { + ii++; + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + } + } +} + +void position_side_tof_modules(Int_t modNType) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(180.); + TGeoCombiTrans* module_combi_trans = NULL; + + // Int_t numModules=(Int_t)( (Inner_Module_Last_Y_Position-Inner_Module_First_Y_Position)/Module_Size_Y[modType])+1; + Float_t yPos=0.; //Inner_Module_First_Y_Position; + Int_t ii=0; + for (Int_t j=0; j<modNType; j++){ + Int_t modType= InnerSide_Module_Types[j]; + Int_t modNum = 0; + for(Int_t i=0; i<InnerSide_Module_Number[j]; i++) { + ii++; + cout << "InnerSide ii "<<ii<<" Last "<<Last_Size_Y<<","<<Last_Over_Y<<endl; + Float_t DeltaY=Module_Size_Y[modType]+Last_Size_Y-2.*(Module_Over_Y[modType]+Last_Over_Y); + if (ii>1){yPos += DeltaY;} + Last_Size_Y=Module_Size_Y[modType]; + Last_Over_Y=Module_Over_Y[modType]; + Float_t xPos = InnerSide_Module_X_Offset; + Float_t zPos = Wall_Z_Position; + cout <<"Position InnerSide Module "<<i<<" of "<<InnerSide_Module_Number[j]<<" Type "<<modType + <<" at Y = "<<yPos<<" Ysize = "<<Module_Size_Y[modType] + <<" DeltaY = "<<DeltaY<<endl; + + module_trans + = new TGeoTranslation("", xPos, yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + module_trans + = new TGeoTranslation("", -xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + + if (ii>1) { + module_trans + = new TGeoTranslation("", xPos, -yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + module_trans + = new TGeoTranslation("", -xPos, -yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + + module_trans + = new TGeoTranslation("", xPos, yPos-DeltaY/2, zPos+Module_Size_Z[modType]); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + module_trans + = new TGeoTranslation("", -xPos, yPos-DeltaY/2, zPos+Module_Size_Z[modType]); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + + module_trans + = new TGeoTranslation("", xPos, -(yPos-DeltaY/2), zPos+Module_Size_Z[modType]); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_trans); + modNum++; + + module_trans + = new TGeoTranslation("", -xPos,-(yPos-DeltaY/2), zPos+Module_Size_Z[modType]); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum, module_combi_trans); + modNum++; + + } + } + } +} + +void position_outer_tof_modules(Int_t nCol) //modType, Int_t col1, Int_t col2) +{ + TGeoTranslation* module_trans=NULL; + TGeoRotation* module_rot = new TGeoRotation(); + module_rot->RotateZ(180.); + TGeoCombiTrans* module_combi_trans = NULL; + + // Int_t numModules=(Int_t)( (Outer_Module_Last_Y_Position-Outer_Module_First_Y_Position)/Module_Size_Y[modType])+1; + + Int_t modNum[NofModuleTypes]; + for (Int_t k=0; k<NofModuleTypes; k++){ + modNum[k]=0; + } + + Float_t zPos = Wall_Z_Position; + for(Int_t j=0; j<nCol; j++){ + Float_t xPos = Outer_Module_X_Offset + ((j+1)*DxColl); + Last_Size_Y=0.; + Last_Over_Y=0.; + Float_t yPos = 0.; + Int_t ii=0; + Float_t DzPos =0.; + for(Int_t k=0; k<Outer_Module_NTypes; k++){ + Int_t modType= Outer_Module_Types[k][j]; + if(Module_Size_Z[modType]>DzPos){ + if(Outer_Module_Number[k][j]>0){ + DzPos = Module_Size_Z[modType]; + } + } + } + + zPos -= 2.*DzPos; //((j+1)*2*Module_Size_Z[modType]); + + Pole_ZPos[NumberOfPoles] = zPos; + Pole_Col[NumberOfPoles] = j+1; + NumberOfPoles++; + Pole_ZPos[NumberOfPoles] = zPos+DzPos; + Pole_Col[NumberOfPoles] = j+1; + NumberOfPoles++; + //if (j+1==nCol) { + if (1) { + Pole_ZPos[NumberOfPoles] = Pole_ZPos[0]; + Pole_Col[NumberOfPoles] = j+1; + NumberOfPoles++; + + Bar_Size_Z = Pole_ZPos[0] - zPos; + gBar[NumberOfBars] = create_tof_bar(Bar_Size_X, Bar_Size_Y, Bar_Size_Z); + Bar_ZPos[NumberOfBars] = zPos+Bar_Size_Z/2.-Pole_Size_Z/2.; + Bar_XPos[NumberOfBars] = xPos + Pole_Offset; + NumberOfBars++; + } + + for (Int_t k=0; k<Outer_Module_NTypes; k++) { + Int_t modType = Outer_Module_Types[k][j]; + Int_t numModules = Outer_Module_Number[k][j]; + + cout <<" Outer: position "<<numModules<<" of type "<<modType<<" in col "<<j + <<" at z = "<<zPos<<", DzPos = "<<DzPos<<endl; + for(Int_t i=0; i<numModules; i++) { + ii++; + cout << "Outer ii "<<ii<<" Last "<<Last_Size_Y<<","<<Last_Over_Y<<endl; + Float_t DeltaY=Module_Size_Y[modType]+Last_Size_Y-2.*(Module_Over_Y[modType]+Last_Over_Y); + if (ii>1){yPos += DeltaY;} + Last_Size_Y=Module_Size_Y[modType]; + Last_Over_Y=Module_Over_Y[modType]; + cout <<"Position Outer Module "<<i<<" of "<<Outer_Module_Number[k][j]<<" Type "<<modType + <<"(#"<<modNum[modType]<<") "<<" at Y = "<<yPos<<" Ysize = "<<Module_Size_Y[modType] + <<" DeltaY = "<<DeltaY<<endl; + + module_trans = new TGeoTranslation("", xPos, yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans); + modNum[modType]++; + + module_trans = new TGeoTranslation("", -xPos, yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans); + modNum[modType]++; + + if (ii>1) { + module_trans + = new TGeoTranslation("", xPos, -yPos, zPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans); + modNum[modType]++; + module_trans + = new TGeoTranslation("", -xPos, -yPos, zPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans); + modNum[modType]++; + + // second layer + module_trans + = new TGeoTranslation("", xPos, yPos-DeltaY/2., zPos+DzPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans); + modNum[modType]++; + module_trans + = new TGeoTranslation("", -xPos, yPos-DeltaY/2., zPos+DzPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans); + modNum[modType]++; + + module_trans + = new TGeoTranslation("", xPos, -(yPos-DeltaY/2.), zPos+DzPos); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_trans); + modNum[modType]++; + module_trans + = new TGeoTranslation("", -xPos, -(yPos-DeltaY/2.), zPos+DzPos); + module_combi_trans = new TGeoCombiTrans(*module_trans, *module_rot); + gGeoMan->GetVolume(geoVersionStand)->AddNode(gModules[modType], modNum[modType], module_combi_trans); + modNum[modType]++; + + } + } + } + } +} + + +void dump_info_file() +{ + TDatime datetime; // used to get timestamp + + printf("writing info file: %s\n", FileNameInfo.Data()); + + FILE *ifile; + ifile = fopen(FileNameInfo.Data(),"w"); + + if (ifile == NULL) + { + printf("error opening %s\n", FileNameInfo.Data()); + exit(1); + } + + fprintf(ifile,"#\n## %s information file\n#\n\n", geoVersion.Data()); + + fprintf(ifile,"# created %d\n\n", datetime.GetDate()); + + fprintf(ifile,"# TOF setup\n"); + if (TOF_Z_Front == 450) + fprintf(ifile,"SIS 100 hadron setup\n"); + if (TOF_Z_Front == 600) + fprintf(ifile,"SIS 100 electron\n"); + if (TOF_Z_Front == 650) + fprintf(ifile,"SIS 100 muon\n"); + if (TOF_Z_Front == 880) + fprintf(ifile,"SIS 300 electron\n"); + if (TOF_Z_Front == 1020) + fprintf(ifile,"SIS 300 muon\n"); + fprintf(ifile,"\n"); + + const Float_t TOF_Z_Back = Wall_Z_Position + 1.5 * Module_Size_Z[0]; // back of TOF wall + + fprintf(ifile,"# envelope\n"); + // Show extension of TRD + fprintf(ifile,"%7.2f cm start of TOF (z)\n", TOF_Z_Front); + fprintf(ifile,"%7.2f cm end of TOF (z)\n", TOF_Z_Back); + fprintf(ifile,"\n"); + + // Layer thickness + fprintf(ifile,"# central tower position\n"); + fprintf(ifile,"%7.2f cm center of staggered, front RPC cell at x=0\n", Wall_Z_Position); + fprintf(ifile,"\n"); + + fclose(ifile); +} diff --git a/macro/mcbm/geometry/trd/Create_TRD_Geometry_v20a.C b/macro/mcbm/geometry/trd/Create_TRD_Geometry_v20a.C new file mode 100644 index 00000000..95062f84 --- /dev/null +++ b/macro/mcbm/geometry/trd/Create_TRD_Geometry_v20a.C @@ -0,0 +1,4116 @@ +/// +/// \file Create_TRD_Geometry_v20a.C +/// \brief Generates TRD geometry in Root format. +/// + +// 2020-05-23 - DE - v20a - add support structure to TRD v18q, realign module in x +// 2018-08-24 - DE - v18q - use only 1st 2 layers of TRD in 2018 setup +// 2017-11-22 - DE - v18n - do not generate mBUCH at z=125 cm, only mTRD +// 2017-11-22 - DE - v18m - mBUCH at z=125 cm, mTRD at z=149, 171, 193 and 215 cm - layer pitch 22 cm from CAD +// 2017-11-03 - DE - v18l - shift mTRD to z=140 cm for acceptance matching with mSTS (= same result as v18g) +// 2017-11-03 - DE - v18k - plot 4 mTRD modules first, then mBUCH to simplyfy the realignment in x (= same result as v18j) +// 2017-11-02 - DE - v18j - move Muenster TRD modules back to original positions in x (fix bug in v18i) +// 2017-10-17 - DE - v18i - add Bucharest 60x60 cm2 Bucharest TRD module with FASP ASICs +// 2017-05-16 - DE - v18e - re-align all TRD modules to same theta angle using left side of 4th TRD module as reference +// 2017-05-02 - DE - v18a - re-base miniTRD v18e on CBM TRD v17a +// 2017-04-28 - DE - v17 - implement power bus bars as defined in the TDR +// 2017-04-26 - DE - v17 - add aluminium ledge around backpanel +// 2017-01-10 - DE - v17a_3e - replace 6 ultimate density by 9 super density FEBs for TRD type 1 modules +// 2016-07-05 - FU - v16a_3e - identical to v15a, change the way the trd volume is exported to resolve a bug with TGeoShape destructor +// 2015-01-08 - DE - v15a_3e - reduce frame thickness in large modules to 15 mm instead of 20 mm +// 2014-06-25 - DE - v14a_3e - consists of only 3 small and 3 large modules types (was 4+4 before) +// 2014-06-25 - DE - v14a_3e - inner part of all 3 stations is now identical +// 2014-05-02 - DE - v14a_3e - redesign inner part of station 3, now with 5x5-1 small modules, like in station 1 and station 2 +// 2014-05-02 - DE - v14a_3e - include optional GBTX readout boards on each module +// 2014-05-02 - DE - v14a_3e - introduce 3x5=15 Spadic FEBs for ultimate density on module type 1 +// +// 2013-11-14 - DE - v13q_3e - generate information about pad plane layout (CbmTrdPads_v14a.h) for all module types in this macro +// +// 2013-11-04 - DE - v13p4 - adapt the number of front-end boards to the pad layout of the 540 mm modules +// 2013-11-04 - DE - v13p4 - use 8 module types (4x S + 4x L) to better match the occupancy +// 2013-10-31 - DE - v13p4 - modify the support structure of station 1 to match with the MUCH/RICH platform +// 2013-10-29 - DE - v13p4 - build lattice grid as TGeoBBox instead of VolumeAssembly - in run_sim.C save 9% of time compared to v13p7 +// 2013-10-29 - DE - v13p4 - build lattice grid as TGeoBBox instead of CompositeShape - in run_sim.C save 18% of time compared to v13p6 +// +// 2013-10-28 - DE - introduce new geometry naming scheme: v13p1 - SIS 100 hadron +// 2013-10-28 - DE - introduce new geometry naming scheme: v13p2 - SIS 100 electron +// 2013-10-28 - DE - introduce new geometry naming scheme: v13p3 - SIS 100 muon +// 2013-10-28 - DE - introduce new geometry naming scheme: v13p4 - SIS 300 electron +// 2013-10-28 - DE - introduce new geometry naming scheme: v13p5 - SIS 300 muon +// 2013-10-28 - DE - add option to draw the magnetic field vector in the magnet +// 2013-09-27 - DE - do not use TGeoXtru to build the supports, use TGeoBBox instead +// +// 2013-06-25 - DE - v13g trd300_rich (10 layers, z = 4100 ) - TRD right behind SIS300 RICH +// 2013-06-25 - DE - v13h trd100_sts ( 4 layers, z = 2600 ) - TRD completely on RICH/MUCH platform to allow TOF to move upstream +// 2013-06-25 - DE - v13i trd100_rich ( 2 layers, z = 4100 ) - TRD right behind RICH +// 2013-06-25 - DE - v13j trd100_rich ( 3 layers, z = 4100 ) - TRD right behind RICH +// 2013-06-25 - DE - v13k trd100_rich ( 4 layers, z = 4100 ) - TRD right behind RICH +// 2013-06-25 - DE - --- trd100_much_2_absorbers ( 4 layers, z = 4300 ) - same as version at z = 4600 +// 2013-06-25 - DE - v13l trd100_much_3_absorbers ( 4 layers, z = 4600 ) - TRD right behind SIS100 MUCH +// 2013-06-25 - DE - v13m trd300_much_6_absorbers (10 layers, z = 5500 ) - TRD right behind SIS300 MUCH +// 2013-06-25 - DE - v13n trd300_rich_stretched (10 layers, z = 4600 ) - TRD stretched behind SIS300 RICH +// +// 2013-06-19 - DE - add TRD (I, II, III) labels on support structure +// 2013-05-29 - DE - allow for flexible TRD z-positions defined by position of layer01 +// 2013-05-23 - DE - remove "trd_" prefix from node names (except top node) +// 2013-05-22 - DE - radiators G30 (z=240 mm) +// 2013-05-22 - DE - radiators H (z=275 mm - 125 * 2.2mm), (H++ z=335 mm) +// 2013-05-22 - DE - radiators B++ (z=254 mm - 350 * 0.724 mm), K++ (z=254 mm - 350 * 0.724 mm) +// 2013-04-17 - DE - introduce volume assembly for layers, e.g. trd_layer03 +// 2013-03-26 - DE - use Air as ASIC material +// 2013-03-26 - DE - put support structure into its own assembly +// 2013-03-26 - DE - move TRD upstream to z=400m +// 2013-03-26 - DE - RICH will probably end at z=380 cm, TRD can move to 400 cm +// 2013-03-25 - DE - shrink active area from 570 to 540 mm and 960 to 910 mm +// 2013-03-06 - DE - add ASICs on FEBs +// 2013-03-05 - DE - introduce supports for SIS100 and SIS300 +// 2013-03-05 - DE - replace all Float_t by Double_t +// 2013-01-21 - DE - introduce TRD media, use TRDG10 as material for pad plane and FEBs +// 2013-01-21 - DE - put backpanel into the geometry +// 2013-01-11 - DE - allow for misalignment of TRD modules +// 2012-11-04 - DE - add kapton foil, add FR4 padplane +// 2012-11-03 - DE - add lattice grid on entrance window as CompositeShape + +// TODO: +// - use Silicon as ASIC material + +// in root all sizes are given in cm + +#include "TSystem.h" +#include "TGeoManager.h" +#include "TGeoVolume.h" +#include "TGeoMaterial.h" +#include "TGeoMedium.h" +#include "TGeoPgon.h" +#include "TGeoMatrix.h" +#include "TGeoCompositeShape.h" +#include "TGeoXtru.h" +#include "TFile.h" +#include "TString.h" +#include "TList.h" +#include "TRandom3.h" +#include "TDatime.h" + +#include "TGeoArb8.h" +#include "TGeoTube.h" +#include "TGeoCone.h" + +#include <iostream> + +// Name of output file with geometry +const TString tagVersion = "v20a_mcbm"; +//const TString subVersion = "_1h"; +//const TString subVersion = "_1e"; +//const TString subVersion = "_1m"; +//const TString subVersion = "_3e"; +//const TString subVersion = "_3m"; + +const Int_t setupid = 1; // 1e is the default +//const Double_t zfront[5] = { 260., 410., 360., 410., 550. }; +const Double_t zfront[5] = { 260., 177., 360., 410., 550. }; // move 1st TRD to z=177 cm +//const Double_t zfront[5] = { 260., 140., 360., 410., 550. }; +const TString setupVer[5] = { "_1h", "_1e", "_1m", "_3e", "_3m" }; +const TString subVersion = setupVer[setupid]; + +const TString geoVersion = "trd_" + tagVersion; // + subVersion; +const TString FileNameSim = geoVersion + ".geo.root"; +const TString FileNameGeo = geoVersion + "_geo.root"; +const TString FileNameInfo = geoVersion + ".geo.info"; +const TString FileNamePads = "CbmTrdPads_" + tagVersion + ".h"; + +// display switches +const Bool_t IncludeRadiator = false; // false; // true, if radiator is included in geometry +const Bool_t IncludeLattice = true; // false; // true, if lattice grid is included in geometry + +const Bool_t IncludeKaptonFoil = true; // false; // true, if entrance window is included in geometry +const Bool_t IncludeGasFrame = true; // false; // true, if frame around gas volume is included in geometry +const Bool_t IncludePadplane = true; // false; // true, if padplane is included in geometry +const Bool_t IncludeBackpanel = true; // false; // true, if backpanel is included in geometry +const Bool_t IncludeAluLedge = true; // false; // true, if Al-ledge around the backpanel is included in geometry +const Bool_t IncludeGibbet = true; // false; // true, if mTRD gibbet support to be drawn +const Bool_t IncludePowerbars = false; // false; // true, if LV copper bus bars to be drawn + +const Bool_t IncludeFebs = true; // false; // true, if FEBs are included in geometry +const Bool_t IncludeRobs = true; // true, if ROBs are included in geometry +const Bool_t IncludeAsics = true; // true, if ASICs are included in geometry +const Bool_t IncludeSupports = false; // false; // true, if support structure is included in geometry +const Bool_t IncludeLabels = false; // false; // true, if TRD (I, II, III) labels are plotted in (VisLevel 5) +const Bool_t IncludeFieldVector = false; // true, if magnetic field vector to be shown (in the magnet) + +// positioning switches +const Bool_t DisplaceRandom = false; // true; // false; // add random displacement of modules for alignment study +const Bool_t RotateRandom = false; // true; // false; // add random rotation of modules for alignment study +const Bool_t DoExplode = false; // true, // false; // add random displacement of modules for alignment study + +// positioning parameters +const Double_t maxdx = 0.2; // max +- 0.1 cm shift in x +const Double_t maxdy = 0.2; // max +- 0.1 cm shift in y +const Double_t maxdz = 1.0; // max +- 1.0 cm shift in z + +const Double_t maxdrotx = 2.0; // 20.0; // max rotation around x +const Double_t maxdroty = 2.0; // 20.0; // max rotation around y +const Double_t maxdrotz = 2.0; // 20.0; // max rotation around z + +const Double_t ExplodeFactor = 1.02; // 1.02; // Factor by which modules are exploded in the x/y plane + +// initialise random numbers +TRandom3 r3(0); + +// Parameters defining the layout of the complete detector build out of different detector layers. +const Int_t MaxLayers = 10; // max layers + +// select layers to display +// +//const Int_t ShowLayer[MaxLayers] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // 1st layer only +//const Int_t ShowLayer[MaxLayers] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // 2nd layer only +//const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }; // 5th layer only +//const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }; // 6th layer only +//const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }; // 9th layer only +//const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; // 10th layer only +// +//const Int_t ShowLayer[MaxLayers] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // Station 1, layer 1, 2 +//const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 }; // Station 2, layer 5, 6 +//const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; // Station 3, layer 9,10 +//const Int_t ShowLayer[MaxLayers] = { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0 }; // Station 1 and 2 +//const Int_t ShowLayer[MaxLayers] = { 1, 1, 0, 0, 1, 1, 1, 0, 1, 1 }; // Station 1, 2 and 3 +// +//const Int_t ShowLayer[MaxLayers] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // SIS100-2l // 1: plot, 0: hide +//const Int_t ShowLayer[MaxLayers] = { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; // SIS100-3l // 1: plot, 0: hide +// +//const Int_t ShowLayer[MaxLayers] = { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 }; // SIS100-4l // 1: plot, 0: hide +//const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 }; // SIS300-mu // 1: plot, 0: hide +//const Int_t ShowLayer[MaxLayers] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; // SIS300-e // 1: plot, 0: hide +Int_t ShowLayer[MaxLayers] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // SIS100-4l is default + +Int_t BusBarOrientation[MaxLayers] = { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; // 1 = vertical + +Int_t PlaneId[MaxLayers]; // automatically filled with layer ID + +const Int_t LayerType[MaxLayers] = {10, 11, 10, 11, 20, 21, 20, 21, 30, 31}; // ab: a [1-4] - layer type, b [0,1] - vertical/horizontal pads +// ### Layer Type 20 is mCBM Layer Type 2 with Buch prototype module (type 4) with vertical pads +// ### Layer Type 11 is Layer Type 1 with detector modules rotated by 90?? +// ### Layer Type 21 is Layer Type 2 with detector modules rotated by 90?? +// ### Layer Type 31 is Layer Type 3 with detector modules rotated by 90?? +// In the subroutine creating the layers this is recognized automatically + +const Int_t LayerNrInStation[MaxLayers] = { 1, 2, 3, 4, 1, 2, 3, 4, 1, 2 }; + +Double_t LayerPosition[MaxLayers] = { 0. }; // start position = 0 - 2016-07-12 - DE + +// 5x z-positions from 260 till 550 cm +//Double_t LayerPosition[MaxLayers] = { 260. }; // start position - 2013-10-28 - DE - v14_1h - SIS 100 hadron ( 4 layers, z = 2600 ) +//Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-10-28 - DE - v14_1e - SIS 100 electron ( 4 layers, z = 4100 ) +//Double_t LayerPosition[MaxLayers] = { 360. }; // start position - 2014-06-16 - DE - v14_1m - SIS 100 muon ( 4 layers, z = 3600 ) was 460. +//Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-10-28 - DE - v14_3e - SIS 300 electron (10 layers, z = 4100 ) +//Double_t LayerPosition[MaxLayers] = { 550. }; // start position - 2013-10-28 - DE - v14_3m - SIS 300 muon 6_abs (10 layers, z = 5500 ) +// +// obsolete variants +//Double_t LayerPosition[MaxLayers] = { 460. }; // start position - 2013-10-28 - DE - v13x3 - SIS 100 muon ( 4 layers, z = 4600 ) +//Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-06-25 - DE - v13i trd100_rich ( 2 layers, z = 4100 ) +//Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-06-25 - DE - v13j trd100_rich ( 3 layers, z = 4100 ) +//Double_t LayerPosition[MaxLayers] = { 430. }; // start position - 2013-06-25 - DE - --- trd100_much_2_absorbers ( 4 layers, z = 4300 ) +//Double_t LayerPosition[MaxLayers] = { 460. }; // start position - 2013-06-25 - DE - v13n trd300_rich_stretched (10 layers, z = 4600 ) + + +const Double_t LayerThickness = 22.0; // miniCBM - Thickness of one TRD layer in cm +//const Double_t LayerThickness = 25.0; // miniCBM - Thickness of one TRD layer in cm +//const Double_t LayerThickness = 45.0; // Thickness of one TRD layer in cm + +const Double_t LayerOffset[MaxLayers] = { 0., 0., 0., 0., -112., 0., 0., 0., 5., 0. }; // v13x[4,5] - z offset in addition to LayerThickness +//const Double_t LayerOffset[MaxLayers] = { 0., 0., 0., 0., -115., 0., 0., 0., 5., 0. }; // v13x[4,5] - z offset in addition to LayerThickness +// 140 / 165 / 190 / 215 / 240 - 115 = 125 +//const Double_t LayerOffset[MaxLayers] = { 0., 0., 0., 0., -115., 0., 0., 0., 5., 0. }; // v13x[4,5] - z offset in addition to LayerThickness +// 115 / 140 / 165 / 190 / 215 - 125 = 100 + +// const Double_t LayerOffset[MaxLayers] = { 0., -10., 0., 0., 0., 0., 0., 0., 5., 0. }; // v13x[4,5] - z offset in addition to LayerThickness +// 100 / 125 - 10 = 115 / 140 / 165 / 190 + + //const Double_t LayerOffset[MaxLayers] = { 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. }; // SIS100 - z offset in addition to LayerThickness +//const Double_t LayerOffset[MaxLayers] = { 0., 0., 0., 0., 95., 0., 0., 0., 5., 0. }; // v13n - z offset in addition to LayerThickness + +const Int_t LayerArraySize[3][4] = { { 5, 5, 9, 11 }, // for layer[1-3][i,o] below + { 5, 5, 9, 11 }, + { 5, 5, 9, 11 } }; + + +// ### Layer Type 1 +// v14x - module types in the inner sector of layer type 1 - looking upstream +const Int_t layer1i[5][5] = { { 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0 }, + // { 0, 0, 101, 0, 0 }, + { 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0 } }; + +//const Int_t layer1i[5][5] = { { 323, 323, 321, 321, 321 }, // abc: a module type - b orientation (x90 deg) in odd - c even layers +// { 223, 123, 121, 121, 221 }, +// { 203, 103, 0, 101, 201 }, +// { 203, 103, 101, 101, 201 }, +// { 303, 303, 301, 301, 301 } }; +// number of modules: 24 + +// v14x - module types in the outer sector of layer type 1 - looking upstream +const Int_t layer1o[9][11]= { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 821, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; +//// v14x - module types in the outer sector of layer type 1 - looking upstream +//const Int_t layer1o[9][11]= { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +// { 0, 0, 823, 823, 723, 721, 721, 821, 821, 0, 0 }, +// { 0, 0, 823, 623, 0, 0, 0, 621, 821, 0, 0 }, +// { 0, 0, 703, 603, 0, 0, 0, 601, 701, 0, 0 }, +// { 0, 0, 803, 603, 0, 0, 0, 601, 801, 0, 0 }, +// { 0, 0, 803, 803, 703, 701, 701, 801, 801, 0, 0 }, +// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; +// number of modules: 26 +// Layer1 = 24 + 26; // v14a + + +// ### Layer Type 2 -> remapped for Buch prototype +// v14x - module types in the inner sector of layer type 2 - looking upstream +// const Int_t layer2i[5][5] = { { 323, 323, 321, 321, 321 }, // abc: a module type - b orientation (x90 deg) in odd - c even layers +// { 223, 123, 121, 121, 221 }, +// { 203, 103, 0, 101, 201 }, +// { 203, 103, 101, 101, 201 }, +// { 303, 303, 301, 301, 301 } }; +const Int_t layer2i[5][5] = { { 0 }, // abc: a module type - b orientation (x90 deg) in odd - c even layers + { 0 }, + { 0, 0, 401, 0, 0 }, + { 0 }, + { 0 } }; + +// number of modules: 24 + +// v14x - module types in the outer sector of layer type 2 - looking upstream +// const Int_t layer2o[9][11]= { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +// { 0, 823, 823, 823, 823, 821, 821, 821, 821, 821, 0 }, +// { 0, 823, 823, 823, 723, 721, 721, 821, 821, 821, 0 }, +// { 0, 823, 723, 623, 0, 0, 0, 621, 721, 821, 0 }, +// { 0, 803, 703, 603, 0, 0, 0, 601, 701, 801, 0 }, +// { 0, 803, 703, 603, 0, 0, 0, 601, 701, 801, 0 }, +// { 0, 803, 803, 803, 703, 701, 701, 801, 801, 801, 0 }, +// { 0, 803, 803, 803, 803, 801, 801, 801, 801, 801, 0 }, +// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; +const Int_t layer2o[9][11] = { { 0 },{ 0 },{ 0 },{ 0 },{ 0 },{ 0 },{ 0 },{ 0 },{ 0 }}; +// number of modules: 54 +// Layer2 = 24 + 54; // v14a + + +// ### Layer Type 3 +// v14x - module types in the inner sector of layer type 3 - looking upstream +const Int_t layer3i[5][5] = { { 323, 323, 321, 321, 321 }, // abc: a module type - b orientation (x90 deg) in odd - c even layers + { 223, 123, 121, 121, 221 }, + { 203, 103, 0, 101, 201 }, + { 203, 103, 101, 101, 201 }, + { 303, 303, 301, 301, 301 } }; +// number of modules: 24 + +// v14x - module types in the outer sector of layer type 3 - looking upstream +const Int_t layer3o[9][11] = { { 823, 823, 823, 823, 823, 821, 821, 821, 821, 821, 821 }, + { 823, 823, 823, 823, 823, 821, 821, 821, 821, 821, 821 }, + { 823, 823, 823, 723, 623, 621, 621, 721, 821, 821, 821 }, + { 823, 823, 723, 623, 0, 0, 0, 621, 721, 821, 821 }, + { 803, 803, 703, 603, 0, 0, 0, 601, 701, 801, 801 }, + { 803, 803, 703, 603, 0, 0, 0, 601, 701, 801, 801 }, + { 803, 803, 803, 703, 603, 601, 601, 701, 801, 801, 801 }, + { 803, 803, 803, 803, 803, 801, 801, 801, 801, 801, 801 }, + { 803, 803, 803, 803, 803, 801, 801, 801, 801, 801, 801 } }; +// number of modules: 90 +// Layer2 = 24 + 90; // v14a + + +// Parameters defining the layout of the different detector modules +const Int_t NofModuleTypes = 8; +const Int_t ModuleType[NofModuleTypes] = { 0, 0, 0, 2, 1, 1, 1, 1 }; // 0 = small module, 1 = large module, 2 = mCBM Bucharest prototype + +// FEB inclination angle +const Double_t feb_rotation_angle[NofModuleTypes] = { 70, 90, 90, 0, 80, 90, 90, 90 }; // rotation around x-axis, 0 = vertical, 90 = horizontal +//const Double_t feb_rotation_angle[NofModuleTypes] = { 45, 45, 45, 45, 45, 45, 45, 45 }; // rotation around x-axis, 0 = vertical, 90 = horizontal + +// GBTx ROB definitions +const Int_t RobsPerModule[NofModuleTypes] = { 3, 2, 1, 6, 2, 2, 1, 1 }; // number of GBTx ROBs on module +const Int_t GbtxPerRob[NofModuleTypes] = {105,105,105,103,107,105,105,103 }; // number of GBTx ASICs on ROB + +const Int_t GbtxPerModule[NofModuleTypes] = { 15, 10, 5, 18, 0, 10, 5, 3 }; // for .geo.info - TODO: merge with above GbtxPerRob +const Int_t RobTypeOnModule[NofModuleTypes]={555, 55, 5,333333, 0, 55, 5, 3 }; // for .geo.info - TODO: merge with above GbtxPerRob + +//const Int_t RobsPerModule[NofModuleTypes] = { 2, 2, 1, 1, 2, 2, 1, 1 }; // number of GBTx ROBs on module +//const Int_t GbtxPerRob[NofModuleTypes] = {107,105,105,103,107,105,105,103 }; // number of GBTx ASICs on ROB +//const Int_t GbtxPerModule[NofModuleTypes] = { 14, 8, 5, 0, 0, 10, 5, 3 }; // for .geo.info - TODO: merge with above GbtxPerRob +//const Int_t RobTypeOnModule[NofModuleTypes] = { 77, 53, 5, 0, 0, 55, 5, 3 }; // for .geo.info - TODO: merge with above GbtxPerRob + +// super density for type 1 modules - 2017 - 540 mm +const Int_t FebsPerModule[NofModuleTypes] = { 9, 5, 6, 18, 12, 8, 4, 3 }; // number of FEBs on backside +//const Int_t FebsPerModule[NofModuleTypes] = { 9, 6, 3, 4, 12, 8, 4, 2 }; // number of FEBs on backside +const Int_t AsicsPerFeb[NofModuleTypes] = {210,210,210,410,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping +//// ultimate density - 540 mm +//const Int_t FebsPerModule[NofModuleTypes] = { 6, 5, 6, 4, 12, 8, 4, 3 }; // number of FEBs on backside - reduced FEBs (64 ch ASICs) +//const Int_t AsicsPerFeb[NofModuleTypes] = {315,210,105,105,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping +////const Int_t FebsPerModule[NofModuleTypes] = { 6, 5, 3, 2, 6, 3, 4, 3 }; // min number of FEBs // number of FEBs on backside - reduced FEBs (64 ch ASICs) +////const Int_t AsicsPerFeb[NofModuleTypes] = {315,210,210,210,216,216,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping +////const Int_t AsicsPerFeb[NofModuleTypes] = {216,210,210,210,216,216,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping +// +////// super density - 540 mm +//const Int_t FebsPerModule[NofModuleTypes] = { 9, 5, 6, 4, 12, 6, 4, 3 }; // light // number of FEBs on backside - reduced FEBs (64 ch ASICs) +//const Int_t AsicsPerFeb[NofModuleTypes] = {210,210,105,105,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping +// +//// normal density - 540 mm +//const Int_t FebsPerModule[NofModuleTypes] = { 18, 10, 6, 4, 12, 6, 4, 3 }; // number of FEBs on backside (linked to pad layout) - mod4 = mod3, therefore same +//const Int_t AsicsPerFeb[NofModuleTypes] = {105,105,105,105,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping + +// ultimate density - 570 mm +//const Int_t FebsPerModule[NofModuleTypes] = { 6, 5, 3, 2, 5, 3, 2, 1 }; // min number of FEBs // number of FEBs on backside - reduced FEBs (64 ch ASICs) +//const Int_t AsicsPerFeb[NofModuleTypes] = {216,210,210,210,216,216,216,216 }; // %100 gives number of ASICs on FEB, /100 gives grouping +// +//const Int_t FebsPerModule[NofModuleTypes] = { 6, 5, 3, 3, 10, 5, 3, 3 }; // min (6) module types // number of FEBs on backside - reduced FEBs (64 ch ASICs) +//const Int_t AsicsPerFeb[NofModuleTypes] = {216,210,210,210,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping +//// super density - 570 mm +//const Int_t FebsPerModule[NofModuleTypes] = { 10, 5, 5, 5, 12, 6, 4, 3 }; // light // number of FEBs on backside - reduced FEBs (64 ch ASICs) +//const Int_t AsicsPerFeb[NofModuleTypes] = {210,210,105,105,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping +// +//// normal density - 570 mm +//const Int_t FebsPerModule[NofModuleTypes] = { 19, 10, 5, 5, 12, 6, 4, 3 }; // number of FEBs on backside (linked to pad layout) - mod4 = mod3, therefore same +//const Int_t AsicsPerFeb[NofModuleTypes] = {105,105,105,105,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping + + +/* TODO: activate connector grouping info below +// ultimate - grouping of pads to connectors +const Int_t RowsPerConnector[NofModuleTypes] = { 6, 4, 2, 2, 2, 2, 2, 2 }; +const Int_t ColsPerConnector[NofModuleTypes] = { 16, 16, 16, 16, 16, 16, 16, 16 }; +// super - grouping of pads to connectors +const Int_t RowsPerConnector[NofModuleTypes] = { 4, 4, 2, 2, 2, 2, 2, 2 }; +const Int_t ColsPerConnector[NofModuleTypes] = { 16, 16, 16, 16, 16, 16, 16, 16 }; +// normal - grouping of pads to connectors +const Int_t RowsPerConnector[NofModuleTypes] = { 2, 2, 2, 2, 2, 2, 2, 2 }; +const Int_t ColsPerConnector[NofModuleTypes] = { 16, 16, 16, 16, 16, 16, 16, 16 }; +*/ + + +const Double_t feb_z_offset = 0.1; // 1 mm - offset in z of FEBs to backpanel +const Double_t asic_offset = 0.1; // 1 mm - offset of ASICs to FEBs to avoid overlaps + +// ASIC parameters +Double_t asic_distance; + +//const Double_t FrameWidth[2] = { 1.5, 2.0 }; // Width of detector frames in cm +const Double_t FrameWidth[3] = { 1.5, 1.5, 2.5}; // Width of detector frames in cm +// mini - production +const Double_t DetectorSizeX[3] = { 57., 95., 59.0}; // => 54 x 54 cm2 & 91 x 91 cm2 active area +const Double_t DetectorSizeY[3] = { 57., 95., 60.8}; // quadratic modules +//// default +//const Double_t DetectorSizeX[2] = { 60., 100.}; // => 57 x 57 cm2 & 96 x 96 cm2 active area +//const Double_t DetectorSizeY[2] = { 60., 100.}; // quadratic modules + +// Parameters tor the lattice grid reinforcing the entrance window +//const Double_t lattice_o_width[2] = { 1.5, 2.0 }; // Width of outer lattice frame in cm +const Double_t lattice_o_width[2] = { 1.5, 1.5 }; // Width of outer lattice frame in cm +const Double_t lattice_i_width[2] = { 0.2, 0.2 }; // { 0.4, 0.4 }; // Width of inner lattice frame in cm +// Thickness (in z) of lattice frames in cm - see below + +// statistics +Int_t ModuleStats[MaxLayers][NofModuleTypes] = { 0 }; + +// z - geometry of TRD modules +const Double_t radiator_thickness = 0.0; // 35 cm thickness of radiator +//const Double_t radiator_thickness = 30.0; // 30 cm thickness of radiator + shift pad plane to integer multiple of 1 mm +const Double_t radiator_position = - LayerThickness/2. + radiator_thickness/2.; + +//const Double_t lattice_thickness = 1.0; // 1.0; // 10 mm thick lattice frames +const Double_t lattice_thickness = 1.0 - 0.0025; // 0.9975; // 1.0; // 10 mm thick lattice frames +const Double_t lattice_position = radiator_position + radiator_thickness/2. + lattice_thickness/2.; + +const Double_t kapton_thickness = 0.0025; // 25 micron thickness of kapton +const Double_t kapton_position = lattice_position + lattice_thickness/2. + kapton_thickness/2.; + +const Double_t gas_thickness = 1.2; // 12 mm thickness of gas +const Double_t gas_position = kapton_position + kapton_thickness/2. + gas_thickness/2.; + +// frame thickness +const Double_t frame_thickness = gas_thickness; // frame covers gas volume: from kapton foil to pad plane +const Double_t frame_position = - LayerThickness /2. + radiator_thickness + lattice_thickness + kapton_thickness + frame_thickness/2.; + +// pad plane +const Double_t padcopper_thickness = 0.0025; // 25 micron thickness of copper pads +const Double_t padcopper_position = gas_position + gas_thickness/2. + padcopper_thickness/2.; + +const Double_t padplane_thickness = 0.0360; // 360 micron thickness of padplane +const Double_t padplane_position = padcopper_position + padcopper_thickness/2. + padplane_thickness/2.; + +// backpanel components +const Double_t carbon_thickness = 0.0190 * 2; // use 2 layers!! // 190 micron thickness for 1 layer of carbon fibers +const Double_t honeycomb_thickness = 2.3 - kapton_thickness - padcopper_thickness - padplane_thickness - carbon_thickness; // ~ 2.3 mm thickness of honeycomb +const Double_t honeycomb_position = padplane_position + padplane_thickness/2. + honeycomb_thickness/2.; +const Double_t carbon_position = honeycomb_position + honeycomb_thickness/2. + carbon_thickness/2.; + +// aluminium thickness +const Double_t aluminium_thickness = 0.4; // crossbar of 1 x 1 cm at every module edge +const Double_t aluminium_width = 1.0; // crossbar of 1 x 1 cm at every module edge +const Double_t aluminium_position = carbon_position + carbon_thickness/2. + aluminium_thickness/2.; + +// power bus bars +const Double_t powerbar_thickness = 1.0; // 1 cm in z direction +const Double_t powerbar_width = 2.0; // 2 cm in x/y direction +const Double_t powerbar_position = aluminium_position + aluminium_thickness/2. + powerbar_thickness/2.; + +// gibbet support +const Double_t gibbet_thickness = 10.0; // 10 cm in z direction +const Double_t gibbet_width = 10.0; // 10 cm in x/y direction +const Double_t gibbet_position = aluminium_position + aluminium_thickness/2. + gibbet_thickness/2.; + +// module rails +const Double_t rail_thickness = 5.0; // 5 cm in z direction +const Double_t rail_width = 3.0; // 3 cm in x/y direction +const Double_t rail_position = aluminium_position + aluminium_thickness/2. + rail_thickness/2.; + +// readout boards +//const Double_t feb_width = 10.0; // width of FEBs in cm +const Double_t feb_width = 8.5; // width of FEBs in cm +const Double_t feb_thickness = 0.25; // light // 2.5 mm thickness of FEBs +const Double_t febvolume_position = aluminium_position + aluminium_thickness/2. + feb_width/2.; + +// ASIC parameters +const Double_t asic_thickness = 0.25; // 2.5 mm asic_thickness +const Double_t asic_width = 3.0; // 2.0; 1.0; // 1 cm + + +// -------------- BUCHAREST PROTOTYPE SPECIFICS ---------------------------------- +// Frontpanel components +const Double_t carbonBu_thickness = 0.03; // 300 micron thickness for 1 layer of carbon fibers +const Double_t honeycombBu_thickness = 0.94; // 9 mm thickness of honeycomb +const Double_t carbonBu0_position = radiator_position + radiator_thickness/2. + carbonBu_thickness/2.; +const Double_t honeycombBu0_position = carbonBu0_position + carbonBu_thickness/2. + honeycombBu_thickness/2.; +const Double_t carbonBu1_position = honeycombBu0_position + honeycombBu_thickness/2. + carbonBu_thickness/2.; +// Active volume +const Double_t gasBu_position = carbonBu1_position + carbonBu_thickness/2. + gas_thickness/2.; +// Pad plane +const Double_t padcopperBu_position = gasBu_position + gas_thickness/2. + padcopper_thickness/2.; +const Double_t padplaneBu_position = padcopperBu_position + padcopper_thickness/2. + padplane_thickness/2.; +// Backpanel components +const Double_t honeycombBu1_position = padplaneBu_position + padplane_thickness/2. + honeycombBu_thickness/2.; +// PCB +const Double_t glassFibre_thickness = 0.0270; // 300 microns overall PCB thickness +const Double_t cuCoating_thickness = 0.0030; +const Double_t glassFibre_position = honeycombBu1_position + honeycombBu_thickness/2. + glassFibre_thickness/2.; +const Double_t cuCoating_position = glassFibre_position + glassFibre_thickness/2. + cuCoating_thickness/2.; +//Frame around entrance window, active volume and exit window +const Double_t frameBu_thickness = 2*carbonBu_thickness+honeycombBu_thickness+ + gas_thickness+ + padcopper_thickness+padplane_thickness+honeycombBu_thickness+ + glassFibre_thickness+cuCoating_thickness; +const Double_t frameBu_position = radiator_position + radiator_thickness/2. + frameBu_thickness/2.; +// ROB FASP +const Double_t febFASP_zspace = 1.5; // gap size between boards +const Double_t febFASP_width = 5.5; // width of FASP FEBs in cm +const Double_t febFASP_position = cuCoating_position + febFASP_width/2.+1.5; +const Double_t febFASP_thickness = feb_thickness; + +// FASP-ASIC parameters +const Double_t fasp_size[2] = {2, 2.5}; // FASP package size 2x3 cm2 +const Double_t fasp_xoffset = 1.35; // ASIC offset from ROC middle (horizontally) +const Double_t fasp_yoffset = 0.6; // ASIC offset from DET connector (vertical) +// GETS2C-ROB3 connector boord parameters +const Double_t robConn_size_x = 15.0; +const Double_t robConn_size_y = 6.0; +const Double_t robConn_xoffset = 6.0; +const Double_t robConn_FMCwidth = 1.5; // width of a MF FMC connector +const Double_t robConn_FMClength = 6.5; // length of a MF FMC connector +const Double_t robConn_FMCheight = 1.5; // height of a MF FMC connector + +// C-ROB3 parameters : GBTx ROBs +const Double_t rob_size_x = 20.0; // 13.0; // 130 mm +const Double_t rob_size_y = 9.0; // 4.5; // 45 mm +const Double_t rob_yoffset = 0.3; // offset wrt detector frame (on the detector plane) +const Double_t rob_zoffset = -7.5; // offset wrt entrace plane - center board +const Double_t rob_thickness = feb_thickness; +// GBTX parameters +const Double_t gbtx_thickness = 0.25; // 2.5 mm +const Double_t gbtx_width = 3.0; // 2.0; 1.0; // 1 cm +const Double_t gbtx_distance = 0.4; + + +// Names of the different used materials which are used to build the modules +// The materials are defined in the global media.geo file +const TString KeepingVolumeMedium = "air"; +const TString RadiatorVolumeMedium = "TRDpefoam20"; +const TString LatticeVolumeMedium = "TRDG10"; +const TString KaptonVolumeMedium = "TRDkapton"; +const TString GasVolumeMedium = "TRDgas"; +const TString PadCopperVolumeMedium = "TRDcopper"; +const TString PadPcbVolumeMedium = "TRDG10"; // todo - put correct FEB material here +const TString HoneycombVolumeMedium = "TRDaramide"; +const TString CarbonVolumeMedium = "TRDcarbon"; +const TString FebVolumeMedium = "TRDG10"; // todo - put correct FEB material here +const TString AsicVolumeMedium = "air"; // todo - put correct ASIC material here +const TString TextVolumeMedium = "air"; // leave as air +const TString FrameVolumeMedium = "TRDG10"; +const TString PowerBusVolumeMedium = "TRDcopper"; // power bus bars +const TString AluLegdeVolumeMedium = "aluminium"; // aluminium frame around backpanel +const TString AluminiumVolumeMedium = "aluminium"; +const TString Kanya10x10sVolumeMedium = "KANYAProfile10x10Strong"; +const TString Kanya10x10nVolumeMedium = "KANYAProfile10x10Normal"; +const TString Kanya03x05nVolumeMedium = "KANYAProfile3x5Normal"; +//const TString MylarVolumeMedium = "mylar"; +//const TString RadiatorVolumeMedium = "polypropylene"; +//const TString ElectronicsVolumeMedium = "goldcoatedcopper"; + +// some global variables +TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance +TGeoVolume* gModules[NofModuleTypes]; // Global storage for module types + +// Forward declarations +void create_materials_from_media_file(); +TGeoVolume* create_trd_module_type(Int_t moduleType); +TGeoVolume* create_trdi_module_type(); +void create_detector_layers(Int_t layer); +void create_gibbet_support(); +void create_power_bars_vertical(); +void create_power_bars_horizontal(); +void create_xtru_supports(); +void create_box_supports(); +void add_trd_labels(TGeoVolume*, TGeoVolume*, TGeoVolume*); +void create_mag_field_vector(); +void dump_info_file(); +void dump_digi_file(); + + +void Create_TRD_Geometry_v20a() { + + // declare TRD layer layout + if (setupid > 2) + for (Int_t i = 0; i < MaxLayers; i++) + ShowLayer[i]=1; // show all layers + + // Load needed material definition from media.geo file + create_materials_from_media_file(); + + // Position the layers in z + for (Int_t iLayer = 1; iLayer < MaxLayers; iLayer++) + LayerPosition[iLayer] = LayerPosition[iLayer-1] + LayerThickness + LayerOffset[iLayer]; // add offset for extra gaps + + // Get the GeoManager for later usage + gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom"); + gGeoMan->SetVisLevel(10); + + // Create the top volume + TGeoBBox* topbox= new TGeoBBox("", 1000., 1000., 2000.); + TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air")); + gGeoMan->SetTopVolume(top); + + TGeoVolume* trd = new TGeoVolumeAssembly(geoVersion); + top->AddNode(trd, 1); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + Int_t moduleType = iModule + 1; + gModules[iModule] = (iModule==3?create_trdi_module_type():create_trd_module_type(moduleType)); + } + + Int_t nLayer = 0; // active layer counter + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) { + // if ((iLayer != 0) && (iLayer != 3)) continue; // first layer only - comment later on + // if (iLayer != 0) continue; // first layer only - comment later on + if (ShowLayer[iLayer]){ + PlaneId[iLayer]=++nLayer; + create_detector_layers(iLayer); + // printf("calling layer %2d\n",iLayer); + } + } + + // TODO: remove or comment out + // test PlaneId + printf("generated TRD layers: "); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + printf(" %2d",PlaneId[iLayer]); + printf("\n"); + + if (IncludeSupports){ + create_box_supports(); + } + + if (IncludeGibbet){ + create_gibbet_support(); + } + + if (IncludePowerbars){ + create_power_bars_vertical(); + create_power_bars_horizontal(); + } + + if (IncludeFieldVector) + create_mag_field_vector(); + + gGeoMan->CloseGeometry(); +// gGeoMan->CheckOverlaps(0.001); +// gGeoMan->PrintOverlaps(); + gGeoMan->Test(); + + trd->Export(FileNameSim); // an alternative way of writing the trd volume + + TFile* outfile = new TFile(FileNameSim, "UPDATE"); + // TGeoTranslation* trd_placement = new TGeoTranslation("trd_trans", 0., 0., 0.); + // TGeoTranslation* trd_placement = new TGeoTranslation("trd_trans", 0., 0., zfront[setupid]); + TGeoTranslation* trd_placement = new TGeoTranslation("trd_trans", -7., 0., zfront[setupid]); + trd_placement->Write(); + outfile->Close(); + + outfile = new TFile(FileNameGeo,"RECREATE"); + gGeoMan->Write(); // use this is you want GeoManager format in the output + outfile->Close(); + + dump_info_file(); + dump_digi_file(); + + top->Draw("ogl"); + + //top->Raytrace(); + +// cout << "Press Return to exit" << endl; +// cin.get(); +// exit(); +} + + +//============================================================== +void dump_digi_file() +{ + TDatime datetime; // used to get timestamp + + const Double_t ActiveAreaX[3] = { DetectorSizeX[0] - 2 * FrameWidth[0], + DetectorSizeX[1] - 2 * FrameWidth[1], + DetectorSizeX[2] - 2 * FrameWidth[2] }; + const Int_t NofSectors = 3; + const Int_t NofPadsInRow[3] = { 80, 128, 72}; // number of pads in rows + Int_t nrow = 0; // number of rows in module + + const Double_t PadHeightInSector[NofModuleTypes][NofSectors] = // pad height + { { 1.50, 1.50, 1.50 }, // module type 1 - 1.01 mm2 + { 2.25, 2.25, 2.25 }, // module type 2 - 1.52 mm2 +// { 2.75, 2.50, 2.75 }, // module type 2 - 1.86 mm2 + { 4.50, 4.50, 4.50 }, // module type 3 - 3.04 mm2 +// { 2.75, 6.75, 6.75 }, // module type 4 - 4.56 mm2 + { 2.79, 2.79, 2.79 }, // module type 4 - triangular pads H=27.7+0.2 mm, W=7.3+0.2 mm + + { 3.75, 4.00, 3.75 }, // module type 5 - 2.84 mm2 + { 5.75, 5.75, 5.75 }, // module type 6 - 4.13 mm2 + { 11.50, 11.50, 11.50 }, // module type 7 - 8.26 mm2 + { 15.25, 15.50, 15.25 } }; // module type 8 - 11.14 mm2 + // { 23.00, 23.00, 23.00 } }; // module type 8 - 16.52 mm2 +// { 7.50, 7.75, 7.50 }, // module type 6 - 5.51 mm2 +// { 5.50, 5.75, 5.50 }, // module type 6 - 4.09 mm2 +// { 11.25, 11.50, 11.25 }, // module type 7 - 8.18 mm2 + + const Int_t NofRowsInSector[NofModuleTypes][NofSectors] = // number of rows per sector + { { 12, 12, 12 }, // module type 1 + { 8, 8, 8 }, // module type 2 +// { 8, 4, 8 }, // module type 2 + { 4, 4, 4 }, // module type 3 +// { 2, 4, 2 }, // module type 4 + { 2, 16, 2 }, // module type 4 + + { 8, 8, 8 }, // module type 5 + { 4, 8, 4 }, // module type 6 + { 2, 4, 2 }, // module type 7 + { 2, 2, 2 } }; // module type 8 + // { 1, 2, 1 } }; // module type 8 +// { 10, 4, 10 }, // module type 5 +// { 4, 4, 4 }, // module type 6 +// { 2, 12, 2 }, // module type 6 +// { 2, 4, 2 }, // module type 7 +// { 2, 2, 2 } }; // module type 8 + + Double_t HeightOfSector[NofModuleTypes][NofSectors]; + Double_t PadWidth[NofModuleTypes]; + + // calculate pad width + for (Int_t im = 0; im < NofModuleTypes; im++) + PadWidth[im] = ActiveAreaX[ModuleType[im]] / NofPadsInRow[ModuleType[im]]; + + // calculate height of sectors + for (Int_t im = 0; im < NofModuleTypes; im++) + for (Int_t is = 0; is < NofSectors; is++) + HeightOfSector[im][is] = NofRowsInSector[im][is] * PadHeightInSector[im][is]; + + // check, if the entire module size is covered by pads + for (Int_t im = 0; im < NofModuleTypes; im++){ + if (im!=3 && ActiveAreaX[ModuleType[im]] - (HeightOfSector[im][0] + HeightOfSector[im][1] + HeightOfSector[im][2]) != 0) + { + printf("WARNING: sector size does not add up to module size for module type %d\n", im+1); + printf("%.2f = %.2f + %.2f + %.2f\n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][0], HeightOfSector[im][1], HeightOfSector[im][2]); + exit(1); + } + } +//============================================================== + + printf("writing trd pad information file: %s\n", FileNamePads.Data()); + + FILE *ifile; + ifile = fopen(FileNamePads.Data(),"w"); + + if (ifile == NULL) + { + printf("error opening %s\n", FileNamePads.Data()); + exit(1); + } + + fprintf(ifile,"//\n"); + fprintf(ifile,"// TRD pad layout for geometry %s\n", tagVersion.Data()); + fprintf(ifile,"//\n"); + fprintf(ifile,"// automatically generated by Create_TRD_Geometry_%s%s.C\n", tagVersion.Data(), subVersion.Data()); + fprintf(ifile,"// created %d\n", datetime.GetDate()); + fprintf(ifile,"//\n"); + + fprintf(ifile,"\n"); + fprintf(ifile,"#ifndef CBMTRDPADS_H\n"); + fprintf(ifile,"#define CBMTRDPADS_H\n"); + fprintf(ifile,"\n"); + fprintf(ifile,"Int_t fst1_sect_count = 3;\n"); + fprintf(ifile,"// array of pad geometries in the TRD (trd1mod[1-8])\n"); + fprintf(ifile,"// 8 modules // 3 sectors // 4 values \n"); + fprintf(ifile,"Float_t fst1_pad_type[8][3][4] = \n"); +//fprintf(ifile,"Double_t fst1_pad_type[8][3][4] = \n"); + fprintf(ifile," \n"); + + for (Int_t im = 0; im < NofModuleTypes; im++) + { + if (im+1 == 5) + fprintf(ifile,"//---\n\n"); + fprintf(ifile,"// module type %d\n", im+1); + + // number of pads + nrow = 0; // reset number of pad rows to 0 + for (Int_t is = 0; is < NofSectors; is++) + nrow += HeightOfSector[im][is] / PadHeightInSector[im][is]; // add number of rows in this sector + fprintf(ifile,"// number of pads: %3d x %2d = %4d\n", + NofPadsInRow[ModuleType[im]], nrow, NofPadsInRow[ModuleType[im]] * nrow); + + // pad size + fprintf(ifile,"// pad size sector 1: %5.2f cm x %5.2f cm = %5.2f cm2\n", + PadWidth[im], PadHeightInSector[im][1], PadWidth[im] * PadHeightInSector[im][1]); + fprintf(ifile,"// pad size sector 0: %5.2f cm x %5.2f cm = %5.2f cm2\n", + PadWidth[im], PadHeightInSector[im][0], PadWidth[im] * PadHeightInSector[im][0]); + + for (Int_t is = 0; is < NofSectors; is++) + { + if ((im == 0) && (is == 0)) fprintf(ifile," { { "); + else if (is == 0) fprintf(ifile," { "); + else fprintf(ifile," "); + + fprintf(ifile,"{ %.1f, %5.2f, %.1f/%3d, %5.2f }", + ActiveAreaX[ModuleType[im]], HeightOfSector[im][is], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][is]); + + if ((im == NofModuleTypes-1) && (is == 2)) fprintf(ifile," } };"); + else if (is == 2) fprintf(ifile," },"); + else fprintf(ifile,","); + + fprintf(ifile,"\n"); + } + + fprintf(ifile,"\n"); + } + + fprintf(ifile,"#endif\n"); + +// Int_t im = 0; +// fprintf(ifile,"// module type %d \n", im+1); +// fprintf(ifile," { { { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][0], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][0]); +// fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][1], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][1]); +// fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f } }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][2], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][2]); +// fprintf(ifile,"\n"); +// +// for (Int_t im = 1; im < NofModuleTypes-1; im++) +// { +// fprintf(ifile,"// module type %d \n", im+1); +// fprintf(ifile," { { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][0], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][0]); +// fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][1], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][1]); +// fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f } }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][2], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][2]); +// fprintf(ifile,"\n"); +// } +// +// Int_t im = 7; +// fprintf(ifile,"// module type %d \n", im+1); +// fprintf(ifile," { { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][0], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][0]); +// fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][1], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][1]); +// fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f } } };\n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][2], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][2]); +// fprintf(ifile,"\n"); + + fclose(ifile); +} + + +void dump_info_file() +{ + TDatime datetime; // used to get timestamp + + Double_t z_first_layer = 2000; // z position of first layer (front) + Double_t z_last_layer = 0; // z position of last layer (front) + + Double_t xangle; // horizontal angle + Double_t yangle; // vertical angle + + Double_t total_surface = 0; // total surface + Double_t total_actarea = 0; // total active area + + Int_t channels_per_module[NofModuleTypes+1] = { 0 }; // number of channels per module + Int_t channels_per_feb[NofModuleTypes+1] = { 0 }; // number of channels per feb + Int_t asics_per_module[NofModuleTypes+1] = { 0 }; // number of asics per module + + Int_t total_modules[NofModuleTypes+1] = { 0 }; // total number of modules + Int_t total_febs[NofModuleTypes+1] = { 0 }; // total number of febs + Int_t total_asics[NofModuleTypes+1] = { 0 }; // total number of asics + Int_t total_gbtx[NofModuleTypes+1] = { 0 }; // total number of gbtx + Int_t total_rob3[NofModuleTypes+1] = { 0 }; // total number of gbtx rob3 + Int_t total_rob5[NofModuleTypes+1] = { 0 }; // total number of gbtx rob5 + Int_t total_rob7[NofModuleTypes+1] = { 0 }; // total number of gbtx rob7 + Int_t total_channels[NofModuleTypes+1] = { 0 }; // total number of channels + + Int_t total_channels_u = 0; // total number of ultimate channels + Int_t total_channels_s = 0; // total number of super channels + Int_t total_channels_r = 0; // total number of regular channels + + printf("writing summary information file: %s\n", FileNameInfo.Data()); + + FILE *ifile; + ifile = fopen(FileNameInfo.Data(),"w"); + + if (ifile == NULL) + { + printf("error opening %s\n", FileNameInfo.Data()); + exit(1); + } + + fprintf(ifile,"#\n## %s information file\n#\n\n", geoVersion.Data()); + + fprintf(ifile,"# created %d\n\n", datetime.GetDate()); + + // determine first and last TRD layer + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + { + if (ShowLayer[iLayer]) + { + if (z_first_layer > LayerPosition[iLayer]) + z_first_layer = LayerPosition[iLayer]; + if (z_last_layer < LayerPosition[iLayer]) + z_last_layer = LayerPosition[iLayer]; + } + } + + fprintf(ifile,"# envelope\n"); + // Show extension of TRD + fprintf(ifile,"%4f cm start of TRD (z)\n", z_first_layer); + fprintf(ifile,"%4f cm end of TRD (z)\n", z_last_layer + LayerThickness); + fprintf(ifile,"\n"); + + // Layer thickness + fprintf(ifile,"# thickness\n"); + fprintf(ifile,"%4f cm per single layer (z)\n", LayerThickness); + fprintf(ifile,"\n"); + + // Show extra gaps + fprintf(ifile,"# extra gaps\n "); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + fprintf(ifile,"%3f ", LayerOffset[iLayer]); + fprintf(ifile," extra gaps in z (cm)\n"); + fprintf(ifile,"\n"); + + // Show layer flags + fprintf(ifile,"# generated TRD layers\n "); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + fprintf(ifile,"%2d ", PlaneId[iLayer]); + fprintf(ifile," planeID\n"); + fprintf(ifile,"\n"); + + // Dimensions in x + fprintf(ifile,"# dimensions in x\n"); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]){ + if (PlaneId[iLayer] <= 5){ + Int_t type=LayerType[iLayer]/10; + fprintf(ifile,"%5f cm to %5f cm x-dimension of layer %2d\n", -3.5 * DetectorSizeX[type], 3.5 * DetectorSizeX[type], PlaneId[iLayer]); + }else + { + if (PlaneId[iLayer] < 9) + fprintf(ifile,"%5f cm to %5f cm x-dimension of layer %2d\n", -4.5 * DetectorSizeX[1], 4.5 * DetectorSizeX[1], PlaneId[iLayer]); + else + fprintf(ifile,"%5f cm to %5f cm x-dimension of layer %2d\n", -5.5 * DetectorSizeX[1], 5.5 * DetectorSizeX[1], PlaneId[iLayer]); + } + } + fprintf(ifile,"\n"); + + // Dimensions in y + fprintf(ifile,"# dimensions in y\n"); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + { + if (PlaneId[iLayer] <= 5){ + Int_t type=LayerType[iLayer]/10; + fprintf(ifile,"%5f cm to %5f cm y-dimension of layer %2d\n", -2.5 * DetectorSizeY[type], 2.5 * DetectorSizeY[type], PlaneId[iLayer]); + } else + { + if (PlaneId[iLayer] < 9) + fprintf(ifile,"%5f cm to %5f cm y-dimension of layer %2d\n", -3.5 * DetectorSizeY[1], 3.5 * DetectorSizeY[1], PlaneId[iLayer]); + else + fprintf(ifile,"%5f cm to %5f cm y-dimension of layer %2d\n", -4.5 * DetectorSizeY[1], 4.5 * DetectorSizeY[1], PlaneId[iLayer]); + } + } + fprintf(ifile,"\n"); + + // Show layer positions + fprintf(ifile,"# z-positions of layer front\n"); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + { + if (ShowLayer[iLayer]) + fprintf(ifile,"%5f cm z-position of layer %2d\n", LayerPosition[iLayer], PlaneId[iLayer]); + } + fprintf(ifile,"\n"); + + // flags + fprintf(ifile,"# flags\n"); + + fprintf(ifile,"support structure is : "); + if (!IncludeSupports) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"radiator is : "); + if (!IncludeRadiator) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"lattice grid is : "); + if (!IncludeLattice ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"kapton window is : "); + if (!IncludeKaptonFoil) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"gas frame is : "); + if (!IncludeGasFrame ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"padplane is : "); + if (!IncludePadplane ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"backpanel is : "); + if (!IncludeBackpanel ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"Aluminium ledge is : "); + if (!IncludeAluLedge ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"Gibbet support is : "); + if (!IncludeGibbet ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"Power bus bars are : "); + if (!IncludePowerbars ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"asics are : "); + if (!IncludeAsics ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"front-end boards are : "); + if (!IncludeFebs ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"GBTX readout boards are : "); + if (!IncludeRobs ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"\n"); + + + // module statistics +// fprintf(ifile,"#\n## modules\n#\n\n"); +// fprintf(ifile,"number of modules per type and layer:\n"); + fprintf(ifile,"# modules\n"); + + for (Int_t iModule = 1; iModule <= NofModuleTypes; iModule++) + fprintf(ifile," mod%1d", iModule); + fprintf(ifile," total"); + + fprintf(ifile,"\n---------------------------------------------------------------------------------\n"); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + { + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + fprintf(ifile," %8d", ModuleStats[iLayer][iModule]); + total_modules[iModule] += ModuleStats[iLayer][iModule]; // sum up modules across layers + } + fprintf(ifile," layer %2d\n", PlaneId[iLayer]); + } + fprintf(ifile,"\n---------------------------------------------------------------------------------\n"); + + // total statistics + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + fprintf(ifile," %8d", total_modules[iModule]); + total_modules[NofModuleTypes] += total_modules[iModule]; + } + fprintf(ifile," %8d", total_modules[NofModuleTypes]); + fprintf(ifile," number of modules\n"); + + //------------------------------------------------------------------------------ + + // number of FEBs + // fprintf(ifile,"\n#\n## febs\n#\n\n"); + fprintf(ifile,"# febs\n"); + + fprintf(ifile," "); + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if ((AsicsPerFeb[iModule] / 100) == 3) + fprintf(ifile,"%8du", FebsPerModule[iModule]); + else if ((AsicsPerFeb[iModule] / 100) == 2) + fprintf(ifile,"%8ds", FebsPerModule[iModule]); + else + fprintf(ifile,"%8d ", FebsPerModule[iModule]); + } + fprintf(ifile," FEBs per module\n"); + + // FEB total per type + total_febs[NofModuleTypes] = 0; // reset sum to 0 + fprintf(ifile," "); + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if ((AsicsPerFeb[iModule] / 100) == 3) + { + total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule]; + fprintf(ifile,"%8du", total_febs[iModule]); + total_febs[NofModuleTypes] += total_febs[iModule]; + } + else + fprintf(ifile," "); + } + fprintf(ifile,"%8d", total_febs[NofModuleTypes]); + fprintf(ifile," ultimate FEBs\n"); + + // FEB total per type + total_febs[NofModuleTypes] = 0; // reset sum to 0 + fprintf(ifile," "); + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if ((AsicsPerFeb[iModule] / 100) == 2) + { + total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule]; + fprintf(ifile,"%8ds", total_febs[iModule]); + total_febs[NofModuleTypes] += total_febs[iModule]; + } + else + fprintf(ifile," "); + } + fprintf(ifile,"%8d", total_febs[NofModuleTypes]); + fprintf(ifile," super FEBs\n"); + + // FEB total per type + total_febs[NofModuleTypes] = 0; // reset sum to 0 + fprintf(ifile," "); + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if ((AsicsPerFeb[iModule] / 100) == 1) + { + total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule]; + fprintf(ifile,"%8d ", total_febs[iModule]); + total_febs[NofModuleTypes] += total_febs[iModule]; + } + else + fprintf(ifile," "); + } + fprintf(ifile,"%8d", total_febs[NofModuleTypes]); + fprintf(ifile," regular FEBs\n"); + + // FEB total over all types + total_febs[NofModuleTypes] = 0; // reset sum to 0 + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule]; + fprintf(ifile," %8d", total_febs[iModule]); + total_febs[NofModuleTypes] += total_febs[iModule]; + } + fprintf(ifile," %8d", total_febs[NofModuleTypes]); + fprintf(ifile," number of FEBs\n"); + + //------------------------------------------------------------------------------ + + // number of ASICs + // fprintf(ifile,"\n#\n## asics\n#\n\n"); + fprintf(ifile,"# asics\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + fprintf(ifile," %8d", AsicsPerFeb[iModule] %100); + } + fprintf(ifile," ASICs per FEB\n"); + + // ASICs per module + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + asics_per_module[iModule] = FebsPerModule[iModule] * (AsicsPerFeb[iModule] %100); + fprintf(ifile," %8d", asics_per_module[iModule]); + } + fprintf(ifile," ASICs per module\n"); + + // ASICs per module type + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + total_asics[iModule] = total_febs[iModule] * (AsicsPerFeb[iModule] %100); + fprintf(ifile," %8d", total_asics[iModule]); + total_asics[NofModuleTypes] += total_asics[iModule]; + } + fprintf(ifile," %8d", total_asics[NofModuleTypes]); + fprintf(ifile," number of ASICs\n"); + + //------------------------------------------------------------------------------ + + // number of GBTXs + // fprintf(ifile,"\n#\n## asics\n#\n\n"); + fprintf(ifile,"# gbtx\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + fprintf(ifile," %8d", GbtxPerModule[iModule]); + } + fprintf(ifile," GBTXs per module\n"); + + // GBTXs per module type + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + total_gbtx[iModule] = total_modules[iModule] * GbtxPerModule[iModule]; + fprintf(ifile," %8d", total_gbtx[iModule]); + total_gbtx[NofModuleTypes] += total_gbtx[iModule]; + } + fprintf(ifile," %8d", total_gbtx[NofModuleTypes]); + fprintf(ifile," number of GBTXs\n"); + + // GBTX ROB types per module type + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + fprintf(ifile," %8d", RobTypeOnModule[iModule]); + } + fprintf(ifile," GBTX ROB types on module\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if ((RobTypeOnModule[iModule] % 10) == 7) + total_rob7[iModule]++; + if ((RobTypeOnModule[iModule] / 10 % 10) == 7) + total_rob7[iModule]++; + if ((RobTypeOnModule[iModule] / 100) == 7) + total_rob7[iModule]++; + + if ((RobTypeOnModule[iModule] % 10) == 5) + total_rob5[iModule]++; + if ((RobTypeOnModule[iModule] / 10 % 10) == 5) + total_rob5[iModule]++; + if ((RobTypeOnModule[iModule] / 100) == 5) + total_rob5[iModule]++; + + if ((RobTypeOnModule[iModule] % 10) == 3) + total_rob3[iModule]++; + if ((RobTypeOnModule[iModule] / 10 % 10) == 3) + total_rob3[iModule]++; + if ((RobTypeOnModule[iModule] / 100 % 10) == 3) + total_rob3[iModule]++; + if ((RobTypeOnModule[iModule] / 1000 % 10) == 3) + total_rob3[iModule]++; + if ((RobTypeOnModule[iModule] / 10000 % 10) == 3) + total_rob3[iModule]++; + if ((RobTypeOnModule[iModule] / 100000) == 3) + total_rob3[iModule]++; + } + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + total_rob7[iModule] *= total_modules[iModule]; + fprintf(ifile," %8d", total_rob7[iModule]); + total_rob7[NofModuleTypes] += total_rob7[iModule]; + } + fprintf(ifile," %8d", total_rob7[NofModuleTypes]); + fprintf(ifile," number of GBTX ROB7\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + total_rob5[iModule] *= total_modules[iModule]; + fprintf(ifile," %8d", total_rob5[iModule]); + total_rob5[NofModuleTypes] += total_rob5[iModule]; + } + fprintf(ifile," %8d", total_rob5[NofModuleTypes]); + fprintf(ifile," number of GBTX ROB5\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + total_rob3[iModule] *= total_modules[iModule]; + fprintf(ifile," %8d", total_rob3[iModule]); + total_rob3[NofModuleTypes] += total_rob3[iModule]; + } + fprintf(ifile," %8d", total_rob3[NofModuleTypes]); + fprintf(ifile," number of GBTX ROB3\n"); + + //------------------------------------------------------------------------------ + fprintf(ifile,"# e-links\n"); + + // e-links used + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + fprintf(ifile," %8d", asics_per_module[iModule] *2); + fprintf(ifile," %8d", total_asics[NofModuleTypes] *2); + fprintf(ifile," e-links used\n"); + + // e-links available + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + fprintf(ifile," %8d", GbtxPerModule[iModule] *14); + fprintf(ifile," %8d", total_gbtx[NofModuleTypes] *14); + fprintf(ifile," e-links available\n"); + + // e-link efficiency + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if (total_gbtx[iModule]!=0) + fprintf(ifile," %7.1f%%", (float)total_asics[iModule] *2 / (total_gbtx[iModule] *14) *100); + else + fprintf(ifile," -"); + } + if (total_gbtx[NofModuleTypes]!=0) + fprintf(ifile," %7.1f%%", (float)total_asics[NofModuleTypes] *2 / (total_gbtx[NofModuleTypes] *14) *100); + fprintf(ifile," e-link efficiency\n\n"); + + //------------------------------------------------------------------------------ + + // number of channels + fprintf(ifile,"# channels\n"); + + // channels per module + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if ((AsicsPerFeb[iModule] %100) == 16) + { + channels_per_feb[iModule] = 80 * 6; // rows // 84, if 63 of 64 ch used + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + if ((AsicsPerFeb[iModule] %100) == 15) + { + channels_per_feb[iModule] = 80 * 6; // rows + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + if ((AsicsPerFeb[iModule] %100) == 10) + { +// channels_per_feb[iModule] = 80 * 4; // rows + channels_per_feb[iModule] = (AsicsPerFeb[iModule] %100) * 16; // electronic channels + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + if ((AsicsPerFeb[iModule] %100) == 5) + { + channels_per_feb[iModule] = 80 * 2; // rows + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + + if ((AsicsPerFeb[iModule] %100) == 8) + { + channels_per_feb[iModule] = 128 * 2; // rows + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + } + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + fprintf(ifile," %8d", channels_per_module[iModule]); + fprintf(ifile," channels per module\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + fprintf(ifile," %8d", channels_per_feb[iModule]); + fprintf(ifile," channels per feb\n"); + + // channels used + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + total_channels[iModule] = channels_per_module[iModule] * total_modules[iModule]; + fprintf(ifile," %8d", total_channels[iModule]); + total_channels[NofModuleTypes] += total_channels[iModule]; + } + fprintf(ifile," %8d", total_channels[NofModuleTypes]); + fprintf(ifile," channels used\n"); + + // channels available + fprintf(ifile," "); + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if ((AsicsPerFeb[iModule] / 100) == 4) // FASP case + { + fprintf(ifile,"%8dF", total_asics[iModule] * 16); + total_channels_u += total_asics[iModule] * 16; + } + else if ((AsicsPerFeb[iModule] / 100) == 3) + { + fprintf(ifile,"%8du", total_asics[iModule] * 32); + total_channels_u += total_asics[iModule] * 32; + } + else if ((AsicsPerFeb[iModule] / 100) == 2) + { + fprintf(ifile,"%8ds", total_asics[iModule] * 32); + total_channels_s += total_asics[iModule] * 32; + } + else + { + fprintf(ifile,"%8d ", total_asics[iModule] * 32); + total_channels_r += total_asics[iModule] * 32; + } + } + fprintf(ifile,"%8d", total_asics[NofModuleTypes] * 32); + fprintf(ifile," channels available\n"); + + // channel ratio for u,s,r density + fprintf(ifile," "); + fprintf(ifile,"%7.1f%%u", (float)total_channels_u / (total_asics[NofModuleTypes] * 32) * 100); + fprintf(ifile,"%7.1f%%s", (float)total_channels_s / (total_asics[NofModuleTypes] * 32) * 100); + fprintf(ifile,"%7.1f%%r", (float)total_channels_r / (total_asics[NofModuleTypes] * 32) * 100); + fprintf(ifile," channel ratio\n"); + + fprintf(ifile,"\n"); + fprintf(ifile,"%8.1f%% channel efficiency\n", 1. * total_channels[NofModuleTypes] / (total_asics[NofModuleTypes] * 32) * 100); + + //------------------------------------------------------------------------------ + + // total surface of TRD + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + if (iModule <= 3) + { + total_surface += total_modules[iModule] * DetectorSizeX[0] / 100 * DetectorSizeY[0] / 100; + total_actarea += total_modules[iModule] * (DetectorSizeX[0]-2*FrameWidth[0]) / 100 * (DetectorSizeY[0]-2*FrameWidth[0]) / 100; + } + else + { + total_surface += total_modules[iModule] * DetectorSizeX[1] / 100 * DetectorSizeY[1] / 100; + total_actarea += total_modules[iModule] * (DetectorSizeX[1]-2*FrameWidth[1]) / 100 * (DetectorSizeY[1]-2*FrameWidth[1]) / 100; + } + fprintf(ifile,"\n"); + + // summary + fprintf(ifile,"%7.2f m2 total surface \n", total_surface); + fprintf(ifile,"%7.2f m2 total active area\n", total_actarea); + fprintf(ifile,"%7.2f m3 total gas volume \n", total_actarea * gas_thickness / 100); // convert cm to m for thickness + + fprintf(ifile,"%7.2f cm2/ch average channel size\n", 100. * 100 * total_actarea / total_channels[NofModuleTypes]); + fprintf(ifile,"%7.2f ch/m2 channels per m2 active area\n", 1. * total_channels[NofModuleTypes] / total_actarea); + fprintf(ifile,"\n"); + + // gas volume position + fprintf(ifile,"# gas volume position\n"); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + fprintf(ifile,"%10.4f cm position of gas volume - layer %2d\n", LayerPosition[iLayer] + LayerThickness/2. + gas_position, PlaneId[iLayer]); + fprintf(ifile,"\n"); + + // angles + fprintf(ifile,"# angles of acceptance\n"); + + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + { + if (iLayer <= 5) + { + // fprintf(ifile,"y %10.4f cm x %10.4f cm\n", 2.5 * DetectorSizeY[1], 3.5 * DetectorSizeX[1]); + Int_t type(LayerType[iLayer]/10); + yangle = atan(2.5 * DetectorSizeY[type] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + xangle = atan(3.5 * DetectorSizeX[type] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + } + if ((iLayer > 5) && (iLayer < 8)) + { + // fprintf(ifile,"y %10.4f cm x %10.4f cm\n", 3.5 * DetectorSizeY[1], 4.5 * DetectorSizeX[1]); + yangle = atan(3.5 * DetectorSizeY[1] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + xangle = atan(4.5 * DetectorSizeX[1] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + } + if ((iLayer >= 8) && (iLayer <10)) + { + // fprintf(ifile,"y %10.4f cm x %10.4f cm\n", 4.5 * DetectorSizeY[1], 5.5 * DetectorSizeX[1]); + yangle = atan(4.5 * DetectorSizeY[1] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + xangle = atan(5.5 * DetectorSizeX[1] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + } + fprintf(ifile,"v: %5.2f deg, h: %5.2f deg - vertical/horizontal - layer %2d\n", yangle, xangle, PlaneId[iLayer]); + } + fprintf(ifile,"\n"); + + // aperture + fprintf(ifile,"# inner aperture\n"); + + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + { + if (iLayer <= 5) + { + // fprintf(ifile,"y %10.4f cm x %10.4f cm\n", 2.5 * DetectorSizeY[1], 3.5 * DetectorSizeX[1]); + yangle = atan(0.5 * DetectorSizeY[0] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + xangle = atan(0.5 * DetectorSizeX[0] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + } + if ((iLayer > 5) && (iLayer < 8)) + { + // fprintf(ifile,"y %10.4f cm x %10.4f cm\n", 3.5 * DetectorSizeY[1], 4.5 * DetectorSizeX[1]); + yangle = atan(0.5 * DetectorSizeY[0] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + xangle = atan(0.5 * DetectorSizeX[0] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + } + if ((iLayer >= 8) && (iLayer <10)) + { + // fprintf(ifile,"y %10.4f cm x %10.4f cm\n", 4.5 * DetectorSizeY[1], 5.5 * DetectorSizeX[1]); + yangle = atan(0.5 * DetectorSizeY[0] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + xangle = atan(0.5 * DetectorSizeX[0] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + } + fprintf(ifile,"v: %5.2f deg, h: %5.2f deg - vertical/horizontal - layer %2d\n", yangle, xangle, PlaneId[iLayer]); + } + fprintf(ifile,"\n"); + + fclose(ifile); +} + + +void create_materials_from_media_file() +{ + // Use the FairRoot geometry interface to load the media which are already defined + FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader"); + FairGeoInterface* geoFace = geoLoad->getGeoInterface(); + TString geoPath = gSystem->Getenv("VMCWORKDIR"); + TString medFile = geoPath + "/geometry/media.geo"; + geoFace->setMediaFile(medFile); + geoFace->readMedia(); + + // Read the required media and create them in the GeoManager + FairGeoMedia* geoMedia = geoFace->getMedia(); + FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder(); + + FairGeoMedium* air = geoMedia->getMedium(KeepingVolumeMedium); + FairGeoMedium* pefoam20 = geoMedia->getMedium(RadiatorVolumeMedium); + FairGeoMedium* G10 = geoMedia->getMedium(LatticeVolumeMedium); + FairGeoMedium* kapton = geoMedia->getMedium(KaptonVolumeMedium); + FairGeoMedium* trdGas = geoMedia->getMedium(GasVolumeMedium); + FairGeoMedium* copper = geoMedia->getMedium(PadCopperVolumeMedium); + FairGeoMedium* carbon = geoMedia->getMedium(CarbonVolumeMedium); + FairGeoMedium* honeycomb = geoMedia->getMedium(HoneycombVolumeMedium); + FairGeoMedium* aluminium = geoMedia->getMedium(AluminiumVolumeMedium); + +// FairGeoMedium* goldCoatedCopper = geoMedia->getMedium("goldcoatedcopper"); +// FairGeoMedium* polypropylene = geoMedia->getMedium("polypropylene"); +// FairGeoMedium* mylar = geoMedia->getMedium("mylar"); + + geoBuild->createMedium(air); + geoBuild->createMedium(pefoam20); + geoBuild->createMedium(trdGas); + geoBuild->createMedium(honeycomb); + geoBuild->createMedium(carbon); + geoBuild->createMedium(G10); + geoBuild->createMedium(copper); + geoBuild->createMedium(kapton); + geoBuild->createMedium(aluminium); + +// geoBuild->createMedium(goldCoatedCopper); +// geoBuild->createMedium(polypropylene); +// geoBuild->createMedium(mylar); +} + +TGeoVolume* create_trd_module_type(Int_t moduleType) +{ + Int_t type = ModuleType[moduleType - 1]; + Double_t sizeX = DetectorSizeX[type]; + Double_t sizeY = DetectorSizeY[type]; + Double_t frameWidth = FrameWidth[type]; + Double_t activeAreaX = sizeX - 2 * frameWidth; + Double_t activeAreaY = sizeY - 2 * frameWidth; + + TGeoMedium* keepVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + TGeoMedium* radVolMed = gGeoMan->GetMedium(RadiatorVolumeMedium); + TGeoMedium* latticeVolMed = gGeoMan->GetMedium(LatticeVolumeMedium); + TGeoMedium* kaptonVolMed = gGeoMan->GetMedium(KaptonVolumeMedium); + TGeoMedium* gasVolMed = gGeoMan->GetMedium(GasVolumeMedium); + TGeoMedium* padcopperVolMed = gGeoMan->GetMedium(PadCopperVolumeMedium); + TGeoMedium* padpcbVolMed = gGeoMan->GetMedium(PadPcbVolumeMedium); + TGeoMedium* honeycombVolMed = gGeoMan->GetMedium(HoneycombVolumeMedium); + TGeoMedium* carbonVolMed = gGeoMan->GetMedium(CarbonVolumeMedium); +// TGeoMedium* mylarVolMed = gGeoMan->GetMedium(MylarVolumeMedium); +// TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsVolumeMedium); + TGeoMedium* frameVolMed = gGeoMan->GetMedium(FrameVolumeMedium); + TGeoMedium* aluledgeVolMed = gGeoMan->GetMedium(AluLegdeVolumeMedium); + TGeoMedium* febVolMed = gGeoMan->GetMedium(FebVolumeMedium); + TGeoMedium* asicVolMed = gGeoMan->GetMedium(AsicVolumeMedium); +// TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium); + + TString name = Form("module%d", moduleType); + TGeoVolume* module = new TGeoVolumeAssembly(name); + + + if(IncludeRadiator) + { + // Radiator + // TGeoBBox* trd_radiator = new TGeoBBox("", activeAreaX /2., activeAreaY /2., radiator_thickness /2.); + TGeoBBox* trd_radiator = new TGeoBBox("trd_radiator", sizeX /2., sizeY /2., radiator_thickness /2.); + TGeoVolume* trdmod1_radvol = new TGeoVolume("radiator", trd_radiator, radVolMed); + // TGeoVolume* trdmod1_radvol = new TGeoVolume(Form("module%d_radiator", moduleType), trd_radiator, radVolMed); + // TGeoVolume* trdmod1_radvol = new TGeoVolume(Form("trd1mod%dradiator", moduleType), trd_radiator, radVolMed); + trdmod1_radvol->SetLineColor(kBlue); + trdmod1_radvol->SetTransparency(70); // (60); // (70); // set transparency for the TRD radiator + TGeoTranslation* trd_radiator_trans = new TGeoTranslation("", 0., 0., radiator_position); + module->AddNode(trdmod1_radvol, 1, trd_radiator_trans); + } + + // Lattice grid + if(IncludeLattice) + { + + if (type==0) // inner modules + { + // printf("lattice type %d\n", type); + // drift window - lattice grid - sprossenfenster + TGeoBBox* trd_lattice_mod0_ho = new TGeoBBox("trd_lattice_mod0_ho", sizeX/2., lattice_o_width[type]/2., lattice_thickness/2.); // horizontal outer + TGeoBBox* trd_lattice_mod0_hi = new TGeoBBox("trd_lattice_mod0_hi", sizeX/2.-lattice_o_width[type], lattice_i_width[type]/2., lattice_thickness/2.); // horizontal inner + TGeoBBox* trd_lattice_mod0_vo = new TGeoBBox("trd_lattice_mod0_vo", lattice_o_width[type]/2., sizeX/2.-lattice_o_width[type], lattice_thickness/2.); // vertical outer + TGeoBBox* trd_lattice_mod0_vi = new TGeoBBox("trd_lattice_mod0_vi", lattice_i_width[type]/2., 0.20*activeAreaY/2.-lattice_i_width[type]/2., lattice_thickness/2.); // vertical inner + TGeoBBox* trd_lattice_mod0_vb = new TGeoBBox("trd_lattice_mod0_vb", lattice_i_width[type]/2., 0.20*activeAreaY/2.-lattice_i_width[type]/4., lattice_thickness/2.); // vertical border + + TGeoVolume* trd_lattice_mod0_vol_ho = new TGeoVolume("lattice0ho", trd_lattice_mod0_ho, latticeVolMed); + TGeoVolume* trd_lattice_mod0_vol_hi = new TGeoVolume("lattice0hi", trd_lattice_mod0_hi, latticeVolMed); + TGeoVolume* trd_lattice_mod0_vol_vo = new TGeoVolume("lattice0vo", trd_lattice_mod0_vo, latticeVolMed); + TGeoVolume* trd_lattice_mod0_vol_vi = new TGeoVolume("lattice0vi", trd_lattice_mod0_vi, latticeVolMed); + TGeoVolume* trd_lattice_mod0_vol_vb = new TGeoVolume("lattice0vb", trd_lattice_mod0_vb, latticeVolMed); + + trd_lattice_mod0_vol_ho->SetLineColor(kYellow); // kBlue); + trd_lattice_mod0_vol_vo->SetLineColor(kYellow); // kOrange); + trd_lattice_mod0_vol_hi->SetLineColor(kYellow); // kRed); + trd_lattice_mod0_vol_vi->SetLineColor(kYellow); // kWhite); + trd_lattice_mod0_vol_vb->SetLineColor(kYellow); + + TGeoTranslation *tv010 = new TGeoTranslation("tv010", 0., (1.00*activeAreaY/2.+lattice_o_width[type]/2.), 0); + TGeoTranslation *tv015 = new TGeoTranslation("tv015", 0., -(1.00*activeAreaY/2.+lattice_o_width[type]/2.), 0); + + TGeoTranslation *th020 = new TGeoTranslation("th020", (1.00*activeAreaX/2.+lattice_o_width[type]/2.), 0., 0); + TGeoTranslation *th025 = new TGeoTranslation("th025", -(1.00*activeAreaX/2.+lattice_o_width[type]/2.), 0., 0); + + Double_t hypos0[4] = { (0.60*activeAreaY/2.), + (0.20*activeAreaY/2.), + -(0.20*activeAreaY/2.), + -(0.60*activeAreaY/2.) }; + + Double_t vxpos0[4] = { (0.60*activeAreaX/2.), + (0.20*activeAreaX/2.), + -(0.20*activeAreaX/2.), + -(0.60*activeAreaX/2.) }; + + Double_t vypos0[5] = { (0.80*activeAreaY/2.+lattice_i_width[type]/4.), + (0.40*activeAreaY/2.) , + (0.00*activeAreaY/2.) , + -(0.40*activeAreaY/2.) , + -(0.80*activeAreaY/2.+lattice_i_width[type]/4.) }; + +// TGeoVolumeAssembly* trdmod0_lattice = new TGeoVolumeAssembly("mod0lattice"); // volume for lattice grid + + TGeoBBox* trd_lattice_mod0 = new TGeoBBox("trd_lattice_mod0", sizeX /2., sizeY /2., lattice_thickness /2.); + TGeoVolume* trdmod0_lattice = new TGeoVolume("lat_grid_mod0", trd_lattice_mod0, keepVolMed); + + // trdmod0_lattice->SetLineColor(kGreen); // set color for keeping volume + + // outer frame + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_ho, 1, tv010); + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_ho, 2, tv015); + + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vo, 3, th020); + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vo, 4, th025); + + // lattice piece number + Int_t lat0_no = 5; + + // horizontal bars + for (Int_t y = 0; y < 4; y++) + { + TGeoTranslation *t0xy = new TGeoTranslation("", 0, hypos0[y], 0); + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_hi, lat0_no, t0xy); + lat0_no++; + } + + // vertical bars + for (Int_t x = 0; x < 4; x++) + for (Int_t y = 0; y < 5; y++) + { + TGeoTranslation *t0xy = new TGeoTranslation("", vxpos0[x], vypos0[y], 0); + if ( (y==0) || (y==4) ) + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vb, lat0_no, t0xy); // border piece + else + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vi, lat0_no, t0xy); // middle piece + lat0_no++; + } + + // add lattice to module + TGeoTranslation *trd_lattice_trans = new TGeoTranslation("", 0., 0., lattice_position); + module->AddNode(trdmod0_lattice, 1, trd_lattice_trans); + } + + else if (type==1) // outer modules + { + // printf("lattice type %d\n", type); + // drift window - lattice grid - sprossenfenster + TGeoBBox *trd_lattice_mod1_ho = new TGeoBBox("trd_lattice_mod1_ho", sizeX/2., lattice_o_width[type]/2., lattice_thickness/2.); // horizontal outer + TGeoBBox *trd_lattice_mod1_hi = new TGeoBBox("trd_lattice_mod1_hi", sizeX/2.-lattice_o_width[type], lattice_i_width[type]/2., lattice_thickness/2.); // horizontal inner + TGeoBBox *trd_lattice_mod1_vo = new TGeoBBox("trd_lattice_mod1_vo", lattice_o_width[type]/2., sizeX/2.-lattice_o_width[type], lattice_thickness/2.); // vertical outer + TGeoBBox *trd_lattice_mod1_vi = new TGeoBBox("trd_lattice_mod1_vi", lattice_i_width[type]/2., 0.125*activeAreaY/2.-lattice_i_width[type]/2., lattice_thickness/2.); // vertical inner + TGeoBBox *trd_lattice_mod1_vb = new TGeoBBox("trd_lattice_mod1_vb", lattice_i_width[type]/2., 0.125*activeAreaY/2.-lattice_i_width[type]/4., lattice_thickness/2.); // vertical border + + TGeoVolume* trd_lattice_mod1_vol_ho = new TGeoVolume("lattice1ho", trd_lattice_mod1_ho, latticeVolMed); + TGeoVolume* trd_lattice_mod1_vol_hi = new TGeoVolume("lattice1hi", trd_lattice_mod1_hi, latticeVolMed); + TGeoVolume* trd_lattice_mod1_vol_vo = new TGeoVolume("lattice1vo", trd_lattice_mod1_vo, latticeVolMed); + TGeoVolume* trd_lattice_mod1_vol_vi = new TGeoVolume("lattice1vi", trd_lattice_mod1_vi, latticeVolMed); + TGeoVolume* trd_lattice_mod1_vol_vb = new TGeoVolume("lattice1vb", trd_lattice_mod1_vb, latticeVolMed); + + trd_lattice_mod1_vol_ho->SetLineColor(kYellow); // kBlue); + trd_lattice_mod1_vol_vo->SetLineColor(kYellow); // kOrange); + trd_lattice_mod1_vol_hi->SetLineColor(kYellow); // kRed); + trd_lattice_mod1_vol_vi->SetLineColor(kYellow); // kWhite); + trd_lattice_mod1_vol_vb->SetLineColor(kYellow); + + TGeoTranslation *tv110 = new TGeoTranslation("tv110", 0., (1.00*activeAreaY/2.+lattice_o_width[type]/2.), 0); + TGeoTranslation *tv118 = new TGeoTranslation("tv118", 0., -(1.00*activeAreaY/2.+lattice_o_width[type]/2.), 0); + + TGeoTranslation *th120 = new TGeoTranslation("th120", (1.00*activeAreaX/2.+lattice_o_width[type]/2.), 0., 0); + TGeoTranslation *th128 = new TGeoTranslation("th128", -(1.00*activeAreaX/2.+lattice_o_width[type]/2.), 0., 0); + + Double_t hypos1[7] = { (0.75*activeAreaY/2.), + (0.50*activeAreaY/2.), + (0.25*activeAreaY/2.), + (0.00*activeAreaY/2.), + -(0.25*activeAreaY/2.), + -(0.50*activeAreaY/2.), + -(0.75*activeAreaY/2.) }; + + Double_t vxpos1[7] = { (0.75*activeAreaX/2.), + (0.50*activeAreaX/2.), + (0.25*activeAreaX/2.), + (0.00*activeAreaX/2.), + -(0.25*activeAreaX/2.), + -(0.50*activeAreaX/2.), + -(0.75*activeAreaX/2.) }; + + Double_t vypos1[8] = { (0.875*activeAreaY/2.+lattice_i_width[type]/4.), + (0.625*activeAreaY/2.) , + (0.375*activeAreaY/2.) , + (0.125*activeAreaY/2.) , + -(0.125*activeAreaY/2.) , + -(0.375*activeAreaY/2.) , + -(0.625*activeAreaY/2.) , + -(0.875*activeAreaY/2.+lattice_i_width[type]/4.) }; + +// TGeoVolumeAssembly* trdmod1_lattice = new TGeoVolumeAssembly("mod1lattice"); // volume for lattice grid + + TGeoBBox* trd_lattice_mod1 = new TGeoBBox("trd_lattice_mod1", sizeX /2., sizeY /2., lattice_thickness /2.); + TGeoVolume* trdmod1_lattice = new TGeoVolume("lat_grid_mod1", trd_lattice_mod1, keepVolMed); + + // trdmod1_lattice->SetLineColor(kGreen); // set color for keeping volume + + // outer frame + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_ho, 1, tv110); + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_ho, 2, tv118); + + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vo, 3, th120); + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vo, 4, th128); + + // lattice piece number + Int_t lat1_no = 5; + + // horizontal bars + for (Int_t y = 0; y < 7; y++) + { + TGeoTranslation *t1xy = new TGeoTranslation("", 0, hypos1[y], 0); + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_hi, lat1_no, t1xy); + lat1_no++; + } + + // vertical bars + for (Int_t x = 0; x < 7; x++) + for (Int_t y = 0; y < 8; y++) + { + TGeoTranslation *t1xy = new TGeoTranslation("", vxpos1[x], vypos1[y], 0); + if ( (y==0) || (y==7) ) + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vb, lat1_no, t1xy); // border piece + else + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vi, lat1_no, t1xy); // middle piece + lat1_no++; + } + + // add lattice to module + TGeoTranslation *trd_lattice_trans = new TGeoTranslation("", 0., 0., lattice_position); + module->AddNode(trdmod1_lattice, 1, trd_lattice_trans); + } + + } // with lattice grid + + if(IncludeKaptonFoil) + { + // Kapton Foil + TGeoBBox* trd_kapton = new TGeoBBox("trd_kapton", sizeX /2., sizeY /2., kapton_thickness /2.); + TGeoVolume* trdmod1_kaptonvol = new TGeoVolume("kaptonfoil", trd_kapton, kaptonVolMed); + // TGeoVolume* trdmod1_kaptonvol = new TGeoVolume(Form("module%d_kaptonfoil", moduleType), trd_kapton, kaptonVolMed); + // TGeoVolume* trdmod1_kaptonvol = new TGeoVolume(Form("trd1mod%dkapton", moduleType), trd_kapton, kaptonVolMed); + trdmod1_kaptonvol->SetLineColor(kGreen); + TGeoTranslation* trd_kapton_trans = new TGeoTranslation("", 0., 0., kapton_position); + module->AddNode(trdmod1_kaptonvol, 1, trd_kapton_trans); + } + + // start of Frame in z + // Gas + TGeoBBox* trd_gas = new TGeoBBox("trd_gas", activeAreaX /2., activeAreaY /2., gas_thickness /2.); + TGeoVolume* trdmod1_gasvol = new TGeoVolume("gas", trd_gas, gasVolMed); + // TGeoVolume* trdmod1_gasvol = new TGeoVolume(Form("module%d_gas", moduleType), trd_gas, gasVolMed); + // TGeoVolume* trdmod1_gasvol = new TGeoVolume(Form("trd1mod%dgas", moduleType), trd_gas, gasVolMed); + // trdmod1_gasvol->SetLineColor(kBlue); + trdmod1_gasvol->SetLineColor(kGreen); // to avoid blue overlaps in the screenshots + trdmod1_gasvol->SetTransparency(40); // set transparency for the TRD gas + TGeoTranslation* trd_gas_trans = new TGeoTranslation("", 0., 0., gas_position); + module->AddNode(trdmod1_gasvol, 1, trd_gas_trans); + // end of Frame in z + + if(IncludeGasFrame) + { + // frame1 + TGeoBBox* trd_frame1 = new TGeoBBox("trd_frame1", sizeX /2., frameWidth /2., frame_thickness/2.); + TGeoVolume* trdmod1_frame1vol = new TGeoVolume("frame1", trd_frame1, frameVolMed); + trdmod1_frame1vol->SetLineColor(kRed); + + // translations + TGeoTranslation* trd_frame1_trans = new TGeoTranslation("", 0., activeAreaY /2. + frameWidth /2., frame_position); + module->AddNode(trdmod1_frame1vol, 1, trd_frame1_trans); + trd_frame1_trans = new TGeoTranslation("", 0., -(activeAreaY /2. + frameWidth /2.), frame_position); + module->AddNode(trdmod1_frame1vol, 2, trd_frame1_trans); + + + // frame2 + TGeoBBox* trd_frame2 = new TGeoBBox("trd_frame2", frameWidth /2., activeAreaY /2., frame_thickness /2.); + TGeoVolume* trdmod1_frame2vol = new TGeoVolume("frame2", trd_frame2, frameVolMed); + trdmod1_frame2vol->SetLineColor(kRed); + + // translations + TGeoTranslation* trd_frame2_trans = new TGeoTranslation("", activeAreaX /2. + frameWidth /2., 0., frame_position); + module->AddNode(trdmod1_frame2vol, 1, trd_frame2_trans); + trd_frame2_trans = new TGeoTranslation("", -(activeAreaX /2. + frameWidth /2.), 0., frame_position); + module->AddNode(trdmod1_frame2vol, 2, trd_frame2_trans); + } + + if(IncludePadplane) + { + // Pad Copper + TGeoBBox* trd_padcopper = new TGeoBBox("trd_padcopper", sizeX /2., sizeY /2., padcopper_thickness /2.); + TGeoVolume* trdmod1_padcoppervol = new TGeoVolume("padcopper", trd_padcopper, padcopperVolMed); + // TGeoVolume* trdmod1_padcoppervol = new TGeoVolume(Form("module%d_padcopper", moduleType), trd_padcopper, padcopperVolMed); + // TGeoVolume* trdmod1_padcoppervol = new TGeoVolume(Form("trd1mod%dpadcopper", moduleType), trd_padcopper, padcopperVolMed); + trdmod1_padcoppervol->SetLineColor(kOrange); + TGeoTranslation *trd_padcopper_trans = new TGeoTranslation("", 0., 0., padcopper_position); + module->AddNode(trdmod1_padcoppervol, 1, trd_padcopper_trans); + + // Pad Plane + TGeoBBox* trd_padpcb = new TGeoBBox("trd_padpcb", sizeX /2., sizeY /2., padplane_thickness /2.); + TGeoVolume* trdmod1_padpcbvol = new TGeoVolume("padplane", trd_padpcb, padpcbVolMed); + // TGeoVolume* trdmod1_padpcbvol = new TGeoVolume(Form("module%d_padplane", moduleType), trd_padpcb, padpcbVolMed); + // TGeoVolume* trdmod1_padpcbvol = new TGeoVolume(Form("trd1mod%dpadplane", moduleType), trd_padpcb, padpcbVolMed); + trdmod1_padpcbvol->SetLineColor(kBlue); + TGeoTranslation *trd_padpcb_trans = new TGeoTranslation("", 0., 0., padplane_position); + module->AddNode(trdmod1_padpcbvol, 1, trd_padpcb_trans); + } + + if(IncludeBackpanel) + { + // Honeycomb + TGeoBBox* trd_honeycomb = new TGeoBBox("trd_honeycomb", sizeX /2., sizeY /2., honeycomb_thickness /2.); + TGeoVolume* trdmod1_honeycombvol = new TGeoVolume("honeycomb", trd_honeycomb, honeycombVolMed); + // TGeoVolume* trdmod1_honeycombvol = new TGeoVolume(Form("module%d_honeycomb", moduleType), trd_honeycomb, honeycombVolMed); + // TGeoVolume* trdmod1_honeycombvol = new TGeoVolume(Form("trd1mod%dhoneycomb", moduleType), trd_honeycomb, honeycombVolMed); + trdmod1_honeycombvol->SetLineColor(kOrange); + TGeoTranslation* trd_honeycomb_trans = new TGeoTranslation("", 0., 0., honeycomb_position); + module->AddNode(trdmod1_honeycombvol, 1, trd_honeycomb_trans); + + // Carbon fiber layers + TGeoBBox* trd_carbon = new TGeoBBox("trd_carbon", sizeX /2., sizeY /2., carbon_thickness /2.); + TGeoVolume* trdmod1_carbonvol = new TGeoVolume("carbonsheet", trd_carbon, carbonVolMed); + // TGeoVolume* trdmod1_carbonvol = new TGeoVolume(Form("module%d_carbonsheet", moduleType), trd_carbon, carbonVolMed); + // TGeoVolume* trdmod1_carbonvol = new TGeoVolume(Form("trd1mod%dcarbon", moduleType), trd_carbon, carbonVolMed); + trdmod1_carbonvol->SetLineColor(kGreen); + TGeoTranslation* trd_carbon_trans = new TGeoTranslation("", 0., 0., carbon_position); + module->AddNode(trdmod1_carbonvol, 1, trd_carbon_trans); + } + + if(IncludeAluLedge) + { + // Al-ledge + TGeoBBox* trd_aluledge1 = new TGeoBBox("trd_aluledge1", sizeY /2., aluminium_width /2., aluminium_thickness /2.); + TGeoVolume* trdmod1_aluledge1vol = new TGeoVolume("aluledge1", trd_aluledge1, aluledgeVolMed); + trdmod1_aluledge1vol->SetLineColor(kRed); + + // translations + TGeoTranslation* trd_aluledge1_trans = new TGeoTranslation("", 0., sizeY /2. - aluminium_width /2., aluminium_position); + module->AddNode(trdmod1_aluledge1vol, 1, trd_aluledge1_trans); + trd_aluledge1_trans = new TGeoTranslation("", 0., -(sizeY /2. - aluminium_width /2.), aluminium_position); + module->AddNode(trdmod1_aluledge1vol, 2, trd_aluledge1_trans); + + + // Al-ledge + TGeoBBox* trd_aluledge2 = new TGeoBBox("trd_aluledge2", aluminium_width /2., sizeY /2. - aluminium_width, aluminium_thickness /2.); + TGeoVolume* trdmod1_aluledge2vol = new TGeoVolume("aluledge2", trd_aluledge2, aluledgeVolMed); + trdmod1_aluledge2vol->SetLineColor(kRed); + + // translations + TGeoTranslation* trd_aluledge2_trans = new TGeoTranslation("", sizeX /2. - aluminium_width /2., 0., aluminium_position); + module->AddNode(trdmod1_aluledge2vol, 1, trd_aluledge2_trans); + trd_aluledge2_trans = new TGeoTranslation("", -(sizeX /2. - aluminium_width /2.), 0., aluminium_position); + module->AddNode(trdmod1_aluledge2vol, 2, trd_aluledge2_trans); + } + + // FEBs + if (IncludeFebs) + { + // assemblies + TGeoVolumeAssembly* trd_feb_vol = new TGeoVolumeAssembly("febvol"); // the mother volume of all FEBs + TGeoVolumeAssembly* trd_feb_box = new TGeoVolumeAssembly("febbox"); // volume for inclined FEBs, then shifted along y + //TGeoVolumeAssembly* trd_feb_vol = new TGeoVolumeAssembly(Form("module%d_febvol", moduleType)); // the mother volume of all FEBs + //TGeoVolumeAssembly* trd_feb_box = new TGeoVolumeAssembly(Form("module%d_febbox", moduleType)); // volume for inclined FEBs, then shifted along y + //TGeoVolumeAssembly* trd_feb_vol = new TGeoVolumeAssembly(Form("trd1mod%dfebvol", moduleType)); // the mother volume of all FEBs + //TGeoVolumeAssembly* trd_feb_box = new TGeoVolumeAssembly(Form("trd1mod%dfebbox", moduleType)); // volume for inclined FEBs, then shifted along y + + // translations + rotations + TGeoTranslation *trd_feb_trans1; // center to corner + TGeoTranslation *trd_feb_trans2; // corner back + TGeoRotation *trd_feb_rotation; // rotation around x axis + TGeoTranslation *trd_feb_y_position; // shift to y position on TRD +// TGeoTranslation *trd_feb_null; // no displacement + +// replaced by matrix operation (see below) +// // Double_t yback, zback; +// // TGeoCombiTrans *trd_feb_placement; +// // // fix Z back offset 0.3 at some point +// // yback = - sin(feb_rotation_angle/180*3.141) * feb_width /2.; +// // zback = - (1-cos(feb_rotation_angle/180*3.141)) * feb_width /2. + 0.3; +// // trd_feb_placement = new TGeoCombiTrans(0, feb_pos_y + yback, zback, trd_feb_rotation); +// // trd_feb_box->AddNode(trdmod1_feb, iFeb+1, trd_feb_placement); + +// trd_feb_null = new TGeoTranslation("", 0., 0., 0.); // empty operation + trd_feb_trans1 = new TGeoTranslation("", 0.,-feb_thickness/2.,-feb_width/2.); // move bottom right corner to center + trd_feb_trans2 = new TGeoTranslation("", 0., feb_thickness/2., feb_width/2.); // move bottom right corner back + trd_feb_rotation = new TGeoRotation(); trd_feb_rotation->RotateX(feb_rotation_angle[moduleType-1]); + + TGeoHMatrix *incline_feb = new TGeoHMatrix(""); + +// (*incline_feb) = (*trd_feb_null); // OK +// (*incline_feb) = (*trd_feb_y_position); // OK +// (*incline_feb) = (*trd_feb_trans1); // OK +// (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_y_position); // OK +// (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_trans2); // OK +// (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_rotation); // OK +// (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_rotation) * (*trd_feb_trans2) * (*trd_feb_y_position); // not OK + // trd_feb_y_position is displaced in rotated coordinate system + + // matrix operation to rotate FEB PCB around its corner on the backanel + (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_rotation) * (*trd_feb_trans2); // OK + + // Create all FEBs and place them in an assembly which will be added to the TRD module + TGeoBBox* trd_feb = new TGeoBBox("trd_feb", activeAreaX/2., feb_thickness/2., feb_width/2.); // the FEB itself - as a cuboid + TGeoVolume* trdmod1_feb = new TGeoVolume("feb", trd_feb, febVolMed); // the FEB made of a certain medium + // TGeoVolume* trdmod1_feb = new TGeoVolume(Form("module%d_feb", moduleType), trd_feb, febVolMed); // the FEB made of a certain medium + // TGeoVolume* trdmod1_feb = new TGeoVolume(Form("trd1mod%dfeb", moduleType), trd_feb, febVolMed); // the FEB made of a certain medium + trdmod1_feb->SetLineColor(kYellow); // set yellow color + trd_feb_box->AddNode(trdmod1_feb, 1, incline_feb); + // now we have an inclined FEB + + // ASICs + if (IncludeAsics) + { + Double_t asic_pos; + Double_t asic_pos_x; + TGeoTranslation *trd_asic_trans0; // ASIC on FEB x position + TGeoTranslation *trd_asic_trans1; // center to corner + TGeoTranslation *trd_asic_trans2; // corner back + TGeoRotation *trd_asic_rotation; // rotation around x axis + + trd_asic_trans1 = new TGeoTranslation("", 0., -(feb_thickness + asic_offset + asic_thickness/2.), -feb_width/2.); // move ASIC center to FEB corner + trd_asic_trans2 = new TGeoTranslation("", 0., feb_thickness + asic_offset + asic_thickness/2. , feb_width/2.); // move FEB corner back to asic center + trd_asic_rotation = new TGeoRotation(); trd_asic_rotation->RotateX(feb_rotation_angle[moduleType-1]); + + TGeoHMatrix *incline_asic; + + // put many ASICs on each inclined FEB + TGeoBBox* trd_asic = new TGeoBBox("trd_asic", asic_width/2., asic_thickness/2., asic_width/2.); // ASIC dimensions + // TODO: use Silicon as ASICs material + TGeoVolume* trdmod1_asic = new TGeoVolume("asic", trd_asic, asicVolMed); // the ASIC made of a certain medium + // TGeoVolume* trdmod1_asic = new TGeoVolume(Form("module%d_asic", moduleType), trd_asic, asicVolMed); // the ASIC made of a certain medium + // TGeoVolume* trdmod1_asic = new TGeoVolume(Form("trd1mod%dasic", moduleType), trd_asic, asicVolMed); // the ASIC made of a certain medium + trdmod1_asic->SetLineColor(kBlue); // set blue color for ASICs + + Int_t nofAsics = AsicsPerFeb[ moduleType - 1 ] % 100; + Int_t groupAsics = AsicsPerFeb[ moduleType - 1 ] / 100; // either 1 or 2 or 3 (new ultimate) + + if ((nofAsics == 16) && (activeAreaX < 60)) + asic_distance = 0.0; // for 57 cm // 0.1; // for 60 cm + else + asic_distance = 0.4; + + for (Int_t iAsic = 0; iAsic < (nofAsics / groupAsics); iAsic++) + { + if (groupAsics == 1) // single ASICs + { + asic_pos = (iAsic + 0.5) / nofAsics - 0.5; // equal spacing of ASICs on the FEB, e.g. for no=3 : -1/3, 0, +1/3 + + // ASIC 1 + asic_pos_x = asic_pos * activeAreaX; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness/2.+asic_thickness/2.+asic_offset, 0.); // move asic on top of FEB + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, iAsic+1, incline_asic); // now we have ASICs on the inclined FEB + } + + if (groupAsics == 2) // pairs of ASICs + { + asic_pos = (iAsic + 0.5) / (nofAsics / groupAsics) - 0.5; // equal spacing of ASICs on the FEB, e.g. for no=3 : -1/3, 0, +1/3 + + // ASIC 1 + asic_pos_x = asic_pos * activeAreaX + (0.5 + asic_distance/2.) * asic_width; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness/2.+asic_thickness/2.+asic_offset, 0.); // move asic on top of FEB); + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, 2*iAsic+1, incline_asic); // now we have ASICs on the inclined FEB + + // ASIC 2 + asic_pos_x = asic_pos * activeAreaX - (0.5 + asic_distance/2.) * asic_width; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness/2.+asic_thickness/2.+asic_offset, 0.); // move asic on top of FEB + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, 2*iAsic+2, incline_asic); // now we have ASICs on the inclined FEB + } + + if (groupAsics == 3) // triplets of ASICs + { + asic_pos = (iAsic + 0.5) / (nofAsics / groupAsics) - 0.5; // equal spacing of ASICs on the FEB, e.g. for no=3 : -1/3, 0, +1/3 + + // ASIC 1 + asic_pos_x = asic_pos * activeAreaX + 1.1 * asic_width; // (0.5 + asic_distance/2.) * asic_width; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness/2.+asic_thickness/2.+asic_offset, 0.); // move asic on top of FEB); + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, 3*iAsic+1, incline_asic); // now we have ASICs on the inclined FEB + + // ASIC 2 + asic_pos_x = asic_pos * activeAreaX; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness/2.+asic_thickness/2.+asic_offset, 0.); // move asic on top of FEB + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, 3*iAsic+2, incline_asic); // now we have ASICs on the inclined FEB + + // ASIC 3 + asic_pos_x = asic_pos * activeAreaX - 1.1 * asic_width; // (0.5 + asic_distance/2.) * asic_width; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness/2.+asic_thickness/2.+asic_offset, 0.); // move asic on top of FEB + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, 3*iAsic+3, incline_asic); // now we have ASICs on the inclined FEB + } + + } + // now we have an inclined FEB with ASICs + } + + + // now go on with FEB placement + Double_t feb_pos; + Double_t feb_pos_y; + + Int_t nofFebs = FebsPerModule[ moduleType - 1 ]; + for (Int_t iFeb = 0; iFeb < nofFebs; iFeb++) + { + feb_pos = (iFeb + 0.5) / nofFebs - 0.5; // equal spacing of FEBs on the backpanel + // cout << "feb_pos " << iFeb << ": " << feb_pos << endl; + feb_pos_y = feb_pos * activeAreaY; + feb_pos_y += feb_width/2. * sin( feb_rotation_angle[moduleType-1] * acos(-1.)/180.); + + // shift inclined FEB in y to its final position + trd_feb_y_position = new TGeoTranslation("", 0., feb_pos_y, feb_z_offset); // with additional fixed offset in z direction + // trd_feb_y_position = new TGeoTranslation("", 0., feb_pos_y, 0.0); // touching the backpanel with the corner + trd_feb_vol->AddNode(trd_feb_box, iFeb+1, trd_feb_y_position); // position FEB in y + } + + if (IncludeRobs) + { + // GBTx ROBs + Double_t rob_size_x = 20.0; // 13.0; // 130 mm + Double_t rob_size_y = 9.0; // 4.5; // 45 mm + Double_t rob_offset = 1.2; + Double_t rob_thickness = feb_thickness; + + TGeoVolumeAssembly* trd_rob_box = new TGeoVolumeAssembly("robbox"); // volume for inclined FEBs, then shifted along y + TGeoBBox* trd_rob = new TGeoBBox("trd_rob", rob_size_x/2., rob_size_y/2., rob_thickness/2.); // the ROB itself + TGeoVolume* trdmod1_rob = new TGeoVolume("rob", trd_rob, febVolMed); // the ROB made of a certain medium + trdmod1_rob->SetLineColor(kRed); // set color + + // TGeoHMatrix *incline_rob = new TGeoHMatrix(""); + trd_rob_box->AddNode(trdmod1_rob, 1); + + // GBTXs + Double_t gbtx_pos; + Double_t gbtx_pos_x; + Double_t gbtx_pos_y; + TGeoTranslation *trd_gbtx_trans1; // center to corner + + // GBTX parameters + const Double_t gbtx_thickness = 0.25; // 2.5 mm + const Double_t gbtx_width = 3.0; // 2.0; 1.0; // 1 cm + + // put many GBTXs on each inclined FEB + TGeoBBox* trd_gbtx = new TGeoBBox("trd_gbtx", gbtx_width/2., gbtx_width/2., gbtx_thickness/2.); // GBTX dimensions + TGeoVolume* trdmod1_gbtx = new TGeoVolume("gbtx", trd_gbtx, asicVolMed); // the GBTX made of a certain medium + trdmod1_gbtx->SetLineColor(kGreen); // set color for GBTXs + + Int_t nofGbtxs = GbtxPerRob[ moduleType - 1 ] % 100; + Int_t groupGbtxs = GbtxPerRob[ moduleType - 1 ] / 100; // usually 1 + + // nofGbtxs = 7; + // groupGbtxs = 1; + + Int_t nofGbtxX = (nofGbtxs - 1) / 2. + 1; // +1 is for GBTx master + Int_t nofGbtxY = 2; + + Double_t gbtx_distance = 0.4; + Int_t iGbtx = 1; + + for (Int_t iGbtxX = 0; iGbtxX < nofGbtxX; iGbtxX++) + { + gbtx_pos = (iGbtxX + 0.5) / nofGbtxX - 0.5; // equal spacing of GBTXs on the FEB, e.g. for no=3 : -1/3, 0, +1/3 + gbtx_pos_x = -gbtx_pos * rob_size_x; + + if (iGbtxX > 0) + for (Int_t iGbtxY = 0; iGbtxY < nofGbtxY; iGbtxY++) + { + gbtx_pos = (iGbtxY + 0.5) / nofGbtxY - 0.5; // equal spacing of GBTXs on the FEB, e.g. for no=3 : -1/3, 0, +1/3 + gbtx_pos_y = gbtx_pos * rob_size_y; + + trd_gbtx_trans1 = new TGeoTranslation("", gbtx_pos_x, gbtx_pos_y, rob_thickness/2.+gbtx_thickness/2.); // move gbtx on top of ROB + trd_rob_box->AddNode(trdmod1_gbtx, iGbtx++, trd_gbtx_trans1); // now we have GBTXs on the ROB + } + else + { + gbtx_pos_y = 0; + + trd_gbtx_trans1 = new TGeoTranslation("", gbtx_pos_x, gbtx_pos_y, rob_thickness/2.+gbtx_thickness/2.); // move gbtx on top of ROB + trd_rob_box->AddNode(trdmod1_gbtx, iGbtx++, trd_gbtx_trans1); // now we have GBTXs on the ROB + } + + } + + // now go on with ROB placement + Double_t rob_pos; + Double_t rob_pos_y; + TGeoTranslation *trd_rob_y_position; // shift to y position on TRD + + Int_t nofRobs = RobsPerModule[ moduleType - 1 ]; + for (Int_t iRob = 0; iRob < nofRobs; iRob++) + { + rob_pos = (iRob + 0.5) / nofRobs - 0.5; // equal spacing of ROBs on the backpanel + rob_pos_y = rob_pos * activeAreaY; + + // shift inclined ROB in y to its final position + if ( feb_rotation_angle[moduleType-1] == 90 ) // if FEB parallel to backpanel + trd_rob_y_position = new TGeoTranslation("", 0., rob_pos_y, -feb_width/2. + rob_offset); // place ROBs close to FEBs + else + { +// Int_t rob_z_pos = 0.; // test where ROB is placed by default + Int_t rob_z_pos = -feb_width/2. + feb_width * cos( feb_rotation_angle[moduleType-1] * acos(-1.)/180. ) + rob_offset; + if (rob_z_pos > feb_width/2.) // if the rob is too far out + { + rob_z_pos = feb_width/2. - rob_thickness; // place ROBs at end of feb volume + std::cout << "GBTx ROB was outside of the FEB volume, check overlap with FEB" << std::endl; + } + trd_rob_y_position = new TGeoTranslation("", 0., rob_pos_y, rob_z_pos); + } + trd_feb_vol->AddNode(trd_rob_box, iRob+1, trd_rob_y_position); // position FEB in y + } + + } // IncludeGbtx + + // put FEB box on module + TGeoTranslation* trd_febvolume_trans = new TGeoTranslation("", 0., 0., febvolume_position); + gGeoMan->GetVolume(name)->AddNode(trd_feb_vol, 1, trd_febvolume_trans); // put febvolume at correct z position wrt to the module + } + + // DE123 + + return module; +} + + +//________________________________________________________________________________________________ +TGeoVolume* create_trdi_module_type() +{ + Int_t lyType = 2, moduleType = 4; + Double_t sizeX = DetectorSizeX[lyType]; + Double_t sizeY = DetectorSizeY[lyType]; + Double_t frameWidth = FrameWidth[lyType]; + Double_t activeAreaX = sizeX - 2 * frameWidth; + Double_t activeAreaY = sizeY - 2 * frameWidth; + + TGeoMedium* keepVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + TGeoMedium* radVolMed = gGeoMan->GetMedium(RadiatorVolumeMedium); + TGeoMedium* latticeVolMed = gGeoMan->GetMedium(LatticeVolumeMedium); + TGeoMedium* kaptonVolMed = gGeoMan->GetMedium(KaptonVolumeMedium); + TGeoMedium* gasVolMed = gGeoMan->GetMedium(GasVolumeMedium); + TGeoMedium* padcopperVolMed = gGeoMan->GetMedium(PadCopperVolumeMedium); + TGeoMedium* padpcbVolMed = gGeoMan->GetMedium(PadPcbVolumeMedium); + TGeoMedium* honeycombVolMed = gGeoMan->GetMedium(HoneycombVolumeMedium); + TGeoMedium* carbonVolMed = gGeoMan->GetMedium(CarbonVolumeMedium); +// TGeoMedium* mylarVolMed = gGeoMan->GetMedium(MylarVolumeMedium); +// TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsVolumeMedium); + TGeoMedium* frameVolMed = gGeoMan->GetMedium(FrameVolumeMedium); + TGeoMedium* febVolMed = gGeoMan->GetMedium(FebVolumeMedium); + TGeoMedium* asicVolMed = gGeoMan->GetMedium(AsicVolumeMedium); +// TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium); + + TString name = "moduleBu"; + TGeoVolume* module = new TGeoVolumeAssembly(name); + + + if(IncludeRadiator){ // Radiator + TGeoBBox* trd_radiator = new TGeoBBox("trd_radiator", sizeX /2., sizeY /2., radiator_thickness /2.); + TGeoVolume* trdmod1_radvol = new TGeoVolume("radiator", trd_radiator, radVolMed); + trdmod1_radvol->SetLineColor(kRed); + trdmod1_radvol->SetTransparency(50); // (60); // (70); // set transparency for the TRD radiator + TGeoTranslation* trd_radiator_trans = new TGeoTranslation("", 0., 0., radiator_position); + module->AddNode(trdmod1_radvol, 1, trd_radiator_trans); + } + + + if(IncludeLattice){ // Entrance window in the case of the Bucharest prototype + // Carbon fiber layers + TGeoBBox* trd_carbon = new TGeoBBox("trd_carbon", activeAreaX /2., activeAreaY /2., carbonBu_thickness /2.); + TGeoVolume* trdmod1_carbonvol = new TGeoVolume("EntranceWinC", trd_carbon, carbonVolMed); + trdmod1_carbonvol->SetLineColor(kGray); + // Honeycomb layer + TGeoBBox* trd_honeycomb = new TGeoBBox("trd_honeycombBu", activeAreaX /2., activeAreaY /2., honeycombBu_thickness /2.); + TGeoVolume* trdmod1_honeycombvol = new TGeoVolume("EntranceWinHC", trd_honeycomb, honeycombVolMed); + trdmod1_honeycombvol->SetLineColor(kOrange); + + module->AddNode(trdmod1_carbonvol, 1, + new TGeoTranslation("", 0., 0., carbonBu1_position)); + module->AddNode(trdmod1_honeycombvol, 1, + new TGeoTranslation("", 0., 0., honeycombBu0_position)); + module->AddNode(trdmod1_carbonvol, 2, + new TGeoTranslation("", 0., 0., carbonBu0_position)); + } + + // Gas + TGeoBBox* trd_gas = new TGeoBBox("trd_gas", activeAreaX /2., activeAreaY /2., gas_thickness /2.); + TGeoVolume* trdmod1_gasvol = new TGeoVolume("gas", trd_gas, gasVolMed); + trdmod1_gasvol->SetLineColor(kWhite); // to avoid blue overlaps in the screenshots + trdmod1_gasvol->SetTransparency(40); // set transparency for the TRD gas + module->AddNode(trdmod1_gasvol, 1, new TGeoTranslation("", 0., 0., gasBu_position)); + // end of Frame in z + + if(IncludeGasFrame) { + // frame1 + TGeoBBox* trd_frame1 = new TGeoBBox("trd_frame1", sizeX /2., frameWidth /2., frameBu_thickness/2.); + TGeoVolume* trdmod1_frame1vol = new TGeoVolume("frameH", trd_frame1, frameVolMed); + trdmod1_frame1vol->SetLineColor(kBlue); + module->AddNode(trdmod1_frame1vol, 1, + new TGeoTranslation("", 0., activeAreaY /2. + frameWidth/2., frameBu_position)); + module->AddNode(trdmod1_frame1vol, 2, + new TGeoTranslation("", 0., -(activeAreaY /2. + frameWidth/2.), frameBu_position)); + // frame2 + TGeoBBox* trd_frame2 = new TGeoBBox("trd_frame2", frameWidth /2., activeAreaY /2., frameBu_thickness/2.); + TGeoVolume* trdmod1_frame2vol = new TGeoVolume("frameV", trd_frame2, frameVolMed); + trdmod1_frame2vol->SetLineColor(kBlue); + module->AddNode(trdmod1_frame2vol, 1, + new TGeoTranslation("", activeAreaX /2. + frameWidth/2., 0., frameBu_position)); + module->AddNode(trdmod1_frame2vol, 2, + new TGeoTranslation("", -(activeAreaX /2. + frameWidth/2.), 0., frameBu_position)); + } + + if(IncludePadplane) { + // Pad Copper + TGeoBBox* trd_padcopper = new TGeoBBox("trd_padcopper", activeAreaX /2., activeAreaY /2., padcopper_thickness /2.); + TGeoVolume* trdmod1_padcoppervol = new TGeoVolume("pads", trd_padcopper, padcopperVolMed); + trdmod1_padcoppervol->SetLineColor(kRed); + module->AddNode(trdmod1_padcoppervol, 1, + new TGeoTranslation("", 0., 0., padcopperBu_position)); + // Pad Plane + TGeoBBox* trd_padpcb = new TGeoBBox("trd_padpcb", activeAreaX /2., activeAreaY /2., padplane_thickness /2.); + TGeoVolume* trdmod1_padpcbvol = new TGeoVolume("padsPCB", trd_padpcb, padpcbVolMed); + trdmod1_padpcbvol->SetLineColor(kGreen); + module->AddNode(trdmod1_padpcbvol, 1, + new TGeoTranslation("", 0., 0., padplaneBu_position)); + } + + if(IncludeBackpanel) { + // Honeycomb + TGeoBBox* trd_honeycomb = new TGeoBBox("trd_honeycomb", activeAreaX /2., activeAreaY /2., honeycombBu_thickness /2.); + TGeoVolume* trdmod1_honeycombvol = new TGeoVolume("BackpanelHC", trd_honeycomb, honeycombVolMed); + trdmod1_honeycombvol->SetLineColor(kOrange); + module->AddNode(trdmod1_honeycombvol, 1, + new TGeoTranslation("", 0., 0., honeycombBu1_position)); + // Screen fibre-glass support (PCB) + TGeoBBox* trd_screenpcb = new TGeoBBox("trd_padpcb", activeAreaX /2., activeAreaY /2., glassFibre_thickness/2.); + TGeoVolume* trdmod1_screenpcbvol = new TGeoVolume("BackpanelPCB", trd_screenpcb, padpcbVolMed); + trdmod1_screenpcbvol->SetLineColor(kGreen); + module->AddNode(trdmod1_screenpcbvol, 1, + new TGeoTranslation("", 0., 0., glassFibre_position)); + // Pad Copper + TGeoBBox* trd_screencopper = new TGeoBBox("trd_padcopper", activeAreaX /2., activeAreaY /2., cuCoating_thickness/2.); + TGeoVolume* trdmod1_screencoppervol = new TGeoVolume("BackpanelScreen", trd_screencopper, padcopperVolMed); + trdmod1_screencoppervol->SetLineColor(kRed); + module->AddNode(trdmod1_screencoppervol, 1, + new TGeoTranslation("", 0., 0., cuCoating_position)); + } + + // FEBs + if (IncludeFebs) { + TGeoVolumeAssembly* trd_feb_vol = new TGeoVolumeAssembly("febvol"); // the mother volume of all FEBs + TGeoVolumeAssembly* trd_feb_box = new TGeoVolumeAssembly("febbox"); + TGeoTranslation *trd_feb_position; // trnslation for positioning FEBs on TRD + + // Create all FEBs and place them in an assembly which will be added to the TRD module + TGeoBBox* trd_feb = new TGeoBBox("trd_feb", febFASP_width/2., activeAreaY/4.-0.5, febFASP_thickness/2.); + TGeoVolume* trdmod1_feb = new TGeoVolume("feb", trd_feb, febVolMed); // the FEB made of PCB + trdmod1_feb->SetLineColor(kYellow); + trd_feb_box->AddNode(trdmod1_feb, 1); + + // ASICs + if (IncludeAsics) { + Double_t asic_pos; + Double_t asic_pos_y; + TGeoTranslation *trd_asic_pos; // ASIC on FEB x position + + // put many ASICs on each inclined FEB + TGeoBBox* trd_asic = new TGeoBBox("trd_fasp", 0.5*fasp_size[0], 0.5*fasp_size[1], asic_thickness/2.); // ASIC dimensions + // TODO: use Silicon as ASICs material + TGeoVolume* trdmod1_asic = new TGeoVolume("fasp", trd_asic, asicVolMed); // the ASIC made of a certain medium + trdmod1_asic->SetLineColor(kBlack); + + Int_t nofAsics = AsicsPerFeb[ moduleType - 1 ] % 100; + for (Int_t iAsic(0), jAsic(1); iAsic < nofAsics; iAsic++) { + asic_pos = (iAsic + 0.5) /nofAsics - 0.5; // equal spacing of ASICs on the FEB + asic_pos_y = asic_pos * activeAreaY/2.; + trd_asic_pos = new TGeoTranslation("", + (iAsic%2?-1:1)*fasp_xoffset, + asic_pos_y+(iAsic%2?-1:1)*fasp_yoffset, + feb_thickness/2.+asic_thickness/2.+asic_offset); + trd_feb_box->AddNode(trdmod1_asic, jAsic++, trd_asic_pos); + } + } + + + // now go on with FEB placement + Double_t feb_pos; + Double_t feb_pos_x, feb_pos_y; + + Int_t nofFebs = FebsPerModule[ moduleType - 1 ], nofFebsHalf(nofFebs/2); + Double_t zfeb_pos(febFASP_position); + for(Int_t iFebLy(0), jFeb(1); iFebLy<4; iFebLy++){ + for (Int_t iFeb(0); iFeb < nofFebsHalf; iFeb++) { + feb_pos = (iFeb + 0.5) / nofFebsHalf - 0.5; // equal spacing of FEBs on the backpanel + feb_pos_x = feb_pos * activeAreaX; + feb_pos_y = activeAreaY/4; + + // move to final position over the detector for : + // the upper row ... + trd_feb_position = new TGeoTranslation("", feb_pos_x, feb_pos_y, zfeb_pos); + trd_feb_vol->AddNode(trd_feb_box, jFeb++, trd_feb_position); + // ... and the bottom row + trd_feb_position = new TGeoTranslation("", feb_pos_x, -feb_pos_y, zfeb_pos); + trd_feb_vol->AddNode(trd_feb_box, jFeb++, trd_feb_position); + } + zfeb_pos+=febFASP_zspace; + } + if (IncludeRobs) { + TGeoVolumeAssembly* trd_rob_box = new TGeoVolumeAssembly("robbox"); + TGeoBBox* trd_rob = new TGeoBBox("trd_rob", rob_size_x/2., rob_size_y/2., rob_thickness/2.); + TGeoVolume* trdmod1_rob = new TGeoVolume("rob", trd_rob, febVolMed); // the ROB made of PCB + trdmod1_rob->SetLineColor(kRed); // set color + trd_rob_box->AddNode(trdmod1_rob, 1); + + // Add connector PCB + TGeoBBox* trd_robConn = new TGeoBBox("trd_robConn", robConn_size_y/2., robConn_size_x/2., rob_thickness/2.); + TGeoVolume* trdmod1_robConn = new TGeoVolume("robConn", trd_robConn, febVolMed); // the ROB made of PCB + trdmod1_robConn->SetLineColor(kRed); // set color + // shift to x position on C-ROB3 + TGeoTranslation *trd_robConn_position = + new TGeoTranslation("", robConn_xoffset, 0, -robConn_FMCheight-feb_thickness); + trd_rob_box->AddNode(trdmod1_robConn, 1, trd_robConn_position); + + // Add FMC connector + TGeoBBox* trd_fmcConn = new TGeoBBox("trd_fmcConn", robConn_FMCwidth/2., robConn_FMClength/2., robConn_FMCheight/2.); + TGeoVolume* trdmod1_fmcConn = new TGeoVolume("robConn", trd_fmcConn, frameVolMed); // the FMC made of Al + trdmod1_fmcConn->SetLineColor(kGray); // set color + // shift to x position on C-ROB3 + TGeoTranslation *trd_fmcConn_position = + new TGeoTranslation("", robConn_xoffset+2, 0, -robConn_FMCheight/2-feb_thickness/2); + trd_rob_box->AddNode(trdmod1_fmcConn, 1, trd_fmcConn_position); + + // GBTXs + Double_t gbtx_pos; + Double_t gbtx_pos_x; + Double_t gbtx_pos_y; + TGeoTranslation *trd_gbtx_trans1; // center to corner + + // put 3 GBTXs on each C-ROC + TGeoBBox* trd_gbtx = new TGeoBBox("trd_gbtx", gbtx_width/2., gbtx_width/2., gbtx_thickness/2.); + TGeoVolume* trdmod1_gbtx = new TGeoVolume("gbtx", trd_gbtx, asicVolMed); + trdmod1_gbtx->SetLineColor(kGreen); + + Int_t nofGbtxs = GbtxPerRob[ moduleType - 1 ] % 100; + Int_t groupGbtxs = GbtxPerRob[ moduleType - 1 ] / 100; // usually 1 + + Int_t nofGbtxX = (nofGbtxs - 1) / 2. + 1; // +1 is for GBTx master + Int_t nofGbtxY = 2; + + for (Int_t iGbtxX(0), iGbtx(1); iGbtxX < nofGbtxX; iGbtxX++) { + gbtx_pos = (iGbtxX + 0.5) / nofGbtxX - 0.5; + gbtx_pos_x = -gbtx_pos * rob_size_x; + + if (iGbtxX > 0){ + for (Int_t iGbtxY = 0; iGbtxY < nofGbtxY; iGbtxY++) { + gbtx_pos = (iGbtxY + 0.5) / nofGbtxY - 0.5; + gbtx_pos_y = gbtx_pos * rob_size_y; + + trd_gbtx_trans1 = new TGeoTranslation("", gbtx_pos_x, gbtx_pos_y, rob_thickness/2.+gbtx_thickness/2.); // move gbtx on top of ROB + trd_rob_box->AddNode(trdmod1_gbtx, iGbtx++, trd_gbtx_trans1); + } + } else { + gbtx_pos_y = 0; + + trd_gbtx_trans1 = new TGeoTranslation("", gbtx_pos_x, gbtx_pos_y, rob_thickness/2.+gbtx_thickness/2.); // move gbtx on top of ROB + trd_rob_box->AddNode(trdmod1_gbtx, iGbtx++, trd_gbtx_trans1); // now we have GBTXs on the ROB + } + } + TGeoRotation *trd_rob_rotation = new TGeoRotation(); + trd_rob_rotation->RotateZ(90.); trd_rob_rotation->RotateX(90.); + + // now go on with ROB placement + Double_t rob_pos; + Double_t rob_pos_y; + TGeoTranslation *trd_rob_y_position; // shift to y position on TRD + + Int_t nofRobs = RobsPerModule[ moduleType - 1 ], nofRobsHalf(nofRobs/2); + for (Int_t iRob = 0; iRob < nofRobsHalf; iRob++) { + rob_pos = (iRob + 0.5) / nofRobsHalf - 0.5; // equal spacing of ROBs on the backpanel + rob_pos_y = rob_pos * activeAreaY; + trd_rob_y_position = new TGeoTranslation("", rob_zoffset, rob_pos_y, sizeY/2.+rob_yoffset); + TGeoHMatrix *trd_rob_transform = new TGeoHMatrix(""); + (*trd_rob_transform)=(*trd_rob_rotation)*(*trd_rob_y_position); + trd_feb_vol->AddNode(trd_rob_box, iRob+1, trd_rob_transform); + } + trd_rob_rotation->RotateZ(180.); + for (Int_t iRob = 0; iRob < nofRobsHalf; iRob++) { + rob_pos = (iRob + 0.5) / nofRobsHalf - 0.5; // equal spacing of ROBs on the backpanel + rob_pos_y = rob_pos * activeAreaY; + trd_rob_y_position = new TGeoTranslation("", rob_zoffset, rob_pos_y, sizeY/2.+rob_yoffset); + TGeoHMatrix *trd_rob_transform = new TGeoHMatrix(""); + (*trd_rob_transform)=(*trd_rob_rotation)*(*trd_rob_y_position); + trd_feb_vol->AddNode(trd_rob_box, iRob+1, trd_rob_transform); // position FEB in y + } + } // IncludeGbtx + + // put FEB box on module + TGeoTranslation* trd_febvolume_trans = new TGeoTranslation("", 0., 0., febvolume_position); + gGeoMan->GetVolume(name)->AddNode(trd_feb_vol, 1, trd_febvolume_trans); // put febvolume at correct z position wrt to the module + } + + + return module; +} + + + +Int_t copy_nr(Int_t stationNr, Int_t copyNr, Int_t isRotated, Int_t planeNr, Int_t modinplaneNr) +{ + if (modinplaneNr > 128) + printf("Warning: too many modules in this layer %02d (max 128 according to CbmTrdAddress)\n", planeNr); + + return (stationNr * 100000000 // 1 digit + + copyNr * 1000000 // 2 digit + + isRotated * 100000 // 1 digit + + planeNr * 1000 // 2 digit + + modinplaneNr * 1 ); // 3 digit +} + +void create_detector_layers(Int_t layerId) +{ + Int_t module_id = 0; + Int_t layerType = LayerType[layerId] / 10; // this is also a station number + Int_t isRotated = LayerType[layerId] % 10; // is 1 for layers 2,4, ... + + TGeoRotation* module_rotation = new TGeoRotation(); + + Int_t stationNr = layerType; + +// rotation is now done in the for loop for each module individually +// if ( isRotated == 1 ) { +// module_rotation = new TGeoRotation(); +// module_rotation->RotateZ(90.); +// } else { +// module_rotation = new TGeoRotation(); +// module_rotation->RotateZ( 0.); +// } + + Int_t innerarray_size1 = LayerArraySize[layerType - 1][0]; + Int_t innerarray_size2 = LayerArraySize[layerType - 1][1]; + const Int_t* innerLayer; + + Int_t outerarray_size1 = LayerArraySize[layerType - 1][2]; + Int_t outerarray_size2 = LayerArraySize[layerType - 1][3]; + const Int_t* outerLayer; + + if ( 1 == layerType ) { + innerLayer = (Int_t*) layer1i; + outerLayer = (Int_t*) layer1o; + } else if ( 2 == layerType ) { + innerLayer = (Int_t*) layer2i; + outerLayer = (Int_t*) layer2o; + } else if ( 3 == layerType ) { + innerLayer = (Int_t*) layer3i; + outerLayer = (Int_t*) layer3o; + } else { + std::cout << "Type of layer not known" << std::endl; + } + +// add layer keeping volume + TString layername = Form("layer%02d", PlaneId[layerId]); + TGeoVolume* layer = new TGeoVolumeAssembly(layername); + + // compute layer copy number + Int_t i = LayerType[layerId] / 10 * 10000 // 1 digit // fStation + + LayerType[layerId] % 10 * 1000 // 1 digit // isRotated + + LayerNrInStation[layerId] * 100 // 1 digit // fLayer + + PlaneId[layerId]; // 2 digits // fPlane // layer type as leading digit in copy number of layer + gGeoMan->GetVolume(geoVersion)->AddNode(layer, i); + +// Int_t i = 100 + PlaneId[layerId]; +// gGeoMan->GetVolume(geoVersion)->AddNode(layer, 1); +// cout << layername << endl; + + Double_t ExplodeScale = 1.00; + if(DoExplode) // if explosion, set scale + ExplodeScale = ExplodeFactor; + + Int_t modId = 0; // module id, only within this layer + + Int_t copyNrIn[4] = { 0, 0, 0, 0 }; // copy number for each module type + for ( Int_t type = 1; type <= 4; type++) { + for ( Int_t j = (innerarray_size1-1); j >= 0; j--) { // start from the bottom + for ( Int_t i = 0; i < innerarray_size2; i++) { + module_id = *(innerLayer + (j * innerarray_size2 + i)); + if ( module_id /100 == type) { + Int_t y = -(j-2); + Int_t x = i-2; + + // displacement + Double_t dx = 0; + Double_t dy = 0; + Double_t dz = 0; + + if(DisplaceRandom) + { + dx = (r3.Rndm()-.5) * 2 * maxdx; // max +- 0.1 cm shift + dy = (r3.Rndm()-.5) * 2 * maxdy; // max +- 0.1 cm shift + dz = (r3.Rndm()-.5) * 2 * maxdz; // max +- 1.0 cm shift + } + + Double_t xPos = DetectorSizeX[0] * x * ExplodeScale + dx; + Double_t yPos = DetectorSizeY[0] * y * ExplodeScale + dy; + copyNrIn[type - 1]++; + modId++; + + // statistics per layer and module type + ModuleStats[layerId][type - 1]++; + +// Int_t copy = copy_nr_modid(stationNr, layerNrInStation, copyNrIn[type - 1], PlaneId[layerId], modId); // with modID +// Int_t copy = copy_nr(stationNr, copyNrIn[type - 1], isRotated, PlaneId[layerId], modId); + + // take care of FEB orientation - away from beam + Int_t copy = 0; + module_rotation = new TGeoRotation(); // need to renew rotation to start from 0 degree angle + if ( isRotated == 0 ) // layer 1,3 ... + { + copy = copy_nr(stationNr, copyNrIn[type - 1], module_id /10 %10, PlaneId[layerId], modId); + module_rotation->RotateZ( (module_id /10 %10) * 90. ); // rotate module by 0 or 180 degrees, see layer[1-3][i,o] - vertical pads + } + else // layer 2,4 ... + { + copy = copy_nr(stationNr, copyNrIn[type - 1], module_id %10 , PlaneId[layerId], modId); + module_rotation->RotateZ( (module_id %10) * 90. ); // rotate module by 90 or 270 degrees, see layer[1-3][i,o] - horizontal pads + } + + // rotation + Double_t drotx = 0; + Double_t droty = 0; + Double_t drotz = 0; + + if(RotateRandom) + { + drotx = (r3.Rndm()-.5) * 2 * maxdrotx; + droty = (r3.Rndm()-.5) * 2 * maxdroty; + drotz = (r3.Rndm()-.5) * 2 * maxdrotz; + + module_rotation->RotateZ( drotz ); + module_rotation->RotateY( droty ); + module_rotation->RotateX( drotx ); + } + + TGeoCombiTrans* module_placement = new TGeoCombiTrans(xPos, yPos, LayerPosition[layerId] + LayerThickness/2 + dz, module_rotation); // shift by half layer thickness +// gGeoMan->GetVolume(geoVersion)->AddNode(gModules[type - 1], copy, module_placement); +// add module to layer + gGeoMan->GetVolume(layername)->AddNode(gModules[type - 1], copy, module_placement); +// + } + } + } + } + + Int_t copyNrOut[4] = { 0, 0, 0, 0 }; // copy number for each module type + for ( Int_t type = 5; type <= 8; type++) { + for ( Int_t j = (outerarray_size1-1); j >= 0; j--) { // start from the bottom + for ( Int_t i = 0; i < outerarray_size2; i++) { + module_id = *(outerLayer + (j * outerarray_size2 + i)); + if ( module_id /100 == type) { + Int_t y = -(j-4); + Int_t x = i-5; + + // displacement + Double_t dx = 0; + Double_t dy = 0; + Double_t dz = 0; + + if(DisplaceRandom) + { + dx = (r3.Rndm()-.5) * 2 * maxdx; // max +- 0.1 cm shift + dy = (r3.Rndm()-.5) * 2 * maxdy; // max +- 0.1 cm shift + dz = (r3.Rndm()-.5) * 2 * maxdz; // max +- 1.0 cm shift + } + + Double_t xPos = DetectorSizeX[1] * x * ExplodeScale + dx; + Double_t yPos = DetectorSizeY[1] * y * ExplodeScale + dy; + copyNrOut[type - 5]++; + modId++; + + // statistics per layer and module type + ModuleStats[layerId][type - 1]++; + +// Int_t copy = copy_nr_modid(stationNr, layerNrInStation, copyNrOut[type - 5], PlaneId[layerId], modId); // with modID +// Int_t copy = copy_nr(stationNr, copyNrOut[type - 5], isRotated, PlaneId[layerId], modId); + + // take care of FEB orientation - away from beam + Int_t copy = 0; + module_rotation = new TGeoRotation(); // need to renew rotation to start from 0 degree angle + if ( isRotated == 0 ) // layer 1,3 ... + { + copy = copy_nr(stationNr, copyNrOut[type - 5], module_id /10 %10, PlaneId[layerId], modId); + module_rotation->RotateZ( (module_id /10 %10) * 90. ); // rotate module by 0 or 180 degrees, see layer[1-3][i,o] - vertical pads + } + else // layer 2,4 ... + { + copy = copy_nr(stationNr, copyNrOut[type - 5], module_id %10 , PlaneId[layerId], modId); + module_rotation->RotateZ( (module_id %10) * 90. ); // rotate module by 90 or 270 degrees, see layer[1-3][i,o] - horizontal pads + } + + // rotation + Double_t drotx = 0; + Double_t droty = 0; + Double_t drotz = 0; + + if(RotateRandom) + { + drotx = (r3.Rndm()-.5) * 2 * maxdrotx; + droty = (r3.Rndm()-.5) * 2 * maxdroty; + drotz = (r3.Rndm()-.5) * 2 * maxdrotz; + + module_rotation->RotateZ( drotz ); + module_rotation->RotateY( droty ); + module_rotation->RotateX( drotx ); + } + + Double_t frameref_angle = 0; + Double_t layer_angle = 0; + + cout << "layer " << layerId << " ---" << endl; + frameref_angle = atan( (DetectorSizeX[1]/2. - FrameWidth[1]) / (zfront[setupid] + 3 * LayerThickness) ); + // frameref_angle = 15. / 180. * acos(-1); // set a fixed reference angle + cout << "reference angle " << frameref_angle * 180 / acos(-1) << endl; + + layer_angle = atan( (DetectorSizeX[1]/2. - FrameWidth[1]) / (zfront[setupid] + layerId * LayerThickness) ); + cout << "layer angle " << layer_angle * 180 / acos(-1) << endl; + // DEDE + // xPos = tan( frameref_angle ) * (zfront[setupid] + layerId * LayerThickness) - (DetectorSizeX[1]/2. - FrameWidth[1]); // shift module along x-axis + xPos = 0; + cout << "layer " << layerId << " - xPos " << xPos << endl; + + layer_angle = atan( (DetectorSizeX[1]/2. - FrameWidth[1] + xPos) / (zfront[setupid] + layerId * LayerThickness) ); + cout << "corrected angle " << layer_angle * 180 / acos(-1) << endl; + + +// Double_t frameangle[4] = {0}; +// for ( Int_t ilayer = 3; ilayer >= 0; ilayer--) +// { +// frameangle[ilayer] = atan( (DetectorSizeX[1]/2. - FrameWidth[1]) / (zfront[setupid] + ilayer * LayerThickness) ); +// cout << "layer " << ilayer << " - angle " << frameangle[ilayer] * 180 / acos(-1) << endl; +// +// xPos = (DetectorSizeX[1]/2. - FrameWidth[1]); +// cout << "layer " << ilayer << " - xPos " << xPos << endl; +// +// xPos = tan( frameangle[3] ) * (zfront[setupid] + ilayer * LayerThickness); +// cout << "layer " << ilayer << " - xPos " << xPos << endl; +// +// xPos = (DetectorSizeX[1]/2. - FrameWidth[1]) - ( tan( frameangle[3] ) * (zfront[setupid] + ilayer * LayerThickness) ); // shift module along x-axis +// cout << "layer " << ilayer << " - xPos " << xPos << endl; +// } + + + TGeoCombiTrans* module_placement = new TGeoCombiTrans(xPos, yPos, LayerPosition[layerId] + LayerThickness/2 + dz, module_rotation); // shift by half layer thickness + +// add module to layer + gGeoMan->GetVolume(layername)->AddNode(gModules[type - 1], copy, module_placement); +// + } + } + } + } +} + + +void create_mag_field_vector() +{ + const TString cbmfield_01 = "cbm_field"; + TGeoVolume* cbmfield_1 = new TGeoVolumeAssembly(cbmfield_01); + + TGeoMedium* copperVolMed = gGeoMan->GetMedium(PadCopperVolumeMedium); // define Volume Medium + + TGeoRotation *rotx090 = new TGeoRotation("rotx090"); rotx090->RotateX( 90.); // rotate 90 deg around x-axis + TGeoRotation *rotx270 = new TGeoRotation("rotx270"); rotx270->RotateX( 270.); // rotate 270 deg around x-axis + + Int_t tube_length = 500; + Int_t cone_length = 120; + Int_t cone_width = 280; + + // field tube + TGeoTube* trd_field = new TGeoTube("", 0., 100/2., tube_length/2.); + TGeoVolume* trdmod1_fieldvol = new TGeoVolume("tube", trd_field, copperVolMed); + trdmod1_fieldvol->SetLineColor(kRed); + trdmod1_fieldvol->SetTransparency(30); // transparency for the TRD + TGeoTranslation* trd_field_trans = new TGeoTranslation("", 0., 0., 0.); // tube position + cbmfield_1->AddNode(trdmod1_fieldvol, 1, trd_field_trans); + + // field cone + TGeoCone* trd_cone = new TGeoCone("", cone_length/2., 0., cone_width/2., 0., 0.); + TGeoVolume* trdmod1_conevol = new TGeoVolume("cone", trd_cone, copperVolMed); + trdmod1_conevol->SetLineColor(kRed); + trdmod1_conevol->SetTransparency(30); // transparency for the TRD + TGeoTranslation* trd_cone_trans = new TGeoTranslation("", 0., 0., (tube_length+cone_length)/2.); // cone position + cbmfield_1->AddNode(trdmod1_conevol, 1, trd_cone_trans); + + TGeoCombiTrans* field_combi01 = new TGeoCombiTrans(0., 0., 40., rotx270); // point in +y direction + gGeoMan->GetVolume(geoVersion)->AddNode(cbmfield_1, 1, field_combi01); + + // TGeoCombiTrans* field_combi02 = new TGeoCombiTrans( 200., 0., 0., rotx090); // point in -y direction + // gGeoMan->GetVolume(geoVersion)->AddNode(cbmfield_1, 2, field_combi02); +} + + +void create_gibbet_support() +{ + const TString gibbet_01 = "gibbet_bars_trd1"; + TGeoVolume* gibbet_1 = new TGeoVolumeAssembly(gibbet_01); + + TGeoBBox* gibbet1; + TGeoBBox* gibbet2; + TGeoBBox* gibbet3; + TGeoBBox* gibbet4; + + TGeoVolume* gibbet1_vol; + TGeoVolume* gibbet2_vol; + TGeoVolume* gibbet3_vol; + TGeoVolume* gibbet4_vol; + + TGeoTranslation* gibbet1_trans; + TGeoTranslation* gibbet2_trans; + TGeoTranslation* gibbet3_trans; + TGeoTranslation* gibbet4_trans; + TGeoTranslation* gibbet5_trans; + + Int_t x_offset = 0.0; // x position of gibbet rim towards module + // Int_t x_offset = -10.0; // x position of gibbet rim towards module + + const Int_t kColor1010n = kAzure+8; // gibbet color + const Int_t kColor1010s = kGray; // gibbet color + const Int_t kColor0305n = kBlue; // gibbet color + + TGeoMedium* k1010nVolMed = gGeoMan->GetMedium(Kanya10x10nVolumeMedium); + TGeoMedium* k1010sVolMed = gGeoMan->GetMedium(Kanya10x10sVolumeMedium); + TGeoMedium* k0305nVolMed = gGeoMan->GetMedium(Kanya03x05nVolumeMedium); + + const Int_t kanya01 = 105; // kanyahoritop + const Int_t kanya02 = 90; // kanyavertnear + const Int_t kanya03 = 150; // kanyavertpill + + const Int_t gapx = 5; // gap in x direction + const Int_t gapy = 2; // gap in y direction + const Int_t gapxpill = 2; // gap in x direction between vertical pillars + + // horizontal gibbet 2020 + gibbet1 = new TGeoBBox("gibbet1", kanya01 /2., gibbet_width /2., gibbet_thickness /2.); + gibbet1_vol = new TGeoVolume("gibbetvol1", gibbet1, k1010nVolMed); + gibbet1_vol->SetLineColor(kColor1010n); + + // translations + gibbet1_trans = new TGeoTranslation("", (kanya01 - DetectorSizeX[1]) /2. - gapx + x_offset, + (DetectorSizeY[1] + gibbet_width) /2. + gapy, + 0.); + gibbet_1->AddNode(gibbet1_vol, 1, gibbet1_trans); + + // vertical gibbet 2020 + gibbet2 = new TGeoBBox("gibbet2", gibbet_width /2., kanya02 /2., gibbet_thickness /2.); + gibbet2_vol = new TGeoVolume("gibbetvol2", gibbet2, k1010nVolMed); + gibbet2_vol->SetLineColor(kColor1010n); + + // translations + gibbet2_trans = new TGeoTranslation("", -(DetectorSizeX[1] + gibbet_width)/2. - gapx + x_offset, + (DetectorSizeY[1] - kanya02) /2. + gapy + 2 * gibbet_width, + 0.); + gibbet_1->AddNode(gibbet2_vol, 2, gibbet2_trans); + + // vertical gibbet pillar 2020 + gibbet3 = new TGeoBBox("gibbet3", gibbet_width /2., kanya03 /2., gibbet_thickness /2.); + gibbet3_vol = new TGeoVolume("gibbetvol3", gibbet3, k1010sVolMed); + gibbet3_vol->SetLineColor(kColor1010s); + + // translations + gibbet3_trans = new TGeoTranslation("", -(DetectorSizeX[1] + 3 * gibbet_width)/2. - gapx - gapxpill + x_offset, + 0., 0.); + gibbet_1->AddNode(gibbet3_vol, 3, gibbet3_trans); + + // vertical mount rails 2020 + gibbet4 = new TGeoBBox("gibbet4", rail_width /2., (DetectorSizeY[1] + gapy) /2., rail_thickness /2.); + gibbet4_vol = new TGeoVolume("gibbetvol4", gibbet4, k0305nVolMed); + gibbet4_vol->SetLineColor(kColor0305n); + + // translations + gibbet4_trans = new TGeoTranslation("", -(DetectorSizeX[1] - rail_width)/2. + x_offset, + +gapy/2., + 0.); + gibbet_1->AddNode(gibbet4_vol, 4, gibbet4_trans); + + // translations + gibbet5_trans = new TGeoTranslation("", (DetectorSizeX[1] - rail_width)/2. + x_offset, + +gapy/2., + 0.); + gibbet_1->AddNode(gibbet4_vol, 5, gibbet5_trans); + + Int_t l; + for (l=0; l<4; l++) + if ((ShowLayer[l]) && (BusBarOrientation[l] == 1)) // if geometry contains layer l + { + TString layername = Form("layer%02d", l+1); + TGeoTranslation* gibbet_placement = new TGeoTranslation(0, 0, LayerPosition[l] + LayerThickness/2. + gibbet_position); + gGeoMan->GetVolume(layername)->AddNode(gibbet_1, l, gibbet_placement); + } + +} + + +void create_power_bars_vertical() +{ + const TString power_01 = "power_bars_trd1"; + TGeoVolume* power_1 = new TGeoVolumeAssembly(power_01); + + TGeoBBox* power1; + TGeoBBox* power2; + + TGeoVolume* power1_vol; + TGeoVolume* power2_vol; + + TGeoTranslation* power1_trans; + TGeoTranslation* power2_trans; + + const Int_t kColor = kBlue; // bus bar color + + TGeoMedium* powerBusVolMed = gGeoMan->GetMedium(PowerBusVolumeMedium); + + // powerbus - horizontal short + power1 = new TGeoBBox("power1", (DetectorSizeX[1] - DetectorSizeX[0] - powerbar_width)/2., powerbar_width /2., powerbar_thickness /2.); + power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed); + power1_vol->SetLineColor(kColor); + + // translations + power1_trans = new TGeoTranslation("", 1 * (DetectorSizeX[1] - DetectorSizeY[0]/2.), 1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power1_vol, 1, power1_trans); + + power1_trans = new TGeoTranslation("", -1 * (DetectorSizeX[1] - DetectorSizeY[0]/2.), -1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power1_vol, 2, power1_trans); + + // powerbus - horizontal long + power1 = new TGeoBBox("power1", (DetectorSizeX[0] - powerbar_width)/2., powerbar_width /2., powerbar_thickness /2.); + power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed); + power1_vol->SetLineColor(kColor); + + // translations + power1_trans = new TGeoTranslation("", -1 * DetectorSizeX[0], 1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power1_vol, 3, power1_trans); + + power1_trans = new TGeoTranslation("", 1 * DetectorSizeX[0], -1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power1_vol, 4, power1_trans); + + + // powerbus - vertical long + power2 = new TGeoBBox("power2", powerbar_width /2., (5 * DetectorSizeY[1] + powerbar_width) /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", -3.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 1, power2_trans); + power2_trans = new TGeoTranslation("", 3.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 2, power2_trans); + + power2_trans = new TGeoTranslation("", -2.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 3, power2_trans); + power2_trans = new TGeoTranslation("", 2.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 4, power2_trans); + + power2_trans = new TGeoTranslation("", -1.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 5, power2_trans); + power2_trans = new TGeoTranslation("", 1.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 6, power2_trans); + + // powerbus - vertical middle + power2 = new TGeoBBox("power2", powerbar_width /2., (3 * DetectorSizeY[1] + powerbar_width) /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", -1.5 * DetectorSizeX[0], 0., 0.); + power_1->AddNode(power2_vol, 7, power2_trans); + power2_trans = new TGeoTranslation("", 1.5 * DetectorSizeX[0], 0., 0.); + power_1->AddNode(power2_vol, 8, power2_trans); + + // powerbus - vertical short 1 + power2 = new TGeoBBox("power2", powerbar_width /2., 1 * DetectorSizeY[1] /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + // power2_vol->SetLineColor(kRed); + + // translations + power2_trans = new TGeoTranslation("", -0.5 * DetectorSizeX[1], (2.0 * DetectorSizeY[1] + powerbar_width/2.), 0.); + power_1->AddNode(power2_vol, 9, power2_trans); + power2_trans = new TGeoTranslation("", 0.5 * DetectorSizeX[1], -(2.0 * DetectorSizeY[1] + powerbar_width/2.), 0.); + power_1->AddNode(power2_vol,10, power2_trans); + + // powerbus - vertical short 2 + power2 = new TGeoBBox("power2", powerbar_width /2., (1 * DetectorSizeY[1] + powerbar_width) /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", -0.5 * DetectorSizeX[1], -2.0 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol,11, power2_trans); + power2_trans = new TGeoTranslation("", 0.5 * DetectorSizeX[1], 2.0 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol,12, power2_trans); + + // powerbus - vertical short 3 + power2 = new TGeoBBox("power2", powerbar_width /2., (2 * DetectorSizeY[0] + powerbar_width/2.) /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", -0.5 * DetectorSizeX[0], (1.5 * DetectorSizeY[0] + powerbar_width/4.), 0.); + power_1->AddNode(power2_vol,11, power2_trans); + power2_trans = new TGeoTranslation("", 0.5 * DetectorSizeX[0], -(1.5 * DetectorSizeY[0] + powerbar_width/4.), 0.); + power_1->AddNode(power2_vol,12, power2_trans); + + Int_t l; + for (l=0; l<4; l++) + if ((ShowLayer[l]) && (BusBarOrientation[l] == 1)) // if geometry contains layer l + { + TString layername = Form("layer%02d", l+1); + TGeoTranslation* power_placement = new TGeoTranslation(0, 0, LayerPosition[l] + LayerThickness/2. + powerbar_position); + gGeoMan->GetVolume(layername)->AddNode(power_1, l, power_placement); + } + +} + + +void create_power_bars_horizontal() +{ + const TString power_01 = "power_bars_trd1"; + TGeoVolume* power_1 = new TGeoVolumeAssembly(power_01); + + TGeoBBox* power1; + TGeoBBox* power2; + + TGeoVolume* power1_vol; + TGeoVolume* power2_vol; + + TGeoTranslation* power1_trans; + TGeoTranslation* power2_trans; + + const Int_t kColor = kBlue; // bus bar color + + TGeoMedium* powerBusVolMed = gGeoMan->GetMedium(PowerBusVolumeMedium); + + // powerbus - vertical short + power1 = new TGeoBBox("power1", powerbar_width /2., (DetectorSizeY[1] - DetectorSizeY[0] - powerbar_width)/2., powerbar_thickness /2.); + power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed); + power1_vol->SetLineColor(kColor); + + // translations + power1_trans = new TGeoTranslation("", 1.5 * DetectorSizeX[1], -1 * (DetectorSizeY[1] - DetectorSizeY[0]/2.), 0.); + power_1->AddNode(power1_vol, 1, power1_trans); + + power1_trans = new TGeoTranslation("", -1.5 * DetectorSizeX[1], 1 * (DetectorSizeY[1] - DetectorSizeY[0]/2.), 0.); + power_1->AddNode(power1_vol, 2, power1_trans); + + // powerbus - vertical long + power1 = new TGeoBBox("power1", powerbar_width /2., (DetectorSizeY[0] - powerbar_width)/2., powerbar_thickness /2.); + power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed); + power1_vol->SetLineColor(kColor); + + // translations + power1_trans = new TGeoTranslation("", 1.5 * DetectorSizeX[1], 1 * DetectorSizeY[0], 0.); + power_1->AddNode(power1_vol, 3, power1_trans); + + power1_trans = new TGeoTranslation("", -1.5 * DetectorSizeX[1], -1 * DetectorSizeY[0], 0.); + power_1->AddNode(power1_vol, 4, power1_trans); + + + // powerbus - horizontal long + power2 = new TGeoBBox("power2", (7 * DetectorSizeX[1] + powerbar_width) /2., powerbar_width /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", 0., -2.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 1, power2_trans); + power2_trans = new TGeoTranslation("", 0., 2.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 2, power2_trans); + + power2_trans = new TGeoTranslation("", 0., -1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 3, power2_trans); + power2_trans = new TGeoTranslation("", 0., 1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 4, power2_trans); + + // powerbus - horizontal middle + power2 = new TGeoBBox("power2", (3 * DetectorSizeX[1] + powerbar_width) /2., powerbar_width /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", 0., -1.5 * DetectorSizeY[0], 0.); + power_1->AddNode(power2_vol, 7, power2_trans); + power2_trans = new TGeoTranslation("", 0., 1.5 * DetectorSizeY[0], 0.); + power_1->AddNode(power2_vol, 8, power2_trans); + + // powerbus - horizontal short 1 + power2 = new TGeoBBox("power2", 2 * DetectorSizeX[1] /2., powerbar_width /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + // power2_vol->SetLineColor(kRed); + + // translations + power2_trans = new TGeoTranslation("", (2.5 * DetectorSizeX[1] + powerbar_width/2.), 0.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 9, power2_trans); + power2_trans = new TGeoTranslation("", -(2.5 * DetectorSizeX[1] + powerbar_width/2.), -0.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol,10, power2_trans); + + // powerbus - horizontal short 2 + power2 = new TGeoBBox("power2", (2 * DetectorSizeX[1] + powerbar_width) /2., powerbar_width /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", -2.5 * DetectorSizeX[1], 0.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol,11, power2_trans); + power2_trans = new TGeoTranslation("", 2.5 * DetectorSizeX[1], -0.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol,12, power2_trans); + + // powerbus - horizontal short 3 + power2 = new TGeoBBox("power2", (2 * DetectorSizeX[0] + powerbar_width/2.) /2., powerbar_width /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", (1.5 * DetectorSizeX[0] + powerbar_width/4.), 0.5 * DetectorSizeY[0], 0.); + power_1->AddNode(power2_vol,11, power2_trans); + power2_trans = new TGeoTranslation("", -(1.5 * DetectorSizeX[0] + powerbar_width/4.), -0.5 * DetectorSizeY[0], 0.); + power_1->AddNode(power2_vol,12, power2_trans); + + Int_t l; + for (l=0; l<4; l++) + if ((ShowLayer[l]) && (BusBarOrientation[l] == 0)) // if geometry contains layer l + { + TString layername = Form("layer%02d", l+1); + TGeoTranslation* power_placement = new TGeoTranslation(0, 0, LayerPosition[l] + LayerThickness/2. + powerbar_position); + gGeoMan->GetVolume(layername)->AddNode(power_1, l, power_placement); + } + +} + + +void create_xtru_supports() +{ + const TString trd_01 = "support_trd1"; + TGeoVolume* trd_1 = new TGeoVolumeAssembly(trd_01); + + const TString trd_02 = "support_trd2"; + TGeoVolume* trd_2 = new TGeoVolumeAssembly(trd_02); + + const TString trd_03 = "support_trd3"; + TGeoVolume* trd_3 = new TGeoVolumeAssembly(trd_03); + +// const TString trdSupport = "supportframe"; +// TGeoVolume* trdsupport = new TGeoVolumeAssembly(trdSupport); +// +// trdsupport->AddNode(trd_1, 1); +// trdsupport->AddNode(trd_2, 2); +// trdsupport->AddNode(trd_3, 3); + + TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium); // define Volume Medium + + const Double_t x[12] = { -15,-15, -1, -1,-15,-15, 15, 15, 1, 1, 15, 15 }; // IPB 400 + const Double_t y[12] = { -20,-18,-18, 18, 18, 20, 20, 18, 18,-18,-18,-20 }; // 30 x 40 cm in size, 2 cm wall thickness + const Double_t Hwid = -2*x[0]; // 30 + const Double_t Hhei = -2*y[0]; // 40 + + Double_t AperX[3] = { 450., 550., 600.}; // inner aperture in X of support structure for stations 1,2,3 + Double_t AperY[3] = { 350., 450., 500.}; // inner aperture in Y of support structure for stations 1,2,3 + Double_t PilPosX; + Double_t BarPosY; + + const Double_t BeamHeight = 570; // beamline is at 5.7m above floor + + Double_t PilPosZ[6]; // PilPosZ +// PilPosZ[0] = LayerPosition[0] + LayerThickness/2.; +// PilPosZ[1] = LayerPosition[3] + LayerThickness/2.; +// PilPosZ[2] = LayerPosition[4] + LayerThickness/2.; +// PilPosZ[3] = LayerPosition[7] + LayerThickness/2.; +// PilPosZ[4] = LayerPosition[8] + LayerThickness/2.; +// PilPosZ[5] = LayerPosition[9] + LayerThickness/2.; + + PilPosZ[0] = LayerPosition[0] + 15; + PilPosZ[1] = LayerPosition[3] - 15 + LayerThickness; + PilPosZ[2] = LayerPosition[4] + 15; + PilPosZ[3] = LayerPosition[7] - 15 + LayerThickness; + PilPosZ[4] = LayerPosition[8] + 15; + PilPosZ[5] = LayerPosition[9] - 15 + LayerThickness; + +// cout << "PilPosZ[0]: " << PilPosZ[0] << endl; +// cout << "PilPosZ[1]: " << PilPosZ[1] << endl; + + TGeoRotation *rotx090 = new TGeoRotation("rotx090"); rotx090->RotateX( 90.); // rotate 90 deg around x-axis + TGeoRotation *roty090 = new TGeoRotation("roty090"); roty090->RotateY( 90.); // rotate 90 deg around y-axis + TGeoRotation *rotz090 = new TGeoRotation("rotz090"); rotz090->RotateZ( 90.); // rotate 90 deg around y-axis + TGeoRotation *roty270 = new TGeoRotation("roty270"); roty270->RotateY(270.); // rotate 270 deg around y-axis + + TGeoRotation *rotzx01 = new TGeoRotation("rotzx01"); + rotzx01->RotateZ( 90.); // rotate 90 deg around z-axis + rotzx01->RotateX( 90.); // rotate 90 deg around x-axis + +// TGeoRotation *rotxz01 = new TGeoRotation("rotxz01"); +// rotxz01->RotateX( 90.); // rotate 90 deg around x-axis +// rotxz01->RotateZ( 90.); // rotate 90 deg around z-axis + + Double_t ang1 = atan(3./4.) * 180. / acos(-1.); + // cout << "DEDE " << ang1 << endl; + // Double_t sin1 = acos(-1.); + // cout << "DEDE " << sin1 << endl; + TGeoRotation *rotx080 = new TGeoRotation("rotx080"); rotx080->RotateX( 90.-ang1); // rotate 80 deg around x-axis + TGeoRotation *rotx100 = new TGeoRotation("rotx100"); rotx100->RotateX( 90.+ang1); // rotate 100 deg around x-axis + + TGeoRotation *rotxy01 = new TGeoRotation("rotxy01"); + rotxy01->RotateX( 90.); // rotate 90 deg around x-axis + rotxy01->RotateZ(-ang1); // rotate ang1 around rotated y-axis + + TGeoRotation *rotxy02 = new TGeoRotation("rotxy02"); + rotxy02->RotateX( 90.); // rotate 90 deg around x-axis + rotxy02->RotateZ( ang1); // rotate ang1 around rotated y-axis + + +//------------------- +// vertical pillars (Y) +//------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + TGeoXtru* trd_H_vert1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_vert1->DefinePolygon(12,x,y); + trd_H_vert1->DefineSection( 0,-(AperY[0]+Hhei), 0, 0, 1.0); + trd_H_vert1->DefineSection( 1, BeamHeight, 0, 0, 1.0); + TGeoVolume* trd_H_vert_vol1 = new TGeoVolume("trd_H_y_01", trd_H_vert1, aluminiumVolMed); + trd_H_vert_vol1->SetLineColor(kYellow); + PilPosX = AperX[0]; + + TGeoCombiTrans* trd_H_vert_combi01 = new TGeoCombiTrans( (PilPosX+Hhei/2.), 0., PilPosZ[0], rotzx01); + trd_1->AddNode(trd_H_vert_vol1, 11, trd_H_vert_combi01); + TGeoCombiTrans* trd_H_vert_combi02 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), 0., PilPosZ[0], rotzx01); + trd_1->AddNode(trd_H_vert_vol1, 12, trd_H_vert_combi02); + TGeoCombiTrans* trd_H_vert_combi03 = new TGeoCombiTrans( (PilPosX+Hhei/2.), 0., PilPosZ[1], rotzx01); + trd_1->AddNode(trd_H_vert_vol1, 13, trd_H_vert_combi03); + TGeoCombiTrans* trd_H_vert_combi04 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), 0., PilPosZ[1], rotzx01); + trd_1->AddNode(trd_H_vert_vol1, 14, trd_H_vert_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoXtru* trd_H_vert1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_vert1->DefinePolygon(12,x,y); + trd_H_vert1->DefineSection( 0,-(AperY[1]+Hhei), 0, 0, 1.0); + trd_H_vert1->DefineSection( 1, BeamHeight, 0, 0, 1.0); + TGeoVolume* trd_H_vert_vol1 = new TGeoVolume("trd_H_y_02", trd_H_vert1, aluminiumVolMed); + trd_H_vert_vol1->SetLineColor(kYellow); + PilPosX = AperX[1]; + + TGeoCombiTrans* trd_H_vert_combi01 = new TGeoCombiTrans( (PilPosX+Hhei/2.), 0., PilPosZ[2], rotzx01); + trd_2->AddNode(trd_H_vert_vol1, 21, trd_H_vert_combi01); + TGeoCombiTrans* trd_H_vert_combi02 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), 0., PilPosZ[2], rotzx01); + trd_2->AddNode(trd_H_vert_vol1, 22, trd_H_vert_combi02); + TGeoCombiTrans* trd_H_vert_combi03 = new TGeoCombiTrans( (PilPosX+Hhei/2.), 0., PilPosZ[3], rotzx01); + trd_2->AddNode(trd_H_vert_vol1, 23, trd_H_vert_combi03); + TGeoCombiTrans* trd_H_vert_combi04 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), 0., PilPosZ[3], rotzx01); + trd_2->AddNode(trd_H_vert_vol1, 24, trd_H_vert_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoXtru* trd_H_vert1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_vert1->DefinePolygon(12,x,y); + trd_H_vert1->DefineSection( 0,-(AperY[2]+Hhei), 0, 0, 1.0); + trd_H_vert1->DefineSection( 1, BeamHeight, 0, 0, 1.0); + TGeoVolume* trd_H_vert_vol1 = new TGeoVolume("trd_H_y_03", trd_H_vert1, aluminiumVolMed); + trd_H_vert_vol1->SetLineColor(kYellow); + PilPosX = AperX[2]; + + TGeoCombiTrans* trd_H_vert_combi01 = new TGeoCombiTrans( (PilPosX+Hhei/2.), 0., PilPosZ[4], rotzx01); + trd_3->AddNode(trd_H_vert_vol1, 31, trd_H_vert_combi01); + TGeoCombiTrans* trd_H_vert_combi02 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), 0., PilPosZ[4], rotzx01); + trd_3->AddNode(trd_H_vert_vol1, 32, trd_H_vert_combi02); + TGeoCombiTrans* trd_H_vert_combi03 = new TGeoCombiTrans( (PilPosX+Hhei/2.), 0., PilPosZ[5], rotzx01); + trd_3->AddNode(trd_H_vert_vol1, 33, trd_H_vert_combi03); + TGeoCombiTrans* trd_H_vert_combi04 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), 0., PilPosZ[5], rotzx01); + trd_3->AddNode(trd_H_vert_vol1, 34, trd_H_vert_combi04); + } + + +//------------------- +// horizontal supports (X) +//------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + TGeoXtru* trd_H_hori1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_hori1->DefinePolygon(12,x,y); + trd_H_hori1->DefineSection( 0,-AperX[0], 0, 0, 1.0); + trd_H_hori1->DefineSection( 1, AperX[0], 0, 0, 1.0); + TGeoVolume* trd_H_hori_vol1 = new TGeoVolume("trd_H_x_01", trd_H_hori1, aluminiumVolMed); + trd_H_hori_vol1->SetLineColor(kRed); + BarPosY = AperY[0]; + + TGeoCombiTrans* trd_H_hori_combi01 = new TGeoCombiTrans(0., (BarPosY+Hhei/2.), PilPosZ[0], roty090); + trd_1->AddNode(trd_H_hori_vol1, 11, trd_H_hori_combi01); + TGeoCombiTrans* trd_H_hori_combi02 = new TGeoCombiTrans(0.,-(BarPosY+Hhei/2.), PilPosZ[0], roty090); + trd_1->AddNode(trd_H_hori_vol1, 12, trd_H_hori_combi02); + TGeoCombiTrans* trd_H_hori_combi03 = new TGeoCombiTrans(0., (BarPosY+Hhei/2.), PilPosZ[1], roty090); + trd_1->AddNode(trd_H_hori_vol1, 13, trd_H_hori_combi03); + TGeoCombiTrans* trd_H_hori_combi04 = new TGeoCombiTrans(0.,-(BarPosY+Hhei/2.), PilPosZ[1], roty090); + trd_1->AddNode(trd_H_hori_vol1, 14, trd_H_hori_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoXtru* trd_H_hori1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_hori1->DefinePolygon(12,x,y); + trd_H_hori1->DefineSection( 0,-AperX[1], 0, 0, 1.0); + trd_H_hori1->DefineSection( 1, AperX[1], 0, 0, 1.0); + TGeoVolume* trd_H_hori_vol1 = new TGeoVolume("trd_H_x_02", trd_H_hori1, aluminiumVolMed); + trd_H_hori_vol1->SetLineColor(kRed); + BarPosY = AperY[1]; + + TGeoCombiTrans* trd_H_hori_combi01 = new TGeoCombiTrans(0., (BarPosY+Hhei/2.), PilPosZ[2], roty090); + trd_2->AddNode(trd_H_hori_vol1, 21, trd_H_hori_combi01); + TGeoCombiTrans* trd_H_hori_combi02 = new TGeoCombiTrans(0.,-(BarPosY+Hhei/2.), PilPosZ[2], roty090); + trd_2->AddNode(trd_H_hori_vol1, 22, trd_H_hori_combi02); + TGeoCombiTrans* trd_H_hori_combi03 = new TGeoCombiTrans(0., (BarPosY+Hhei/2.), PilPosZ[3], roty090); + trd_2->AddNode(trd_H_hori_vol1, 23, trd_H_hori_combi03); + TGeoCombiTrans* trd_H_hori_combi04 = new TGeoCombiTrans(0.,-(BarPosY+Hhei/2.), PilPosZ[3], roty090); + trd_2->AddNode(trd_H_hori_vol1, 24, trd_H_hori_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoXtru* trd_H_hori1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_hori1->DefinePolygon(12,x,y); + trd_H_hori1->DefineSection( 0,-AperX[2], 0, 0, 1.0); + trd_H_hori1->DefineSection( 1, AperX[2], 0, 0, 1.0); + TGeoVolume* trd_H_hori_vol1 = new TGeoVolume("trd_H_x_03", trd_H_hori1, aluminiumVolMed); + trd_H_hori_vol1->SetLineColor(kRed); + BarPosY = AperY[2]; + + TGeoCombiTrans* trd_H_hori_combi01 = new TGeoCombiTrans(0., (BarPosY+Hhei/2.), PilPosZ[4], roty090); + trd_3->AddNode(trd_H_hori_vol1, 31, trd_H_hori_combi01); + TGeoCombiTrans* trd_H_hori_combi02 = new TGeoCombiTrans(0.,-(BarPosY+Hhei/2.), PilPosZ[4], roty090); + trd_3->AddNode(trd_H_hori_vol1, 32, trd_H_hori_combi02); + TGeoCombiTrans* trd_H_hori_combi03 = new TGeoCombiTrans(0., (BarPosY+Hhei/2.), PilPosZ[5], roty090); + trd_3->AddNode(trd_H_hori_vol1, 33, trd_H_hori_combi03); + TGeoCombiTrans* trd_H_hori_combi04 = new TGeoCombiTrans(0.,-(BarPosY+Hhei/2.), PilPosZ[5], roty090); + trd_3->AddNode(trd_H_hori_vol1, 34, trd_H_hori_combi04); + } + + +//------------------- +// horizontal supports (Z) +//------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + TGeoXtru* trd_H_slope1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_slope1->DefinePolygon(12,x,y); + trd_H_slope1->DefineSection( 0,-(PilPosZ[1]-PilPosZ[0]-Hwid)/2., 0, 0, 1.0); + trd_H_slope1->DefineSection( 1,+(PilPosZ[1]-PilPosZ[0]-Hwid)/2., 0, 0, 1.0); + TGeoVolume* trd_H_slope_vol1 = new TGeoVolume("trd_H_z_01", trd_H_slope1, aluminiumVolMed); + trd_H_slope_vol1->SetLineColor(kGreen); + PilPosX = AperX[0]; + BarPosY = AperY[0]; + + TGeoCombiTrans* trd_H_slope_combi01 = new TGeoCombiTrans( (PilPosX+Hhei/2.), (BarPosY+Hhei-Hwid/2.), (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_H_slope_vol1, 11, trd_H_slope_combi01); + TGeoCombiTrans* trd_H_slope_combi02 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), (BarPosY+Hhei-Hwid/2.), (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_H_slope_vol1, 12, trd_H_slope_combi02); + TGeoCombiTrans* trd_H_slope_combi03 = new TGeoCombiTrans( (PilPosX+Hhei/2.),-(BarPosY+Hhei-Hwid/2.), (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_H_slope_vol1, 13, trd_H_slope_combi03); + TGeoCombiTrans* trd_H_slope_combi04 = new TGeoCombiTrans(-(PilPosX+Hhei/2.),-(BarPosY+Hhei-Hwid/2.), (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_H_slope_vol1, 14, trd_H_slope_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoXtru* trd_H_slope1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_slope1->DefinePolygon(12,x,y); + trd_H_slope1->DefineSection( 0,-(PilPosZ[3]-PilPosZ[2]-Hwid)/2., 0, 0, 1.0); + trd_H_slope1->DefineSection( 1,+(PilPosZ[3]-PilPosZ[2]-Hwid)/2., 0, 0, 1.0); + TGeoVolume* trd_H_slope_vol1 = new TGeoVolume("trd_H_z_02", trd_H_slope1, aluminiumVolMed); + trd_H_slope_vol1->SetLineColor(kGreen); + PilPosX = AperX[1]; + BarPosY = AperY[1]; + + TGeoCombiTrans* trd_H_slope_combi01 = new TGeoCombiTrans( (PilPosX+Hhei/2.), (BarPosY+Hhei-Hwid/2.), (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_H_slope_vol1, 21, trd_H_slope_combi01); + TGeoCombiTrans* trd_H_slope_combi02 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), (BarPosY+Hhei-Hwid/2.), (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_H_slope_vol1, 22, trd_H_slope_combi02); + TGeoCombiTrans* trd_H_slope_combi03 = new TGeoCombiTrans( (PilPosX+Hhei/2.),-(BarPosY+Hhei-Hwid/2.), (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_H_slope_vol1, 23, trd_H_slope_combi03); + TGeoCombiTrans* trd_H_slope_combi04 = new TGeoCombiTrans(-(PilPosX+Hhei/2.),-(BarPosY+Hhei-Hwid/2.), (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_H_slope_vol1, 24, trd_H_slope_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoXtru* trd_H_slope1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_slope1->DefinePolygon(12,x,y); + trd_H_slope1->DefineSection( 0,-(PilPosZ[5]-PilPosZ[4]-Hwid)/2., 0, 0, 1.0); + trd_H_slope1->DefineSection( 1,+(PilPosZ[5]-PilPosZ[4]-Hwid)/2., 0, 0, 1.0); + TGeoVolume* trd_H_slope_vol1 = new TGeoVolume("trd_H_z_03", trd_H_slope1, aluminiumVolMed); + trd_H_slope_vol1->SetLineColor(kGreen); + PilPosX = AperX[2]; + BarPosY = AperY[2]; + + TGeoCombiTrans* trd_H_slope_combi01 = new TGeoCombiTrans( (PilPosX+Hhei/2.), (BarPosY+Hhei-Hwid/2.), (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_H_slope_vol1, 31, trd_H_slope_combi01); + TGeoCombiTrans* trd_H_slope_combi02 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), (BarPosY+Hhei-Hwid/2.), (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_H_slope_vol1, 32, trd_H_slope_combi02); + TGeoCombiTrans* trd_H_slope_combi03 = new TGeoCombiTrans( (PilPosX+Hhei/2.),-(BarPosY+Hhei-Hwid/2.), (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_H_slope_vol1, 33, trd_H_slope_combi03); + TGeoCombiTrans* trd_H_slope_combi04 = new TGeoCombiTrans(-(PilPosX+Hhei/2.),-(BarPosY+Hhei-Hwid/2.), (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_H_slope_vol1, 34, trd_H_slope_combi04); + } + + if (IncludeLabels) + { + + Int_t text_height = 40; + Int_t text_thickness = 8; + + TGeoTranslation *tr200 = new TGeoTranslation(0., (AperY[0]+Hhei+ text_height/2.), PilPosZ[0]-15+ text_thickness/2.); + TGeoTranslation *tr201 = new TGeoTranslation(0., (AperY[1]+Hhei+ text_height/2.), PilPosZ[2]-15+ text_thickness/2.); + TGeoTranslation *tr202 = new TGeoTranslation(0., (AperY[2]+Hhei+ text_height/2.), PilPosZ[4]-15+ text_thickness/2.); + + TGeoCombiTrans *tr203 = new TGeoCombiTrans(-(AperX[0]+Hhei+ text_thickness/2.), (AperY[0]+Hhei-Hwid-text_height/2.), (PilPosZ[0]+PilPosZ[1])/2., roty090); + TGeoCombiTrans *tr204 = new TGeoCombiTrans(-(AperX[1]+Hhei+ text_thickness/2.), (AperY[1]+Hhei-Hwid-text_height/2.), (PilPosZ[2]+PilPosZ[3])/2., roty090); + TGeoCombiTrans *tr205 = new TGeoCombiTrans(-(AperX[2]+Hhei+ text_thickness/2.), (AperY[2]+Hhei-Hwid-text_height/2.), (PilPosZ[4]+PilPosZ[5])/2., roty090); + + TGeoCombiTrans *tr206 = new TGeoCombiTrans( (AperX[0]+Hhei+ text_thickness/2.), (AperY[0]+Hhei-Hwid-text_height/2.), (PilPosZ[0]+PilPosZ[1])/2., roty270); + TGeoCombiTrans *tr207 = new TGeoCombiTrans( (AperX[1]+Hhei+ text_thickness/2.), (AperY[1]+Hhei-Hwid-text_height/2.), (PilPosZ[2]+PilPosZ[3])/2., roty270); + TGeoCombiTrans *tr208 = new TGeoCombiTrans( (AperX[2]+Hhei+ text_thickness/2.), (AperY[2]+Hhei-Hwid-text_height/2.), (PilPosZ[4]+PilPosZ[5])/2., roty270); + + TGeoVolume* trdbox1 = new TGeoVolumeAssembly("trdbox1"); // volume for TRD text (108, 40, 8) + TGeoVolume* trdbox2 = new TGeoVolumeAssembly("trdbox2"); // volume for TRD text (108, 40, 8) + TGeoVolume* trdbox3 = new TGeoVolumeAssembly("trdbox3"); // volume for TRD text (108, 40, 8) + add_trd_labels(trdbox1, trdbox2, trdbox3); + + // final placement + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + // trd_1->AddNode(trdbox1, 1, tr200); + trd_1->AddNode(trdbox1, 4, tr203); + trd_1->AddNode(trdbox1, 7, tr206); + } + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + // trd_2->AddNode(trdbox2, 2, tr201); + trd_2->AddNode(trdbox2, 5, tr204); + trd_2->AddNode(trdbox2, 8, tr207); + } + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + // trd_3->AddNode(trdbox3, 3, tr202); + trd_3->AddNode(trdbox3, 6, tr205); + trd_3->AddNode(trdbox3, 9, tr208); + } + } + + // gGeoMan->GetVolume(geoVersion)->AddNode(trdsupport,1); + + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_1, 1); + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_2, 2); + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_3, 3); + +} + + +void add_trd_labels(TGeoVolume* trdbox1, TGeoVolume* trdbox2, TGeoVolume* trdbox3) +{ +// write TRD (the 3 characters) in a simple geometry + TGeoMedium* textVolMed = gGeoMan->GetMedium(TextVolumeMedium); + + Int_t Tcolor = kBlue; // kRed; + Int_t Rcolor = kBlue; // kRed; // kRed; + Int_t Dcolor = kBlue; // kRed; // kYellow; + Int_t Icolor = kBlue; // kRed; + +// define transformations for letter pieces +// T + TGeoTranslation *tr01 = new TGeoTranslation( 0. , -4., 0.); + TGeoTranslation *tr02 = new TGeoTranslation( 0. , 16., 0.); + +// R + TGeoTranslation *tr11 = new TGeoTranslation( 10, 0., 0.); + TGeoTranslation *tr12 = new TGeoTranslation( 2, 0., 0.); + TGeoTranslation *tr13 = new TGeoTranslation( 2, 16., 0.); + TGeoTranslation *tr14 = new TGeoTranslation( -2, 8., 0.); + TGeoTranslation *tr15 = new TGeoTranslation( -6, 0., 0.); + +// D + TGeoTranslation *tr21 = new TGeoTranslation( 12., 0., 0.); + TGeoTranslation *tr22 = new TGeoTranslation( 6., 16., 0.); + TGeoTranslation *tr23 = new TGeoTranslation( 6.,-16., 0.); + TGeoTranslation *tr24 = new TGeoTranslation( 4., 0., 0.); + +// I + TGeoTranslation *tr31 = new TGeoTranslation( 0. , 0., 0.); + TGeoTranslation *tr32 = new TGeoTranslation( 0. , 16., 0.); + TGeoTranslation *tr33 = new TGeoTranslation( 0. ,-16., 0.); + +// make letter T +// TGeoVolume *T = geom->MakeBox("T", Vacuum, 25., 25., 5.); +// T->SetVisibility(kFALSE); + TGeoVolume* T = new TGeoVolumeAssembly("Tbox"); // volume for T + + TGeoBBox* Tbar1b = new TGeoBBox("trd_Tbar1b", 4., 16., 4.); // | vertical + TGeoVolume *Tbar1 = new TGeoVolume("Tbar1", Tbar1b, textVolMed); + Tbar1->SetLineColor(Tcolor); + T->AddNode(Tbar1, 1, tr01); + TGeoBBox* Tbar2b = new TGeoBBox("trd_Tbar2b", 16, 4., 4.); // - top + TGeoVolume *Tbar2 = new TGeoVolume("Tbar2", Tbar2b, textVolMed); + Tbar2->SetLineColor(Tcolor); + T->AddNode(Tbar2, 1, tr02); + +// make letter R +// TGeoVolume *R = geom->MakeBox("R", Vacuum, 25., 25., 5.); +// R->SetVisibility(kFALSE); + TGeoVolume* R = new TGeoVolumeAssembly("Rbox"); // volume for R + + TGeoBBox* Rbar1b = new TGeoBBox("trd_Rbar1b", 4., 20, 4.); + TGeoVolume *Rbar1 = new TGeoVolume("Rbar1", Rbar1b, textVolMed); + Rbar1->SetLineColor(Rcolor); + R->AddNode(Rbar1, 1, tr11); + TGeoBBox* Rbar2b = new TGeoBBox("trd_Rbar2b", 4., 4., 4.); + TGeoVolume *Rbar2 = new TGeoVolume("Rbar2", Rbar2b, textVolMed); + Rbar2->SetLineColor(Rcolor); + R->AddNode(Rbar2, 1, tr12); + R->AddNode(Rbar2, 2, tr13); + TGeoTubeSeg* Rtub1b = new TGeoTubeSeg("trd_Rtub1b", 4., 12, 4., 90., 270.); + TGeoVolume *Rtub1 = new TGeoVolume("Rtub1", (TGeoShape *) Rtub1b, textVolMed); + Rtub1->SetLineColor(Rcolor); + R->AddNode(Rtub1, 1, tr14); + TGeoArb8* Rbar3b = new TGeoArb8("trd_Rbar3b", 4.); + TGeoVolume *Rbar3 = new TGeoVolume("Rbar3", Rbar3b, textVolMed); + Rbar3->SetLineColor(Rcolor); + TGeoArb8 *arb = (TGeoArb8*)Rbar3->GetShape(); + arb->SetVertex(0, 12., -4.); + arb->SetVertex(1, 0., -20.); + arb->SetVertex(2, -8., -20.); + arb->SetVertex(3, 4., -4.); + arb->SetVertex(4, 12., -4.); + arb->SetVertex(5, 0., -20.); + arb->SetVertex(6, -8., -20.); + arb->SetVertex(7, 4., -4.); + R->AddNode(Rbar3, 1, tr15); + +// make letter D +// TGeoVolume *D = geom->MakeBox("D", Vacuum, 25., 25., 5.); +// D->SetVisibility(kFALSE); + TGeoVolume* D = new TGeoVolumeAssembly("Dbox"); // volume for D + + TGeoBBox* Dbar1b = new TGeoBBox("trd_Dbar1b", 4., 20, 4.); + TGeoVolume *Dbar1 = new TGeoVolume("Dbar1", Dbar1b, textVolMed); + Dbar1->SetLineColor(Dcolor); + D->AddNode(Dbar1, 1, tr21); + TGeoBBox* Dbar2b = new TGeoBBox("trd_Dbar2b", 2., 4., 4.); + TGeoVolume *Dbar2 = new TGeoVolume("Dbar2", Dbar2b, textVolMed); + Dbar2->SetLineColor(Dcolor); + D->AddNode(Dbar2, 1, tr22); + D->AddNode(Dbar2, 2, tr23); + TGeoTubeSeg* Dtub1b = new TGeoTubeSeg("trd_Dtub1b", 12, 20, 4., 90., 270.); + TGeoVolume *Dtub1 = new TGeoVolume("Dtub1", (TGeoShape *) Dtub1b, textVolMed); + Dtub1->SetLineColor(Dcolor); + D->AddNode(Dtub1, 1, tr24); + +// make letter I + TGeoVolume* I = new TGeoVolumeAssembly("Ibox"); // volume for I + + TGeoBBox* Ibar1b = new TGeoBBox("trd_Ibar1b", 4., 12., 4.); // | vertical + TGeoVolume *Ibar1 = new TGeoVolume("Ibar1", Ibar1b, textVolMed); + Ibar1->SetLineColor(Icolor); + I->AddNode(Ibar1, 1, tr31); + TGeoBBox* Ibar2b = new TGeoBBox("trd_Ibar2b", 10., 4., 4.); // - top + TGeoVolume *Ibar2 = new TGeoVolume("Ibar2", Ibar2b, textVolMed); + Ibar2->SetLineColor(Icolor); + I->AddNode(Ibar2, 1, tr32); + I->AddNode(Ibar2, 2, tr33); + + +// build text block "TRD" <32> + 8 + <28> + 8 + <32> = 108 + +// TGeoBBox *trdboxb = new TGeoBBox("", 108./2, 40./2, 8./2); +// TGeoVolume *trdbox = new TGeoVolume("trdboxb", trdboxb, textVolMed); +// trdbox->SetVisibility(kFALSE); + +// TGeoVolume* trdbox[0] = new TGeoVolumeAssembly("trdbox1"); // volume for TRD text (108, 40, 8) +// TGeoVolume* trdbox[1] = new TGeoVolumeAssembly("trdbox2"); // volume for TRD text (108, 40, 8) +// TGeoVolume* trdbox[2] = new TGeoVolumeAssembly("trdbox3"); // volume for TRD text (108, 40, 8) + + TGeoTranslation *tr100 = new TGeoTranslation( 38., 0., 0.); + TGeoTranslation *tr101 = new TGeoTranslation( 0., 0., 0.); + TGeoTranslation *tr102 = new TGeoTranslation(-38., 0., 0.); + +// TGeoTranslation *tr103 = new TGeoTranslation( -70., 0., 0.); // on the same line +// TGeoTranslation *tr104 = new TGeoTranslation( -86., 0., 0.); // on the same line +// TGeoTranslation *tr105 = new TGeoTranslation(-102., 0., 0.); // on the same line + + TGeoTranslation *tr110 = new TGeoTranslation( 0., -50., 0.); + TGeoTranslation *tr111 = new TGeoTranslation( 8., -50., 0.); + TGeoTranslation *tr112 = new TGeoTranslation( -8., -50., 0.); + TGeoTranslation *tr113 = new TGeoTranslation( 16., -50., 0.); + TGeoTranslation *tr114 = new TGeoTranslation( -16., -50., 0.); + + TGeoTranslation *tr200 = new TGeoTranslation( 0., 0., 0.); + TGeoTranslation *tr201 = new TGeoTranslation( 0., -50., 0.); + TGeoTranslation *tr202 = new TGeoTranslation( 0.,-100., 0.); + + TGeoTranslation *tr210 = new TGeoTranslation( 0.,-150., 0.); + TGeoTranslation *tr213 = new TGeoTranslation( 16.,-150., 0.); + TGeoTranslation *tr214 = new TGeoTranslation( -16.,-150., 0.); + +// station 1 + trdbox1->AddNode(T, 1, tr100); + trdbox1->AddNode(R, 1, tr101); + trdbox1->AddNode(D, 1, tr102); + + trdbox1->AddNode(I, 1, tr110); + +// station 2 + trdbox2->AddNode(T, 1, tr100); + trdbox2->AddNode(R, 1, tr101); + trdbox2->AddNode(D, 1, tr102); + + trdbox2->AddNode(I, 1, tr111); + trdbox2->AddNode(I, 2, tr112); + +//// station 3 +// trdbox3->AddNode(T, 1, tr100); +// trdbox3->AddNode(R, 1, tr101); +// trdbox3->AddNode(D, 1, tr102); +// +// trdbox3->AddNode(I, 1, tr110); +// trdbox3->AddNode(I, 2, tr113); +// trdbox3->AddNode(I, 3, tr114); + +// station 3 + trdbox3->AddNode(T, 1, tr200); + trdbox3->AddNode(R, 1, tr201); + trdbox3->AddNode(D, 1, tr202); + + trdbox3->AddNode(I, 1, tr210); + trdbox3->AddNode(I, 2, tr213); + trdbox3->AddNode(I, 3, tr214); + +// TGeoScale *sc100 = new TGeoScale( 36./50., 36./50., 1.); // text is vertical 50 cm, H-bar opening is 36 cm +// +// // scale text +// TGeoHMatrix *mat100 = new TGeoHMatrix(""); +// TGeoHMatrix *mat101 = new TGeoHMatrix(""); +// TGeoHMatrix *mat102 = new TGeoHMatrix(""); +// (*mat100) = (*tr100) * (*sc100); +// (*mat101) = (*tr101) * (*sc100); +// (*mat102) = (*tr102) * (*sc100); +// +// trdbox->AddNode(T, 1, mat100); +// trdbox->AddNode(R, 1, mat101); +// trdbox->AddNode(D, 1, mat102); + +// // final placement +// // TGeoTranslation *tr103 = new TGeoTranslation(0., 400., 500.); +// gGeoMan->GetVolume(geoVersion)->AddNode(trdbox, 1, new TGeoTranslation(0., 400., 500.)); +// gGeoMan->GetVolume(geoVersion)->AddNode(trdbox, 2, new TGeoTranslation(0., 500., 600.)); +// gGeoMan->GetVolume(geoVersion)->AddNode(trdbox, 3, new TGeoTranslation(0., 600., 700.)); + +// return trdbox; + +} + + +void create_box_supports() +{ + const TString trd_01 = "support_trd1"; + TGeoVolume* trd_1 = new TGeoVolumeAssembly(trd_01); + + const TString trd_02 = "support_trd2"; + TGeoVolume* trd_2 = new TGeoVolumeAssembly(trd_02); + + const TString trd_03 = "support_trd3"; + TGeoVolume* trd_3 = new TGeoVolumeAssembly(trd_03); + +// const TString trdSupport = "supportframe"; +// TGeoVolume* trdsupport = new TGeoVolumeAssembly(trdSupport); +// +// trdsupport->AddNode(trd_1, 1); +// trdsupport->AddNode(trd_2, 2); +// trdsupport->AddNode(trd_3, 3); + + TGeoMedium* keepVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium); // define Volume Medium + + const Int_t I_height = 40; // cm // I profile properties + const Int_t I_width = 30; // cm // I profile properties + const Int_t I_thick = 2; // cm // I profile properties + + const Double_t BeamHeight = 570; // beamline is at 5.7m above the floor + const Double_t PlatformHeight = 234; // platform is 2.34m above the floor + const Double_t PlatformOffset = 1; // distance to platform + +// Double_t AperX[3] = { 450., 550., 600.}; // 100 cm modules // inner aperture in X of support structure for stations 1,2,3 +// Double_t AperY[3] = { 350., 450., 500.}; // 100 cm modules // inner aperture in Y of support structure for stations 1,2,3 + + const Double_t AperX[3] = { 4.5*DetectorSizeX[1], 5.5*DetectorSizeX[1], 6*DetectorSizeX[1] }; // inner aperture in X of support structure for stations 1,2,3 + const Double_t AperY[3] = { 3.5*DetectorSizeY[1], 4.5*DetectorSizeY[1], 5*DetectorSizeY[1] }; // inner aperture in Y of support structure for stations 1,2,3 + // platform + const Double_t AperYbot[3] = { BeamHeight-(PlatformHeight+PlatformOffset+I_height), 4.5*DetectorSizeY[1], 5*DetectorSizeY[1] }; // inner aperture for station1 + + const Double_t xBarPosYtop[3] = { AperY[0] +I_height/2., AperY[1]+I_height/2., AperY[2]+I_height/2. }; + const Double_t xBarPosYbot[3] = { AperYbot[0]+I_height/2., xBarPosYtop[1] , xBarPosYtop[2] }; + + const Double_t zBarPosYtop[3] = { AperY[0] +I_height-I_width/2., AperY[1]+I_height-I_width/2., AperY[2]+I_height-I_width/2. }; + const Double_t zBarPosYbot[3] = { AperYbot[0]+I_height-I_width/2., zBarPosYtop[1] , zBarPosYtop[2] }; + + Double_t PilPosX; + Double_t PilPosZ[6]; // PilPosZ + + PilPosZ[0] = LayerPosition[0] + I_width/2.; + PilPosZ[1] = LayerPosition[3] - I_width/2. + LayerThickness; + PilPosZ[2] = LayerPosition[4] + I_width/2.; + PilPosZ[3] = LayerPosition[7] - I_width/2. + LayerThickness; + PilPosZ[4] = LayerPosition[8] + I_width/2.; + PilPosZ[5] = LayerPosition[9] - I_width/2. + LayerThickness; + +// cout << "PilPosZ[0]: " << PilPosZ[0] << endl; +// cout << "PilPosZ[1]: " << PilPosZ[1] << endl; + + TGeoRotation *rotx090 = new TGeoRotation("rotx090"); rotx090->RotateX( 90.); // rotate 90 deg around x-axis + TGeoRotation *roty090 = new TGeoRotation("roty090"); roty090->RotateY( 90.); // rotate 90 deg around y-axis + TGeoRotation *rotz090 = new TGeoRotation("rotz090"); rotz090->RotateZ( 90.); // rotate 90 deg around y-axis + TGeoRotation *roty270 = new TGeoRotation("roty270"); roty270->RotateY(270.); // rotate 270 deg around y-axis + + TGeoRotation *rotzx01 = new TGeoRotation("rotzx01"); + rotzx01->RotateZ( 90.); // rotate 90 deg around z-axis + rotzx01->RotateX( 90.); // rotate 90 deg around x-axis + + TGeoRotation *rotzx02 = new TGeoRotation("rotzx02"); + rotzx02->RotateZ( 270.); // rotate 270 deg around z-axis + rotzx02->RotateX( 90.); // rotate 90 deg around x-axis + + Double_t ang1 = atan(3./4.) * 180. / acos(-1.); + // cout << "DEDE " << ang1 << endl; + // Double_t sin1 = acos(-1.); + // cout << "DEDE " << sin1 << endl; + TGeoRotation *rotx080 = new TGeoRotation("rotx080"); rotx080->RotateX( 90.-ang1); // rotate 80 deg around x-axis + TGeoRotation *rotx100 = new TGeoRotation("rotx100"); rotx100->RotateX( 90.+ang1); // rotate 100 deg around x-axis + + TGeoRotation *rotxy01 = new TGeoRotation("rotxy01"); + rotxy01->RotateX( 90.); // rotate 90 deg around x-axis + rotxy01->RotateZ(-ang1); // rotate ang1 around rotated y-axis + + TGeoRotation *rotxy02 = new TGeoRotation("rotxy02"); + rotxy02->RotateX( 90.); // rotate 90 deg around x-axis + rotxy02->RotateZ( ang1); // rotate ang1 around rotated y-axis + + +//------------------- +// vertical pillars (Y) +//------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { +// TGeoBBox* trd_I_vert1_keep = new TGeoBBox("", I_thick /2., I_height /2. - I_thick, (BeamHeight + (AperY[0]+I_height) ) /2.); + TGeoBBox* trd_I_vert1_keep = new TGeoBBox("trd_I_vert1_keep", I_thick /2., I_height /2. - I_thick, ( (AperYbot[0]+I_height) + (AperY[0]+I_height) ) /2.); + TGeoVolume* trd_I_vert1 = new TGeoVolume("trd_I_y11", trd_I_vert1_keep, aluminiumVolMed); + // TGeoBBox* trd_I_vert2_keep = new TGeoBBox("", I_width /2., I_thick /2., (BeamHeight + (AperY[0]+I_height) ) /2.); + TGeoBBox* trd_I_vert2_keep = new TGeoBBox("trd_I_vert2_keep", I_width /2., I_thick /2., ( (AperYbot[0]+I_height) + (AperY[0]+I_height) ) /2.); + TGeoVolume* trd_I_vert2 = new TGeoVolume("trd_I_y12", trd_I_vert2_keep, aluminiumVolMed); + + trd_I_vert1->SetLineColor(kGreen); // kBlue); // Yellow); // kOrange); + trd_I_vert2->SetLineColor(kGreen); // kBlue); // Yellow); // kOrange); + + TGeoTranslation *ty01 = new TGeoTranslation("ty01", 0., 0., 0.); + TGeoTranslation *ty02 = new TGeoTranslation("ty02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *ty03 = new TGeoTranslation("ty03", 0., -(I_height-I_thick) /2., 0.); + + // TGeoBBox* trd_I_vert_vol1_keep = new TGeoBBox("", I_width /2., I_height /2., (BeamHeight + (AperY[0]+I_height) ) /2.); + TGeoBBox* trd_I_vert_vol1_keep = new TGeoBBox("trd_I_vert_vol1_keep", I_width /2., I_height /2., ( (AperYbot[0]+I_height) + (AperY[0]+I_height) ) /2.); + TGeoVolume* trd_I_vert_vol1 = new TGeoVolume("trd_I_y10", trd_I_vert_vol1_keep, keepVolMed); + + // set green color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_vert_vol1->SetLineColor(kGreen); + + // build I-bar trd_I_vert_vol1 + trd_I_vert_vol1->AddNode(trd_I_vert1, 1, ty01); + trd_I_vert_vol1->AddNode(trd_I_vert2, 2, ty02); + trd_I_vert_vol1->AddNode(trd_I_vert2, 3, ty03); + + // close gap to horizontal z-bars + TGeoBBox* trd_I_vert3_keep = new TGeoBBox("trd_I_vert3_keep", (I_width-I_thick)/2. /2., I_height /2. - I_thick, I_thick /2.); + TGeoVolume* trd_I_vert3 = new TGeoVolume("trd_I_y13", trd_I_vert3_keep, aluminiumVolMed); + trd_I_vert3->SetLineColor(kGreen); +// TGeoTranslation *ty04 = new TGeoTranslation("ty04", (I_thick/2. + (I_width-I_thick)/2./2.), 0., -( (AperYbot[0]+I_height) + (AperY[0]+I_height) - I_width) /2.); // top +// TGeoTranslation *ty05 = new TGeoTranslation("ty05", (I_thick/2. + (I_width-I_thick)/2./2.), 0., ( (AperYbot[0]+I_height) + (AperY[0]+I_height) - I_width) /2.); // bottom + TGeoTranslation *ty04 = new TGeoTranslation("ty04", (I_thick/2. + (I_width-I_thick)/2./2.), 0., -( zBarPosYbot[0] + zBarPosYtop[0] )/2. ); // top + TGeoTranslation *ty05 = new TGeoTranslation("ty05", (I_thick/2. + (I_width-I_thick)/2./2.), 0., ( zBarPosYbot[0] + zBarPosYtop[0] )/2. ); // bottom + trd_I_vert_vol1->AddNode(trd_I_vert3, 4, ty04); + trd_I_vert_vol1->AddNode(trd_I_vert3, 5, ty05); + + PilPosX = AperX[0]; + + TGeoCombiTrans* trd_I_vert_combi01 = new TGeoCombiTrans( (PilPosX+I_height/2.), -( (AperYbot[0]+I_height) - (AperY[0]+I_height))/2., PilPosZ[0], rotzx01); + trd_1->AddNode(trd_I_vert_vol1, 11, trd_I_vert_combi01); + TGeoCombiTrans* trd_I_vert_combi02 = new TGeoCombiTrans(-(PilPosX+I_height/2.), -( (AperYbot[0]+I_height) - (AperY[0]+I_height))/2., PilPosZ[0], rotzx01); + trd_1->AddNode(trd_I_vert_vol1, 12, trd_I_vert_combi02); + TGeoCombiTrans* trd_I_vert_combi03 = new TGeoCombiTrans( (PilPosX+I_height/2.), -( (AperYbot[0]+I_height) - (AperY[0]+I_height))/2., PilPosZ[1], rotzx02); + trd_1->AddNode(trd_I_vert_vol1, 13, trd_I_vert_combi03); + TGeoCombiTrans* trd_I_vert_combi04 = new TGeoCombiTrans(-(PilPosX+I_height/2.), -( (AperYbot[0]+I_height) - (AperY[0]+I_height))/2., PilPosZ[1], rotzx02); + trd_1->AddNode(trd_I_vert_vol1, 14, trd_I_vert_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoBBox* trd_I_vert1_keep = new TGeoBBox("trd_I_vert1_keep", I_thick /2., I_height /2. - I_thick, (BeamHeight + (AperY[1]+I_height) ) /2.); + TGeoVolume* trd_I_vert1 = new TGeoVolume("trd_I_y21", trd_I_vert1_keep, aluminiumVolMed); + TGeoBBox* trd_I_vert2_keep = new TGeoBBox("trd_I_vert2_keep", I_width /2., I_thick /2., (BeamHeight + (AperY[1]+I_height) ) /2.); + TGeoVolume* trd_I_vert2 = new TGeoVolume("trd_I_y22", trd_I_vert2_keep, aluminiumVolMed); + + trd_I_vert1->SetLineColor(kGreen); + trd_I_vert2->SetLineColor(kGreen); + + TGeoTranslation *ty01 = new TGeoTranslation("ty01", 0., 0., 0.); + TGeoTranslation *ty02 = new TGeoTranslation("ty02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *ty03 = new TGeoTranslation("ty03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_vert_vol1_keep = new TGeoBBox("trd_I_vert_vol1_keep", I_width /2., I_height /2., (BeamHeight + (AperY[1]+I_height) ) /2.); + TGeoVolume* trd_I_vert_vol1 = new TGeoVolume("trd_I_y20", trd_I_vert_vol1_keep, keepVolMed); + + // set green color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_vert_vol1->SetLineColor(kGreen); + + // build I-bar trd_I_vert_vol1 + trd_I_vert_vol1->AddNode(trd_I_vert1, 1, ty01); + trd_I_vert_vol1->AddNode(trd_I_vert2, 2, ty02); + trd_I_vert_vol1->AddNode(trd_I_vert2, 3, ty03); + + // close gap to horizontal z-bars + TGeoBBox* trd_I_vert3_keep = new TGeoBBox("trd_I_vert3_keep", (I_width-I_thick)/2. /2., I_height /2. - I_thick, I_thick /2.); + TGeoVolume* trd_I_vert3 = new TGeoVolume("trd_I_y23", trd_I_vert3_keep, aluminiumVolMed); + trd_I_vert3->SetLineColor(kGreen); + TGeoTranslation *ty04 = new TGeoTranslation("ty04", (I_thick/2. + (I_width-I_thick)/2./2.), 0., -(BeamHeight + (AperY[1]+I_height) - I_width) /2.); // top + TGeoTranslation *ty05 = new TGeoTranslation("ty05", (I_thick/2. + (I_width-I_thick)/2./2.), 0., -(BeamHeight - (AperY[1]+I_height) )/2. + zBarPosYbot[1] ); // bottom + trd_I_vert_vol1->AddNode(trd_I_vert3, 4, ty04); + trd_I_vert_vol1->AddNode(trd_I_vert3, 5, ty05); + + PilPosX = AperX[1]; + + TGeoCombiTrans* trd_I_vert_combi01 = new TGeoCombiTrans( (PilPosX+I_height/2.), -(BeamHeight - (AperY[1]+I_height))/2., PilPosZ[2], rotzx01); + trd_2->AddNode(trd_I_vert_vol1, 21, trd_I_vert_combi01); + TGeoCombiTrans* trd_I_vert_combi02 = new TGeoCombiTrans(-(PilPosX+I_height/2.), -(BeamHeight - (AperY[1]+I_height))/2., PilPosZ[2], rotzx01); + trd_2->AddNode(trd_I_vert_vol1, 22, trd_I_vert_combi02); + TGeoCombiTrans* trd_I_vert_combi03 = new TGeoCombiTrans( (PilPosX+I_height/2.), -(BeamHeight - (AperY[1]+I_height))/2., PilPosZ[3], rotzx02); + trd_2->AddNode(trd_I_vert_vol1, 23, trd_I_vert_combi03); + TGeoCombiTrans* trd_I_vert_combi04 = new TGeoCombiTrans(-(PilPosX+I_height/2.), -(BeamHeight - (AperY[1]+I_height))/2., PilPosZ[3], rotzx02); + trd_2->AddNode(trd_I_vert_vol1, 24, trd_I_vert_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoBBox* trd_I_vert1_keep = new TGeoBBox("trd_I_vert1_keep", I_thick /2., I_height /2. - I_thick, (BeamHeight + (AperY[2]+I_height) ) /2.); + TGeoVolume* trd_I_vert1 = new TGeoVolume("trd_I_y31", trd_I_vert1_keep, aluminiumVolMed); + TGeoBBox* trd_I_vert2_keep = new TGeoBBox("trd_I_vert2_keep", I_width /2., I_thick /2., (BeamHeight + (AperY[2]+I_height) ) /2.); + TGeoVolume* trd_I_vert2 = new TGeoVolume("trd_I_y32", trd_I_vert2_keep, aluminiumVolMed); + + trd_I_vert1->SetLineColor(kGreen); + trd_I_vert2->SetLineColor(kGreen); + + TGeoTranslation *ty01 = new TGeoTranslation("ty01", 0., 0., 0.); + TGeoTranslation *ty02 = new TGeoTranslation("ty02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *ty03 = new TGeoTranslation("ty03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_vert_vol1_keep = new TGeoBBox("trd_I_vert_vol1_keep", I_width /2., I_height /2., (BeamHeight + (AperY[2]+I_height) ) /2.); + TGeoVolume* trd_I_vert_vol1 = new TGeoVolume("trd_I_y30", trd_I_vert_vol1_keep, keepVolMed); + + // set green color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_vert_vol1->SetLineColor(kGreen); + + // build I-bar trd_I_vert_vol1 + trd_I_vert_vol1->AddNode(trd_I_vert1, 1, ty01); + trd_I_vert_vol1->AddNode(trd_I_vert2, 2, ty02); + trd_I_vert_vol1->AddNode(trd_I_vert2, 3, ty03); + + // close gap to horizontal z-bars + TGeoBBox* trd_I_vert3_keep = new TGeoBBox("trd_I_vert3_keep", (I_width-I_thick)/2. /2., I_height /2. - I_thick, I_thick /2.); + TGeoVolume* trd_I_vert3 = new TGeoVolume("trd_I_y33", trd_I_vert3_keep, aluminiumVolMed); + trd_I_vert3->SetLineColor(kGreen); + TGeoTranslation *ty04 = new TGeoTranslation("ty04", (I_thick/2. + (I_width-I_thick)/2./2.), 0., -(BeamHeight + (AperY[2]+I_height) - I_width) /2.); // top + TGeoTranslation *ty05 = new TGeoTranslation("ty05", (I_thick/2. + (I_width-I_thick)/2./2.), 0., -(BeamHeight - (AperY[2]+I_height) )/2. + zBarPosYbot[2] ); // bottom + trd_I_vert_vol1->AddNode(trd_I_vert3, 4, ty04); + trd_I_vert_vol1->AddNode(trd_I_vert3, 5, ty05); + + PilPosX = AperX[2]; + + TGeoCombiTrans* trd_I_vert_combi01 = new TGeoCombiTrans( (PilPosX+I_height/2.), -(BeamHeight - (AperY[2]+I_height))/2., PilPosZ[4], rotzx01); + trd_3->AddNode(trd_I_vert_vol1, 31, trd_I_vert_combi01); + TGeoCombiTrans* trd_I_vert_combi02 = new TGeoCombiTrans(-(PilPosX+I_height/2.), -(BeamHeight - (AperY[2]+I_height))/2., PilPosZ[4], rotzx01); + trd_3->AddNode(trd_I_vert_vol1, 32, trd_I_vert_combi02); + TGeoCombiTrans* trd_I_vert_combi03 = new TGeoCombiTrans( (PilPosX+I_height/2.), -(BeamHeight - (AperY[2]+I_height))/2., PilPosZ[5], rotzx02); + trd_3->AddNode(trd_I_vert_vol1, 33, trd_I_vert_combi03); + TGeoCombiTrans* trd_I_vert_combi04 = new TGeoCombiTrans(-(PilPosX+I_height/2.), -(BeamHeight - (AperY[2]+I_height))/2., PilPosZ[5], rotzx02); + trd_3->AddNode(trd_I_vert_vol1, 34, trd_I_vert_combi04); + } + + +//------------------- +// horizontal supports (X) +//------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + TGeoBBox* trd_I_hori1_keep = new TGeoBBox("trd_I_hori1_keep", I_thick /2., I_height /2. - I_thick, AperX[0]); + TGeoVolume* trd_I_hori1 = new TGeoVolume("trd_I_x11", trd_I_hori1_keep, aluminiumVolMed); + TGeoBBox* trd_I_hori2_keep = new TGeoBBox("trd_I_hori2_keep", I_width /2., I_thick /2., AperX[0]); + TGeoVolume* trd_I_hori2 = new TGeoVolume("trd_I_x12", trd_I_hori2_keep, aluminiumVolMed); + + trd_I_hori1->SetLineColor(kRed); // Yellow); + trd_I_hori2->SetLineColor(kRed); // Yellow); + + TGeoTranslation *tx01 = new TGeoTranslation("tx01", 0., 0., 0.); + TGeoTranslation *tx02 = new TGeoTranslation("tx02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *tx03 = new TGeoTranslation("tx03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_hori_vol1_keep = new TGeoBBox("trd_I_hori_vol1_keep", I_width /2., I_height /2., AperX[0]); + TGeoVolume* trd_I_hori_vol1 = new TGeoVolume("trd_I_x10", trd_I_hori_vol1_keep, keepVolMed); + + // set red color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_hori_vol1->SetLineColor(kRed); + + // build I-bar trd_I_hori_vol1 + trd_I_hori_vol1->AddNode(trd_I_hori1, 1, tx01); + trd_I_hori_vol1->AddNode(trd_I_hori2, 2, tx02); + trd_I_hori_vol1->AddNode(trd_I_hori2, 3, tx03); + + TGeoCombiTrans* trd_I_hori_combi01 = new TGeoCombiTrans(0., xBarPosYtop[0], PilPosZ[0], roty090); + trd_1->AddNode(trd_I_hori_vol1, 11, trd_I_hori_combi01); + TGeoCombiTrans* trd_I_hori_combi02 = new TGeoCombiTrans(0.,-xBarPosYbot[0], PilPosZ[0], roty090); + trd_1->AddNode(trd_I_hori_vol1, 12, trd_I_hori_combi02); + TGeoCombiTrans* trd_I_hori_combi03 = new TGeoCombiTrans(0., xBarPosYtop[0], PilPosZ[1], roty090); + trd_1->AddNode(trd_I_hori_vol1, 13, trd_I_hori_combi03); + TGeoCombiTrans* trd_I_hori_combi04 = new TGeoCombiTrans(0.,-xBarPosYbot[0], PilPosZ[1], roty090); + trd_1->AddNode(trd_I_hori_vol1, 14, trd_I_hori_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoBBox* trd_I_hori1_keep = new TGeoBBox("trd_I_hori1_keep", I_thick /2., I_height /2. - I_thick, AperX[1]); + TGeoVolume* trd_I_hori1 = new TGeoVolume("trd_I_x21", trd_I_hori1_keep, aluminiumVolMed); + TGeoBBox* trd_I_hori2_keep = new TGeoBBox("trd_I_hori2_keep", I_width /2., I_thick /2., AperX[1]); + TGeoVolume* trd_I_hori2 = new TGeoVolume("trd_I_x22", trd_I_hori2_keep, aluminiumVolMed); + + trd_I_hori1->SetLineColor(kRed); + trd_I_hori2->SetLineColor(kRed); + + TGeoTranslation *tx01 = new TGeoTranslation("tx01", 0., 0., 0.); + TGeoTranslation *tx02 = new TGeoTranslation("tx02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *tx03 = new TGeoTranslation("tx03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_hori_vol1_keep = new TGeoBBox("trd_I_hori_vol1_keep", I_width /2., I_height /2., AperX[1]); + TGeoVolume* trd_I_hori_vol1 = new TGeoVolume("trd_I_x20", trd_I_hori_vol1_keep, keepVolMed); + + // set red color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_hori_vol1->SetLineColor(kRed); + + // build I-bar trd_I_hori_vol1 + trd_I_hori_vol1->AddNode(trd_I_hori1, 1, tx01); + trd_I_hori_vol1->AddNode(trd_I_hori2, 2, tx02); + trd_I_hori_vol1->AddNode(trd_I_hori2, 3, tx03); + + TGeoCombiTrans* trd_I_hori_combi01 = new TGeoCombiTrans(0., xBarPosYtop[1], PilPosZ[2], roty090); + trd_2->AddNode(trd_I_hori_vol1, 21, trd_I_hori_combi01); + TGeoCombiTrans* trd_I_hori_combi02 = new TGeoCombiTrans(0.,-xBarPosYbot[1], PilPosZ[2], roty090); + trd_2->AddNode(trd_I_hori_vol1, 22, trd_I_hori_combi02); + TGeoCombiTrans* trd_I_hori_combi03 = new TGeoCombiTrans(0., xBarPosYtop[1], PilPosZ[3], roty090); + trd_2->AddNode(trd_I_hori_vol1, 23, trd_I_hori_combi03); + TGeoCombiTrans* trd_I_hori_combi04 = new TGeoCombiTrans(0.,-xBarPosYbot[1], PilPosZ[3], roty090); + trd_2->AddNode(trd_I_hori_vol1, 24, trd_I_hori_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoBBox* trd_I_hori1_keep = new TGeoBBox("trd_I_hori1_keep", I_thick /2., I_height /2. - I_thick, AperX[2]); + TGeoVolume* trd_I_hori1 = new TGeoVolume("trd_I_x31", trd_I_hori1_keep, aluminiumVolMed); + TGeoBBox* trd_I_hori2_keep = new TGeoBBox("trd_I_hori2_keep", I_width /2., I_thick /2., AperX[2]); + TGeoVolume* trd_I_hori2 = new TGeoVolume("trd_I_x32", trd_I_hori2_keep, aluminiumVolMed); + + trd_I_hori1->SetLineColor(kRed); + trd_I_hori2->SetLineColor(kRed); + + TGeoTranslation *tx01 = new TGeoTranslation("tx01", 0., 0., 0.); + TGeoTranslation *tx02 = new TGeoTranslation("tx02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *tx03 = new TGeoTranslation("tx03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_hori_vol1_keep = new TGeoBBox("trd_I_hori_vol1_keep", I_width /2., I_height /2., AperX[2]); + TGeoVolume* trd_I_hori_vol1 = new TGeoVolume("trd_I_x30", trd_I_hori_vol1_keep, keepVolMed); + + // set red color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_hori_vol1->SetLineColor(kRed); + + // build I-bar trd_I_hori_vol1 + trd_I_hori_vol1->AddNode(trd_I_hori1, 1, tx01); + trd_I_hori_vol1->AddNode(trd_I_hori2, 2, tx02); + trd_I_hori_vol1->AddNode(trd_I_hori2, 3, tx03); + + TGeoCombiTrans* trd_I_hori_combi01 = new TGeoCombiTrans(0., xBarPosYtop[2], PilPosZ[4], roty090); + trd_3->AddNode(trd_I_hori_vol1, 31, trd_I_hori_combi01); + TGeoCombiTrans* trd_I_hori_combi02 = new TGeoCombiTrans(0.,-xBarPosYbot[2], PilPosZ[4], roty090); + trd_3->AddNode(trd_I_hori_vol1, 32, trd_I_hori_combi02); + TGeoCombiTrans* trd_I_hori_combi03 = new TGeoCombiTrans(0., xBarPosYtop[2], PilPosZ[5], roty090); + trd_3->AddNode(trd_I_hori_vol1, 33, trd_I_hori_combi03); + TGeoCombiTrans* trd_I_hori_combi04 = new TGeoCombiTrans(0.,-xBarPosYbot[2], PilPosZ[5], roty090); + trd_3->AddNode(trd_I_hori_vol1, 34, trd_I_hori_combi04); + } + + +//------------------- +// horizontal supports (Z) +//------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + TGeoBBox* trd_I_slope1_keep = new TGeoBBox("trd_I_slope1_keep", I_thick /2., I_height /2. - I_thick, (PilPosZ[1]-PilPosZ[0]-I_width)/2.); + TGeoVolume* trd_I_slope1 = new TGeoVolume("trd_I_z11", trd_I_slope1_keep, aluminiumVolMed); + TGeoBBox* trd_I_slope2_keep = new TGeoBBox("trd_I_slope2_keep", I_width /2., I_thick /2., (PilPosZ[1]-PilPosZ[0]-I_width)/2.); + TGeoVolume* trd_I_slope2 = new TGeoVolume("trd_I_z12", trd_I_slope2_keep, aluminiumVolMed); + + trd_I_slope1->SetLineColor(kYellow); + trd_I_slope2->SetLineColor(kYellow); + + TGeoTranslation *tz01 = new TGeoTranslation("tz01", 0., 0., 0.); + TGeoTranslation *tz02 = new TGeoTranslation("tz02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *tz03 = new TGeoTranslation("tz03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_slope_vol1_keep = new TGeoBBox("trd_I_slope_vol1_keep", I_width /2., I_height /2., (PilPosZ[1]-PilPosZ[0]-I_width)/2.); + TGeoVolume* trd_I_slope_vol1 = new TGeoVolume("trd_I_z10", trd_I_slope_vol1_keep, keepVolMed); + + // set yellow color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_slope_vol1->SetLineColor(kYellow); + + // build I-bar trd_I_slope_vol1 + trd_I_slope_vol1->AddNode(trd_I_slope1, 1, tz01); + trd_I_slope_vol1->AddNode(trd_I_slope2, 2, tz02); + trd_I_slope_vol1->AddNode(trd_I_slope2, 3, tz03); + + PilPosX = AperX[0]; + + TGeoCombiTrans* trd_I_slope_combi01 = new TGeoCombiTrans( (PilPosX+I_height/2.), zBarPosYtop[0], (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_I_slope_vol1, 11, trd_I_slope_combi01); + TGeoCombiTrans* trd_I_slope_combi02 = new TGeoCombiTrans(-(PilPosX+I_height/2.), zBarPosYtop[0], (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_I_slope_vol1, 12, trd_I_slope_combi02); + TGeoCombiTrans* trd_I_slope_combi03 = new TGeoCombiTrans( (PilPosX+I_height/2.),-zBarPosYbot[0], (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_I_slope_vol1, 13, trd_I_slope_combi03); + TGeoCombiTrans* trd_I_slope_combi04 = new TGeoCombiTrans(-(PilPosX+I_height/2.),-zBarPosYbot[0], (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_I_slope_vol1, 14, trd_I_slope_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoBBox* trd_I_slope1_keep = new TGeoBBox("trd_I_slope1_keep", I_thick /2., I_height /2. - I_thick, (PilPosZ[3]-PilPosZ[2]-I_width)/2.); + TGeoVolume* trd_I_slope1 = new TGeoVolume("trd_I_z21", trd_I_slope1_keep, aluminiumVolMed); + TGeoBBox* trd_I_slope2_keep = new TGeoBBox("trd_I_slope2_keep", I_width /2., I_thick /2., (PilPosZ[3]-PilPosZ[2]-I_width)/2.); + TGeoVolume* trd_I_slope2 = new TGeoVolume("trd_I_z22", trd_I_slope2_keep, aluminiumVolMed); + + trd_I_slope1->SetLineColor(kYellow); + trd_I_slope2->SetLineColor(kYellow); + + TGeoTranslation *tz01 = new TGeoTranslation("tz01", 0., 0., 0.); + TGeoTranslation *tz02 = new TGeoTranslation("tz02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *tz03 = new TGeoTranslation("tz03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_slope_vol1_keep = new TGeoBBox("trd_I_slope_vol1_keep", I_width /2., I_height /2., (PilPosZ[3]-PilPosZ[2]-I_width)/2.); + TGeoVolume* trd_I_slope_vol1 = new TGeoVolume("trd_I_z20", trd_I_slope_vol1_keep, keepVolMed); + + // set yellow color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_slope_vol1->SetLineColor(kYellow); + + // build I-bar trd_I_slope_vol1 + trd_I_slope_vol1->AddNode(trd_I_slope1, 1, tz01); + trd_I_slope_vol1->AddNode(trd_I_slope2, 2, tz02); + trd_I_slope_vol1->AddNode(trd_I_slope2, 3, tz03); + + PilPosX = AperX[1]; + + TGeoCombiTrans* trd_I_slope_combi01 = new TGeoCombiTrans( (PilPosX+I_height/2.), zBarPosYtop[1], (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_I_slope_vol1, 21, trd_I_slope_combi01); + TGeoCombiTrans* trd_I_slope_combi02 = new TGeoCombiTrans(-(PilPosX+I_height/2.), zBarPosYtop[1], (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_I_slope_vol1, 22, trd_I_slope_combi02); + TGeoCombiTrans* trd_I_slope_combi03 = new TGeoCombiTrans( (PilPosX+I_height/2.),-zBarPosYbot[1], (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_I_slope_vol1, 23, trd_I_slope_combi03); + TGeoCombiTrans* trd_I_slope_combi04 = new TGeoCombiTrans(-(PilPosX+I_height/2.),-zBarPosYbot[1], (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_I_slope_vol1, 24, trd_I_slope_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoBBox* trd_I_slope1_keep = new TGeoBBox("trd_I_slope1_keep", I_thick /2., I_height /2. - I_thick, (PilPosZ[5]-PilPosZ[4]-I_width)/2.); + TGeoVolume* trd_I_slope1 = new TGeoVolume("trd_I_z31", trd_I_slope1_keep, aluminiumVolMed); + TGeoBBox* trd_I_slope2_keep = new TGeoBBox("trd_I_slope2_keep", I_width /2., I_thick /2., (PilPosZ[5]-PilPosZ[4]-I_width)/2.); + TGeoVolume* trd_I_slope2 = new TGeoVolume("trd_I_z32", trd_I_slope2_keep, aluminiumVolMed); + + trd_I_slope1->SetLineColor(kYellow); + trd_I_slope2->SetLineColor(kYellow); + + TGeoTranslation *tz01 = new TGeoTranslation("tz01", 0., 0., 0.); + TGeoTranslation *tz02 = new TGeoTranslation("tz02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *tz03 = new TGeoTranslation("tz03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_slope_vol1_keep = new TGeoBBox("trd_I_slope_vol1_keep", I_width /2., I_height /2., (PilPosZ[5]-PilPosZ[4]-I_width)/2.); + TGeoVolume* trd_I_slope_vol1 = new TGeoVolume("trd_I_z30", trd_I_slope_vol1_keep, keepVolMed); + + // set yellow color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_slope_vol1->SetLineColor(kYellow); + + // build I-bar trd_I_slope_vol1 + trd_I_slope_vol1->AddNode(trd_I_slope1, 1, tz01); + trd_I_slope_vol1->AddNode(trd_I_slope2, 2, tz02); + trd_I_slope_vol1->AddNode(trd_I_slope2, 3, tz03); + + PilPosX = AperX[2]; + + TGeoCombiTrans* trd_I_slope_combi01 = new TGeoCombiTrans( (PilPosX+I_height/2.), zBarPosYtop[2], (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_I_slope_vol1, 31, trd_I_slope_combi01); + TGeoCombiTrans* trd_I_slope_combi02 = new TGeoCombiTrans(-(PilPosX+I_height/2.), zBarPosYtop[2], (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_I_slope_vol1, 32, trd_I_slope_combi02); + TGeoCombiTrans* trd_I_slope_combi03 = new TGeoCombiTrans( (PilPosX+I_height/2.),-zBarPosYbot[2], (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_I_slope_vol1, 33, trd_I_slope_combi03); + TGeoCombiTrans* trd_I_slope_combi04 = new TGeoCombiTrans(-(PilPosX+I_height/2.),-zBarPosYbot[2], (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_I_slope_vol1, 34, trd_I_slope_combi04); + } + + if (IncludeLabels) + { + + Int_t text_height = 40; + Int_t text_thickness = 8; + + TGeoTranslation *tr200 = new TGeoTranslation(0., (AperY[0]+I_height+ text_height/2.), PilPosZ[0]-I_width/2.+ text_thickness/2.); + TGeoTranslation *tr201 = new TGeoTranslation(0., (AperY[1]+I_height+ text_height/2.), PilPosZ[2]-I_width/2.+ text_thickness/2.); + TGeoTranslation *tr202 = new TGeoTranslation(0., (AperY[2]+I_height+ text_height/2.), PilPosZ[4]-I_width/2.+ text_thickness/2.); + + TGeoCombiTrans *tr203 = new TGeoCombiTrans(-(AperX[0]+I_height+ text_thickness/2.), (AperY[0]+I_height-I_width-text_height/2.), (PilPosZ[0]+PilPosZ[1])/2., roty090); + TGeoCombiTrans *tr204 = new TGeoCombiTrans(-(AperX[1]+I_height+ text_thickness/2.), (AperY[1]+I_height-I_width-text_height/2.), (PilPosZ[2]+PilPosZ[3])/2., roty090); + TGeoCombiTrans *tr205 = new TGeoCombiTrans(-(AperX[2]+I_height+ text_thickness/2.), (AperY[2]+I_height-I_width-text_height/2.), (PilPosZ[4]+PilPosZ[5])/2., roty090); + + TGeoCombiTrans *tr206 = new TGeoCombiTrans( (AperX[0]+I_height+ text_thickness/2.), (AperY[0]+I_height-I_width-text_height/2.), (PilPosZ[0]+PilPosZ[1])/2., roty270); + TGeoCombiTrans *tr207 = new TGeoCombiTrans( (AperX[1]+I_height+ text_thickness/2.), (AperY[1]+I_height-I_width-text_height/2.), (PilPosZ[2]+PilPosZ[3])/2., roty270); + TGeoCombiTrans *tr208 = new TGeoCombiTrans( (AperX[2]+I_height+ text_thickness/2.), (AperY[2]+I_height-I_width-text_height/2.), (PilPosZ[4]+PilPosZ[5])/2., roty270); + + TGeoVolume* trdbox1 = new TGeoVolumeAssembly("trdbox1"); // volume for TRD text (108, 40, 8) + TGeoVolume* trdbox2 = new TGeoVolumeAssembly("trdbox2"); // volume for TRD text (108, 40, 8) + TGeoVolume* trdbox3 = new TGeoVolumeAssembly("trdbox3"); // volume for TRD text (108, 40, 8) + add_trd_labels(trdbox1, trdbox2, trdbox3); + + // final placement + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + // trd_1->AddNode(trdbox1, 1, tr200); + trd_1->AddNode(trdbox1, 4, tr203); + trd_1->AddNode(trdbox1, 7, tr206); + } + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + // trd_2->AddNode(trdbox2, 2, tr201); + trd_2->AddNode(trdbox2, 5, tr204); + trd_2->AddNode(trdbox2, 8, tr207); + } + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + // trd_3->AddNode(trdbox3, 3, tr202); + trd_3->AddNode(trdbox3, 6, tr205); + trd_3->AddNode(trdbox3, 9, tr208); + } + } + + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_1, 1); + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_2, 2); + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_3, 3); + +} + diff --git a/macro/mcbm/geometry/trd/Create_TRD_Geometry_v20b.C b/macro/mcbm/geometry/trd/Create_TRD_Geometry_v20b.C new file mode 100644 index 00000000..390bb0e4 --- /dev/null +++ b/macro/mcbm/geometry/trd/Create_TRD_Geometry_v20b.C @@ -0,0 +1,4117 @@ +/// +/// \file Create_TRD_Geometry_v20b.C +/// \brief Generates TRD geometry in Root format. +/// + +// 2020-05-25 - DE - v20b - based on v20a, use 2 TRD modules for 2021 setup +// 2020-05-23 - DE - v20a - add support structure to TRD v18q, realign module in x +// 2018-08-24 - DE - v18q - use only 1st 2 layers of TRD in 2018 setup +// 2017-11-22 - DE - v18n - do not generate mBUCH at z=125 cm, only mTRD +// 2017-11-22 - DE - v18m - mBUCH at z=125 cm, mTRD at z=149, 171, 193 and 215 cm - layer pitch 22 cm from CAD +// 2017-11-03 - DE - v18l - shift mTRD to z=140 cm for acceptance matching with mSTS (= same result as v18g) +// 2017-11-03 - DE - v18k - plot 4 mTRD modules first, then mBUCH to simplyfy the realignment in x (= same result as v18j) +// 2017-11-02 - DE - v18j - move Muenster TRD modules back to original positions in x (fix bug in v18i) +// 2017-10-17 - DE - v18i - add Bucharest 60x60 cm2 Bucharest TRD module with FASP ASICs +// 2017-05-16 - DE - v18e - re-align all TRD modules to same theta angle using left side of 4th TRD module as reference +// 2017-05-02 - DE - v18a - re-base miniTRD v18e on CBM TRD v17a +// 2017-04-28 - DE - v17 - implement power bus bars as defined in the TDR +// 2017-04-26 - DE - v17 - add aluminium ledge around backpanel +// 2017-01-10 - DE - v17a_3e - replace 6 ultimate density by 9 super density FEBs for TRD type 1 modules +// 2016-07-05 - FU - v16a_3e - identical to v15a, change the way the trd volume is exported to resolve a bug with TGeoShape destructor +// 2015-01-08 - DE - v15a_3e - reduce frame thickness in large modules to 15 mm instead of 20 mm +// 2014-06-25 - DE - v14a_3e - consists of only 3 small and 3 large modules types (was 4+4 before) +// 2014-06-25 - DE - v14a_3e - inner part of all 3 stations is now identical +// 2014-05-02 - DE - v14a_3e - redesign inner part of station 3, now with 5x5-1 small modules, like in station 1 and station 2 +// 2014-05-02 - DE - v14a_3e - include optional GBTX readout boards on each module +// 2014-05-02 - DE - v14a_3e - introduce 3x5=15 Spadic FEBs for ultimate density on module type 1 +// +// 2013-11-14 - DE - v13q_3e - generate information about pad plane layout (CbmTrdPads_v14a.h) for all module types in this macro +// +// 2013-11-04 - DE - v13p4 - adapt the number of front-end boards to the pad layout of the 540 mm modules +// 2013-11-04 - DE - v13p4 - use 8 module types (4x S + 4x L) to better match the occupancy +// 2013-10-31 - DE - v13p4 - modify the support structure of station 1 to match with the MUCH/RICH platform +// 2013-10-29 - DE - v13p4 - build lattice grid as TGeoBBox instead of VolumeAssembly - in run_sim.C save 9% of time compared to v13p7 +// 2013-10-29 - DE - v13p4 - build lattice grid as TGeoBBox instead of CompositeShape - in run_sim.C save 18% of time compared to v13p6 +// +// 2013-10-28 - DE - introduce new geometry naming scheme: v13p1 - SIS 100 hadron +// 2013-10-28 - DE - introduce new geometry naming scheme: v13p2 - SIS 100 electron +// 2013-10-28 - DE - introduce new geometry naming scheme: v13p3 - SIS 100 muon +// 2013-10-28 - DE - introduce new geometry naming scheme: v13p4 - SIS 300 electron +// 2013-10-28 - DE - introduce new geometry naming scheme: v13p5 - SIS 300 muon +// 2013-10-28 - DE - add option to draw the magnetic field vector in the magnet +// 2013-09-27 - DE - do not use TGeoXtru to build the supports, use TGeoBBox instead +// +// 2013-06-25 - DE - v13g trd300_rich (10 layers, z = 4100 ) - TRD right behind SIS300 RICH +// 2013-06-25 - DE - v13h trd100_sts ( 4 layers, z = 2600 ) - TRD completely on RICH/MUCH platform to allow TOF to move upstream +// 2013-06-25 - DE - v13i trd100_rich ( 2 layers, z = 4100 ) - TRD right behind RICH +// 2013-06-25 - DE - v13j trd100_rich ( 3 layers, z = 4100 ) - TRD right behind RICH +// 2013-06-25 - DE - v13k trd100_rich ( 4 layers, z = 4100 ) - TRD right behind RICH +// 2013-06-25 - DE - --- trd100_much_2_absorbers ( 4 layers, z = 4300 ) - same as version at z = 4600 +// 2013-06-25 - DE - v13l trd100_much_3_absorbers ( 4 layers, z = 4600 ) - TRD right behind SIS100 MUCH +// 2013-06-25 - DE - v13m trd300_much_6_absorbers (10 layers, z = 5500 ) - TRD right behind SIS300 MUCH +// 2013-06-25 - DE - v13n trd300_rich_stretched (10 layers, z = 4600 ) - TRD stretched behind SIS300 RICH +// +// 2013-06-19 - DE - add TRD (I, II, III) labels on support structure +// 2013-05-29 - DE - allow for flexible TRD z-positions defined by position of layer01 +// 2013-05-23 - DE - remove "trd_" prefix from node names (except top node) +// 2013-05-22 - DE - radiators G30 (z=240 mm) +// 2013-05-22 - DE - radiators H (z=275 mm - 125 * 2.2mm), (H++ z=335 mm) +// 2013-05-22 - DE - radiators B++ (z=254 mm - 350 * 0.724 mm), K++ (z=254 mm - 350 * 0.724 mm) +// 2013-04-17 - DE - introduce volume assembly for layers, e.g. trd_layer03 +// 2013-03-26 - DE - use Air as ASIC material +// 2013-03-26 - DE - put support structure into its own assembly +// 2013-03-26 - DE - move TRD upstream to z=400m +// 2013-03-26 - DE - RICH will probably end at z=380 cm, TRD can move to 400 cm +// 2013-03-25 - DE - shrink active area from 570 to 540 mm and 960 to 910 mm +// 2013-03-06 - DE - add ASICs on FEBs +// 2013-03-05 - DE - introduce supports for SIS100 and SIS300 +// 2013-03-05 - DE - replace all Float_t by Double_t +// 2013-01-21 - DE - introduce TRD media, use TRDG10 as material for pad plane and FEBs +// 2013-01-21 - DE - put backpanel into the geometry +// 2013-01-11 - DE - allow for misalignment of TRD modules +// 2012-11-04 - DE - add kapton foil, add FR4 padplane +// 2012-11-03 - DE - add lattice grid on entrance window as CompositeShape + +// TODO: +// - use Silicon as ASIC material + +// in root all sizes are given in cm + +#include "TSystem.h" +#include "TGeoManager.h" +#include "TGeoVolume.h" +#include "TGeoMaterial.h" +#include "TGeoMedium.h" +#include "TGeoPgon.h" +#include "TGeoMatrix.h" +#include "TGeoCompositeShape.h" +#include "TGeoXtru.h" +#include "TFile.h" +#include "TString.h" +#include "TList.h" +#include "TRandom3.h" +#include "TDatime.h" + +#include "TGeoArb8.h" +#include "TGeoTube.h" +#include "TGeoCone.h" + +#include <iostream> + +// Name of output file with geometry +const TString tagVersion = "v20b_mcbm"; +//const TString subVersion = "_1h"; +//const TString subVersion = "_1e"; +//const TString subVersion = "_1m"; +//const TString subVersion = "_3e"; +//const TString subVersion = "_3m"; + +const Int_t setupid = 1; // 1e is the default +//const Double_t zfront[5] = { 260., 410., 360., 410., 550. }; +const Double_t zfront[5] = { 260., 177., 360., 410., 550. }; // move 1st TRD to z=177 cm +//const Double_t zfront[5] = { 260., 140., 360., 410., 550. }; +const TString setupVer[5] = { "_1h", "_1e", "_1m", "_3e", "_3m" }; +const TString subVersion = setupVer[setupid]; + +const TString geoVersion = "trd_" + tagVersion; // + subVersion; +const TString FileNameSim = geoVersion + ".geo.root"; +const TString FileNameGeo = geoVersion + "_geo.root"; +const TString FileNameInfo = geoVersion + ".geo.info"; +const TString FileNamePads = "CbmTrdPads_" + tagVersion + ".h"; + +// display switches +const Bool_t IncludeRadiator = false; // false; // true, if radiator is included in geometry +const Bool_t IncludeLattice = true; // false; // true, if lattice grid is included in geometry + +const Bool_t IncludeKaptonFoil = true; // false; // true, if entrance window is included in geometry +const Bool_t IncludeGasFrame = true; // false; // true, if frame around gas volume is included in geometry +const Bool_t IncludePadplane = true; // false; // true, if padplane is included in geometry +const Bool_t IncludeBackpanel = true; // false; // true, if backpanel is included in geometry +const Bool_t IncludeAluLedge = true; // false; // true, if Al-ledge around the backpanel is included in geometry +const Bool_t IncludeGibbet = true; // false; // true, if mTRD gibbet support to be drawn +const Bool_t IncludePowerbars = false; // false; // true, if LV copper bus bars to be drawn + +const Bool_t IncludeFebs = true; // false; // true, if FEBs are included in geometry +const Bool_t IncludeRobs = true; // true, if ROBs are included in geometry +const Bool_t IncludeAsics = true; // true, if ASICs are included in geometry +const Bool_t IncludeSupports = false; // false; // true, if support structure is included in geometry +const Bool_t IncludeLabels = false; // false; // true, if TRD (I, II, III) labels are plotted in (VisLevel 5) +const Bool_t IncludeFieldVector = false; // true, if magnetic field vector to be shown (in the magnet) + +// positioning switches +const Bool_t DisplaceRandom = false; // true; // false; // add random displacement of modules for alignment study +const Bool_t RotateRandom = false; // true; // false; // add random rotation of modules for alignment study +const Bool_t DoExplode = false; // true, // false; // add random displacement of modules for alignment study + +// positioning parameters +const Double_t maxdx = 0.2; // max +- 0.1 cm shift in x +const Double_t maxdy = 0.2; // max +- 0.1 cm shift in y +const Double_t maxdz = 1.0; // max +- 1.0 cm shift in z + +const Double_t maxdrotx = 2.0; // 20.0; // max rotation around x +const Double_t maxdroty = 2.0; // 20.0; // max rotation around y +const Double_t maxdrotz = 2.0; // 20.0; // max rotation around z + +const Double_t ExplodeFactor = 1.02; // 1.02; // Factor by which modules are exploded in the x/y plane + +// initialise random numbers +TRandom3 r3(0); + +// Parameters defining the layout of the complete detector build out of different detector layers. +const Int_t MaxLayers = 10; // max layers + +// select layers to display +// +//const Int_t ShowLayer[MaxLayers] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // 1st layer only +//const Int_t ShowLayer[MaxLayers] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // 2nd layer only +//const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }; // 5th layer only +//const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }; // 6th layer only +//const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }; // 9th layer only +//const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; // 10th layer only +// +//const Int_t ShowLayer[MaxLayers] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // Station 1, layer 1, 2 +//const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 }; // Station 2, layer 5, 6 +//const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; // Station 3, layer 9,10 +//const Int_t ShowLayer[MaxLayers] = { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0 }; // Station 1 and 2 +//const Int_t ShowLayer[MaxLayers] = { 1, 1, 0, 0, 1, 1, 1, 0, 1, 1 }; // Station 1, 2 and 3 +// +//const Int_t ShowLayer[MaxLayers] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // SIS100-2l // 1: plot, 0: hide +//const Int_t ShowLayer[MaxLayers] = { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; // SIS100-3l // 1: plot, 0: hide +// +//const Int_t ShowLayer[MaxLayers] = { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 }; // SIS100-4l // 1: plot, 0: hide +//const Int_t ShowLayer[MaxLayers] = { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 }; // SIS300-mu // 1: plot, 0: hide +//const Int_t ShowLayer[MaxLayers] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; // SIS300-e // 1: plot, 0: hide +Int_t ShowLayer[MaxLayers] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; // SIS100-4l is default + +Int_t BusBarOrientation[MaxLayers] = { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; // 1 = vertical + +Int_t PlaneId[MaxLayers]; // automatically filled with layer ID + +const Int_t LayerType[MaxLayers] = {10, 11, 10, 11, 20, 21, 20, 21, 30, 31}; // ab: a [1-4] - layer type, b [0,1] - vertical/horizontal pads +// ### Layer Type 20 is mCBM Layer Type 2 with Buch prototype module (type 4) with vertical pads +// ### Layer Type 11 is Layer Type 1 with detector modules rotated by 90?? +// ### Layer Type 21 is Layer Type 2 with detector modules rotated by 90?? +// ### Layer Type 31 is Layer Type 3 with detector modules rotated by 90?? +// In the subroutine creating the layers this is recognized automatically + +const Int_t LayerNrInStation[MaxLayers] = { 1, 2, 3, 4, 1, 2, 3, 4, 1, 2 }; + +Double_t LayerPosition[MaxLayers] = { 0. }; // start position = 0 - 2016-07-12 - DE + +// 5x z-positions from 260 till 550 cm +//Double_t LayerPosition[MaxLayers] = { 260. }; // start position - 2013-10-28 - DE - v14_1h - SIS 100 hadron ( 4 layers, z = 2600 ) +//Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-10-28 - DE - v14_1e - SIS 100 electron ( 4 layers, z = 4100 ) +//Double_t LayerPosition[MaxLayers] = { 360. }; // start position - 2014-06-16 - DE - v14_1m - SIS 100 muon ( 4 layers, z = 3600 ) was 460. +//Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-10-28 - DE - v14_3e - SIS 300 electron (10 layers, z = 4100 ) +//Double_t LayerPosition[MaxLayers] = { 550. }; // start position - 2013-10-28 - DE - v14_3m - SIS 300 muon 6_abs (10 layers, z = 5500 ) +// +// obsolete variants +//Double_t LayerPosition[MaxLayers] = { 460. }; // start position - 2013-10-28 - DE - v13x3 - SIS 100 muon ( 4 layers, z = 4600 ) +//Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-06-25 - DE - v13i trd100_rich ( 2 layers, z = 4100 ) +//Double_t LayerPosition[MaxLayers] = { 410. }; // start position - 2013-06-25 - DE - v13j trd100_rich ( 3 layers, z = 4100 ) +//Double_t LayerPosition[MaxLayers] = { 430. }; // start position - 2013-06-25 - DE - --- trd100_much_2_absorbers ( 4 layers, z = 4300 ) +//Double_t LayerPosition[MaxLayers] = { 460. }; // start position - 2013-06-25 - DE - v13n trd300_rich_stretched (10 layers, z = 4600 ) + + +const Double_t LayerThickness = 22.0; // miniCBM - Thickness of one TRD layer in cm +//const Double_t LayerThickness = 25.0; // miniCBM - Thickness of one TRD layer in cm +//const Double_t LayerThickness = 45.0; // Thickness of one TRD layer in cm + +const Double_t LayerOffset[MaxLayers] = { 0., 0., 0., 0., -112., 0., 0., 0., 5., 0. }; // v13x[4,5] - z offset in addition to LayerThickness +//const Double_t LayerOffset[MaxLayers] = { 0., 0., 0., 0., -115., 0., 0., 0., 5., 0. }; // v13x[4,5] - z offset in addition to LayerThickness +// 140 / 165 / 190 / 215 / 240 - 115 = 125 +//const Double_t LayerOffset[MaxLayers] = { 0., 0., 0., 0., -115., 0., 0., 0., 5., 0. }; // v13x[4,5] - z offset in addition to LayerThickness +// 115 / 140 / 165 / 190 / 215 - 125 = 100 + +// const Double_t LayerOffset[MaxLayers] = { 0., -10., 0., 0., 0., 0., 0., 0., 5., 0. }; // v13x[4,5] - z offset in addition to LayerThickness +// 100 / 125 - 10 = 115 / 140 / 165 / 190 + + //const Double_t LayerOffset[MaxLayers] = { 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. }; // SIS100 - z offset in addition to LayerThickness +//const Double_t LayerOffset[MaxLayers] = { 0., 0., 0., 0., 95., 0., 0., 0., 5., 0. }; // v13n - z offset in addition to LayerThickness + +const Int_t LayerArraySize[3][4] = { { 5, 5, 9, 11 }, // for layer[1-3][i,o] below + { 5, 5, 9, 11 }, + { 5, 5, 9, 11 } }; + + +// ### Layer Type 1 +// v14x - module types in the inner sector of layer type 1 - looking upstream +const Int_t layer1i[5][5] = { { 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0 }, + // { 0, 0, 101, 0, 0 }, + { 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0 } }; + +//const Int_t layer1i[5][5] = { { 323, 323, 321, 321, 321 }, // abc: a module type - b orientation (x90 deg) in odd - c even layers +// { 223, 123, 121, 121, 221 }, +// { 203, 103, 0, 101, 201 }, +// { 203, 103, 101, 101, 201 }, +// { 303, 303, 301, 301, 301 } }; +// number of modules: 24 + +// v14x - module types in the outer sector of layer type 1 - looking upstream +const Int_t layer1o[9][11]= { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 821, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; +//// v14x - module types in the outer sector of layer type 1 - looking upstream +//const Int_t layer1o[9][11]= { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +// { 0, 0, 823, 823, 723, 721, 721, 821, 821, 0, 0 }, +// { 0, 0, 823, 623, 0, 0, 0, 621, 821, 0, 0 }, +// { 0, 0, 703, 603, 0, 0, 0, 601, 701, 0, 0 }, +// { 0, 0, 803, 603, 0, 0, 0, 601, 801, 0, 0 }, +// { 0, 0, 803, 803, 703, 701, 701, 801, 801, 0, 0 }, +// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; +// number of modules: 26 +// Layer1 = 24 + 26; // v14a + + +// ### Layer Type 2 -> remapped for Buch prototype +// v14x - module types in the inner sector of layer type 2 - looking upstream +// const Int_t layer2i[5][5] = { { 323, 323, 321, 321, 321 }, // abc: a module type - b orientation (x90 deg) in odd - c even layers +// { 223, 123, 121, 121, 221 }, +// { 203, 103, 0, 101, 201 }, +// { 203, 103, 101, 101, 201 }, +// { 303, 303, 301, 301, 301 } }; +const Int_t layer2i[5][5] = { { 0 }, // abc: a module type - b orientation (x90 deg) in odd - c even layers + { 0 }, + { 0, 0, 401, 0, 0 }, + { 0 }, + { 0 } }; + +// number of modules: 24 + +// v14x - module types in the outer sector of layer type 2 - looking upstream +// const Int_t layer2o[9][11]= { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +// { 0, 823, 823, 823, 823, 821, 821, 821, 821, 821, 0 }, +// { 0, 823, 823, 823, 723, 721, 721, 821, 821, 821, 0 }, +// { 0, 823, 723, 623, 0, 0, 0, 621, 721, 821, 0 }, +// { 0, 803, 703, 603, 0, 0, 0, 601, 701, 801, 0 }, +// { 0, 803, 703, 603, 0, 0, 0, 601, 701, 801, 0 }, +// { 0, 803, 803, 803, 703, 701, 701, 801, 801, 801, 0 }, +// { 0, 803, 803, 803, 803, 801, 801, 801, 801, 801, 0 }, +// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; +const Int_t layer2o[9][11] = { { 0 },{ 0 },{ 0 },{ 0 },{ 0 },{ 0 },{ 0 },{ 0 },{ 0 }}; +// number of modules: 54 +// Layer2 = 24 + 54; // v14a + + +// ### Layer Type 3 +// v14x - module types in the inner sector of layer type 3 - looking upstream +const Int_t layer3i[5][5] = { { 323, 323, 321, 321, 321 }, // abc: a module type - b orientation (x90 deg) in odd - c even layers + { 223, 123, 121, 121, 221 }, + { 203, 103, 0, 101, 201 }, + { 203, 103, 101, 101, 201 }, + { 303, 303, 301, 301, 301 } }; +// number of modules: 24 + +// v14x - module types in the outer sector of layer type 3 - looking upstream +const Int_t layer3o[9][11] = { { 823, 823, 823, 823, 823, 821, 821, 821, 821, 821, 821 }, + { 823, 823, 823, 823, 823, 821, 821, 821, 821, 821, 821 }, + { 823, 823, 823, 723, 623, 621, 621, 721, 821, 821, 821 }, + { 823, 823, 723, 623, 0, 0, 0, 621, 721, 821, 821 }, + { 803, 803, 703, 603, 0, 0, 0, 601, 701, 801, 801 }, + { 803, 803, 703, 603, 0, 0, 0, 601, 701, 801, 801 }, + { 803, 803, 803, 703, 603, 601, 601, 701, 801, 801, 801 }, + { 803, 803, 803, 803, 803, 801, 801, 801, 801, 801, 801 }, + { 803, 803, 803, 803, 803, 801, 801, 801, 801, 801, 801 } }; +// number of modules: 90 +// Layer2 = 24 + 90; // v14a + + +// Parameters defining the layout of the different detector modules +const Int_t NofModuleTypes = 8; +const Int_t ModuleType[NofModuleTypes] = { 0, 0, 0, 2, 1, 1, 1, 1 }; // 0 = small module, 1 = large module, 2 = mCBM Bucharest prototype + +// FEB inclination angle +const Double_t feb_rotation_angle[NofModuleTypes] = { 70, 90, 90, 0, 80, 90, 90, 90 }; // rotation around x-axis, 0 = vertical, 90 = horizontal +//const Double_t feb_rotation_angle[NofModuleTypes] = { 45, 45, 45, 45, 45, 45, 45, 45 }; // rotation around x-axis, 0 = vertical, 90 = horizontal + +// GBTx ROB definitions +const Int_t RobsPerModule[NofModuleTypes] = { 3, 2, 1, 6, 2, 2, 1, 1 }; // number of GBTx ROBs on module +const Int_t GbtxPerRob[NofModuleTypes] = {105,105,105,103,107,105,105,103 }; // number of GBTx ASICs on ROB + +const Int_t GbtxPerModule[NofModuleTypes] = { 15, 10, 5, 18, 0, 10, 5, 3 }; // for .geo.info - TODO: merge with above GbtxPerRob +const Int_t RobTypeOnModule[NofModuleTypes]={555, 55, 5,333333, 0, 55, 5, 3 }; // for .geo.info - TODO: merge with above GbtxPerRob + +//const Int_t RobsPerModule[NofModuleTypes] = { 2, 2, 1, 1, 2, 2, 1, 1 }; // number of GBTx ROBs on module +//const Int_t GbtxPerRob[NofModuleTypes] = {107,105,105,103,107,105,105,103 }; // number of GBTx ASICs on ROB +//const Int_t GbtxPerModule[NofModuleTypes] = { 14, 8, 5, 0, 0, 10, 5, 3 }; // for .geo.info - TODO: merge with above GbtxPerRob +//const Int_t RobTypeOnModule[NofModuleTypes] = { 77, 53, 5, 0, 0, 55, 5, 3 }; // for .geo.info - TODO: merge with above GbtxPerRob + +// super density for type 1 modules - 2017 - 540 mm +const Int_t FebsPerModule[NofModuleTypes] = { 9, 5, 6, 18, 12, 8, 4, 3 }; // number of FEBs on backside +//const Int_t FebsPerModule[NofModuleTypes] = { 9, 6, 3, 4, 12, 8, 4, 2 }; // number of FEBs on backside +const Int_t AsicsPerFeb[NofModuleTypes] = {210,210,210,410,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping +//// ultimate density - 540 mm +//const Int_t FebsPerModule[NofModuleTypes] = { 6, 5, 6, 4, 12, 8, 4, 3 }; // number of FEBs on backside - reduced FEBs (64 ch ASICs) +//const Int_t AsicsPerFeb[NofModuleTypes] = {315,210,105,105,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping +////const Int_t FebsPerModule[NofModuleTypes] = { 6, 5, 3, 2, 6, 3, 4, 3 }; // min number of FEBs // number of FEBs on backside - reduced FEBs (64 ch ASICs) +////const Int_t AsicsPerFeb[NofModuleTypes] = {315,210,210,210,216,216,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping +////const Int_t AsicsPerFeb[NofModuleTypes] = {216,210,210,210,216,216,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping +// +////// super density - 540 mm +//const Int_t FebsPerModule[NofModuleTypes] = { 9, 5, 6, 4, 12, 6, 4, 3 }; // light // number of FEBs on backside - reduced FEBs (64 ch ASICs) +//const Int_t AsicsPerFeb[NofModuleTypes] = {210,210,105,105,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping +// +//// normal density - 540 mm +//const Int_t FebsPerModule[NofModuleTypes] = { 18, 10, 6, 4, 12, 6, 4, 3 }; // number of FEBs on backside (linked to pad layout) - mod4 = mod3, therefore same +//const Int_t AsicsPerFeb[NofModuleTypes] = {105,105,105,105,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping + +// ultimate density - 570 mm +//const Int_t FebsPerModule[NofModuleTypes] = { 6, 5, 3, 2, 5, 3, 2, 1 }; // min number of FEBs // number of FEBs on backside - reduced FEBs (64 ch ASICs) +//const Int_t AsicsPerFeb[NofModuleTypes] = {216,210,210,210,216,216,216,216 }; // %100 gives number of ASICs on FEB, /100 gives grouping +// +//const Int_t FebsPerModule[NofModuleTypes] = { 6, 5, 3, 3, 10, 5, 3, 3 }; // min (6) module types // number of FEBs on backside - reduced FEBs (64 ch ASICs) +//const Int_t AsicsPerFeb[NofModuleTypes] = {216,210,210,210,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping +//// super density - 570 mm +//const Int_t FebsPerModule[NofModuleTypes] = { 10, 5, 5, 5, 12, 6, 4, 3 }; // light // number of FEBs on backside - reduced FEBs (64 ch ASICs) +//const Int_t AsicsPerFeb[NofModuleTypes] = {210,210,105,105,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping +// +//// normal density - 570 mm +//const Int_t FebsPerModule[NofModuleTypes] = { 19, 10, 5, 5, 12, 6, 4, 3 }; // number of FEBs on backside (linked to pad layout) - mod4 = mod3, therefore same +//const Int_t AsicsPerFeb[NofModuleTypes] = {105,105,105,105,108,108,108,108 }; // %100 gives number of ASICs on FEB, /100 gives grouping + + +/* TODO: activate connector grouping info below +// ultimate - grouping of pads to connectors +const Int_t RowsPerConnector[NofModuleTypes] = { 6, 4, 2, 2, 2, 2, 2, 2 }; +const Int_t ColsPerConnector[NofModuleTypes] = { 16, 16, 16, 16, 16, 16, 16, 16 }; +// super - grouping of pads to connectors +const Int_t RowsPerConnector[NofModuleTypes] = { 4, 4, 2, 2, 2, 2, 2, 2 }; +const Int_t ColsPerConnector[NofModuleTypes] = { 16, 16, 16, 16, 16, 16, 16, 16 }; +// normal - grouping of pads to connectors +const Int_t RowsPerConnector[NofModuleTypes] = { 2, 2, 2, 2, 2, 2, 2, 2 }; +const Int_t ColsPerConnector[NofModuleTypes] = { 16, 16, 16, 16, 16, 16, 16, 16 }; +*/ + + +const Double_t feb_z_offset = 0.1; // 1 mm - offset in z of FEBs to backpanel +const Double_t asic_offset = 0.1; // 1 mm - offset of ASICs to FEBs to avoid overlaps + +// ASIC parameters +Double_t asic_distance; + +//const Double_t FrameWidth[2] = { 1.5, 2.0 }; // Width of detector frames in cm +const Double_t FrameWidth[3] = { 1.5, 1.5, 2.5}; // Width of detector frames in cm +// mini - production +const Double_t DetectorSizeX[3] = { 57., 95., 59.0}; // => 54 x 54 cm2 & 91 x 91 cm2 active area +const Double_t DetectorSizeY[3] = { 57., 95., 60.8}; // quadratic modules +//// default +//const Double_t DetectorSizeX[2] = { 60., 100.}; // => 57 x 57 cm2 & 96 x 96 cm2 active area +//const Double_t DetectorSizeY[2] = { 60., 100.}; // quadratic modules + +// Parameters tor the lattice grid reinforcing the entrance window +//const Double_t lattice_o_width[2] = { 1.5, 2.0 }; // Width of outer lattice frame in cm +const Double_t lattice_o_width[2] = { 1.5, 1.5 }; // Width of outer lattice frame in cm +const Double_t lattice_i_width[2] = { 0.2, 0.2 }; // { 0.4, 0.4 }; // Width of inner lattice frame in cm +// Thickness (in z) of lattice frames in cm - see below + +// statistics +Int_t ModuleStats[MaxLayers][NofModuleTypes] = { 0 }; + +// z - geometry of TRD modules +const Double_t radiator_thickness = 0.0; // 35 cm thickness of radiator +//const Double_t radiator_thickness = 30.0; // 30 cm thickness of radiator + shift pad plane to integer multiple of 1 mm +const Double_t radiator_position = - LayerThickness/2. + radiator_thickness/2.; + +//const Double_t lattice_thickness = 1.0; // 1.0; // 10 mm thick lattice frames +const Double_t lattice_thickness = 1.0 - 0.0025; // 0.9975; // 1.0; // 10 mm thick lattice frames +const Double_t lattice_position = radiator_position + radiator_thickness/2. + lattice_thickness/2.; + +const Double_t kapton_thickness = 0.0025; // 25 micron thickness of kapton +const Double_t kapton_position = lattice_position + lattice_thickness/2. + kapton_thickness/2.; + +const Double_t gas_thickness = 1.2; // 12 mm thickness of gas +const Double_t gas_position = kapton_position + kapton_thickness/2. + gas_thickness/2.; + +// frame thickness +const Double_t frame_thickness = gas_thickness; // frame covers gas volume: from kapton foil to pad plane +const Double_t frame_position = - LayerThickness /2. + radiator_thickness + lattice_thickness + kapton_thickness + frame_thickness/2.; + +// pad plane +const Double_t padcopper_thickness = 0.0025; // 25 micron thickness of copper pads +const Double_t padcopper_position = gas_position + gas_thickness/2. + padcopper_thickness/2.; + +const Double_t padplane_thickness = 0.0360; // 360 micron thickness of padplane +const Double_t padplane_position = padcopper_position + padcopper_thickness/2. + padplane_thickness/2.; + +// backpanel components +const Double_t carbon_thickness = 0.0190 * 2; // use 2 layers!! // 190 micron thickness for 1 layer of carbon fibers +const Double_t honeycomb_thickness = 2.3 - kapton_thickness - padcopper_thickness - padplane_thickness - carbon_thickness; // ~ 2.3 mm thickness of honeycomb +const Double_t honeycomb_position = padplane_position + padplane_thickness/2. + honeycomb_thickness/2.; +const Double_t carbon_position = honeycomb_position + honeycomb_thickness/2. + carbon_thickness/2.; + +// aluminium thickness +const Double_t aluminium_thickness = 0.4; // crossbar of 1 x 1 cm at every module edge +const Double_t aluminium_width = 1.0; // crossbar of 1 x 1 cm at every module edge +const Double_t aluminium_position = carbon_position + carbon_thickness/2. + aluminium_thickness/2.; + +// power bus bars +const Double_t powerbar_thickness = 1.0; // 1 cm in z direction +const Double_t powerbar_width = 2.0; // 2 cm in x/y direction +const Double_t powerbar_position = aluminium_position + aluminium_thickness/2. + powerbar_thickness/2.; + +// gibbet support +const Double_t gibbet_thickness = 10.0; // 10 cm in z direction +const Double_t gibbet_width = 10.0; // 10 cm in x/y direction +const Double_t gibbet_position = aluminium_position + aluminium_thickness/2. + gibbet_thickness/2.; + +// module rails +const Double_t rail_thickness = 5.0; // 5 cm in z direction +const Double_t rail_width = 3.0; // 3 cm in x/y direction +const Double_t rail_position = aluminium_position + aluminium_thickness/2. + rail_thickness/2.; + +// readout boards +//const Double_t feb_width = 10.0; // width of FEBs in cm +const Double_t feb_width = 8.5; // width of FEBs in cm +const Double_t feb_thickness = 0.25; // light // 2.5 mm thickness of FEBs +const Double_t febvolume_position = aluminium_position + aluminium_thickness/2. + feb_width/2.; + +// ASIC parameters +const Double_t asic_thickness = 0.25; // 2.5 mm asic_thickness +const Double_t asic_width = 3.0; // 2.0; 1.0; // 1 cm + + +// -------------- BUCHAREST PROTOTYPE SPECIFICS ---------------------------------- +// Frontpanel components +const Double_t carbonBu_thickness = 0.03; // 300 micron thickness for 1 layer of carbon fibers +const Double_t honeycombBu_thickness = 0.94; // 9 mm thickness of honeycomb +const Double_t carbonBu0_position = radiator_position + radiator_thickness/2. + carbonBu_thickness/2.; +const Double_t honeycombBu0_position = carbonBu0_position + carbonBu_thickness/2. + honeycombBu_thickness/2.; +const Double_t carbonBu1_position = honeycombBu0_position + honeycombBu_thickness/2. + carbonBu_thickness/2.; +// Active volume +const Double_t gasBu_position = carbonBu1_position + carbonBu_thickness/2. + gas_thickness/2.; +// Pad plane +const Double_t padcopperBu_position = gasBu_position + gas_thickness/2. + padcopper_thickness/2.; +const Double_t padplaneBu_position = padcopperBu_position + padcopper_thickness/2. + padplane_thickness/2.; +// Backpanel components +const Double_t honeycombBu1_position = padplaneBu_position + padplane_thickness/2. + honeycombBu_thickness/2.; +// PCB +const Double_t glassFibre_thickness = 0.0270; // 300 microns overall PCB thickness +const Double_t cuCoating_thickness = 0.0030; +const Double_t glassFibre_position = honeycombBu1_position + honeycombBu_thickness/2. + glassFibre_thickness/2.; +const Double_t cuCoating_position = glassFibre_position + glassFibre_thickness/2. + cuCoating_thickness/2.; +//Frame around entrance window, active volume and exit window +const Double_t frameBu_thickness = 2*carbonBu_thickness+honeycombBu_thickness+ + gas_thickness+ + padcopper_thickness+padplane_thickness+honeycombBu_thickness+ + glassFibre_thickness+cuCoating_thickness; +const Double_t frameBu_position = radiator_position + radiator_thickness/2. + frameBu_thickness/2.; +// ROB FASP +const Double_t febFASP_zspace = 1.5; // gap size between boards +const Double_t febFASP_width = 5.5; // width of FASP FEBs in cm +const Double_t febFASP_position = cuCoating_position + febFASP_width/2.+1.5; +const Double_t febFASP_thickness = feb_thickness; + +// FASP-ASIC parameters +const Double_t fasp_size[2] = {2, 2.5}; // FASP package size 2x3 cm2 +const Double_t fasp_xoffset = 1.35; // ASIC offset from ROC middle (horizontally) +const Double_t fasp_yoffset = 0.6; // ASIC offset from DET connector (vertical) +// GETS2C-ROB3 connector boord parameters +const Double_t robConn_size_x = 15.0; +const Double_t robConn_size_y = 6.0; +const Double_t robConn_xoffset = 6.0; +const Double_t robConn_FMCwidth = 1.5; // width of a MF FMC connector +const Double_t robConn_FMClength = 6.5; // length of a MF FMC connector +const Double_t robConn_FMCheight = 1.5; // height of a MF FMC connector + +// C-ROB3 parameters : GBTx ROBs +const Double_t rob_size_x = 20.0; // 13.0; // 130 mm +const Double_t rob_size_y = 9.0; // 4.5; // 45 mm +const Double_t rob_yoffset = 0.3; // offset wrt detector frame (on the detector plane) +const Double_t rob_zoffset = -7.5; // offset wrt entrace plane - center board +const Double_t rob_thickness = feb_thickness; +// GBTX parameters +const Double_t gbtx_thickness = 0.25; // 2.5 mm +const Double_t gbtx_width = 3.0; // 2.0; 1.0; // 1 cm +const Double_t gbtx_distance = 0.4; + + +// Names of the different used materials which are used to build the modules +// The materials are defined in the global media.geo file +const TString KeepingVolumeMedium = "air"; +const TString RadiatorVolumeMedium = "TRDpefoam20"; +const TString LatticeVolumeMedium = "TRDG10"; +const TString KaptonVolumeMedium = "TRDkapton"; +const TString GasVolumeMedium = "TRDgas"; +const TString PadCopperVolumeMedium = "TRDcopper"; +const TString PadPcbVolumeMedium = "TRDG10"; // todo - put correct FEB material here +const TString HoneycombVolumeMedium = "TRDaramide"; +const TString CarbonVolumeMedium = "TRDcarbon"; +const TString FebVolumeMedium = "TRDG10"; // todo - put correct FEB material here +const TString AsicVolumeMedium = "air"; // todo - put correct ASIC material here +const TString TextVolumeMedium = "air"; // leave as air +const TString FrameVolumeMedium = "TRDG10"; +const TString PowerBusVolumeMedium = "TRDcopper"; // power bus bars +const TString AluLegdeVolumeMedium = "aluminium"; // aluminium frame around backpanel +const TString AluminiumVolumeMedium = "aluminium"; +const TString Kanya10x10sVolumeMedium = "KANYAProfile10x10Strong"; +const TString Kanya10x10nVolumeMedium = "KANYAProfile10x10Normal"; +const TString Kanya03x05nVolumeMedium = "KANYAProfile3x5Normal"; +//const TString MylarVolumeMedium = "mylar"; +//const TString RadiatorVolumeMedium = "polypropylene"; +//const TString ElectronicsVolumeMedium = "goldcoatedcopper"; + +// some global variables +TGeoManager* gGeoMan = NULL; // Pointer to TGeoManager instance +TGeoVolume* gModules[NofModuleTypes]; // Global storage for module types + +// Forward declarations +void create_materials_from_media_file(); +TGeoVolume* create_trd_module_type(Int_t moduleType); +TGeoVolume* create_trdi_module_type(); +void create_detector_layers(Int_t layer); +void create_gibbet_support(); +void create_power_bars_vertical(); +void create_power_bars_horizontal(); +void create_xtru_supports(); +void create_box_supports(); +void add_trd_labels(TGeoVolume*, TGeoVolume*, TGeoVolume*); +void create_mag_field_vector(); +void dump_info_file(); +void dump_digi_file(); + + +void Create_TRD_Geometry_v20b() { + + // declare TRD layer layout + if (setupid > 2) + for (Int_t i = 0; i < MaxLayers; i++) + ShowLayer[i]=1; // show all layers + + // Load needed material definition from media.geo file + create_materials_from_media_file(); + + // Position the layers in z + for (Int_t iLayer = 1; iLayer < MaxLayers; iLayer++) + LayerPosition[iLayer] = LayerPosition[iLayer-1] + LayerThickness + LayerOffset[iLayer]; // add offset for extra gaps + + // Get the GeoManager for later usage + gGeoMan = (TGeoManager*) gROOT->FindObject("FAIRGeom"); + gGeoMan->SetVisLevel(10); + + // Create the top volume + TGeoBBox* topbox= new TGeoBBox("", 1000., 1000., 2000.); + TGeoVolume* top = new TGeoVolume("top", topbox, gGeoMan->GetMedium("air")); + gGeoMan->SetTopVolume(top); + + TGeoVolume* trd = new TGeoVolumeAssembly(geoVersion); + top->AddNode(trd, 1); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) { + Int_t moduleType = iModule + 1; + gModules[iModule] = (iModule==3?create_trdi_module_type():create_trd_module_type(moduleType)); + } + + Int_t nLayer = 0; // active layer counter + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) { + // if ((iLayer != 0) && (iLayer != 3)) continue; // first layer only - comment later on + // if (iLayer != 0) continue; // first layer only - comment later on + if (ShowLayer[iLayer]){ + PlaneId[iLayer]=++nLayer; + create_detector_layers(iLayer); + // printf("calling layer %2d\n",iLayer); + } + } + + // TODO: remove or comment out + // test PlaneId + printf("generated TRD layers: "); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + printf(" %2d",PlaneId[iLayer]); + printf("\n"); + + if (IncludeSupports){ + create_box_supports(); + } + + if (IncludeGibbet){ + create_gibbet_support(); + } + + if (IncludePowerbars){ + create_power_bars_vertical(); + create_power_bars_horizontal(); + } + + if (IncludeFieldVector) + create_mag_field_vector(); + + gGeoMan->CloseGeometry(); +// gGeoMan->CheckOverlaps(0.001); +// gGeoMan->PrintOverlaps(); + gGeoMan->Test(); + + trd->Export(FileNameSim); // an alternative way of writing the trd volume + + TFile* outfile = new TFile(FileNameSim, "UPDATE"); + // TGeoTranslation* trd_placement = new TGeoTranslation("trd_trans", 0., 0., 0.); + // TGeoTranslation* trd_placement = new TGeoTranslation("trd_trans", 0., 0., zfront[setupid]); + TGeoTranslation* trd_placement = new TGeoTranslation("trd_trans", -7., 0., zfront[setupid]); + trd_placement->Write(); + outfile->Close(); + + outfile = new TFile(FileNameGeo,"RECREATE"); + gGeoMan->Write(); // use this is you want GeoManager format in the output + outfile->Close(); + + dump_info_file(); + dump_digi_file(); + + top->Draw("ogl"); + + //top->Raytrace(); + +// cout << "Press Return to exit" << endl; +// cin.get(); +// exit(); +} + + +//============================================================== +void dump_digi_file() +{ + TDatime datetime; // used to get timestamp + + const Double_t ActiveAreaX[3] = { DetectorSizeX[0] - 2 * FrameWidth[0], + DetectorSizeX[1] - 2 * FrameWidth[1], + DetectorSizeX[2] - 2 * FrameWidth[2] }; + const Int_t NofSectors = 3; + const Int_t NofPadsInRow[3] = { 80, 128, 72}; // number of pads in rows + Int_t nrow = 0; // number of rows in module + + const Double_t PadHeightInSector[NofModuleTypes][NofSectors] = // pad height + { { 1.50, 1.50, 1.50 }, // module type 1 - 1.01 mm2 + { 2.25, 2.25, 2.25 }, // module type 2 - 1.52 mm2 +// { 2.75, 2.50, 2.75 }, // module type 2 - 1.86 mm2 + { 4.50, 4.50, 4.50 }, // module type 3 - 3.04 mm2 +// { 2.75, 6.75, 6.75 }, // module type 4 - 4.56 mm2 + { 2.79, 2.79, 2.79 }, // module type 4 - triangular pads H=27.7+0.2 mm, W=7.3+0.2 mm + + { 3.75, 4.00, 3.75 }, // module type 5 - 2.84 mm2 + { 5.75, 5.75, 5.75 }, // module type 6 - 4.13 mm2 + { 11.50, 11.50, 11.50 }, // module type 7 - 8.26 mm2 + { 15.25, 15.50, 15.25 } }; // module type 8 - 11.14 mm2 + // { 23.00, 23.00, 23.00 } }; // module type 8 - 16.52 mm2 +// { 7.50, 7.75, 7.50 }, // module type 6 - 5.51 mm2 +// { 5.50, 5.75, 5.50 }, // module type 6 - 4.09 mm2 +// { 11.25, 11.50, 11.25 }, // module type 7 - 8.18 mm2 + + const Int_t NofRowsInSector[NofModuleTypes][NofSectors] = // number of rows per sector + { { 12, 12, 12 }, // module type 1 + { 8, 8, 8 }, // module type 2 +// { 8, 4, 8 }, // module type 2 + { 4, 4, 4 }, // module type 3 +// { 2, 4, 2 }, // module type 4 + { 2, 16, 2 }, // module type 4 + + { 8, 8, 8 }, // module type 5 + { 4, 8, 4 }, // module type 6 + { 2, 4, 2 }, // module type 7 + { 2, 2, 2 } }; // module type 8 + // { 1, 2, 1 } }; // module type 8 +// { 10, 4, 10 }, // module type 5 +// { 4, 4, 4 }, // module type 6 +// { 2, 12, 2 }, // module type 6 +// { 2, 4, 2 }, // module type 7 +// { 2, 2, 2 } }; // module type 8 + + Double_t HeightOfSector[NofModuleTypes][NofSectors]; + Double_t PadWidth[NofModuleTypes]; + + // calculate pad width + for (Int_t im = 0; im < NofModuleTypes; im++) + PadWidth[im] = ActiveAreaX[ModuleType[im]] / NofPadsInRow[ModuleType[im]]; + + // calculate height of sectors + for (Int_t im = 0; im < NofModuleTypes; im++) + for (Int_t is = 0; is < NofSectors; is++) + HeightOfSector[im][is] = NofRowsInSector[im][is] * PadHeightInSector[im][is]; + + // check, if the entire module size is covered by pads + for (Int_t im = 0; im < NofModuleTypes; im++){ + if (im!=3 && ActiveAreaX[ModuleType[im]] - (HeightOfSector[im][0] + HeightOfSector[im][1] + HeightOfSector[im][2]) != 0) + { + printf("WARNING: sector size does not add up to module size for module type %d\n", im+1); + printf("%.2f = %.2f + %.2f + %.2f\n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][0], HeightOfSector[im][1], HeightOfSector[im][2]); + exit(1); + } + } +//============================================================== + + printf("writing trd pad information file: %s\n", FileNamePads.Data()); + + FILE *ifile; + ifile = fopen(FileNamePads.Data(),"w"); + + if (ifile == NULL) + { + printf("error opening %s\n", FileNamePads.Data()); + exit(1); + } + + fprintf(ifile,"//\n"); + fprintf(ifile,"// TRD pad layout for geometry %s\n", tagVersion.Data()); + fprintf(ifile,"//\n"); + fprintf(ifile,"// automatically generated by Create_TRD_Geometry_%s%s.C\n", tagVersion.Data(), subVersion.Data()); + fprintf(ifile,"// created %d\n", datetime.GetDate()); + fprintf(ifile,"//\n"); + + fprintf(ifile,"\n"); + fprintf(ifile,"#ifndef CBMTRDPADS_H\n"); + fprintf(ifile,"#define CBMTRDPADS_H\n"); + fprintf(ifile,"\n"); + fprintf(ifile,"Int_t fst1_sect_count = 3;\n"); + fprintf(ifile,"// array of pad geometries in the TRD (trd1mod[1-8])\n"); + fprintf(ifile,"// 8 modules // 3 sectors // 4 values \n"); + fprintf(ifile,"Float_t fst1_pad_type[8][3][4] = \n"); +//fprintf(ifile,"Double_t fst1_pad_type[8][3][4] = \n"); + fprintf(ifile," \n"); + + for (Int_t im = 0; im < NofModuleTypes; im++) + { + if (im+1 == 5) + fprintf(ifile,"//---\n\n"); + fprintf(ifile,"// module type %d\n", im+1); + + // number of pads + nrow = 0; // reset number of pad rows to 0 + for (Int_t is = 0; is < NofSectors; is++) + nrow += HeightOfSector[im][is] / PadHeightInSector[im][is]; // add number of rows in this sector + fprintf(ifile,"// number of pads: %3d x %2d = %4d\n", + NofPadsInRow[ModuleType[im]], nrow, NofPadsInRow[ModuleType[im]] * nrow); + + // pad size + fprintf(ifile,"// pad size sector 1: %5.2f cm x %5.2f cm = %5.2f cm2\n", + PadWidth[im], PadHeightInSector[im][1], PadWidth[im] * PadHeightInSector[im][1]); + fprintf(ifile,"// pad size sector 0: %5.2f cm x %5.2f cm = %5.2f cm2\n", + PadWidth[im], PadHeightInSector[im][0], PadWidth[im] * PadHeightInSector[im][0]); + + for (Int_t is = 0; is < NofSectors; is++) + { + if ((im == 0) && (is == 0)) fprintf(ifile," { { "); + else if (is == 0) fprintf(ifile," { "); + else fprintf(ifile," "); + + fprintf(ifile,"{ %.1f, %5.2f, %.1f/%3d, %5.2f }", + ActiveAreaX[ModuleType[im]], HeightOfSector[im][is], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][is]); + + if ((im == NofModuleTypes-1) && (is == 2)) fprintf(ifile," } };"); + else if (is == 2) fprintf(ifile," },"); + else fprintf(ifile,","); + + fprintf(ifile,"\n"); + } + + fprintf(ifile,"\n"); + } + + fprintf(ifile,"#endif\n"); + +// Int_t im = 0; +// fprintf(ifile,"// module type %d \n", im+1); +// fprintf(ifile," { { { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][0], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][0]); +// fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][1], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][1]); +// fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f } }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][2], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][2]); +// fprintf(ifile,"\n"); +// +// for (Int_t im = 1; im < NofModuleTypes-1; im++) +// { +// fprintf(ifile,"// module type %d \n", im+1); +// fprintf(ifile," { { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][0], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][0]); +// fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][1], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][1]); +// fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f } }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][2], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][2]); +// fprintf(ifile,"\n"); +// } +// +// Int_t im = 7; +// fprintf(ifile,"// module type %d \n", im+1); +// fprintf(ifile," { { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][0], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][0]); +// fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f }, \n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][1], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][1]); +// fprintf(ifile," { %.1f, %5.2f, %.1f/%3d, %5.2f } } };\n", ActiveAreaX[ModuleType[im]], HeightOfSector[im][2], ActiveAreaX[ModuleType[im]], NofPadsInRow[ModuleType[im]], PadHeightInSector[im][2]); +// fprintf(ifile,"\n"); + + fclose(ifile); +} + + +void dump_info_file() +{ + TDatime datetime; // used to get timestamp + + Double_t z_first_layer = 2000; // z position of first layer (front) + Double_t z_last_layer = 0; // z position of last layer (front) + + Double_t xangle; // horizontal angle + Double_t yangle; // vertical angle + + Double_t total_surface = 0; // total surface + Double_t total_actarea = 0; // total active area + + Int_t channels_per_module[NofModuleTypes+1] = { 0 }; // number of channels per module + Int_t channels_per_feb[NofModuleTypes+1] = { 0 }; // number of channels per feb + Int_t asics_per_module[NofModuleTypes+1] = { 0 }; // number of asics per module + + Int_t total_modules[NofModuleTypes+1] = { 0 }; // total number of modules + Int_t total_febs[NofModuleTypes+1] = { 0 }; // total number of febs + Int_t total_asics[NofModuleTypes+1] = { 0 }; // total number of asics + Int_t total_gbtx[NofModuleTypes+1] = { 0 }; // total number of gbtx + Int_t total_rob3[NofModuleTypes+1] = { 0 }; // total number of gbtx rob3 + Int_t total_rob5[NofModuleTypes+1] = { 0 }; // total number of gbtx rob5 + Int_t total_rob7[NofModuleTypes+1] = { 0 }; // total number of gbtx rob7 + Int_t total_channels[NofModuleTypes+1] = { 0 }; // total number of channels + + Int_t total_channels_u = 0; // total number of ultimate channels + Int_t total_channels_s = 0; // total number of super channels + Int_t total_channels_r = 0; // total number of regular channels + + printf("writing summary information file: %s\n", FileNameInfo.Data()); + + FILE *ifile; + ifile = fopen(FileNameInfo.Data(),"w"); + + if (ifile == NULL) + { + printf("error opening %s\n", FileNameInfo.Data()); + exit(1); + } + + fprintf(ifile,"#\n## %s information file\n#\n\n", geoVersion.Data()); + + fprintf(ifile,"# created %d\n\n", datetime.GetDate()); + + // determine first and last TRD layer + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + { + if (ShowLayer[iLayer]) + { + if (z_first_layer > LayerPosition[iLayer]) + z_first_layer = LayerPosition[iLayer]; + if (z_last_layer < LayerPosition[iLayer]) + z_last_layer = LayerPosition[iLayer]; + } + } + + fprintf(ifile,"# envelope\n"); + // Show extension of TRD + fprintf(ifile,"%4f cm start of TRD (z)\n", z_first_layer); + fprintf(ifile,"%4f cm end of TRD (z)\n", z_last_layer + LayerThickness); + fprintf(ifile,"\n"); + + // Layer thickness + fprintf(ifile,"# thickness\n"); + fprintf(ifile,"%4f cm per single layer (z)\n", LayerThickness); + fprintf(ifile,"\n"); + + // Show extra gaps + fprintf(ifile,"# extra gaps\n "); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + fprintf(ifile,"%3f ", LayerOffset[iLayer]); + fprintf(ifile," extra gaps in z (cm)\n"); + fprintf(ifile,"\n"); + + // Show layer flags + fprintf(ifile,"# generated TRD layers\n "); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + fprintf(ifile,"%2d ", PlaneId[iLayer]); + fprintf(ifile," planeID\n"); + fprintf(ifile,"\n"); + + // Dimensions in x + fprintf(ifile,"# dimensions in x\n"); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]){ + if (PlaneId[iLayer] <= 5){ + Int_t type=LayerType[iLayer]/10; + fprintf(ifile,"%5f cm to %5f cm x-dimension of layer %2d\n", -3.5 * DetectorSizeX[type], 3.5 * DetectorSizeX[type], PlaneId[iLayer]); + }else + { + if (PlaneId[iLayer] < 9) + fprintf(ifile,"%5f cm to %5f cm x-dimension of layer %2d\n", -4.5 * DetectorSizeX[1], 4.5 * DetectorSizeX[1], PlaneId[iLayer]); + else + fprintf(ifile,"%5f cm to %5f cm x-dimension of layer %2d\n", -5.5 * DetectorSizeX[1], 5.5 * DetectorSizeX[1], PlaneId[iLayer]); + } + } + fprintf(ifile,"\n"); + + // Dimensions in y + fprintf(ifile,"# dimensions in y\n"); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + { + if (PlaneId[iLayer] <= 5){ + Int_t type=LayerType[iLayer]/10; + fprintf(ifile,"%5f cm to %5f cm y-dimension of layer %2d\n", -2.5 * DetectorSizeY[type], 2.5 * DetectorSizeY[type], PlaneId[iLayer]); + } else + { + if (PlaneId[iLayer] < 9) + fprintf(ifile,"%5f cm to %5f cm y-dimension of layer %2d\n", -3.5 * DetectorSizeY[1], 3.5 * DetectorSizeY[1], PlaneId[iLayer]); + else + fprintf(ifile,"%5f cm to %5f cm y-dimension of layer %2d\n", -4.5 * DetectorSizeY[1], 4.5 * DetectorSizeY[1], PlaneId[iLayer]); + } + } + fprintf(ifile,"\n"); + + // Show layer positions + fprintf(ifile,"# z-positions of layer front\n"); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + { + if (ShowLayer[iLayer]) + fprintf(ifile,"%5f cm z-position of layer %2d\n", LayerPosition[iLayer], PlaneId[iLayer]); + } + fprintf(ifile,"\n"); + + // flags + fprintf(ifile,"# flags\n"); + + fprintf(ifile,"support structure is : "); + if (!IncludeSupports) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"radiator is : "); + if (!IncludeRadiator) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"lattice grid is : "); + if (!IncludeLattice ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"kapton window is : "); + if (!IncludeKaptonFoil) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"gas frame is : "); + if (!IncludeGasFrame ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"padplane is : "); + if (!IncludePadplane ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"backpanel is : "); + if (!IncludeBackpanel ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"Aluminium ledge is : "); + if (!IncludeAluLedge ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"Gibbet support is : "); + if (!IncludeGibbet ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"Power bus bars are : "); + if (!IncludePowerbars ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"asics are : "); + if (!IncludeAsics ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"front-end boards are : "); + if (!IncludeFebs ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"GBTX readout boards are : "); + if (!IncludeRobs ) fprintf(ifile,"NOT "); + fprintf(ifile,"included\n"); + + fprintf(ifile,"\n"); + + + // module statistics +// fprintf(ifile,"#\n## modules\n#\n\n"); +// fprintf(ifile,"number of modules per type and layer:\n"); + fprintf(ifile,"# modules\n"); + + for (Int_t iModule = 1; iModule <= NofModuleTypes; iModule++) + fprintf(ifile," mod%1d", iModule); + fprintf(ifile," total"); + + fprintf(ifile,"\n---------------------------------------------------------------------------------\n"); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + { + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + fprintf(ifile," %8d", ModuleStats[iLayer][iModule]); + total_modules[iModule] += ModuleStats[iLayer][iModule]; // sum up modules across layers + } + fprintf(ifile," layer %2d\n", PlaneId[iLayer]); + } + fprintf(ifile,"\n---------------------------------------------------------------------------------\n"); + + // total statistics + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + fprintf(ifile," %8d", total_modules[iModule]); + total_modules[NofModuleTypes] += total_modules[iModule]; + } + fprintf(ifile," %8d", total_modules[NofModuleTypes]); + fprintf(ifile," number of modules\n"); + + //------------------------------------------------------------------------------ + + // number of FEBs + // fprintf(ifile,"\n#\n## febs\n#\n\n"); + fprintf(ifile,"# febs\n"); + + fprintf(ifile," "); + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if ((AsicsPerFeb[iModule] / 100) == 3) + fprintf(ifile,"%8du", FebsPerModule[iModule]); + else if ((AsicsPerFeb[iModule] / 100) == 2) + fprintf(ifile,"%8ds", FebsPerModule[iModule]); + else + fprintf(ifile,"%8d ", FebsPerModule[iModule]); + } + fprintf(ifile," FEBs per module\n"); + + // FEB total per type + total_febs[NofModuleTypes] = 0; // reset sum to 0 + fprintf(ifile," "); + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if ((AsicsPerFeb[iModule] / 100) == 3) + { + total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule]; + fprintf(ifile,"%8du", total_febs[iModule]); + total_febs[NofModuleTypes] += total_febs[iModule]; + } + else + fprintf(ifile," "); + } + fprintf(ifile,"%8d", total_febs[NofModuleTypes]); + fprintf(ifile," ultimate FEBs\n"); + + // FEB total per type + total_febs[NofModuleTypes] = 0; // reset sum to 0 + fprintf(ifile," "); + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if ((AsicsPerFeb[iModule] / 100) == 2) + { + total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule]; + fprintf(ifile,"%8ds", total_febs[iModule]); + total_febs[NofModuleTypes] += total_febs[iModule]; + } + else + fprintf(ifile," "); + } + fprintf(ifile,"%8d", total_febs[NofModuleTypes]); + fprintf(ifile," super FEBs\n"); + + // FEB total per type + total_febs[NofModuleTypes] = 0; // reset sum to 0 + fprintf(ifile," "); + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if ((AsicsPerFeb[iModule] / 100) == 1) + { + total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule]; + fprintf(ifile,"%8d ", total_febs[iModule]); + total_febs[NofModuleTypes] += total_febs[iModule]; + } + else + fprintf(ifile," "); + } + fprintf(ifile,"%8d", total_febs[NofModuleTypes]); + fprintf(ifile," regular FEBs\n"); + + // FEB total over all types + total_febs[NofModuleTypes] = 0; // reset sum to 0 + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + total_febs[iModule] = total_modules[iModule] * FebsPerModule[iModule]; + fprintf(ifile," %8d", total_febs[iModule]); + total_febs[NofModuleTypes] += total_febs[iModule]; + } + fprintf(ifile," %8d", total_febs[NofModuleTypes]); + fprintf(ifile," number of FEBs\n"); + + //------------------------------------------------------------------------------ + + // number of ASICs + // fprintf(ifile,"\n#\n## asics\n#\n\n"); + fprintf(ifile,"# asics\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + fprintf(ifile," %8d", AsicsPerFeb[iModule] %100); + } + fprintf(ifile," ASICs per FEB\n"); + + // ASICs per module + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + asics_per_module[iModule] = FebsPerModule[iModule] * (AsicsPerFeb[iModule] %100); + fprintf(ifile," %8d", asics_per_module[iModule]); + } + fprintf(ifile," ASICs per module\n"); + + // ASICs per module type + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + total_asics[iModule] = total_febs[iModule] * (AsicsPerFeb[iModule] %100); + fprintf(ifile," %8d", total_asics[iModule]); + total_asics[NofModuleTypes] += total_asics[iModule]; + } + fprintf(ifile," %8d", total_asics[NofModuleTypes]); + fprintf(ifile," number of ASICs\n"); + + //------------------------------------------------------------------------------ + + // number of GBTXs + // fprintf(ifile,"\n#\n## asics\n#\n\n"); + fprintf(ifile,"# gbtx\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + fprintf(ifile," %8d", GbtxPerModule[iModule]); + } + fprintf(ifile," GBTXs per module\n"); + + // GBTXs per module type + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + total_gbtx[iModule] = total_modules[iModule] * GbtxPerModule[iModule]; + fprintf(ifile," %8d", total_gbtx[iModule]); + total_gbtx[NofModuleTypes] += total_gbtx[iModule]; + } + fprintf(ifile," %8d", total_gbtx[NofModuleTypes]); + fprintf(ifile," number of GBTXs\n"); + + // GBTX ROB types per module type + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + fprintf(ifile," %8d", RobTypeOnModule[iModule]); + } + fprintf(ifile," GBTX ROB types on module\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if ((RobTypeOnModule[iModule] % 10) == 7) + total_rob7[iModule]++; + if ((RobTypeOnModule[iModule] / 10 % 10) == 7) + total_rob7[iModule]++; + if ((RobTypeOnModule[iModule] / 100) == 7) + total_rob7[iModule]++; + + if ((RobTypeOnModule[iModule] % 10) == 5) + total_rob5[iModule]++; + if ((RobTypeOnModule[iModule] / 10 % 10) == 5) + total_rob5[iModule]++; + if ((RobTypeOnModule[iModule] / 100) == 5) + total_rob5[iModule]++; + + if ((RobTypeOnModule[iModule] % 10) == 3) + total_rob3[iModule]++; + if ((RobTypeOnModule[iModule] / 10 % 10) == 3) + total_rob3[iModule]++; + if ((RobTypeOnModule[iModule] / 100 % 10) == 3) + total_rob3[iModule]++; + if ((RobTypeOnModule[iModule] / 1000 % 10) == 3) + total_rob3[iModule]++; + if ((RobTypeOnModule[iModule] / 10000 % 10) == 3) + total_rob3[iModule]++; + if ((RobTypeOnModule[iModule] / 100000) == 3) + total_rob3[iModule]++; + } + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + total_rob7[iModule] *= total_modules[iModule]; + fprintf(ifile," %8d", total_rob7[iModule]); + total_rob7[NofModuleTypes] += total_rob7[iModule]; + } + fprintf(ifile," %8d", total_rob7[NofModuleTypes]); + fprintf(ifile," number of GBTX ROB7\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + total_rob5[iModule] *= total_modules[iModule]; + fprintf(ifile," %8d", total_rob5[iModule]); + total_rob5[NofModuleTypes] += total_rob5[iModule]; + } + fprintf(ifile," %8d", total_rob5[NofModuleTypes]); + fprintf(ifile," number of GBTX ROB5\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + total_rob3[iModule] *= total_modules[iModule]; + fprintf(ifile," %8d", total_rob3[iModule]); + total_rob3[NofModuleTypes] += total_rob3[iModule]; + } + fprintf(ifile," %8d", total_rob3[NofModuleTypes]); + fprintf(ifile," number of GBTX ROB3\n"); + + //------------------------------------------------------------------------------ + fprintf(ifile,"# e-links\n"); + + // e-links used + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + fprintf(ifile," %8d", asics_per_module[iModule] *2); + fprintf(ifile," %8d", total_asics[NofModuleTypes] *2); + fprintf(ifile," e-links used\n"); + + // e-links available + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + fprintf(ifile," %8d", GbtxPerModule[iModule] *14); + fprintf(ifile," %8d", total_gbtx[NofModuleTypes] *14); + fprintf(ifile," e-links available\n"); + + // e-link efficiency + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if (total_gbtx[iModule]!=0) + fprintf(ifile," %7.1f%%", (float)total_asics[iModule] *2 / (total_gbtx[iModule] *14) *100); + else + fprintf(ifile," -"); + } + if (total_gbtx[NofModuleTypes]!=0) + fprintf(ifile," %7.1f%%", (float)total_asics[NofModuleTypes] *2 / (total_gbtx[NofModuleTypes] *14) *100); + fprintf(ifile," e-link efficiency\n\n"); + + //------------------------------------------------------------------------------ + + // number of channels + fprintf(ifile,"# channels\n"); + + // channels per module + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if ((AsicsPerFeb[iModule] %100) == 16) + { + channels_per_feb[iModule] = 80 * 6; // rows // 84, if 63 of 64 ch used + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + if ((AsicsPerFeb[iModule] %100) == 15) + { + channels_per_feb[iModule] = 80 * 6; // rows + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + if ((AsicsPerFeb[iModule] %100) == 10) + { +// channels_per_feb[iModule] = 80 * 4; // rows + channels_per_feb[iModule] = (AsicsPerFeb[iModule] %100) * 16; // electronic channels + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + if ((AsicsPerFeb[iModule] %100) == 5) + { + channels_per_feb[iModule] = 80 * 2; // rows + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + + if ((AsicsPerFeb[iModule] %100) == 8) + { + channels_per_feb[iModule] = 128 * 2; // rows + channels_per_module[iModule] = channels_per_feb[iModule] * FebsPerModule[iModule]; + } + } + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + fprintf(ifile," %8d", channels_per_module[iModule]); + fprintf(ifile," channels per module\n"); + + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + fprintf(ifile," %8d", channels_per_feb[iModule]); + fprintf(ifile," channels per feb\n"); + + // channels used + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + total_channels[iModule] = channels_per_module[iModule] * total_modules[iModule]; + fprintf(ifile," %8d", total_channels[iModule]); + total_channels[NofModuleTypes] += total_channels[iModule]; + } + fprintf(ifile," %8d", total_channels[NofModuleTypes]); + fprintf(ifile," channels used\n"); + + // channels available + fprintf(ifile," "); + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + { + if ((AsicsPerFeb[iModule] / 100) == 4) // FASP case + { + fprintf(ifile,"%8dF", total_asics[iModule] * 16); + total_channels_u += total_asics[iModule] * 16; + } + else if ((AsicsPerFeb[iModule] / 100) == 3) + { + fprintf(ifile,"%8du", total_asics[iModule] * 32); + total_channels_u += total_asics[iModule] * 32; + } + else if ((AsicsPerFeb[iModule] / 100) == 2) + { + fprintf(ifile,"%8ds", total_asics[iModule] * 32); + total_channels_s += total_asics[iModule] * 32; + } + else + { + fprintf(ifile,"%8d ", total_asics[iModule] * 32); + total_channels_r += total_asics[iModule] * 32; + } + } + fprintf(ifile,"%8d", total_asics[NofModuleTypes] * 32); + fprintf(ifile," channels available\n"); + + // channel ratio for u,s,r density + fprintf(ifile," "); + fprintf(ifile,"%7.1f%%u", (float)total_channels_u / (total_asics[NofModuleTypes] * 32) * 100); + fprintf(ifile,"%7.1f%%s", (float)total_channels_s / (total_asics[NofModuleTypes] * 32) * 100); + fprintf(ifile,"%7.1f%%r", (float)total_channels_r / (total_asics[NofModuleTypes] * 32) * 100); + fprintf(ifile," channel ratio\n"); + + fprintf(ifile,"\n"); + fprintf(ifile,"%8.1f%% channel efficiency\n", 1. * total_channels[NofModuleTypes] / (total_asics[NofModuleTypes] * 32) * 100); + + //------------------------------------------------------------------------------ + + // total surface of TRD + for (Int_t iModule = 0; iModule < NofModuleTypes; iModule++) + if (iModule <= 3) + { + total_surface += total_modules[iModule] * DetectorSizeX[0] / 100 * DetectorSizeY[0] / 100; + total_actarea += total_modules[iModule] * (DetectorSizeX[0]-2*FrameWidth[0]) / 100 * (DetectorSizeY[0]-2*FrameWidth[0]) / 100; + } + else + { + total_surface += total_modules[iModule] * DetectorSizeX[1] / 100 * DetectorSizeY[1] / 100; + total_actarea += total_modules[iModule] * (DetectorSizeX[1]-2*FrameWidth[1]) / 100 * (DetectorSizeY[1]-2*FrameWidth[1]) / 100; + } + fprintf(ifile,"\n"); + + // summary + fprintf(ifile,"%7.2f m2 total surface \n", total_surface); + fprintf(ifile,"%7.2f m2 total active area\n", total_actarea); + fprintf(ifile,"%7.2f m3 total gas volume \n", total_actarea * gas_thickness / 100); // convert cm to m for thickness + + fprintf(ifile,"%7.2f cm2/ch average channel size\n", 100. * 100 * total_actarea / total_channels[NofModuleTypes]); + fprintf(ifile,"%7.2f ch/m2 channels per m2 active area\n", 1. * total_channels[NofModuleTypes] / total_actarea); + fprintf(ifile,"\n"); + + // gas volume position + fprintf(ifile,"# gas volume position\n"); + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + fprintf(ifile,"%10.4f cm position of gas volume - layer %2d\n", LayerPosition[iLayer] + LayerThickness/2. + gas_position, PlaneId[iLayer]); + fprintf(ifile,"\n"); + + // angles + fprintf(ifile,"# angles of acceptance\n"); + + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + { + if (iLayer <= 5) + { + // fprintf(ifile,"y %10.4f cm x %10.4f cm\n", 2.5 * DetectorSizeY[1], 3.5 * DetectorSizeX[1]); + Int_t type(LayerType[iLayer]/10); + yangle = atan(2.5 * DetectorSizeY[type] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + xangle = atan(3.5 * DetectorSizeX[type] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + } + if ((iLayer > 5) && (iLayer < 8)) + { + // fprintf(ifile,"y %10.4f cm x %10.4f cm\n", 3.5 * DetectorSizeY[1], 4.5 * DetectorSizeX[1]); + yangle = atan(3.5 * DetectorSizeY[1] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + xangle = atan(4.5 * DetectorSizeX[1] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + } + if ((iLayer >= 8) && (iLayer <10)) + { + // fprintf(ifile,"y %10.4f cm x %10.4f cm\n", 4.5 * DetectorSizeY[1], 5.5 * DetectorSizeX[1]); + yangle = atan(4.5 * DetectorSizeY[1] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + xangle = atan(5.5 * DetectorSizeX[1] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + } + fprintf(ifile,"v: %5.2f deg, h: %5.2f deg - vertical/horizontal - layer %2d\n", yangle, xangle, PlaneId[iLayer]); + } + fprintf(ifile,"\n"); + + // aperture + fprintf(ifile,"# inner aperture\n"); + + for (Int_t iLayer = 0; iLayer < MaxLayers; iLayer++) + if (ShowLayer[iLayer]) + { + if (iLayer <= 5) + { + // fprintf(ifile,"y %10.4f cm x %10.4f cm\n", 2.5 * DetectorSizeY[1], 3.5 * DetectorSizeX[1]); + yangle = atan(0.5 * DetectorSizeY[0] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + xangle = atan(0.5 * DetectorSizeX[0] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + } + if ((iLayer > 5) && (iLayer < 8)) + { + // fprintf(ifile,"y %10.4f cm x %10.4f cm\n", 3.5 * DetectorSizeY[1], 4.5 * DetectorSizeX[1]); + yangle = atan(0.5 * DetectorSizeY[0] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + xangle = atan(0.5 * DetectorSizeX[0] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + } + if ((iLayer >= 8) && (iLayer <10)) + { + // fprintf(ifile,"y %10.4f cm x %10.4f cm\n", 4.5 * DetectorSizeY[1], 5.5 * DetectorSizeX[1]); + yangle = atan(0.5 * DetectorSizeY[0] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + xangle = atan(0.5 * DetectorSizeX[0] / (LayerPosition[iLayer] + LayerThickness/2. + padplane_position)) * 180. / acos(-1.); + } + fprintf(ifile,"v: %5.2f deg, h: %5.2f deg - vertical/horizontal - layer %2d\n", yangle, xangle, PlaneId[iLayer]); + } + fprintf(ifile,"\n"); + + fclose(ifile); +} + + +void create_materials_from_media_file() +{ + // Use the FairRoot geometry interface to load the media which are already defined + FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader"); + FairGeoInterface* geoFace = geoLoad->getGeoInterface(); + TString geoPath = gSystem->Getenv("VMCWORKDIR"); + TString medFile = geoPath + "/geometry/media.geo"; + geoFace->setMediaFile(medFile); + geoFace->readMedia(); + + // Read the required media and create them in the GeoManager + FairGeoMedia* geoMedia = geoFace->getMedia(); + FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder(); + + FairGeoMedium* air = geoMedia->getMedium(KeepingVolumeMedium); + FairGeoMedium* pefoam20 = geoMedia->getMedium(RadiatorVolumeMedium); + FairGeoMedium* G10 = geoMedia->getMedium(LatticeVolumeMedium); + FairGeoMedium* kapton = geoMedia->getMedium(KaptonVolumeMedium); + FairGeoMedium* trdGas = geoMedia->getMedium(GasVolumeMedium); + FairGeoMedium* copper = geoMedia->getMedium(PadCopperVolumeMedium); + FairGeoMedium* carbon = geoMedia->getMedium(CarbonVolumeMedium); + FairGeoMedium* honeycomb = geoMedia->getMedium(HoneycombVolumeMedium); + FairGeoMedium* aluminium = geoMedia->getMedium(AluminiumVolumeMedium); + +// FairGeoMedium* goldCoatedCopper = geoMedia->getMedium("goldcoatedcopper"); +// FairGeoMedium* polypropylene = geoMedia->getMedium("polypropylene"); +// FairGeoMedium* mylar = geoMedia->getMedium("mylar"); + + geoBuild->createMedium(air); + geoBuild->createMedium(pefoam20); + geoBuild->createMedium(trdGas); + geoBuild->createMedium(honeycomb); + geoBuild->createMedium(carbon); + geoBuild->createMedium(G10); + geoBuild->createMedium(copper); + geoBuild->createMedium(kapton); + geoBuild->createMedium(aluminium); + +// geoBuild->createMedium(goldCoatedCopper); +// geoBuild->createMedium(polypropylene); +// geoBuild->createMedium(mylar); +} + +TGeoVolume* create_trd_module_type(Int_t moduleType) +{ + Int_t type = ModuleType[moduleType - 1]; + Double_t sizeX = DetectorSizeX[type]; + Double_t sizeY = DetectorSizeY[type]; + Double_t frameWidth = FrameWidth[type]; + Double_t activeAreaX = sizeX - 2 * frameWidth; + Double_t activeAreaY = sizeY - 2 * frameWidth; + + TGeoMedium* keepVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + TGeoMedium* radVolMed = gGeoMan->GetMedium(RadiatorVolumeMedium); + TGeoMedium* latticeVolMed = gGeoMan->GetMedium(LatticeVolumeMedium); + TGeoMedium* kaptonVolMed = gGeoMan->GetMedium(KaptonVolumeMedium); + TGeoMedium* gasVolMed = gGeoMan->GetMedium(GasVolumeMedium); + TGeoMedium* padcopperVolMed = gGeoMan->GetMedium(PadCopperVolumeMedium); + TGeoMedium* padpcbVolMed = gGeoMan->GetMedium(PadPcbVolumeMedium); + TGeoMedium* honeycombVolMed = gGeoMan->GetMedium(HoneycombVolumeMedium); + TGeoMedium* carbonVolMed = gGeoMan->GetMedium(CarbonVolumeMedium); +// TGeoMedium* mylarVolMed = gGeoMan->GetMedium(MylarVolumeMedium); +// TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsVolumeMedium); + TGeoMedium* frameVolMed = gGeoMan->GetMedium(FrameVolumeMedium); + TGeoMedium* aluledgeVolMed = gGeoMan->GetMedium(AluLegdeVolumeMedium); + TGeoMedium* febVolMed = gGeoMan->GetMedium(FebVolumeMedium); + TGeoMedium* asicVolMed = gGeoMan->GetMedium(AsicVolumeMedium); +// TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium); + + TString name = Form("module%d", moduleType); + TGeoVolume* module = new TGeoVolumeAssembly(name); + + + if(IncludeRadiator) + { + // Radiator + // TGeoBBox* trd_radiator = new TGeoBBox("", activeAreaX /2., activeAreaY /2., radiator_thickness /2.); + TGeoBBox* trd_radiator = new TGeoBBox("trd_radiator", sizeX /2., sizeY /2., radiator_thickness /2.); + TGeoVolume* trdmod1_radvol = new TGeoVolume("radiator", trd_radiator, radVolMed); + // TGeoVolume* trdmod1_radvol = new TGeoVolume(Form("module%d_radiator", moduleType), trd_radiator, radVolMed); + // TGeoVolume* trdmod1_radvol = new TGeoVolume(Form("trd1mod%dradiator", moduleType), trd_radiator, radVolMed); + trdmod1_radvol->SetLineColor(kBlue); + trdmod1_radvol->SetTransparency(70); // (60); // (70); // set transparency for the TRD radiator + TGeoTranslation* trd_radiator_trans = new TGeoTranslation("", 0., 0., radiator_position); + module->AddNode(trdmod1_radvol, 1, trd_radiator_trans); + } + + // Lattice grid + if(IncludeLattice) + { + + if (type==0) // inner modules + { + // printf("lattice type %d\n", type); + // drift window - lattice grid - sprossenfenster + TGeoBBox* trd_lattice_mod0_ho = new TGeoBBox("trd_lattice_mod0_ho", sizeX/2., lattice_o_width[type]/2., lattice_thickness/2.); // horizontal outer + TGeoBBox* trd_lattice_mod0_hi = new TGeoBBox("trd_lattice_mod0_hi", sizeX/2.-lattice_o_width[type], lattice_i_width[type]/2., lattice_thickness/2.); // horizontal inner + TGeoBBox* trd_lattice_mod0_vo = new TGeoBBox("trd_lattice_mod0_vo", lattice_o_width[type]/2., sizeX/2.-lattice_o_width[type], lattice_thickness/2.); // vertical outer + TGeoBBox* trd_lattice_mod0_vi = new TGeoBBox("trd_lattice_mod0_vi", lattice_i_width[type]/2., 0.20*activeAreaY/2.-lattice_i_width[type]/2., lattice_thickness/2.); // vertical inner + TGeoBBox* trd_lattice_mod0_vb = new TGeoBBox("trd_lattice_mod0_vb", lattice_i_width[type]/2., 0.20*activeAreaY/2.-lattice_i_width[type]/4., lattice_thickness/2.); // vertical border + + TGeoVolume* trd_lattice_mod0_vol_ho = new TGeoVolume("lattice0ho", trd_lattice_mod0_ho, latticeVolMed); + TGeoVolume* trd_lattice_mod0_vol_hi = new TGeoVolume("lattice0hi", trd_lattice_mod0_hi, latticeVolMed); + TGeoVolume* trd_lattice_mod0_vol_vo = new TGeoVolume("lattice0vo", trd_lattice_mod0_vo, latticeVolMed); + TGeoVolume* trd_lattice_mod0_vol_vi = new TGeoVolume("lattice0vi", trd_lattice_mod0_vi, latticeVolMed); + TGeoVolume* trd_lattice_mod0_vol_vb = new TGeoVolume("lattice0vb", trd_lattice_mod0_vb, latticeVolMed); + + trd_lattice_mod0_vol_ho->SetLineColor(kYellow); // kBlue); + trd_lattice_mod0_vol_vo->SetLineColor(kYellow); // kOrange); + trd_lattice_mod0_vol_hi->SetLineColor(kYellow); // kRed); + trd_lattice_mod0_vol_vi->SetLineColor(kYellow); // kWhite); + trd_lattice_mod0_vol_vb->SetLineColor(kYellow); + + TGeoTranslation *tv010 = new TGeoTranslation("tv010", 0., (1.00*activeAreaY/2.+lattice_o_width[type]/2.), 0); + TGeoTranslation *tv015 = new TGeoTranslation("tv015", 0., -(1.00*activeAreaY/2.+lattice_o_width[type]/2.), 0); + + TGeoTranslation *th020 = new TGeoTranslation("th020", (1.00*activeAreaX/2.+lattice_o_width[type]/2.), 0., 0); + TGeoTranslation *th025 = new TGeoTranslation("th025", -(1.00*activeAreaX/2.+lattice_o_width[type]/2.), 0., 0); + + Double_t hypos0[4] = { (0.60*activeAreaY/2.), + (0.20*activeAreaY/2.), + -(0.20*activeAreaY/2.), + -(0.60*activeAreaY/2.) }; + + Double_t vxpos0[4] = { (0.60*activeAreaX/2.), + (0.20*activeAreaX/2.), + -(0.20*activeAreaX/2.), + -(0.60*activeAreaX/2.) }; + + Double_t vypos0[5] = { (0.80*activeAreaY/2.+lattice_i_width[type]/4.), + (0.40*activeAreaY/2.) , + (0.00*activeAreaY/2.) , + -(0.40*activeAreaY/2.) , + -(0.80*activeAreaY/2.+lattice_i_width[type]/4.) }; + +// TGeoVolumeAssembly* trdmod0_lattice = new TGeoVolumeAssembly("mod0lattice"); // volume for lattice grid + + TGeoBBox* trd_lattice_mod0 = new TGeoBBox("trd_lattice_mod0", sizeX /2., sizeY /2., lattice_thickness /2.); + TGeoVolume* trdmod0_lattice = new TGeoVolume("lat_grid_mod0", trd_lattice_mod0, keepVolMed); + + // trdmod0_lattice->SetLineColor(kGreen); // set color for keeping volume + + // outer frame + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_ho, 1, tv010); + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_ho, 2, tv015); + + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vo, 3, th020); + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vo, 4, th025); + + // lattice piece number + Int_t lat0_no = 5; + + // horizontal bars + for (Int_t y = 0; y < 4; y++) + { + TGeoTranslation *t0xy = new TGeoTranslation("", 0, hypos0[y], 0); + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_hi, lat0_no, t0xy); + lat0_no++; + } + + // vertical bars + for (Int_t x = 0; x < 4; x++) + for (Int_t y = 0; y < 5; y++) + { + TGeoTranslation *t0xy = new TGeoTranslation("", vxpos0[x], vypos0[y], 0); + if ( (y==0) || (y==4) ) + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vb, lat0_no, t0xy); // border piece + else + trdmod0_lattice->AddNode(trd_lattice_mod0_vol_vi, lat0_no, t0xy); // middle piece + lat0_no++; + } + + // add lattice to module + TGeoTranslation *trd_lattice_trans = new TGeoTranslation("", 0., 0., lattice_position); + module->AddNode(trdmod0_lattice, 1, trd_lattice_trans); + } + + else if (type==1) // outer modules + { + // printf("lattice type %d\n", type); + // drift window - lattice grid - sprossenfenster + TGeoBBox *trd_lattice_mod1_ho = new TGeoBBox("trd_lattice_mod1_ho", sizeX/2., lattice_o_width[type]/2., lattice_thickness/2.); // horizontal outer + TGeoBBox *trd_lattice_mod1_hi = new TGeoBBox("trd_lattice_mod1_hi", sizeX/2.-lattice_o_width[type], lattice_i_width[type]/2., lattice_thickness/2.); // horizontal inner + TGeoBBox *trd_lattice_mod1_vo = new TGeoBBox("trd_lattice_mod1_vo", lattice_o_width[type]/2., sizeX/2.-lattice_o_width[type], lattice_thickness/2.); // vertical outer + TGeoBBox *trd_lattice_mod1_vi = new TGeoBBox("trd_lattice_mod1_vi", lattice_i_width[type]/2., 0.125*activeAreaY/2.-lattice_i_width[type]/2., lattice_thickness/2.); // vertical inner + TGeoBBox *trd_lattice_mod1_vb = new TGeoBBox("trd_lattice_mod1_vb", lattice_i_width[type]/2., 0.125*activeAreaY/2.-lattice_i_width[type]/4., lattice_thickness/2.); // vertical border + + TGeoVolume* trd_lattice_mod1_vol_ho = new TGeoVolume("lattice1ho", trd_lattice_mod1_ho, latticeVolMed); + TGeoVolume* trd_lattice_mod1_vol_hi = new TGeoVolume("lattice1hi", trd_lattice_mod1_hi, latticeVolMed); + TGeoVolume* trd_lattice_mod1_vol_vo = new TGeoVolume("lattice1vo", trd_lattice_mod1_vo, latticeVolMed); + TGeoVolume* trd_lattice_mod1_vol_vi = new TGeoVolume("lattice1vi", trd_lattice_mod1_vi, latticeVolMed); + TGeoVolume* trd_lattice_mod1_vol_vb = new TGeoVolume("lattice1vb", trd_lattice_mod1_vb, latticeVolMed); + + trd_lattice_mod1_vol_ho->SetLineColor(kYellow); // kBlue); + trd_lattice_mod1_vol_vo->SetLineColor(kYellow); // kOrange); + trd_lattice_mod1_vol_hi->SetLineColor(kYellow); // kRed); + trd_lattice_mod1_vol_vi->SetLineColor(kYellow); // kWhite); + trd_lattice_mod1_vol_vb->SetLineColor(kYellow); + + TGeoTranslation *tv110 = new TGeoTranslation("tv110", 0., (1.00*activeAreaY/2.+lattice_o_width[type]/2.), 0); + TGeoTranslation *tv118 = new TGeoTranslation("tv118", 0., -(1.00*activeAreaY/2.+lattice_o_width[type]/2.), 0); + + TGeoTranslation *th120 = new TGeoTranslation("th120", (1.00*activeAreaX/2.+lattice_o_width[type]/2.), 0., 0); + TGeoTranslation *th128 = new TGeoTranslation("th128", -(1.00*activeAreaX/2.+lattice_o_width[type]/2.), 0., 0); + + Double_t hypos1[7] = { (0.75*activeAreaY/2.), + (0.50*activeAreaY/2.), + (0.25*activeAreaY/2.), + (0.00*activeAreaY/2.), + -(0.25*activeAreaY/2.), + -(0.50*activeAreaY/2.), + -(0.75*activeAreaY/2.) }; + + Double_t vxpos1[7] = { (0.75*activeAreaX/2.), + (0.50*activeAreaX/2.), + (0.25*activeAreaX/2.), + (0.00*activeAreaX/2.), + -(0.25*activeAreaX/2.), + -(0.50*activeAreaX/2.), + -(0.75*activeAreaX/2.) }; + + Double_t vypos1[8] = { (0.875*activeAreaY/2.+lattice_i_width[type]/4.), + (0.625*activeAreaY/2.) , + (0.375*activeAreaY/2.) , + (0.125*activeAreaY/2.) , + -(0.125*activeAreaY/2.) , + -(0.375*activeAreaY/2.) , + -(0.625*activeAreaY/2.) , + -(0.875*activeAreaY/2.+lattice_i_width[type]/4.) }; + +// TGeoVolumeAssembly* trdmod1_lattice = new TGeoVolumeAssembly("mod1lattice"); // volume for lattice grid + + TGeoBBox* trd_lattice_mod1 = new TGeoBBox("trd_lattice_mod1", sizeX /2., sizeY /2., lattice_thickness /2.); + TGeoVolume* trdmod1_lattice = new TGeoVolume("lat_grid_mod1", trd_lattice_mod1, keepVolMed); + + // trdmod1_lattice->SetLineColor(kGreen); // set color for keeping volume + + // outer frame + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_ho, 1, tv110); + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_ho, 2, tv118); + + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vo, 3, th120); + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vo, 4, th128); + + // lattice piece number + Int_t lat1_no = 5; + + // horizontal bars + for (Int_t y = 0; y < 7; y++) + { + TGeoTranslation *t1xy = new TGeoTranslation("", 0, hypos1[y], 0); + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_hi, lat1_no, t1xy); + lat1_no++; + } + + // vertical bars + for (Int_t x = 0; x < 7; x++) + for (Int_t y = 0; y < 8; y++) + { + TGeoTranslation *t1xy = new TGeoTranslation("", vxpos1[x], vypos1[y], 0); + if ( (y==0) || (y==7) ) + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vb, lat1_no, t1xy); // border piece + else + trdmod1_lattice->AddNode(trd_lattice_mod1_vol_vi, lat1_no, t1xy); // middle piece + lat1_no++; + } + + // add lattice to module + TGeoTranslation *trd_lattice_trans = new TGeoTranslation("", 0., 0., lattice_position); + module->AddNode(trdmod1_lattice, 1, trd_lattice_trans); + } + + } // with lattice grid + + if(IncludeKaptonFoil) + { + // Kapton Foil + TGeoBBox* trd_kapton = new TGeoBBox("trd_kapton", sizeX /2., sizeY /2., kapton_thickness /2.); + TGeoVolume* trdmod1_kaptonvol = new TGeoVolume("kaptonfoil", trd_kapton, kaptonVolMed); + // TGeoVolume* trdmod1_kaptonvol = new TGeoVolume(Form("module%d_kaptonfoil", moduleType), trd_kapton, kaptonVolMed); + // TGeoVolume* trdmod1_kaptonvol = new TGeoVolume(Form("trd1mod%dkapton", moduleType), trd_kapton, kaptonVolMed); + trdmod1_kaptonvol->SetLineColor(kGreen); + TGeoTranslation* trd_kapton_trans = new TGeoTranslation("", 0., 0., kapton_position); + module->AddNode(trdmod1_kaptonvol, 1, trd_kapton_trans); + } + + // start of Frame in z + // Gas + TGeoBBox* trd_gas = new TGeoBBox("trd_gas", activeAreaX /2., activeAreaY /2., gas_thickness /2.); + TGeoVolume* trdmod1_gasvol = new TGeoVolume("gas", trd_gas, gasVolMed); + // TGeoVolume* trdmod1_gasvol = new TGeoVolume(Form("module%d_gas", moduleType), trd_gas, gasVolMed); + // TGeoVolume* trdmod1_gasvol = new TGeoVolume(Form("trd1mod%dgas", moduleType), trd_gas, gasVolMed); + // trdmod1_gasvol->SetLineColor(kBlue); + trdmod1_gasvol->SetLineColor(kGreen); // to avoid blue overlaps in the screenshots + trdmod1_gasvol->SetTransparency(40); // set transparency for the TRD gas + TGeoTranslation* trd_gas_trans = new TGeoTranslation("", 0., 0., gas_position); + module->AddNode(trdmod1_gasvol, 1, trd_gas_trans); + // end of Frame in z + + if(IncludeGasFrame) + { + // frame1 + TGeoBBox* trd_frame1 = new TGeoBBox("trd_frame1", sizeX /2., frameWidth /2., frame_thickness/2.); + TGeoVolume* trdmod1_frame1vol = new TGeoVolume("frame1", trd_frame1, frameVolMed); + trdmod1_frame1vol->SetLineColor(kRed); + + // translations + TGeoTranslation* trd_frame1_trans = new TGeoTranslation("", 0., activeAreaY /2. + frameWidth /2., frame_position); + module->AddNode(trdmod1_frame1vol, 1, trd_frame1_trans); + trd_frame1_trans = new TGeoTranslation("", 0., -(activeAreaY /2. + frameWidth /2.), frame_position); + module->AddNode(trdmod1_frame1vol, 2, trd_frame1_trans); + + + // frame2 + TGeoBBox* trd_frame2 = new TGeoBBox("trd_frame2", frameWidth /2., activeAreaY /2., frame_thickness /2.); + TGeoVolume* trdmod1_frame2vol = new TGeoVolume("frame2", trd_frame2, frameVolMed); + trdmod1_frame2vol->SetLineColor(kRed); + + // translations + TGeoTranslation* trd_frame2_trans = new TGeoTranslation("", activeAreaX /2. + frameWidth /2., 0., frame_position); + module->AddNode(trdmod1_frame2vol, 1, trd_frame2_trans); + trd_frame2_trans = new TGeoTranslation("", -(activeAreaX /2. + frameWidth /2.), 0., frame_position); + module->AddNode(trdmod1_frame2vol, 2, trd_frame2_trans); + } + + if(IncludePadplane) + { + // Pad Copper + TGeoBBox* trd_padcopper = new TGeoBBox("trd_padcopper", sizeX /2., sizeY /2., padcopper_thickness /2.); + TGeoVolume* trdmod1_padcoppervol = new TGeoVolume("padcopper", trd_padcopper, padcopperVolMed); + // TGeoVolume* trdmod1_padcoppervol = new TGeoVolume(Form("module%d_padcopper", moduleType), trd_padcopper, padcopperVolMed); + // TGeoVolume* trdmod1_padcoppervol = new TGeoVolume(Form("trd1mod%dpadcopper", moduleType), trd_padcopper, padcopperVolMed); + trdmod1_padcoppervol->SetLineColor(kOrange); + TGeoTranslation *trd_padcopper_trans = new TGeoTranslation("", 0., 0., padcopper_position); + module->AddNode(trdmod1_padcoppervol, 1, trd_padcopper_trans); + + // Pad Plane + TGeoBBox* trd_padpcb = new TGeoBBox("trd_padpcb", sizeX /2., sizeY /2., padplane_thickness /2.); + TGeoVolume* trdmod1_padpcbvol = new TGeoVolume("padplane", trd_padpcb, padpcbVolMed); + // TGeoVolume* trdmod1_padpcbvol = new TGeoVolume(Form("module%d_padplane", moduleType), trd_padpcb, padpcbVolMed); + // TGeoVolume* trdmod1_padpcbvol = new TGeoVolume(Form("trd1mod%dpadplane", moduleType), trd_padpcb, padpcbVolMed); + trdmod1_padpcbvol->SetLineColor(kBlue); + TGeoTranslation *trd_padpcb_trans = new TGeoTranslation("", 0., 0., padplane_position); + module->AddNode(trdmod1_padpcbvol, 1, trd_padpcb_trans); + } + + if(IncludeBackpanel) + { + // Honeycomb + TGeoBBox* trd_honeycomb = new TGeoBBox("trd_honeycomb", sizeX /2., sizeY /2., honeycomb_thickness /2.); + TGeoVolume* trdmod1_honeycombvol = new TGeoVolume("honeycomb", trd_honeycomb, honeycombVolMed); + // TGeoVolume* trdmod1_honeycombvol = new TGeoVolume(Form("module%d_honeycomb", moduleType), trd_honeycomb, honeycombVolMed); + // TGeoVolume* trdmod1_honeycombvol = new TGeoVolume(Form("trd1mod%dhoneycomb", moduleType), trd_honeycomb, honeycombVolMed); + trdmod1_honeycombvol->SetLineColor(kOrange); + TGeoTranslation* trd_honeycomb_trans = new TGeoTranslation("", 0., 0., honeycomb_position); + module->AddNode(trdmod1_honeycombvol, 1, trd_honeycomb_trans); + + // Carbon fiber layers + TGeoBBox* trd_carbon = new TGeoBBox("trd_carbon", sizeX /2., sizeY /2., carbon_thickness /2.); + TGeoVolume* trdmod1_carbonvol = new TGeoVolume("carbonsheet", trd_carbon, carbonVolMed); + // TGeoVolume* trdmod1_carbonvol = new TGeoVolume(Form("module%d_carbonsheet", moduleType), trd_carbon, carbonVolMed); + // TGeoVolume* trdmod1_carbonvol = new TGeoVolume(Form("trd1mod%dcarbon", moduleType), trd_carbon, carbonVolMed); + trdmod1_carbonvol->SetLineColor(kGreen); + TGeoTranslation* trd_carbon_trans = new TGeoTranslation("", 0., 0., carbon_position); + module->AddNode(trdmod1_carbonvol, 1, trd_carbon_trans); + } + + if(IncludeAluLedge) + { + // Al-ledge + TGeoBBox* trd_aluledge1 = new TGeoBBox("trd_aluledge1", sizeY /2., aluminium_width /2., aluminium_thickness /2.); + TGeoVolume* trdmod1_aluledge1vol = new TGeoVolume("aluledge1", trd_aluledge1, aluledgeVolMed); + trdmod1_aluledge1vol->SetLineColor(kRed); + + // translations + TGeoTranslation* trd_aluledge1_trans = new TGeoTranslation("", 0., sizeY /2. - aluminium_width /2., aluminium_position); + module->AddNode(trdmod1_aluledge1vol, 1, trd_aluledge1_trans); + trd_aluledge1_trans = new TGeoTranslation("", 0., -(sizeY /2. - aluminium_width /2.), aluminium_position); + module->AddNode(trdmod1_aluledge1vol, 2, trd_aluledge1_trans); + + + // Al-ledge + TGeoBBox* trd_aluledge2 = new TGeoBBox("trd_aluledge2", aluminium_width /2., sizeY /2. - aluminium_width, aluminium_thickness /2.); + TGeoVolume* trdmod1_aluledge2vol = new TGeoVolume("aluledge2", trd_aluledge2, aluledgeVolMed); + trdmod1_aluledge2vol->SetLineColor(kRed); + + // translations + TGeoTranslation* trd_aluledge2_trans = new TGeoTranslation("", sizeX /2. - aluminium_width /2., 0., aluminium_position); + module->AddNode(trdmod1_aluledge2vol, 1, trd_aluledge2_trans); + trd_aluledge2_trans = new TGeoTranslation("", -(sizeX /2. - aluminium_width /2.), 0., aluminium_position); + module->AddNode(trdmod1_aluledge2vol, 2, trd_aluledge2_trans); + } + + // FEBs + if (IncludeFebs) + { + // assemblies + TGeoVolumeAssembly* trd_feb_vol = new TGeoVolumeAssembly("febvol"); // the mother volume of all FEBs + TGeoVolumeAssembly* trd_feb_box = new TGeoVolumeAssembly("febbox"); // volume for inclined FEBs, then shifted along y + //TGeoVolumeAssembly* trd_feb_vol = new TGeoVolumeAssembly(Form("module%d_febvol", moduleType)); // the mother volume of all FEBs + //TGeoVolumeAssembly* trd_feb_box = new TGeoVolumeAssembly(Form("module%d_febbox", moduleType)); // volume for inclined FEBs, then shifted along y + //TGeoVolumeAssembly* trd_feb_vol = new TGeoVolumeAssembly(Form("trd1mod%dfebvol", moduleType)); // the mother volume of all FEBs + //TGeoVolumeAssembly* trd_feb_box = new TGeoVolumeAssembly(Form("trd1mod%dfebbox", moduleType)); // volume for inclined FEBs, then shifted along y + + // translations + rotations + TGeoTranslation *trd_feb_trans1; // center to corner + TGeoTranslation *trd_feb_trans2; // corner back + TGeoRotation *trd_feb_rotation; // rotation around x axis + TGeoTranslation *trd_feb_y_position; // shift to y position on TRD +// TGeoTranslation *trd_feb_null; // no displacement + +// replaced by matrix operation (see below) +// // Double_t yback, zback; +// // TGeoCombiTrans *trd_feb_placement; +// // // fix Z back offset 0.3 at some point +// // yback = - sin(feb_rotation_angle/180*3.141) * feb_width /2.; +// // zback = - (1-cos(feb_rotation_angle/180*3.141)) * feb_width /2. + 0.3; +// // trd_feb_placement = new TGeoCombiTrans(0, feb_pos_y + yback, zback, trd_feb_rotation); +// // trd_feb_box->AddNode(trdmod1_feb, iFeb+1, trd_feb_placement); + +// trd_feb_null = new TGeoTranslation("", 0., 0., 0.); // empty operation + trd_feb_trans1 = new TGeoTranslation("", 0.,-feb_thickness/2.,-feb_width/2.); // move bottom right corner to center + trd_feb_trans2 = new TGeoTranslation("", 0., feb_thickness/2., feb_width/2.); // move bottom right corner back + trd_feb_rotation = new TGeoRotation(); trd_feb_rotation->RotateX(feb_rotation_angle[moduleType-1]); + + TGeoHMatrix *incline_feb = new TGeoHMatrix(""); + +// (*incline_feb) = (*trd_feb_null); // OK +// (*incline_feb) = (*trd_feb_y_position); // OK +// (*incline_feb) = (*trd_feb_trans1); // OK +// (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_y_position); // OK +// (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_trans2); // OK +// (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_rotation); // OK +// (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_rotation) * (*trd_feb_trans2) * (*trd_feb_y_position); // not OK + // trd_feb_y_position is displaced in rotated coordinate system + + // matrix operation to rotate FEB PCB around its corner on the backanel + (*incline_feb) = (*trd_feb_trans1) * (*trd_feb_rotation) * (*trd_feb_trans2); // OK + + // Create all FEBs and place them in an assembly which will be added to the TRD module + TGeoBBox* trd_feb = new TGeoBBox("trd_feb", activeAreaX/2., feb_thickness/2., feb_width/2.); // the FEB itself - as a cuboid + TGeoVolume* trdmod1_feb = new TGeoVolume("feb", trd_feb, febVolMed); // the FEB made of a certain medium + // TGeoVolume* trdmod1_feb = new TGeoVolume(Form("module%d_feb", moduleType), trd_feb, febVolMed); // the FEB made of a certain medium + // TGeoVolume* trdmod1_feb = new TGeoVolume(Form("trd1mod%dfeb", moduleType), trd_feb, febVolMed); // the FEB made of a certain medium + trdmod1_feb->SetLineColor(kYellow); // set yellow color + trd_feb_box->AddNode(trdmod1_feb, 1, incline_feb); + // now we have an inclined FEB + + // ASICs + if (IncludeAsics) + { + Double_t asic_pos; + Double_t asic_pos_x; + TGeoTranslation *trd_asic_trans0; // ASIC on FEB x position + TGeoTranslation *trd_asic_trans1; // center to corner + TGeoTranslation *trd_asic_trans2; // corner back + TGeoRotation *trd_asic_rotation; // rotation around x axis + + trd_asic_trans1 = new TGeoTranslation("", 0., -(feb_thickness + asic_offset + asic_thickness/2.), -feb_width/2.); // move ASIC center to FEB corner + trd_asic_trans2 = new TGeoTranslation("", 0., feb_thickness + asic_offset + asic_thickness/2. , feb_width/2.); // move FEB corner back to asic center + trd_asic_rotation = new TGeoRotation(); trd_asic_rotation->RotateX(feb_rotation_angle[moduleType-1]); + + TGeoHMatrix *incline_asic; + + // put many ASICs on each inclined FEB + TGeoBBox* trd_asic = new TGeoBBox("trd_asic", asic_width/2., asic_thickness/2., asic_width/2.); // ASIC dimensions + // TODO: use Silicon as ASICs material + TGeoVolume* trdmod1_asic = new TGeoVolume("asic", trd_asic, asicVolMed); // the ASIC made of a certain medium + // TGeoVolume* trdmod1_asic = new TGeoVolume(Form("module%d_asic", moduleType), trd_asic, asicVolMed); // the ASIC made of a certain medium + // TGeoVolume* trdmod1_asic = new TGeoVolume(Form("trd1mod%dasic", moduleType), trd_asic, asicVolMed); // the ASIC made of a certain medium + trdmod1_asic->SetLineColor(kBlue); // set blue color for ASICs + + Int_t nofAsics = AsicsPerFeb[ moduleType - 1 ] % 100; + Int_t groupAsics = AsicsPerFeb[ moduleType - 1 ] / 100; // either 1 or 2 or 3 (new ultimate) + + if ((nofAsics == 16) && (activeAreaX < 60)) + asic_distance = 0.0; // for 57 cm // 0.1; // for 60 cm + else + asic_distance = 0.4; + + for (Int_t iAsic = 0; iAsic < (nofAsics / groupAsics); iAsic++) + { + if (groupAsics == 1) // single ASICs + { + asic_pos = (iAsic + 0.5) / nofAsics - 0.5; // equal spacing of ASICs on the FEB, e.g. for no=3 : -1/3, 0, +1/3 + + // ASIC 1 + asic_pos_x = asic_pos * activeAreaX; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness/2.+asic_thickness/2.+asic_offset, 0.); // move asic on top of FEB + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, iAsic+1, incline_asic); // now we have ASICs on the inclined FEB + } + + if (groupAsics == 2) // pairs of ASICs + { + asic_pos = (iAsic + 0.5) / (nofAsics / groupAsics) - 0.5; // equal spacing of ASICs on the FEB, e.g. for no=3 : -1/3, 0, +1/3 + + // ASIC 1 + asic_pos_x = asic_pos * activeAreaX + (0.5 + asic_distance/2.) * asic_width; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness/2.+asic_thickness/2.+asic_offset, 0.); // move asic on top of FEB); + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, 2*iAsic+1, incline_asic); // now we have ASICs on the inclined FEB + + // ASIC 2 + asic_pos_x = asic_pos * activeAreaX - (0.5 + asic_distance/2.) * asic_width; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness/2.+asic_thickness/2.+asic_offset, 0.); // move asic on top of FEB + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, 2*iAsic+2, incline_asic); // now we have ASICs on the inclined FEB + } + + if (groupAsics == 3) // triplets of ASICs + { + asic_pos = (iAsic + 0.5) / (nofAsics / groupAsics) - 0.5; // equal spacing of ASICs on the FEB, e.g. for no=3 : -1/3, 0, +1/3 + + // ASIC 1 + asic_pos_x = asic_pos * activeAreaX + 1.1 * asic_width; // (0.5 + asic_distance/2.) * asic_width; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness/2.+asic_thickness/2.+asic_offset, 0.); // move asic on top of FEB); + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, 3*iAsic+1, incline_asic); // now we have ASICs on the inclined FEB + + // ASIC 2 + asic_pos_x = asic_pos * activeAreaX; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness/2.+asic_thickness/2.+asic_offset, 0.); // move asic on top of FEB + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, 3*iAsic+2, incline_asic); // now we have ASICs on the inclined FEB + + // ASIC 3 + asic_pos_x = asic_pos * activeAreaX - 1.1 * asic_width; // (0.5 + asic_distance/2.) * asic_width; + trd_asic_trans0 = new TGeoTranslation("", asic_pos_x, feb_thickness/2.+asic_thickness/2.+asic_offset, 0.); // move asic on top of FEB + incline_asic = new TGeoHMatrix(""); + (*incline_asic) = (*trd_asic_trans0) * (*trd_asic_trans1) * (*trd_asic_rotation) * (*trd_asic_trans2); // OK + trd_feb_box->AddNode(trdmod1_asic, 3*iAsic+3, incline_asic); // now we have ASICs on the inclined FEB + } + + } + // now we have an inclined FEB with ASICs + } + + + // now go on with FEB placement + Double_t feb_pos; + Double_t feb_pos_y; + + Int_t nofFebs = FebsPerModule[ moduleType - 1 ]; + for (Int_t iFeb = 0; iFeb < nofFebs; iFeb++) + { + feb_pos = (iFeb + 0.5) / nofFebs - 0.5; // equal spacing of FEBs on the backpanel + // cout << "feb_pos " << iFeb << ": " << feb_pos << endl; + feb_pos_y = feb_pos * activeAreaY; + feb_pos_y += feb_width/2. * sin( feb_rotation_angle[moduleType-1] * acos(-1.)/180.); + + // shift inclined FEB in y to its final position + trd_feb_y_position = new TGeoTranslation("", 0., feb_pos_y, feb_z_offset); // with additional fixed offset in z direction + // trd_feb_y_position = new TGeoTranslation("", 0., feb_pos_y, 0.0); // touching the backpanel with the corner + trd_feb_vol->AddNode(trd_feb_box, iFeb+1, trd_feb_y_position); // position FEB in y + } + + if (IncludeRobs) + { + // GBTx ROBs + Double_t rob_size_x = 20.0; // 13.0; // 130 mm + Double_t rob_size_y = 9.0; // 4.5; // 45 mm + Double_t rob_offset = 1.2; + Double_t rob_thickness = feb_thickness; + + TGeoVolumeAssembly* trd_rob_box = new TGeoVolumeAssembly("robbox"); // volume for inclined FEBs, then shifted along y + TGeoBBox* trd_rob = new TGeoBBox("trd_rob", rob_size_x/2., rob_size_y/2., rob_thickness/2.); // the ROB itself + TGeoVolume* trdmod1_rob = new TGeoVolume("rob", trd_rob, febVolMed); // the ROB made of a certain medium + trdmod1_rob->SetLineColor(kRed); // set color + + // TGeoHMatrix *incline_rob = new TGeoHMatrix(""); + trd_rob_box->AddNode(trdmod1_rob, 1); + + // GBTXs + Double_t gbtx_pos; + Double_t gbtx_pos_x; + Double_t gbtx_pos_y; + TGeoTranslation *trd_gbtx_trans1; // center to corner + + // GBTX parameters + const Double_t gbtx_thickness = 0.25; // 2.5 mm + const Double_t gbtx_width = 3.0; // 2.0; 1.0; // 1 cm + + // put many GBTXs on each inclined FEB + TGeoBBox* trd_gbtx = new TGeoBBox("trd_gbtx", gbtx_width/2., gbtx_width/2., gbtx_thickness/2.); // GBTX dimensions + TGeoVolume* trdmod1_gbtx = new TGeoVolume("gbtx", trd_gbtx, asicVolMed); // the GBTX made of a certain medium + trdmod1_gbtx->SetLineColor(kGreen); // set color for GBTXs + + Int_t nofGbtxs = GbtxPerRob[ moduleType - 1 ] % 100; + Int_t groupGbtxs = GbtxPerRob[ moduleType - 1 ] / 100; // usually 1 + + // nofGbtxs = 7; + // groupGbtxs = 1; + + Int_t nofGbtxX = (nofGbtxs - 1) / 2. + 1; // +1 is for GBTx master + Int_t nofGbtxY = 2; + + Double_t gbtx_distance = 0.4; + Int_t iGbtx = 1; + + for (Int_t iGbtxX = 0; iGbtxX < nofGbtxX; iGbtxX++) + { + gbtx_pos = (iGbtxX + 0.5) / nofGbtxX - 0.5; // equal spacing of GBTXs on the FEB, e.g. for no=3 : -1/3, 0, +1/3 + gbtx_pos_x = -gbtx_pos * rob_size_x; + + if (iGbtxX > 0) + for (Int_t iGbtxY = 0; iGbtxY < nofGbtxY; iGbtxY++) + { + gbtx_pos = (iGbtxY + 0.5) / nofGbtxY - 0.5; // equal spacing of GBTXs on the FEB, e.g. for no=3 : -1/3, 0, +1/3 + gbtx_pos_y = gbtx_pos * rob_size_y; + + trd_gbtx_trans1 = new TGeoTranslation("", gbtx_pos_x, gbtx_pos_y, rob_thickness/2.+gbtx_thickness/2.); // move gbtx on top of ROB + trd_rob_box->AddNode(trdmod1_gbtx, iGbtx++, trd_gbtx_trans1); // now we have GBTXs on the ROB + } + else + { + gbtx_pos_y = 0; + + trd_gbtx_trans1 = new TGeoTranslation("", gbtx_pos_x, gbtx_pos_y, rob_thickness/2.+gbtx_thickness/2.); // move gbtx on top of ROB + trd_rob_box->AddNode(trdmod1_gbtx, iGbtx++, trd_gbtx_trans1); // now we have GBTXs on the ROB + } + + } + + // now go on with ROB placement + Double_t rob_pos; + Double_t rob_pos_y; + TGeoTranslation *trd_rob_y_position; // shift to y position on TRD + + Int_t nofRobs = RobsPerModule[ moduleType - 1 ]; + for (Int_t iRob = 0; iRob < nofRobs; iRob++) + { + rob_pos = (iRob + 0.5) / nofRobs - 0.5; // equal spacing of ROBs on the backpanel + rob_pos_y = rob_pos * activeAreaY; + + // shift inclined ROB in y to its final position + if ( feb_rotation_angle[moduleType-1] == 90 ) // if FEB parallel to backpanel + trd_rob_y_position = new TGeoTranslation("", 0., rob_pos_y, -feb_width/2. + rob_offset); // place ROBs close to FEBs + else + { +// Int_t rob_z_pos = 0.; // test where ROB is placed by default + Int_t rob_z_pos = -feb_width/2. + feb_width * cos( feb_rotation_angle[moduleType-1] * acos(-1.)/180. ) + rob_offset; + if (rob_z_pos > feb_width/2.) // if the rob is too far out + { + rob_z_pos = feb_width/2. - rob_thickness; // place ROBs at end of feb volume + std::cout << "GBTx ROB was outside of the FEB volume, check overlap with FEB" << std::endl; + } + trd_rob_y_position = new TGeoTranslation("", 0., rob_pos_y, rob_z_pos); + } + trd_feb_vol->AddNode(trd_rob_box, iRob+1, trd_rob_y_position); // position FEB in y + } + + } // IncludeGbtx + + // put FEB box on module + TGeoTranslation* trd_febvolume_trans = new TGeoTranslation("", 0., 0., febvolume_position); + gGeoMan->GetVolume(name)->AddNode(trd_feb_vol, 1, trd_febvolume_trans); // put febvolume at correct z position wrt to the module + } + + // DE123 + + return module; +} + + +//________________________________________________________________________________________________ +TGeoVolume* create_trdi_module_type() +{ + Int_t lyType = 2, moduleType = 4; + Double_t sizeX = DetectorSizeX[lyType]; + Double_t sizeY = DetectorSizeY[lyType]; + Double_t frameWidth = FrameWidth[lyType]; + Double_t activeAreaX = sizeX - 2 * frameWidth; + Double_t activeAreaY = sizeY - 2 * frameWidth; + + TGeoMedium* keepVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + TGeoMedium* radVolMed = gGeoMan->GetMedium(RadiatorVolumeMedium); + TGeoMedium* latticeVolMed = gGeoMan->GetMedium(LatticeVolumeMedium); + TGeoMedium* kaptonVolMed = gGeoMan->GetMedium(KaptonVolumeMedium); + TGeoMedium* gasVolMed = gGeoMan->GetMedium(GasVolumeMedium); + TGeoMedium* padcopperVolMed = gGeoMan->GetMedium(PadCopperVolumeMedium); + TGeoMedium* padpcbVolMed = gGeoMan->GetMedium(PadPcbVolumeMedium); + TGeoMedium* honeycombVolMed = gGeoMan->GetMedium(HoneycombVolumeMedium); + TGeoMedium* carbonVolMed = gGeoMan->GetMedium(CarbonVolumeMedium); +// TGeoMedium* mylarVolMed = gGeoMan->GetMedium(MylarVolumeMedium); +// TGeoMedium* electronicsVolMed = gGeoMan->GetMedium(ElectronicsVolumeMedium); + TGeoMedium* frameVolMed = gGeoMan->GetMedium(FrameVolumeMedium); + TGeoMedium* febVolMed = gGeoMan->GetMedium(FebVolumeMedium); + TGeoMedium* asicVolMed = gGeoMan->GetMedium(AsicVolumeMedium); +// TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium); + + TString name = "moduleBu"; + TGeoVolume* module = new TGeoVolumeAssembly(name); + + + if(IncludeRadiator){ // Radiator + TGeoBBox* trd_radiator = new TGeoBBox("trd_radiator", sizeX /2., sizeY /2., radiator_thickness /2.); + TGeoVolume* trdmod1_radvol = new TGeoVolume("radiator", trd_radiator, radVolMed); + trdmod1_radvol->SetLineColor(kRed); + trdmod1_radvol->SetTransparency(50); // (60); // (70); // set transparency for the TRD radiator + TGeoTranslation* trd_radiator_trans = new TGeoTranslation("", 0., 0., radiator_position); + module->AddNode(trdmod1_radvol, 1, trd_radiator_trans); + } + + + if(IncludeLattice){ // Entrance window in the case of the Bucharest prototype + // Carbon fiber layers + TGeoBBox* trd_carbon = new TGeoBBox("trd_carbon", activeAreaX /2., activeAreaY /2., carbonBu_thickness /2.); + TGeoVolume* trdmod1_carbonvol = new TGeoVolume("EntranceWinC", trd_carbon, carbonVolMed); + trdmod1_carbonvol->SetLineColor(kGray); + // Honeycomb layer + TGeoBBox* trd_honeycomb = new TGeoBBox("trd_honeycombBu", activeAreaX /2., activeAreaY /2., honeycombBu_thickness /2.); + TGeoVolume* trdmod1_honeycombvol = new TGeoVolume("EntranceWinHC", trd_honeycomb, honeycombVolMed); + trdmod1_honeycombvol->SetLineColor(kOrange); + + module->AddNode(trdmod1_carbonvol, 1, + new TGeoTranslation("", 0., 0., carbonBu1_position)); + module->AddNode(trdmod1_honeycombvol, 1, + new TGeoTranslation("", 0., 0., honeycombBu0_position)); + module->AddNode(trdmod1_carbonvol, 2, + new TGeoTranslation("", 0., 0., carbonBu0_position)); + } + + // Gas + TGeoBBox* trd_gas = new TGeoBBox("trd_gas", activeAreaX /2., activeAreaY /2., gas_thickness /2.); + TGeoVolume* trdmod1_gasvol = new TGeoVolume("gas", trd_gas, gasVolMed); + trdmod1_gasvol->SetLineColor(kWhite); // to avoid blue overlaps in the screenshots + trdmod1_gasvol->SetTransparency(40); // set transparency for the TRD gas + module->AddNode(trdmod1_gasvol, 1, new TGeoTranslation("", 0., 0., gasBu_position)); + // end of Frame in z + + if(IncludeGasFrame) { + // frame1 + TGeoBBox* trd_frame1 = new TGeoBBox("trd_frame1", sizeX /2., frameWidth /2., frameBu_thickness/2.); + TGeoVolume* trdmod1_frame1vol = new TGeoVolume("frameH", trd_frame1, frameVolMed); + trdmod1_frame1vol->SetLineColor(kBlue); + module->AddNode(trdmod1_frame1vol, 1, + new TGeoTranslation("", 0., activeAreaY /2. + frameWidth/2., frameBu_position)); + module->AddNode(trdmod1_frame1vol, 2, + new TGeoTranslation("", 0., -(activeAreaY /2. + frameWidth/2.), frameBu_position)); + // frame2 + TGeoBBox* trd_frame2 = new TGeoBBox("trd_frame2", frameWidth /2., activeAreaY /2., frameBu_thickness/2.); + TGeoVolume* trdmod1_frame2vol = new TGeoVolume("frameV", trd_frame2, frameVolMed); + trdmod1_frame2vol->SetLineColor(kBlue); + module->AddNode(trdmod1_frame2vol, 1, + new TGeoTranslation("", activeAreaX /2. + frameWidth/2., 0., frameBu_position)); + module->AddNode(trdmod1_frame2vol, 2, + new TGeoTranslation("", -(activeAreaX /2. + frameWidth/2.), 0., frameBu_position)); + } + + if(IncludePadplane) { + // Pad Copper + TGeoBBox* trd_padcopper = new TGeoBBox("trd_padcopper", activeAreaX /2., activeAreaY /2., padcopper_thickness /2.); + TGeoVolume* trdmod1_padcoppervol = new TGeoVolume("pads", trd_padcopper, padcopperVolMed); + trdmod1_padcoppervol->SetLineColor(kRed); + module->AddNode(trdmod1_padcoppervol, 1, + new TGeoTranslation("", 0., 0., padcopperBu_position)); + // Pad Plane + TGeoBBox* trd_padpcb = new TGeoBBox("trd_padpcb", activeAreaX /2., activeAreaY /2., padplane_thickness /2.); + TGeoVolume* trdmod1_padpcbvol = new TGeoVolume("padsPCB", trd_padpcb, padpcbVolMed); + trdmod1_padpcbvol->SetLineColor(kGreen); + module->AddNode(trdmod1_padpcbvol, 1, + new TGeoTranslation("", 0., 0., padplaneBu_position)); + } + + if(IncludeBackpanel) { + // Honeycomb + TGeoBBox* trd_honeycomb = new TGeoBBox("trd_honeycomb", activeAreaX /2., activeAreaY /2., honeycombBu_thickness /2.); + TGeoVolume* trdmod1_honeycombvol = new TGeoVolume("BackpanelHC", trd_honeycomb, honeycombVolMed); + trdmod1_honeycombvol->SetLineColor(kOrange); + module->AddNode(trdmod1_honeycombvol, 1, + new TGeoTranslation("", 0., 0., honeycombBu1_position)); + // Screen fibre-glass support (PCB) + TGeoBBox* trd_screenpcb = new TGeoBBox("trd_padpcb", activeAreaX /2., activeAreaY /2., glassFibre_thickness/2.); + TGeoVolume* trdmod1_screenpcbvol = new TGeoVolume("BackpanelPCB", trd_screenpcb, padpcbVolMed); + trdmod1_screenpcbvol->SetLineColor(kGreen); + module->AddNode(trdmod1_screenpcbvol, 1, + new TGeoTranslation("", 0., 0., glassFibre_position)); + // Pad Copper + TGeoBBox* trd_screencopper = new TGeoBBox("trd_padcopper", activeAreaX /2., activeAreaY /2., cuCoating_thickness/2.); + TGeoVolume* trdmod1_screencoppervol = new TGeoVolume("BackpanelScreen", trd_screencopper, padcopperVolMed); + trdmod1_screencoppervol->SetLineColor(kRed); + module->AddNode(trdmod1_screencoppervol, 1, + new TGeoTranslation("", 0., 0., cuCoating_position)); + } + + // FEBs + if (IncludeFebs) { + TGeoVolumeAssembly* trd_feb_vol = new TGeoVolumeAssembly("febvol"); // the mother volume of all FEBs + TGeoVolumeAssembly* trd_feb_box = new TGeoVolumeAssembly("febbox"); + TGeoTranslation *trd_feb_position; // trnslation for positioning FEBs on TRD + + // Create all FEBs and place them in an assembly which will be added to the TRD module + TGeoBBox* trd_feb = new TGeoBBox("trd_feb", febFASP_width/2., activeAreaY/4.-0.5, febFASP_thickness/2.); + TGeoVolume* trdmod1_feb = new TGeoVolume("feb", trd_feb, febVolMed); // the FEB made of PCB + trdmod1_feb->SetLineColor(kYellow); + trd_feb_box->AddNode(trdmod1_feb, 1); + + // ASICs + if (IncludeAsics) { + Double_t asic_pos; + Double_t asic_pos_y; + TGeoTranslation *trd_asic_pos; // ASIC on FEB x position + + // put many ASICs on each inclined FEB + TGeoBBox* trd_asic = new TGeoBBox("trd_fasp", 0.5*fasp_size[0], 0.5*fasp_size[1], asic_thickness/2.); // ASIC dimensions + // TODO: use Silicon as ASICs material + TGeoVolume* trdmod1_asic = new TGeoVolume("fasp", trd_asic, asicVolMed); // the ASIC made of a certain medium + trdmod1_asic->SetLineColor(kBlack); + + Int_t nofAsics = AsicsPerFeb[ moduleType - 1 ] % 100; + for (Int_t iAsic(0), jAsic(1); iAsic < nofAsics; iAsic++) { + asic_pos = (iAsic + 0.5) /nofAsics - 0.5; // equal spacing of ASICs on the FEB + asic_pos_y = asic_pos * activeAreaY/2.; + trd_asic_pos = new TGeoTranslation("", + (iAsic%2?-1:1)*fasp_xoffset, + asic_pos_y+(iAsic%2?-1:1)*fasp_yoffset, + feb_thickness/2.+asic_thickness/2.+asic_offset); + trd_feb_box->AddNode(trdmod1_asic, jAsic++, trd_asic_pos); + } + } + + + // now go on with FEB placement + Double_t feb_pos; + Double_t feb_pos_x, feb_pos_y; + + Int_t nofFebs = FebsPerModule[ moduleType - 1 ], nofFebsHalf(nofFebs/2); + Double_t zfeb_pos(febFASP_position); + for(Int_t iFebLy(0), jFeb(1); iFebLy<4; iFebLy++){ + for (Int_t iFeb(0); iFeb < nofFebsHalf; iFeb++) { + feb_pos = (iFeb + 0.5) / nofFebsHalf - 0.5; // equal spacing of FEBs on the backpanel + feb_pos_x = feb_pos * activeAreaX; + feb_pos_y = activeAreaY/4; + + // move to final position over the detector for : + // the upper row ... + trd_feb_position = new TGeoTranslation("", feb_pos_x, feb_pos_y, zfeb_pos); + trd_feb_vol->AddNode(trd_feb_box, jFeb++, trd_feb_position); + // ... and the bottom row + trd_feb_position = new TGeoTranslation("", feb_pos_x, -feb_pos_y, zfeb_pos); + trd_feb_vol->AddNode(trd_feb_box, jFeb++, trd_feb_position); + } + zfeb_pos+=febFASP_zspace; + } + if (IncludeRobs) { + TGeoVolumeAssembly* trd_rob_box = new TGeoVolumeAssembly("robbox"); + TGeoBBox* trd_rob = new TGeoBBox("trd_rob", rob_size_x/2., rob_size_y/2., rob_thickness/2.); + TGeoVolume* trdmod1_rob = new TGeoVolume("rob", trd_rob, febVolMed); // the ROB made of PCB + trdmod1_rob->SetLineColor(kRed); // set color + trd_rob_box->AddNode(trdmod1_rob, 1); + + // Add connector PCB + TGeoBBox* trd_robConn = new TGeoBBox("trd_robConn", robConn_size_y/2., robConn_size_x/2., rob_thickness/2.); + TGeoVolume* trdmod1_robConn = new TGeoVolume("robConn", trd_robConn, febVolMed); // the ROB made of PCB + trdmod1_robConn->SetLineColor(kRed); // set color + // shift to x position on C-ROB3 + TGeoTranslation *trd_robConn_position = + new TGeoTranslation("", robConn_xoffset, 0, -robConn_FMCheight-feb_thickness); + trd_rob_box->AddNode(trdmod1_robConn, 1, trd_robConn_position); + + // Add FMC connector + TGeoBBox* trd_fmcConn = new TGeoBBox("trd_fmcConn", robConn_FMCwidth/2., robConn_FMClength/2., robConn_FMCheight/2.); + TGeoVolume* trdmod1_fmcConn = new TGeoVolume("robConn", trd_fmcConn, frameVolMed); // the FMC made of Al + trdmod1_fmcConn->SetLineColor(kGray); // set color + // shift to x position on C-ROB3 + TGeoTranslation *trd_fmcConn_position = + new TGeoTranslation("", robConn_xoffset+2, 0, -robConn_FMCheight/2-feb_thickness/2); + trd_rob_box->AddNode(trdmod1_fmcConn, 1, trd_fmcConn_position); + + // GBTXs + Double_t gbtx_pos; + Double_t gbtx_pos_x; + Double_t gbtx_pos_y; + TGeoTranslation *trd_gbtx_trans1; // center to corner + + // put 3 GBTXs on each C-ROC + TGeoBBox* trd_gbtx = new TGeoBBox("trd_gbtx", gbtx_width/2., gbtx_width/2., gbtx_thickness/2.); + TGeoVolume* trdmod1_gbtx = new TGeoVolume("gbtx", trd_gbtx, asicVolMed); + trdmod1_gbtx->SetLineColor(kGreen); + + Int_t nofGbtxs = GbtxPerRob[ moduleType - 1 ] % 100; + Int_t groupGbtxs = GbtxPerRob[ moduleType - 1 ] / 100; // usually 1 + + Int_t nofGbtxX = (nofGbtxs - 1) / 2. + 1; // +1 is for GBTx master + Int_t nofGbtxY = 2; + + for (Int_t iGbtxX(0), iGbtx(1); iGbtxX < nofGbtxX; iGbtxX++) { + gbtx_pos = (iGbtxX + 0.5) / nofGbtxX - 0.5; + gbtx_pos_x = -gbtx_pos * rob_size_x; + + if (iGbtxX > 0){ + for (Int_t iGbtxY = 0; iGbtxY < nofGbtxY; iGbtxY++) { + gbtx_pos = (iGbtxY + 0.5) / nofGbtxY - 0.5; + gbtx_pos_y = gbtx_pos * rob_size_y; + + trd_gbtx_trans1 = new TGeoTranslation("", gbtx_pos_x, gbtx_pos_y, rob_thickness/2.+gbtx_thickness/2.); // move gbtx on top of ROB + trd_rob_box->AddNode(trdmod1_gbtx, iGbtx++, trd_gbtx_trans1); + } + } else { + gbtx_pos_y = 0; + + trd_gbtx_trans1 = new TGeoTranslation("", gbtx_pos_x, gbtx_pos_y, rob_thickness/2.+gbtx_thickness/2.); // move gbtx on top of ROB + trd_rob_box->AddNode(trdmod1_gbtx, iGbtx++, trd_gbtx_trans1); // now we have GBTXs on the ROB + } + } + TGeoRotation *trd_rob_rotation = new TGeoRotation(); + trd_rob_rotation->RotateZ(90.); trd_rob_rotation->RotateX(90.); + + // now go on with ROB placement + Double_t rob_pos; + Double_t rob_pos_y; + TGeoTranslation *trd_rob_y_position; // shift to y position on TRD + + Int_t nofRobs = RobsPerModule[ moduleType - 1 ], nofRobsHalf(nofRobs/2); + for (Int_t iRob = 0; iRob < nofRobsHalf; iRob++) { + rob_pos = (iRob + 0.5) / nofRobsHalf - 0.5; // equal spacing of ROBs on the backpanel + rob_pos_y = rob_pos * activeAreaY; + trd_rob_y_position = new TGeoTranslation("", rob_zoffset, rob_pos_y, sizeY/2.+rob_yoffset); + TGeoHMatrix *trd_rob_transform = new TGeoHMatrix(""); + (*trd_rob_transform)=(*trd_rob_rotation)*(*trd_rob_y_position); + trd_feb_vol->AddNode(trd_rob_box, iRob+1, trd_rob_transform); + } + trd_rob_rotation->RotateZ(180.); + for (Int_t iRob = 0; iRob < nofRobsHalf; iRob++) { + rob_pos = (iRob + 0.5) / nofRobsHalf - 0.5; // equal spacing of ROBs on the backpanel + rob_pos_y = rob_pos * activeAreaY; + trd_rob_y_position = new TGeoTranslation("", rob_zoffset, rob_pos_y, sizeY/2.+rob_yoffset); + TGeoHMatrix *trd_rob_transform = new TGeoHMatrix(""); + (*trd_rob_transform)=(*trd_rob_rotation)*(*trd_rob_y_position); + trd_feb_vol->AddNode(trd_rob_box, iRob+1, trd_rob_transform); // position FEB in y + } + } // IncludeGbtx + + // put FEB box on module + TGeoTranslation* trd_febvolume_trans = new TGeoTranslation("", 0., 0., febvolume_position); + gGeoMan->GetVolume(name)->AddNode(trd_feb_vol, 1, trd_febvolume_trans); // put febvolume at correct z position wrt to the module + } + + + return module; +} + + + +Int_t copy_nr(Int_t stationNr, Int_t copyNr, Int_t isRotated, Int_t planeNr, Int_t modinplaneNr) +{ + if (modinplaneNr > 128) + printf("Warning: too many modules in this layer %02d (max 128 according to CbmTrdAddress)\n", planeNr); + + return (stationNr * 100000000 // 1 digit + + copyNr * 1000000 // 2 digit + + isRotated * 100000 // 1 digit + + planeNr * 1000 // 2 digit + + modinplaneNr * 1 ); // 3 digit +} + +void create_detector_layers(Int_t layerId) +{ + Int_t module_id = 0; + Int_t layerType = LayerType[layerId] / 10; // this is also a station number + Int_t isRotated = LayerType[layerId] % 10; // is 1 for layers 2,4, ... + + TGeoRotation* module_rotation = new TGeoRotation(); + + Int_t stationNr = layerType; + +// rotation is now done in the for loop for each module individually +// if ( isRotated == 1 ) { +// module_rotation = new TGeoRotation(); +// module_rotation->RotateZ(90.); +// } else { +// module_rotation = new TGeoRotation(); +// module_rotation->RotateZ( 0.); +// } + + Int_t innerarray_size1 = LayerArraySize[layerType - 1][0]; + Int_t innerarray_size2 = LayerArraySize[layerType - 1][1]; + const Int_t* innerLayer; + + Int_t outerarray_size1 = LayerArraySize[layerType - 1][2]; + Int_t outerarray_size2 = LayerArraySize[layerType - 1][3]; + const Int_t* outerLayer; + + if ( 1 == layerType ) { + innerLayer = (Int_t*) layer1i; + outerLayer = (Int_t*) layer1o; + } else if ( 2 == layerType ) { + innerLayer = (Int_t*) layer2i; + outerLayer = (Int_t*) layer2o; + } else if ( 3 == layerType ) { + innerLayer = (Int_t*) layer3i; + outerLayer = (Int_t*) layer3o; + } else { + std::cout << "Type of layer not known" << std::endl; + } + +// add layer keeping volume + TString layername = Form("layer%02d", PlaneId[layerId]); + TGeoVolume* layer = new TGeoVolumeAssembly(layername); + + // compute layer copy number + Int_t i = LayerType[layerId] / 10 * 10000 // 1 digit // fStation + + LayerType[layerId] % 10 * 1000 // 1 digit // isRotated + + LayerNrInStation[layerId] * 100 // 1 digit // fLayer + + PlaneId[layerId]; // 2 digits // fPlane // layer type as leading digit in copy number of layer + gGeoMan->GetVolume(geoVersion)->AddNode(layer, i); + +// Int_t i = 100 + PlaneId[layerId]; +// gGeoMan->GetVolume(geoVersion)->AddNode(layer, 1); +// cout << layername << endl; + + Double_t ExplodeScale = 1.00; + if(DoExplode) // if explosion, set scale + ExplodeScale = ExplodeFactor; + + Int_t modId = 0; // module id, only within this layer + + Int_t copyNrIn[4] = { 0, 0, 0, 0 }; // copy number for each module type + for ( Int_t type = 1; type <= 4; type++) { + for ( Int_t j = (innerarray_size1-1); j >= 0; j--) { // start from the bottom + for ( Int_t i = 0; i < innerarray_size2; i++) { + module_id = *(innerLayer + (j * innerarray_size2 + i)); + if ( module_id /100 == type) { + Int_t y = -(j-2); + Int_t x = i-2; + + // displacement + Double_t dx = 0; + Double_t dy = 0; + Double_t dz = 0; + + if(DisplaceRandom) + { + dx = (r3.Rndm()-.5) * 2 * maxdx; // max +- 0.1 cm shift + dy = (r3.Rndm()-.5) * 2 * maxdy; // max +- 0.1 cm shift + dz = (r3.Rndm()-.5) * 2 * maxdz; // max +- 1.0 cm shift + } + + Double_t xPos = DetectorSizeX[0] * x * ExplodeScale + dx; + Double_t yPos = DetectorSizeY[0] * y * ExplodeScale + dy; + copyNrIn[type - 1]++; + modId++; + + // statistics per layer and module type + ModuleStats[layerId][type - 1]++; + +// Int_t copy = copy_nr_modid(stationNr, layerNrInStation, copyNrIn[type - 1], PlaneId[layerId], modId); // with modID +// Int_t copy = copy_nr(stationNr, copyNrIn[type - 1], isRotated, PlaneId[layerId], modId); + + // take care of FEB orientation - away from beam + Int_t copy = 0; + module_rotation = new TGeoRotation(); // need to renew rotation to start from 0 degree angle + if ( isRotated == 0 ) // layer 1,3 ... + { + copy = copy_nr(stationNr, copyNrIn[type - 1], module_id /10 %10, PlaneId[layerId], modId); + module_rotation->RotateZ( (module_id /10 %10) * 90. ); // rotate module by 0 or 180 degrees, see layer[1-3][i,o] - vertical pads + } + else // layer 2,4 ... + { + copy = copy_nr(stationNr, copyNrIn[type - 1], module_id %10 , PlaneId[layerId], modId); + module_rotation->RotateZ( (module_id %10) * 90. ); // rotate module by 90 or 270 degrees, see layer[1-3][i,o] - horizontal pads + } + + // rotation + Double_t drotx = 0; + Double_t droty = 0; + Double_t drotz = 0; + + if(RotateRandom) + { + drotx = (r3.Rndm()-.5) * 2 * maxdrotx; + droty = (r3.Rndm()-.5) * 2 * maxdroty; + drotz = (r3.Rndm()-.5) * 2 * maxdrotz; + + module_rotation->RotateZ( drotz ); + module_rotation->RotateY( droty ); + module_rotation->RotateX( drotx ); + } + + TGeoCombiTrans* module_placement = new TGeoCombiTrans(xPos, yPos, LayerPosition[layerId] + LayerThickness/2 + dz, module_rotation); // shift by half layer thickness +// gGeoMan->GetVolume(geoVersion)->AddNode(gModules[type - 1], copy, module_placement); +// add module to layer + gGeoMan->GetVolume(layername)->AddNode(gModules[type - 1], copy, module_placement); +// + } + } + } + } + + Int_t copyNrOut[4] = { 0, 0, 0, 0 }; // copy number for each module type + for ( Int_t type = 5; type <= 8; type++) { + for ( Int_t j = (outerarray_size1-1); j >= 0; j--) { // start from the bottom + for ( Int_t i = 0; i < outerarray_size2; i++) { + module_id = *(outerLayer + (j * outerarray_size2 + i)); + if ( module_id /100 == type) { + Int_t y = -(j-4); + Int_t x = i-5; + + // displacement + Double_t dx = 0; + Double_t dy = 0; + Double_t dz = 0; + + if(DisplaceRandom) + { + dx = (r3.Rndm()-.5) * 2 * maxdx; // max +- 0.1 cm shift + dy = (r3.Rndm()-.5) * 2 * maxdy; // max +- 0.1 cm shift + dz = (r3.Rndm()-.5) * 2 * maxdz; // max +- 1.0 cm shift + } + + Double_t xPos = DetectorSizeX[1] * x * ExplodeScale + dx; + Double_t yPos = DetectorSizeY[1] * y * ExplodeScale + dy; + copyNrOut[type - 5]++; + modId++; + + // statistics per layer and module type + ModuleStats[layerId][type - 1]++; + +// Int_t copy = copy_nr_modid(stationNr, layerNrInStation, copyNrOut[type - 5], PlaneId[layerId], modId); // with modID +// Int_t copy = copy_nr(stationNr, copyNrOut[type - 5], isRotated, PlaneId[layerId], modId); + + // take care of FEB orientation - away from beam + Int_t copy = 0; + module_rotation = new TGeoRotation(); // need to renew rotation to start from 0 degree angle + if ( isRotated == 0 ) // layer 1,3 ... + { + copy = copy_nr(stationNr, copyNrOut[type - 5], module_id /10 %10, PlaneId[layerId], modId); + module_rotation->RotateZ( (module_id /10 %10) * 90. ); // rotate module by 0 or 180 degrees, see layer[1-3][i,o] - vertical pads + } + else // layer 2,4 ... + { + copy = copy_nr(stationNr, copyNrOut[type - 5], module_id %10 , PlaneId[layerId], modId); + module_rotation->RotateZ( (module_id %10) * 90. ); // rotate module by 90 or 270 degrees, see layer[1-3][i,o] - horizontal pads + } + + // rotation + Double_t drotx = 0; + Double_t droty = 0; + Double_t drotz = 0; + + if(RotateRandom) + { + drotx = (r3.Rndm()-.5) * 2 * maxdrotx; + droty = (r3.Rndm()-.5) * 2 * maxdroty; + drotz = (r3.Rndm()-.5) * 2 * maxdrotz; + + module_rotation->RotateZ( drotz ); + module_rotation->RotateY( droty ); + module_rotation->RotateX( drotx ); + } + + Double_t frameref_angle = 0; + Double_t layer_angle = 0; + + cout << "layer " << layerId << " ---" << endl; + frameref_angle = atan( (DetectorSizeX[1]/2. - FrameWidth[1]) / (zfront[setupid] + 3 * LayerThickness) ); + // frameref_angle = 15. / 180. * acos(-1); // set a fixed reference angle + cout << "reference angle " << frameref_angle * 180 / acos(-1) << endl; + + layer_angle = atan( (DetectorSizeX[1]/2. - FrameWidth[1]) / (zfront[setupid] + layerId * LayerThickness) ); + cout << "layer angle " << layer_angle * 180 / acos(-1) << endl; + // DEDE + // xPos = tan( frameref_angle ) * (zfront[setupid] + layerId * LayerThickness) - (DetectorSizeX[1]/2. - FrameWidth[1]); // shift module along x-axis + xPos = 0; + cout << "layer " << layerId << " - xPos " << xPos << endl; + + layer_angle = atan( (DetectorSizeX[1]/2. - FrameWidth[1] + xPos) / (zfront[setupid] + layerId * LayerThickness) ); + cout << "corrected angle " << layer_angle * 180 / acos(-1) << endl; + + +// Double_t frameangle[4] = {0}; +// for ( Int_t ilayer = 3; ilayer >= 0; ilayer--) +// { +// frameangle[ilayer] = atan( (DetectorSizeX[1]/2. - FrameWidth[1]) / (zfront[setupid] + ilayer * LayerThickness) ); +// cout << "layer " << ilayer << " - angle " << frameangle[ilayer] * 180 / acos(-1) << endl; +// +// xPos = (DetectorSizeX[1]/2. - FrameWidth[1]); +// cout << "layer " << ilayer << " - xPos " << xPos << endl; +// +// xPos = tan( frameangle[3] ) * (zfront[setupid] + ilayer * LayerThickness); +// cout << "layer " << ilayer << " - xPos " << xPos << endl; +// +// xPos = (DetectorSizeX[1]/2. - FrameWidth[1]) - ( tan( frameangle[3] ) * (zfront[setupid] + ilayer * LayerThickness) ); // shift module along x-axis +// cout << "layer " << ilayer << " - xPos " << xPos << endl; +// } + + + TGeoCombiTrans* module_placement = new TGeoCombiTrans(xPos, yPos, LayerPosition[layerId] + LayerThickness/2 + dz, module_rotation); // shift by half layer thickness + +// add module to layer + gGeoMan->GetVolume(layername)->AddNode(gModules[type - 1], copy, module_placement); +// + } + } + } + } +} + + +void create_mag_field_vector() +{ + const TString cbmfield_01 = "cbm_field"; + TGeoVolume* cbmfield_1 = new TGeoVolumeAssembly(cbmfield_01); + + TGeoMedium* copperVolMed = gGeoMan->GetMedium(PadCopperVolumeMedium); // define Volume Medium + + TGeoRotation *rotx090 = new TGeoRotation("rotx090"); rotx090->RotateX( 90.); // rotate 90 deg around x-axis + TGeoRotation *rotx270 = new TGeoRotation("rotx270"); rotx270->RotateX( 270.); // rotate 270 deg around x-axis + + Int_t tube_length = 500; + Int_t cone_length = 120; + Int_t cone_width = 280; + + // field tube + TGeoTube* trd_field = new TGeoTube("", 0., 100/2., tube_length/2.); + TGeoVolume* trdmod1_fieldvol = new TGeoVolume("tube", trd_field, copperVolMed); + trdmod1_fieldvol->SetLineColor(kRed); + trdmod1_fieldvol->SetTransparency(30); // transparency for the TRD + TGeoTranslation* trd_field_trans = new TGeoTranslation("", 0., 0., 0.); // tube position + cbmfield_1->AddNode(trdmod1_fieldvol, 1, trd_field_trans); + + // field cone + TGeoCone* trd_cone = new TGeoCone("", cone_length/2., 0., cone_width/2., 0., 0.); + TGeoVolume* trdmod1_conevol = new TGeoVolume("cone", trd_cone, copperVolMed); + trdmod1_conevol->SetLineColor(kRed); + trdmod1_conevol->SetTransparency(30); // transparency for the TRD + TGeoTranslation* trd_cone_trans = new TGeoTranslation("", 0., 0., (tube_length+cone_length)/2.); // cone position + cbmfield_1->AddNode(trdmod1_conevol, 1, trd_cone_trans); + + TGeoCombiTrans* field_combi01 = new TGeoCombiTrans(0., 0., 40., rotx270); // point in +y direction + gGeoMan->GetVolume(geoVersion)->AddNode(cbmfield_1, 1, field_combi01); + + // TGeoCombiTrans* field_combi02 = new TGeoCombiTrans( 200., 0., 0., rotx090); // point in -y direction + // gGeoMan->GetVolume(geoVersion)->AddNode(cbmfield_1, 2, field_combi02); +} + + +void create_gibbet_support() +{ + const TString gibbet_01 = "gibbet_bars_trd1"; + TGeoVolume* gibbet_1 = new TGeoVolumeAssembly(gibbet_01); + + TGeoBBox* gibbet1; + TGeoBBox* gibbet2; + TGeoBBox* gibbet3; + TGeoBBox* gibbet4; + + TGeoVolume* gibbet1_vol; + TGeoVolume* gibbet2_vol; + TGeoVolume* gibbet3_vol; + TGeoVolume* gibbet4_vol; + + TGeoTranslation* gibbet1_trans; + TGeoTranslation* gibbet2_trans; + TGeoTranslation* gibbet3_trans; + TGeoTranslation* gibbet4_trans; + TGeoTranslation* gibbet5_trans; + + Int_t x_offset = 0.0; // x position of gibbet rim towards module + // Int_t x_offset = -10.0; // x position of gibbet rim towards module + + const Int_t kColor1010n = kAzure+8; // gibbet color + const Int_t kColor1010s = kGray; // gibbet color + const Int_t kColor0305n = kBlue; // gibbet color + + TGeoMedium* k1010nVolMed = gGeoMan->GetMedium(Kanya10x10nVolumeMedium); + TGeoMedium* k1010sVolMed = gGeoMan->GetMedium(Kanya10x10sVolumeMedium); + TGeoMedium* k0305nVolMed = gGeoMan->GetMedium(Kanya03x05nVolumeMedium); + + const Int_t kanya01 = 105; // kanyahoritop + const Int_t kanya02 = 90; // kanyavertnear + const Int_t kanya03 = 150; // kanyavertpill + + const Int_t gapx = 5; // gap in x direction + const Int_t gapy = 2; // gap in y direction + const Int_t gapxpill = 2; // gap in x direction between vertical pillars + + // horizontal gibbet 2020 + gibbet1 = new TGeoBBox("gibbet1", kanya01 /2., gibbet_width /2., gibbet_thickness /2.); + gibbet1_vol = new TGeoVolume("gibbetvol1", gibbet1, k1010nVolMed); + gibbet1_vol->SetLineColor(kColor1010n); + + // translations + gibbet1_trans = new TGeoTranslation("", (kanya01 - DetectorSizeX[1]) /2. - gapx + x_offset, + (DetectorSizeY[1] + gibbet_width) /2. + gapy, + 0.); + gibbet_1->AddNode(gibbet1_vol, 1, gibbet1_trans); + + // vertical gibbet 2020 + gibbet2 = new TGeoBBox("gibbet2", gibbet_width /2., kanya02 /2., gibbet_thickness /2.); + gibbet2_vol = new TGeoVolume("gibbetvol2", gibbet2, k1010nVolMed); + gibbet2_vol->SetLineColor(kColor1010n); + + // translations + gibbet2_trans = new TGeoTranslation("", -(DetectorSizeX[1] + gibbet_width)/2. - gapx + x_offset, + (DetectorSizeY[1] - kanya02) /2. + gapy + 2 * gibbet_width, + 0.); + gibbet_1->AddNode(gibbet2_vol, 2, gibbet2_trans); + + // vertical gibbet pillar 2020 + gibbet3 = new TGeoBBox("gibbet3", gibbet_width /2., kanya03 /2., gibbet_thickness /2.); + gibbet3_vol = new TGeoVolume("gibbetvol3", gibbet3, k1010sVolMed); + gibbet3_vol->SetLineColor(kColor1010s); + + // translations + gibbet3_trans = new TGeoTranslation("", -(DetectorSizeX[1] + 3 * gibbet_width)/2. - gapx - gapxpill + x_offset, + 0., 0.); + gibbet_1->AddNode(gibbet3_vol, 3, gibbet3_trans); + + // vertical mount rails 2020 + gibbet4 = new TGeoBBox("gibbet4", rail_width /2., (DetectorSizeY[1] + gapy) /2., rail_thickness /2.); + gibbet4_vol = new TGeoVolume("gibbetvol4", gibbet4, k0305nVolMed); + gibbet4_vol->SetLineColor(kColor0305n); + + // translations + gibbet4_trans = new TGeoTranslation("", -(DetectorSizeX[1] - rail_width)/2. + x_offset, + +gapy/2., + 0.); + gibbet_1->AddNode(gibbet4_vol, 4, gibbet4_trans); + + // translations + gibbet5_trans = new TGeoTranslation("", (DetectorSizeX[1] - rail_width)/2. + x_offset, + +gapy/2., + 0.); + gibbet_1->AddNode(gibbet4_vol, 5, gibbet5_trans); + + Int_t l; + for (l=0; l<4; l++) + if ((ShowLayer[l]) && (BusBarOrientation[l] == 1)) // if geometry contains layer l + { + TString layername = Form("layer%02d", l+1); + TGeoTranslation* gibbet_placement = new TGeoTranslation(0, 0, LayerPosition[l] + LayerThickness/2. + gibbet_position); + gGeoMan->GetVolume(layername)->AddNode(gibbet_1, l, gibbet_placement); + } + +} + + +void create_power_bars_vertical() +{ + const TString power_01 = "power_bars_trd1"; + TGeoVolume* power_1 = new TGeoVolumeAssembly(power_01); + + TGeoBBox* power1; + TGeoBBox* power2; + + TGeoVolume* power1_vol; + TGeoVolume* power2_vol; + + TGeoTranslation* power1_trans; + TGeoTranslation* power2_trans; + + const Int_t kColor = kBlue; // bus bar color + + TGeoMedium* powerBusVolMed = gGeoMan->GetMedium(PowerBusVolumeMedium); + + // powerbus - horizontal short + power1 = new TGeoBBox("power1", (DetectorSizeX[1] - DetectorSizeX[0] - powerbar_width)/2., powerbar_width /2., powerbar_thickness /2.); + power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed); + power1_vol->SetLineColor(kColor); + + // translations + power1_trans = new TGeoTranslation("", 1 * (DetectorSizeX[1] - DetectorSizeY[0]/2.), 1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power1_vol, 1, power1_trans); + + power1_trans = new TGeoTranslation("", -1 * (DetectorSizeX[1] - DetectorSizeY[0]/2.), -1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power1_vol, 2, power1_trans); + + // powerbus - horizontal long + power1 = new TGeoBBox("power1", (DetectorSizeX[0] - powerbar_width)/2., powerbar_width /2., powerbar_thickness /2.); + power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed); + power1_vol->SetLineColor(kColor); + + // translations + power1_trans = new TGeoTranslation("", -1 * DetectorSizeX[0], 1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power1_vol, 3, power1_trans); + + power1_trans = new TGeoTranslation("", 1 * DetectorSizeX[0], -1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power1_vol, 4, power1_trans); + + + // powerbus - vertical long + power2 = new TGeoBBox("power2", powerbar_width /2., (5 * DetectorSizeY[1] + powerbar_width) /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", -3.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 1, power2_trans); + power2_trans = new TGeoTranslation("", 3.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 2, power2_trans); + + power2_trans = new TGeoTranslation("", -2.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 3, power2_trans); + power2_trans = new TGeoTranslation("", 2.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 4, power2_trans); + + power2_trans = new TGeoTranslation("", -1.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 5, power2_trans); + power2_trans = new TGeoTranslation("", 1.5 * DetectorSizeX[1], 0., 0.); + power_1->AddNode(power2_vol, 6, power2_trans); + + // powerbus - vertical middle + power2 = new TGeoBBox("power2", powerbar_width /2., (3 * DetectorSizeY[1] + powerbar_width) /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", -1.5 * DetectorSizeX[0], 0., 0.); + power_1->AddNode(power2_vol, 7, power2_trans); + power2_trans = new TGeoTranslation("", 1.5 * DetectorSizeX[0], 0., 0.); + power_1->AddNode(power2_vol, 8, power2_trans); + + // powerbus - vertical short 1 + power2 = new TGeoBBox("power2", powerbar_width /2., 1 * DetectorSizeY[1] /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + // power2_vol->SetLineColor(kRed); + + // translations + power2_trans = new TGeoTranslation("", -0.5 * DetectorSizeX[1], (2.0 * DetectorSizeY[1] + powerbar_width/2.), 0.); + power_1->AddNode(power2_vol, 9, power2_trans); + power2_trans = new TGeoTranslation("", 0.5 * DetectorSizeX[1], -(2.0 * DetectorSizeY[1] + powerbar_width/2.), 0.); + power_1->AddNode(power2_vol,10, power2_trans); + + // powerbus - vertical short 2 + power2 = new TGeoBBox("power2", powerbar_width /2., (1 * DetectorSizeY[1] + powerbar_width) /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", -0.5 * DetectorSizeX[1], -2.0 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol,11, power2_trans); + power2_trans = new TGeoTranslation("", 0.5 * DetectorSizeX[1], 2.0 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol,12, power2_trans); + + // powerbus - vertical short 3 + power2 = new TGeoBBox("power2", powerbar_width /2., (2 * DetectorSizeY[0] + powerbar_width/2.) /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", -0.5 * DetectorSizeX[0], (1.5 * DetectorSizeY[0] + powerbar_width/4.), 0.); + power_1->AddNode(power2_vol,11, power2_trans); + power2_trans = new TGeoTranslation("", 0.5 * DetectorSizeX[0], -(1.5 * DetectorSizeY[0] + powerbar_width/4.), 0.); + power_1->AddNode(power2_vol,12, power2_trans); + + Int_t l; + for (l=0; l<4; l++) + if ((ShowLayer[l]) && (BusBarOrientation[l] == 1)) // if geometry contains layer l + { + TString layername = Form("layer%02d", l+1); + TGeoTranslation* power_placement = new TGeoTranslation(0, 0, LayerPosition[l] + LayerThickness/2. + powerbar_position); + gGeoMan->GetVolume(layername)->AddNode(power_1, l, power_placement); + } + +} + + +void create_power_bars_horizontal() +{ + const TString power_01 = "power_bars_trd1"; + TGeoVolume* power_1 = new TGeoVolumeAssembly(power_01); + + TGeoBBox* power1; + TGeoBBox* power2; + + TGeoVolume* power1_vol; + TGeoVolume* power2_vol; + + TGeoTranslation* power1_trans; + TGeoTranslation* power2_trans; + + const Int_t kColor = kBlue; // bus bar color + + TGeoMedium* powerBusVolMed = gGeoMan->GetMedium(PowerBusVolumeMedium); + + // powerbus - vertical short + power1 = new TGeoBBox("power1", powerbar_width /2., (DetectorSizeY[1] - DetectorSizeY[0] - powerbar_width)/2., powerbar_thickness /2.); + power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed); + power1_vol->SetLineColor(kColor); + + // translations + power1_trans = new TGeoTranslation("", 1.5 * DetectorSizeX[1], -1 * (DetectorSizeY[1] - DetectorSizeY[0]/2.), 0.); + power_1->AddNode(power1_vol, 1, power1_trans); + + power1_trans = new TGeoTranslation("", -1.5 * DetectorSizeX[1], 1 * (DetectorSizeY[1] - DetectorSizeY[0]/2.), 0.); + power_1->AddNode(power1_vol, 2, power1_trans); + + // powerbus - vertical long + power1 = new TGeoBBox("power1", powerbar_width /2., (DetectorSizeY[0] - powerbar_width)/2., powerbar_thickness /2.); + power1_vol = new TGeoVolume("powerbus1", power1, powerBusVolMed); + power1_vol->SetLineColor(kColor); + + // translations + power1_trans = new TGeoTranslation("", 1.5 * DetectorSizeX[1], 1 * DetectorSizeY[0], 0.); + power_1->AddNode(power1_vol, 3, power1_trans); + + power1_trans = new TGeoTranslation("", -1.5 * DetectorSizeX[1], -1 * DetectorSizeY[0], 0.); + power_1->AddNode(power1_vol, 4, power1_trans); + + + // powerbus - horizontal long + power2 = new TGeoBBox("power2", (7 * DetectorSizeX[1] + powerbar_width) /2., powerbar_width /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", 0., -2.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 1, power2_trans); + power2_trans = new TGeoTranslation("", 0., 2.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 2, power2_trans); + + power2_trans = new TGeoTranslation("", 0., -1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 3, power2_trans); + power2_trans = new TGeoTranslation("", 0., 1.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 4, power2_trans); + + // powerbus - horizontal middle + power2 = new TGeoBBox("power2", (3 * DetectorSizeX[1] + powerbar_width) /2., powerbar_width /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", 0., -1.5 * DetectorSizeY[0], 0.); + power_1->AddNode(power2_vol, 7, power2_trans); + power2_trans = new TGeoTranslation("", 0., 1.5 * DetectorSizeY[0], 0.); + power_1->AddNode(power2_vol, 8, power2_trans); + + // powerbus - horizontal short 1 + power2 = new TGeoBBox("power2", 2 * DetectorSizeX[1] /2., powerbar_width /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + // power2_vol->SetLineColor(kRed); + + // translations + power2_trans = new TGeoTranslation("", (2.5 * DetectorSizeX[1] + powerbar_width/2.), 0.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol, 9, power2_trans); + power2_trans = new TGeoTranslation("", -(2.5 * DetectorSizeX[1] + powerbar_width/2.), -0.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol,10, power2_trans); + + // powerbus - horizontal short 2 + power2 = new TGeoBBox("power2", (2 * DetectorSizeX[1] + powerbar_width) /2., powerbar_width /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", -2.5 * DetectorSizeX[1], 0.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol,11, power2_trans); + power2_trans = new TGeoTranslation("", 2.5 * DetectorSizeX[1], -0.5 * DetectorSizeY[1], 0.); + power_1->AddNode(power2_vol,12, power2_trans); + + // powerbus - horizontal short 3 + power2 = new TGeoBBox("power2", (2 * DetectorSizeX[0] + powerbar_width/2.) /2., powerbar_width /2., powerbar_thickness /2.); + power2_vol = new TGeoVolume("powerbus2", power2, powerBusVolMed); + power2_vol->SetLineColor(kColor); + + // translations + power2_trans = new TGeoTranslation("", (1.5 * DetectorSizeX[0] + powerbar_width/4.), 0.5 * DetectorSizeY[0], 0.); + power_1->AddNode(power2_vol,11, power2_trans); + power2_trans = new TGeoTranslation("", -(1.5 * DetectorSizeX[0] + powerbar_width/4.), -0.5 * DetectorSizeY[0], 0.); + power_1->AddNode(power2_vol,12, power2_trans); + + Int_t l; + for (l=0; l<4; l++) + if ((ShowLayer[l]) && (BusBarOrientation[l] == 0)) // if geometry contains layer l + { + TString layername = Form("layer%02d", l+1); + TGeoTranslation* power_placement = new TGeoTranslation(0, 0, LayerPosition[l] + LayerThickness/2. + powerbar_position); + gGeoMan->GetVolume(layername)->AddNode(power_1, l, power_placement); + } + +} + + +void create_xtru_supports() +{ + const TString trd_01 = "support_trd1"; + TGeoVolume* trd_1 = new TGeoVolumeAssembly(trd_01); + + const TString trd_02 = "support_trd2"; + TGeoVolume* trd_2 = new TGeoVolumeAssembly(trd_02); + + const TString trd_03 = "support_trd3"; + TGeoVolume* trd_3 = new TGeoVolumeAssembly(trd_03); + +// const TString trdSupport = "supportframe"; +// TGeoVolume* trdsupport = new TGeoVolumeAssembly(trdSupport); +// +// trdsupport->AddNode(trd_1, 1); +// trdsupport->AddNode(trd_2, 2); +// trdsupport->AddNode(trd_3, 3); + + TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium); // define Volume Medium + + const Double_t x[12] = { -15,-15, -1, -1,-15,-15, 15, 15, 1, 1, 15, 15 }; // IPB 400 + const Double_t y[12] = { -20,-18,-18, 18, 18, 20, 20, 18, 18,-18,-18,-20 }; // 30 x 40 cm in size, 2 cm wall thickness + const Double_t Hwid = -2*x[0]; // 30 + const Double_t Hhei = -2*y[0]; // 40 + + Double_t AperX[3] = { 450., 550., 600.}; // inner aperture in X of support structure for stations 1,2,3 + Double_t AperY[3] = { 350., 450., 500.}; // inner aperture in Y of support structure for stations 1,2,3 + Double_t PilPosX; + Double_t BarPosY; + + const Double_t BeamHeight = 570; // beamline is at 5.7m above floor + + Double_t PilPosZ[6]; // PilPosZ +// PilPosZ[0] = LayerPosition[0] + LayerThickness/2.; +// PilPosZ[1] = LayerPosition[3] + LayerThickness/2.; +// PilPosZ[2] = LayerPosition[4] + LayerThickness/2.; +// PilPosZ[3] = LayerPosition[7] + LayerThickness/2.; +// PilPosZ[4] = LayerPosition[8] + LayerThickness/2.; +// PilPosZ[5] = LayerPosition[9] + LayerThickness/2.; + + PilPosZ[0] = LayerPosition[0] + 15; + PilPosZ[1] = LayerPosition[3] - 15 + LayerThickness; + PilPosZ[2] = LayerPosition[4] + 15; + PilPosZ[3] = LayerPosition[7] - 15 + LayerThickness; + PilPosZ[4] = LayerPosition[8] + 15; + PilPosZ[5] = LayerPosition[9] - 15 + LayerThickness; + +// cout << "PilPosZ[0]: " << PilPosZ[0] << endl; +// cout << "PilPosZ[1]: " << PilPosZ[1] << endl; + + TGeoRotation *rotx090 = new TGeoRotation("rotx090"); rotx090->RotateX( 90.); // rotate 90 deg around x-axis + TGeoRotation *roty090 = new TGeoRotation("roty090"); roty090->RotateY( 90.); // rotate 90 deg around y-axis + TGeoRotation *rotz090 = new TGeoRotation("rotz090"); rotz090->RotateZ( 90.); // rotate 90 deg around y-axis + TGeoRotation *roty270 = new TGeoRotation("roty270"); roty270->RotateY(270.); // rotate 270 deg around y-axis + + TGeoRotation *rotzx01 = new TGeoRotation("rotzx01"); + rotzx01->RotateZ( 90.); // rotate 90 deg around z-axis + rotzx01->RotateX( 90.); // rotate 90 deg around x-axis + +// TGeoRotation *rotxz01 = new TGeoRotation("rotxz01"); +// rotxz01->RotateX( 90.); // rotate 90 deg around x-axis +// rotxz01->RotateZ( 90.); // rotate 90 deg around z-axis + + Double_t ang1 = atan(3./4.) * 180. / acos(-1.); + // cout << "DEDE " << ang1 << endl; + // Double_t sin1 = acos(-1.); + // cout << "DEDE " << sin1 << endl; + TGeoRotation *rotx080 = new TGeoRotation("rotx080"); rotx080->RotateX( 90.-ang1); // rotate 80 deg around x-axis + TGeoRotation *rotx100 = new TGeoRotation("rotx100"); rotx100->RotateX( 90.+ang1); // rotate 100 deg around x-axis + + TGeoRotation *rotxy01 = new TGeoRotation("rotxy01"); + rotxy01->RotateX( 90.); // rotate 90 deg around x-axis + rotxy01->RotateZ(-ang1); // rotate ang1 around rotated y-axis + + TGeoRotation *rotxy02 = new TGeoRotation("rotxy02"); + rotxy02->RotateX( 90.); // rotate 90 deg around x-axis + rotxy02->RotateZ( ang1); // rotate ang1 around rotated y-axis + + +//------------------- +// vertical pillars (Y) +//------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + TGeoXtru* trd_H_vert1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_vert1->DefinePolygon(12,x,y); + trd_H_vert1->DefineSection( 0,-(AperY[0]+Hhei), 0, 0, 1.0); + trd_H_vert1->DefineSection( 1, BeamHeight, 0, 0, 1.0); + TGeoVolume* trd_H_vert_vol1 = new TGeoVolume("trd_H_y_01", trd_H_vert1, aluminiumVolMed); + trd_H_vert_vol1->SetLineColor(kYellow); + PilPosX = AperX[0]; + + TGeoCombiTrans* trd_H_vert_combi01 = new TGeoCombiTrans( (PilPosX+Hhei/2.), 0., PilPosZ[0], rotzx01); + trd_1->AddNode(trd_H_vert_vol1, 11, trd_H_vert_combi01); + TGeoCombiTrans* trd_H_vert_combi02 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), 0., PilPosZ[0], rotzx01); + trd_1->AddNode(trd_H_vert_vol1, 12, trd_H_vert_combi02); + TGeoCombiTrans* trd_H_vert_combi03 = new TGeoCombiTrans( (PilPosX+Hhei/2.), 0., PilPosZ[1], rotzx01); + trd_1->AddNode(trd_H_vert_vol1, 13, trd_H_vert_combi03); + TGeoCombiTrans* trd_H_vert_combi04 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), 0., PilPosZ[1], rotzx01); + trd_1->AddNode(trd_H_vert_vol1, 14, trd_H_vert_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoXtru* trd_H_vert1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_vert1->DefinePolygon(12,x,y); + trd_H_vert1->DefineSection( 0,-(AperY[1]+Hhei), 0, 0, 1.0); + trd_H_vert1->DefineSection( 1, BeamHeight, 0, 0, 1.0); + TGeoVolume* trd_H_vert_vol1 = new TGeoVolume("trd_H_y_02", trd_H_vert1, aluminiumVolMed); + trd_H_vert_vol1->SetLineColor(kYellow); + PilPosX = AperX[1]; + + TGeoCombiTrans* trd_H_vert_combi01 = new TGeoCombiTrans( (PilPosX+Hhei/2.), 0., PilPosZ[2], rotzx01); + trd_2->AddNode(trd_H_vert_vol1, 21, trd_H_vert_combi01); + TGeoCombiTrans* trd_H_vert_combi02 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), 0., PilPosZ[2], rotzx01); + trd_2->AddNode(trd_H_vert_vol1, 22, trd_H_vert_combi02); + TGeoCombiTrans* trd_H_vert_combi03 = new TGeoCombiTrans( (PilPosX+Hhei/2.), 0., PilPosZ[3], rotzx01); + trd_2->AddNode(trd_H_vert_vol1, 23, trd_H_vert_combi03); + TGeoCombiTrans* trd_H_vert_combi04 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), 0., PilPosZ[3], rotzx01); + trd_2->AddNode(trd_H_vert_vol1, 24, trd_H_vert_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoXtru* trd_H_vert1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_vert1->DefinePolygon(12,x,y); + trd_H_vert1->DefineSection( 0,-(AperY[2]+Hhei), 0, 0, 1.0); + trd_H_vert1->DefineSection( 1, BeamHeight, 0, 0, 1.0); + TGeoVolume* trd_H_vert_vol1 = new TGeoVolume("trd_H_y_03", trd_H_vert1, aluminiumVolMed); + trd_H_vert_vol1->SetLineColor(kYellow); + PilPosX = AperX[2]; + + TGeoCombiTrans* trd_H_vert_combi01 = new TGeoCombiTrans( (PilPosX+Hhei/2.), 0., PilPosZ[4], rotzx01); + trd_3->AddNode(trd_H_vert_vol1, 31, trd_H_vert_combi01); + TGeoCombiTrans* trd_H_vert_combi02 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), 0., PilPosZ[4], rotzx01); + trd_3->AddNode(trd_H_vert_vol1, 32, trd_H_vert_combi02); + TGeoCombiTrans* trd_H_vert_combi03 = new TGeoCombiTrans( (PilPosX+Hhei/2.), 0., PilPosZ[5], rotzx01); + trd_3->AddNode(trd_H_vert_vol1, 33, trd_H_vert_combi03); + TGeoCombiTrans* trd_H_vert_combi04 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), 0., PilPosZ[5], rotzx01); + trd_3->AddNode(trd_H_vert_vol1, 34, trd_H_vert_combi04); + } + + +//------------------- +// horizontal supports (X) +//------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + TGeoXtru* trd_H_hori1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_hori1->DefinePolygon(12,x,y); + trd_H_hori1->DefineSection( 0,-AperX[0], 0, 0, 1.0); + trd_H_hori1->DefineSection( 1, AperX[0], 0, 0, 1.0); + TGeoVolume* trd_H_hori_vol1 = new TGeoVolume("trd_H_x_01", trd_H_hori1, aluminiumVolMed); + trd_H_hori_vol1->SetLineColor(kRed); + BarPosY = AperY[0]; + + TGeoCombiTrans* trd_H_hori_combi01 = new TGeoCombiTrans(0., (BarPosY+Hhei/2.), PilPosZ[0], roty090); + trd_1->AddNode(trd_H_hori_vol1, 11, trd_H_hori_combi01); + TGeoCombiTrans* trd_H_hori_combi02 = new TGeoCombiTrans(0.,-(BarPosY+Hhei/2.), PilPosZ[0], roty090); + trd_1->AddNode(trd_H_hori_vol1, 12, trd_H_hori_combi02); + TGeoCombiTrans* trd_H_hori_combi03 = new TGeoCombiTrans(0., (BarPosY+Hhei/2.), PilPosZ[1], roty090); + trd_1->AddNode(trd_H_hori_vol1, 13, trd_H_hori_combi03); + TGeoCombiTrans* trd_H_hori_combi04 = new TGeoCombiTrans(0.,-(BarPosY+Hhei/2.), PilPosZ[1], roty090); + trd_1->AddNode(trd_H_hori_vol1, 14, trd_H_hori_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoXtru* trd_H_hori1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_hori1->DefinePolygon(12,x,y); + trd_H_hori1->DefineSection( 0,-AperX[1], 0, 0, 1.0); + trd_H_hori1->DefineSection( 1, AperX[1], 0, 0, 1.0); + TGeoVolume* trd_H_hori_vol1 = new TGeoVolume("trd_H_x_02", trd_H_hori1, aluminiumVolMed); + trd_H_hori_vol1->SetLineColor(kRed); + BarPosY = AperY[1]; + + TGeoCombiTrans* trd_H_hori_combi01 = new TGeoCombiTrans(0., (BarPosY+Hhei/2.), PilPosZ[2], roty090); + trd_2->AddNode(trd_H_hori_vol1, 21, trd_H_hori_combi01); + TGeoCombiTrans* trd_H_hori_combi02 = new TGeoCombiTrans(0.,-(BarPosY+Hhei/2.), PilPosZ[2], roty090); + trd_2->AddNode(trd_H_hori_vol1, 22, trd_H_hori_combi02); + TGeoCombiTrans* trd_H_hori_combi03 = new TGeoCombiTrans(0., (BarPosY+Hhei/2.), PilPosZ[3], roty090); + trd_2->AddNode(trd_H_hori_vol1, 23, trd_H_hori_combi03); + TGeoCombiTrans* trd_H_hori_combi04 = new TGeoCombiTrans(0.,-(BarPosY+Hhei/2.), PilPosZ[3], roty090); + trd_2->AddNode(trd_H_hori_vol1, 24, trd_H_hori_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoXtru* trd_H_hori1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_hori1->DefinePolygon(12,x,y); + trd_H_hori1->DefineSection( 0,-AperX[2], 0, 0, 1.0); + trd_H_hori1->DefineSection( 1, AperX[2], 0, 0, 1.0); + TGeoVolume* trd_H_hori_vol1 = new TGeoVolume("trd_H_x_03", trd_H_hori1, aluminiumVolMed); + trd_H_hori_vol1->SetLineColor(kRed); + BarPosY = AperY[2]; + + TGeoCombiTrans* trd_H_hori_combi01 = new TGeoCombiTrans(0., (BarPosY+Hhei/2.), PilPosZ[4], roty090); + trd_3->AddNode(trd_H_hori_vol1, 31, trd_H_hori_combi01); + TGeoCombiTrans* trd_H_hori_combi02 = new TGeoCombiTrans(0.,-(BarPosY+Hhei/2.), PilPosZ[4], roty090); + trd_3->AddNode(trd_H_hori_vol1, 32, trd_H_hori_combi02); + TGeoCombiTrans* trd_H_hori_combi03 = new TGeoCombiTrans(0., (BarPosY+Hhei/2.), PilPosZ[5], roty090); + trd_3->AddNode(trd_H_hori_vol1, 33, trd_H_hori_combi03); + TGeoCombiTrans* trd_H_hori_combi04 = new TGeoCombiTrans(0.,-(BarPosY+Hhei/2.), PilPosZ[5], roty090); + trd_3->AddNode(trd_H_hori_vol1, 34, trd_H_hori_combi04); + } + + +//------------------- +// horizontal supports (Z) +//------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + TGeoXtru* trd_H_slope1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_slope1->DefinePolygon(12,x,y); + trd_H_slope1->DefineSection( 0,-(PilPosZ[1]-PilPosZ[0]-Hwid)/2., 0, 0, 1.0); + trd_H_slope1->DefineSection( 1,+(PilPosZ[1]-PilPosZ[0]-Hwid)/2., 0, 0, 1.0); + TGeoVolume* trd_H_slope_vol1 = new TGeoVolume("trd_H_z_01", trd_H_slope1, aluminiumVolMed); + trd_H_slope_vol1->SetLineColor(kGreen); + PilPosX = AperX[0]; + BarPosY = AperY[0]; + + TGeoCombiTrans* trd_H_slope_combi01 = new TGeoCombiTrans( (PilPosX+Hhei/2.), (BarPosY+Hhei-Hwid/2.), (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_H_slope_vol1, 11, trd_H_slope_combi01); + TGeoCombiTrans* trd_H_slope_combi02 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), (BarPosY+Hhei-Hwid/2.), (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_H_slope_vol1, 12, trd_H_slope_combi02); + TGeoCombiTrans* trd_H_slope_combi03 = new TGeoCombiTrans( (PilPosX+Hhei/2.),-(BarPosY+Hhei-Hwid/2.), (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_H_slope_vol1, 13, trd_H_slope_combi03); + TGeoCombiTrans* trd_H_slope_combi04 = new TGeoCombiTrans(-(PilPosX+Hhei/2.),-(BarPosY+Hhei-Hwid/2.), (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_H_slope_vol1, 14, trd_H_slope_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoXtru* trd_H_slope1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_slope1->DefinePolygon(12,x,y); + trd_H_slope1->DefineSection( 0,-(PilPosZ[3]-PilPosZ[2]-Hwid)/2., 0, 0, 1.0); + trd_H_slope1->DefineSection( 1,+(PilPosZ[3]-PilPosZ[2]-Hwid)/2., 0, 0, 1.0); + TGeoVolume* trd_H_slope_vol1 = new TGeoVolume("trd_H_z_02", trd_H_slope1, aluminiumVolMed); + trd_H_slope_vol1->SetLineColor(kGreen); + PilPosX = AperX[1]; + BarPosY = AperY[1]; + + TGeoCombiTrans* trd_H_slope_combi01 = new TGeoCombiTrans( (PilPosX+Hhei/2.), (BarPosY+Hhei-Hwid/2.), (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_H_slope_vol1, 21, trd_H_slope_combi01); + TGeoCombiTrans* trd_H_slope_combi02 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), (BarPosY+Hhei-Hwid/2.), (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_H_slope_vol1, 22, trd_H_slope_combi02); + TGeoCombiTrans* trd_H_slope_combi03 = new TGeoCombiTrans( (PilPosX+Hhei/2.),-(BarPosY+Hhei-Hwid/2.), (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_H_slope_vol1, 23, trd_H_slope_combi03); + TGeoCombiTrans* trd_H_slope_combi04 = new TGeoCombiTrans(-(PilPosX+Hhei/2.),-(BarPosY+Hhei-Hwid/2.), (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_H_slope_vol1, 24, trd_H_slope_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoXtru* trd_H_slope1 = new TGeoXtru(2); // define Xtrusion of 2 planes + trd_H_slope1->DefinePolygon(12,x,y); + trd_H_slope1->DefineSection( 0,-(PilPosZ[5]-PilPosZ[4]-Hwid)/2., 0, 0, 1.0); + trd_H_slope1->DefineSection( 1,+(PilPosZ[5]-PilPosZ[4]-Hwid)/2., 0, 0, 1.0); + TGeoVolume* trd_H_slope_vol1 = new TGeoVolume("trd_H_z_03", trd_H_slope1, aluminiumVolMed); + trd_H_slope_vol1->SetLineColor(kGreen); + PilPosX = AperX[2]; + BarPosY = AperY[2]; + + TGeoCombiTrans* trd_H_slope_combi01 = new TGeoCombiTrans( (PilPosX+Hhei/2.), (BarPosY+Hhei-Hwid/2.), (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_H_slope_vol1, 31, trd_H_slope_combi01); + TGeoCombiTrans* trd_H_slope_combi02 = new TGeoCombiTrans(-(PilPosX+Hhei/2.), (BarPosY+Hhei-Hwid/2.), (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_H_slope_vol1, 32, trd_H_slope_combi02); + TGeoCombiTrans* trd_H_slope_combi03 = new TGeoCombiTrans( (PilPosX+Hhei/2.),-(BarPosY+Hhei-Hwid/2.), (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_H_slope_vol1, 33, trd_H_slope_combi03); + TGeoCombiTrans* trd_H_slope_combi04 = new TGeoCombiTrans(-(PilPosX+Hhei/2.),-(BarPosY+Hhei-Hwid/2.), (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_H_slope_vol1, 34, trd_H_slope_combi04); + } + + if (IncludeLabels) + { + + Int_t text_height = 40; + Int_t text_thickness = 8; + + TGeoTranslation *tr200 = new TGeoTranslation(0., (AperY[0]+Hhei+ text_height/2.), PilPosZ[0]-15+ text_thickness/2.); + TGeoTranslation *tr201 = new TGeoTranslation(0., (AperY[1]+Hhei+ text_height/2.), PilPosZ[2]-15+ text_thickness/2.); + TGeoTranslation *tr202 = new TGeoTranslation(0., (AperY[2]+Hhei+ text_height/2.), PilPosZ[4]-15+ text_thickness/2.); + + TGeoCombiTrans *tr203 = new TGeoCombiTrans(-(AperX[0]+Hhei+ text_thickness/2.), (AperY[0]+Hhei-Hwid-text_height/2.), (PilPosZ[0]+PilPosZ[1])/2., roty090); + TGeoCombiTrans *tr204 = new TGeoCombiTrans(-(AperX[1]+Hhei+ text_thickness/2.), (AperY[1]+Hhei-Hwid-text_height/2.), (PilPosZ[2]+PilPosZ[3])/2., roty090); + TGeoCombiTrans *tr205 = new TGeoCombiTrans(-(AperX[2]+Hhei+ text_thickness/2.), (AperY[2]+Hhei-Hwid-text_height/2.), (PilPosZ[4]+PilPosZ[5])/2., roty090); + + TGeoCombiTrans *tr206 = new TGeoCombiTrans( (AperX[0]+Hhei+ text_thickness/2.), (AperY[0]+Hhei-Hwid-text_height/2.), (PilPosZ[0]+PilPosZ[1])/2., roty270); + TGeoCombiTrans *tr207 = new TGeoCombiTrans( (AperX[1]+Hhei+ text_thickness/2.), (AperY[1]+Hhei-Hwid-text_height/2.), (PilPosZ[2]+PilPosZ[3])/2., roty270); + TGeoCombiTrans *tr208 = new TGeoCombiTrans( (AperX[2]+Hhei+ text_thickness/2.), (AperY[2]+Hhei-Hwid-text_height/2.), (PilPosZ[4]+PilPosZ[5])/2., roty270); + + TGeoVolume* trdbox1 = new TGeoVolumeAssembly("trdbox1"); // volume for TRD text (108, 40, 8) + TGeoVolume* trdbox2 = new TGeoVolumeAssembly("trdbox2"); // volume for TRD text (108, 40, 8) + TGeoVolume* trdbox3 = new TGeoVolumeAssembly("trdbox3"); // volume for TRD text (108, 40, 8) + add_trd_labels(trdbox1, trdbox2, trdbox3); + + // final placement + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + // trd_1->AddNode(trdbox1, 1, tr200); + trd_1->AddNode(trdbox1, 4, tr203); + trd_1->AddNode(trdbox1, 7, tr206); + } + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + // trd_2->AddNode(trdbox2, 2, tr201); + trd_2->AddNode(trdbox2, 5, tr204); + trd_2->AddNode(trdbox2, 8, tr207); + } + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + // trd_3->AddNode(trdbox3, 3, tr202); + trd_3->AddNode(trdbox3, 6, tr205); + trd_3->AddNode(trdbox3, 9, tr208); + } + } + + // gGeoMan->GetVolume(geoVersion)->AddNode(trdsupport,1); + + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_1, 1); + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_2, 2); + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_3, 3); + +} + + +void add_trd_labels(TGeoVolume* trdbox1, TGeoVolume* trdbox2, TGeoVolume* trdbox3) +{ +// write TRD (the 3 characters) in a simple geometry + TGeoMedium* textVolMed = gGeoMan->GetMedium(TextVolumeMedium); + + Int_t Tcolor = kBlue; // kRed; + Int_t Rcolor = kBlue; // kRed; // kRed; + Int_t Dcolor = kBlue; // kRed; // kYellow; + Int_t Icolor = kBlue; // kRed; + +// define transformations for letter pieces +// T + TGeoTranslation *tr01 = new TGeoTranslation( 0. , -4., 0.); + TGeoTranslation *tr02 = new TGeoTranslation( 0. , 16., 0.); + +// R + TGeoTranslation *tr11 = new TGeoTranslation( 10, 0., 0.); + TGeoTranslation *tr12 = new TGeoTranslation( 2, 0., 0.); + TGeoTranslation *tr13 = new TGeoTranslation( 2, 16., 0.); + TGeoTranslation *tr14 = new TGeoTranslation( -2, 8., 0.); + TGeoTranslation *tr15 = new TGeoTranslation( -6, 0., 0.); + +// D + TGeoTranslation *tr21 = new TGeoTranslation( 12., 0., 0.); + TGeoTranslation *tr22 = new TGeoTranslation( 6., 16., 0.); + TGeoTranslation *tr23 = new TGeoTranslation( 6.,-16., 0.); + TGeoTranslation *tr24 = new TGeoTranslation( 4., 0., 0.); + +// I + TGeoTranslation *tr31 = new TGeoTranslation( 0. , 0., 0.); + TGeoTranslation *tr32 = new TGeoTranslation( 0. , 16., 0.); + TGeoTranslation *tr33 = new TGeoTranslation( 0. ,-16., 0.); + +// make letter T +// TGeoVolume *T = geom->MakeBox("T", Vacuum, 25., 25., 5.); +// T->SetVisibility(kFALSE); + TGeoVolume* T = new TGeoVolumeAssembly("Tbox"); // volume for T + + TGeoBBox* Tbar1b = new TGeoBBox("trd_Tbar1b", 4., 16., 4.); // | vertical + TGeoVolume *Tbar1 = new TGeoVolume("Tbar1", Tbar1b, textVolMed); + Tbar1->SetLineColor(Tcolor); + T->AddNode(Tbar1, 1, tr01); + TGeoBBox* Tbar2b = new TGeoBBox("trd_Tbar2b", 16, 4., 4.); // - top + TGeoVolume *Tbar2 = new TGeoVolume("Tbar2", Tbar2b, textVolMed); + Tbar2->SetLineColor(Tcolor); + T->AddNode(Tbar2, 1, tr02); + +// make letter R +// TGeoVolume *R = geom->MakeBox("R", Vacuum, 25., 25., 5.); +// R->SetVisibility(kFALSE); + TGeoVolume* R = new TGeoVolumeAssembly("Rbox"); // volume for R + + TGeoBBox* Rbar1b = new TGeoBBox("trd_Rbar1b", 4., 20, 4.); + TGeoVolume *Rbar1 = new TGeoVolume("Rbar1", Rbar1b, textVolMed); + Rbar1->SetLineColor(Rcolor); + R->AddNode(Rbar1, 1, tr11); + TGeoBBox* Rbar2b = new TGeoBBox("trd_Rbar2b", 4., 4., 4.); + TGeoVolume *Rbar2 = new TGeoVolume("Rbar2", Rbar2b, textVolMed); + Rbar2->SetLineColor(Rcolor); + R->AddNode(Rbar2, 1, tr12); + R->AddNode(Rbar2, 2, tr13); + TGeoTubeSeg* Rtub1b = new TGeoTubeSeg("trd_Rtub1b", 4., 12, 4., 90., 270.); + TGeoVolume *Rtub1 = new TGeoVolume("Rtub1", (TGeoShape *) Rtub1b, textVolMed); + Rtub1->SetLineColor(Rcolor); + R->AddNode(Rtub1, 1, tr14); + TGeoArb8* Rbar3b = new TGeoArb8("trd_Rbar3b", 4.); + TGeoVolume *Rbar3 = new TGeoVolume("Rbar3", Rbar3b, textVolMed); + Rbar3->SetLineColor(Rcolor); + TGeoArb8 *arb = (TGeoArb8*)Rbar3->GetShape(); + arb->SetVertex(0, 12., -4.); + arb->SetVertex(1, 0., -20.); + arb->SetVertex(2, -8., -20.); + arb->SetVertex(3, 4., -4.); + arb->SetVertex(4, 12., -4.); + arb->SetVertex(5, 0., -20.); + arb->SetVertex(6, -8., -20.); + arb->SetVertex(7, 4., -4.); + R->AddNode(Rbar3, 1, tr15); + +// make letter D +// TGeoVolume *D = geom->MakeBox("D", Vacuum, 25., 25., 5.); +// D->SetVisibility(kFALSE); + TGeoVolume* D = new TGeoVolumeAssembly("Dbox"); // volume for D + + TGeoBBox* Dbar1b = new TGeoBBox("trd_Dbar1b", 4., 20, 4.); + TGeoVolume *Dbar1 = new TGeoVolume("Dbar1", Dbar1b, textVolMed); + Dbar1->SetLineColor(Dcolor); + D->AddNode(Dbar1, 1, tr21); + TGeoBBox* Dbar2b = new TGeoBBox("trd_Dbar2b", 2., 4., 4.); + TGeoVolume *Dbar2 = new TGeoVolume("Dbar2", Dbar2b, textVolMed); + Dbar2->SetLineColor(Dcolor); + D->AddNode(Dbar2, 1, tr22); + D->AddNode(Dbar2, 2, tr23); + TGeoTubeSeg* Dtub1b = new TGeoTubeSeg("trd_Dtub1b", 12, 20, 4., 90., 270.); + TGeoVolume *Dtub1 = new TGeoVolume("Dtub1", (TGeoShape *) Dtub1b, textVolMed); + Dtub1->SetLineColor(Dcolor); + D->AddNode(Dtub1, 1, tr24); + +// make letter I + TGeoVolume* I = new TGeoVolumeAssembly("Ibox"); // volume for I + + TGeoBBox* Ibar1b = new TGeoBBox("trd_Ibar1b", 4., 12., 4.); // | vertical + TGeoVolume *Ibar1 = new TGeoVolume("Ibar1", Ibar1b, textVolMed); + Ibar1->SetLineColor(Icolor); + I->AddNode(Ibar1, 1, tr31); + TGeoBBox* Ibar2b = new TGeoBBox("trd_Ibar2b", 10., 4., 4.); // - top + TGeoVolume *Ibar2 = new TGeoVolume("Ibar2", Ibar2b, textVolMed); + Ibar2->SetLineColor(Icolor); + I->AddNode(Ibar2, 1, tr32); + I->AddNode(Ibar2, 2, tr33); + + +// build text block "TRD" <32> + 8 + <28> + 8 + <32> = 108 + +// TGeoBBox *trdboxb = new TGeoBBox("", 108./2, 40./2, 8./2); +// TGeoVolume *trdbox = new TGeoVolume("trdboxb", trdboxb, textVolMed); +// trdbox->SetVisibility(kFALSE); + +// TGeoVolume* trdbox[0] = new TGeoVolumeAssembly("trdbox1"); // volume for TRD text (108, 40, 8) +// TGeoVolume* trdbox[1] = new TGeoVolumeAssembly("trdbox2"); // volume for TRD text (108, 40, 8) +// TGeoVolume* trdbox[2] = new TGeoVolumeAssembly("trdbox3"); // volume for TRD text (108, 40, 8) + + TGeoTranslation *tr100 = new TGeoTranslation( 38., 0., 0.); + TGeoTranslation *tr101 = new TGeoTranslation( 0., 0., 0.); + TGeoTranslation *tr102 = new TGeoTranslation(-38., 0., 0.); + +// TGeoTranslation *tr103 = new TGeoTranslation( -70., 0., 0.); // on the same line +// TGeoTranslation *tr104 = new TGeoTranslation( -86., 0., 0.); // on the same line +// TGeoTranslation *tr105 = new TGeoTranslation(-102., 0., 0.); // on the same line + + TGeoTranslation *tr110 = new TGeoTranslation( 0., -50., 0.); + TGeoTranslation *tr111 = new TGeoTranslation( 8., -50., 0.); + TGeoTranslation *tr112 = new TGeoTranslation( -8., -50., 0.); + TGeoTranslation *tr113 = new TGeoTranslation( 16., -50., 0.); + TGeoTranslation *tr114 = new TGeoTranslation( -16., -50., 0.); + + TGeoTranslation *tr200 = new TGeoTranslation( 0., 0., 0.); + TGeoTranslation *tr201 = new TGeoTranslation( 0., -50., 0.); + TGeoTranslation *tr202 = new TGeoTranslation( 0.,-100., 0.); + + TGeoTranslation *tr210 = new TGeoTranslation( 0.,-150., 0.); + TGeoTranslation *tr213 = new TGeoTranslation( 16.,-150., 0.); + TGeoTranslation *tr214 = new TGeoTranslation( -16.,-150., 0.); + +// station 1 + trdbox1->AddNode(T, 1, tr100); + trdbox1->AddNode(R, 1, tr101); + trdbox1->AddNode(D, 1, tr102); + + trdbox1->AddNode(I, 1, tr110); + +// station 2 + trdbox2->AddNode(T, 1, tr100); + trdbox2->AddNode(R, 1, tr101); + trdbox2->AddNode(D, 1, tr102); + + trdbox2->AddNode(I, 1, tr111); + trdbox2->AddNode(I, 2, tr112); + +//// station 3 +// trdbox3->AddNode(T, 1, tr100); +// trdbox3->AddNode(R, 1, tr101); +// trdbox3->AddNode(D, 1, tr102); +// +// trdbox3->AddNode(I, 1, tr110); +// trdbox3->AddNode(I, 2, tr113); +// trdbox3->AddNode(I, 3, tr114); + +// station 3 + trdbox3->AddNode(T, 1, tr200); + trdbox3->AddNode(R, 1, tr201); + trdbox3->AddNode(D, 1, tr202); + + trdbox3->AddNode(I, 1, tr210); + trdbox3->AddNode(I, 2, tr213); + trdbox3->AddNode(I, 3, tr214); + +// TGeoScale *sc100 = new TGeoScale( 36./50., 36./50., 1.); // text is vertical 50 cm, H-bar opening is 36 cm +// +// // scale text +// TGeoHMatrix *mat100 = new TGeoHMatrix(""); +// TGeoHMatrix *mat101 = new TGeoHMatrix(""); +// TGeoHMatrix *mat102 = new TGeoHMatrix(""); +// (*mat100) = (*tr100) * (*sc100); +// (*mat101) = (*tr101) * (*sc100); +// (*mat102) = (*tr102) * (*sc100); +// +// trdbox->AddNode(T, 1, mat100); +// trdbox->AddNode(R, 1, mat101); +// trdbox->AddNode(D, 1, mat102); + +// // final placement +// // TGeoTranslation *tr103 = new TGeoTranslation(0., 400., 500.); +// gGeoMan->GetVolume(geoVersion)->AddNode(trdbox, 1, new TGeoTranslation(0., 400., 500.)); +// gGeoMan->GetVolume(geoVersion)->AddNode(trdbox, 2, new TGeoTranslation(0., 500., 600.)); +// gGeoMan->GetVolume(geoVersion)->AddNode(trdbox, 3, new TGeoTranslation(0., 600., 700.)); + +// return trdbox; + +} + + +void create_box_supports() +{ + const TString trd_01 = "support_trd1"; + TGeoVolume* trd_1 = new TGeoVolumeAssembly(trd_01); + + const TString trd_02 = "support_trd2"; + TGeoVolume* trd_2 = new TGeoVolumeAssembly(trd_02); + + const TString trd_03 = "support_trd3"; + TGeoVolume* trd_3 = new TGeoVolumeAssembly(trd_03); + +// const TString trdSupport = "supportframe"; +// TGeoVolume* trdsupport = new TGeoVolumeAssembly(trdSupport); +// +// trdsupport->AddNode(trd_1, 1); +// trdsupport->AddNode(trd_2, 2); +// trdsupport->AddNode(trd_3, 3); + + TGeoMedium* keepVolMed = gGeoMan->GetMedium(KeepingVolumeMedium); + TGeoMedium* aluminiumVolMed = gGeoMan->GetMedium(AluminiumVolumeMedium); // define Volume Medium + + const Int_t I_height = 40; // cm // I profile properties + const Int_t I_width = 30; // cm // I profile properties + const Int_t I_thick = 2; // cm // I profile properties + + const Double_t BeamHeight = 570; // beamline is at 5.7m above the floor + const Double_t PlatformHeight = 234; // platform is 2.34m above the floor + const Double_t PlatformOffset = 1; // distance to platform + +// Double_t AperX[3] = { 450., 550., 600.}; // 100 cm modules // inner aperture in X of support structure for stations 1,2,3 +// Double_t AperY[3] = { 350., 450., 500.}; // 100 cm modules // inner aperture in Y of support structure for stations 1,2,3 + + const Double_t AperX[3] = { 4.5*DetectorSizeX[1], 5.5*DetectorSizeX[1], 6*DetectorSizeX[1] }; // inner aperture in X of support structure for stations 1,2,3 + const Double_t AperY[3] = { 3.5*DetectorSizeY[1], 4.5*DetectorSizeY[1], 5*DetectorSizeY[1] }; // inner aperture in Y of support structure for stations 1,2,3 + // platform + const Double_t AperYbot[3] = { BeamHeight-(PlatformHeight+PlatformOffset+I_height), 4.5*DetectorSizeY[1], 5*DetectorSizeY[1] }; // inner aperture for station1 + + const Double_t xBarPosYtop[3] = { AperY[0] +I_height/2., AperY[1]+I_height/2., AperY[2]+I_height/2. }; + const Double_t xBarPosYbot[3] = { AperYbot[0]+I_height/2., xBarPosYtop[1] , xBarPosYtop[2] }; + + const Double_t zBarPosYtop[3] = { AperY[0] +I_height-I_width/2., AperY[1]+I_height-I_width/2., AperY[2]+I_height-I_width/2. }; + const Double_t zBarPosYbot[3] = { AperYbot[0]+I_height-I_width/2., zBarPosYtop[1] , zBarPosYtop[2] }; + + Double_t PilPosX; + Double_t PilPosZ[6]; // PilPosZ + + PilPosZ[0] = LayerPosition[0] + I_width/2.; + PilPosZ[1] = LayerPosition[3] - I_width/2. + LayerThickness; + PilPosZ[2] = LayerPosition[4] + I_width/2.; + PilPosZ[3] = LayerPosition[7] - I_width/2. + LayerThickness; + PilPosZ[4] = LayerPosition[8] + I_width/2.; + PilPosZ[5] = LayerPosition[9] - I_width/2. + LayerThickness; + +// cout << "PilPosZ[0]: " << PilPosZ[0] << endl; +// cout << "PilPosZ[1]: " << PilPosZ[1] << endl; + + TGeoRotation *rotx090 = new TGeoRotation("rotx090"); rotx090->RotateX( 90.); // rotate 90 deg around x-axis + TGeoRotation *roty090 = new TGeoRotation("roty090"); roty090->RotateY( 90.); // rotate 90 deg around y-axis + TGeoRotation *rotz090 = new TGeoRotation("rotz090"); rotz090->RotateZ( 90.); // rotate 90 deg around y-axis + TGeoRotation *roty270 = new TGeoRotation("roty270"); roty270->RotateY(270.); // rotate 270 deg around y-axis + + TGeoRotation *rotzx01 = new TGeoRotation("rotzx01"); + rotzx01->RotateZ( 90.); // rotate 90 deg around z-axis + rotzx01->RotateX( 90.); // rotate 90 deg around x-axis + + TGeoRotation *rotzx02 = new TGeoRotation("rotzx02"); + rotzx02->RotateZ( 270.); // rotate 270 deg around z-axis + rotzx02->RotateX( 90.); // rotate 90 deg around x-axis + + Double_t ang1 = atan(3./4.) * 180. / acos(-1.); + // cout << "DEDE " << ang1 << endl; + // Double_t sin1 = acos(-1.); + // cout << "DEDE " << sin1 << endl; + TGeoRotation *rotx080 = new TGeoRotation("rotx080"); rotx080->RotateX( 90.-ang1); // rotate 80 deg around x-axis + TGeoRotation *rotx100 = new TGeoRotation("rotx100"); rotx100->RotateX( 90.+ang1); // rotate 100 deg around x-axis + + TGeoRotation *rotxy01 = new TGeoRotation("rotxy01"); + rotxy01->RotateX( 90.); // rotate 90 deg around x-axis + rotxy01->RotateZ(-ang1); // rotate ang1 around rotated y-axis + + TGeoRotation *rotxy02 = new TGeoRotation("rotxy02"); + rotxy02->RotateX( 90.); // rotate 90 deg around x-axis + rotxy02->RotateZ( ang1); // rotate ang1 around rotated y-axis + + +//------------------- +// vertical pillars (Y) +//------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { +// TGeoBBox* trd_I_vert1_keep = new TGeoBBox("", I_thick /2., I_height /2. - I_thick, (BeamHeight + (AperY[0]+I_height) ) /2.); + TGeoBBox* trd_I_vert1_keep = new TGeoBBox("trd_I_vert1_keep", I_thick /2., I_height /2. - I_thick, ( (AperYbot[0]+I_height) + (AperY[0]+I_height) ) /2.); + TGeoVolume* trd_I_vert1 = new TGeoVolume("trd_I_y11", trd_I_vert1_keep, aluminiumVolMed); + // TGeoBBox* trd_I_vert2_keep = new TGeoBBox("", I_width /2., I_thick /2., (BeamHeight + (AperY[0]+I_height) ) /2.); + TGeoBBox* trd_I_vert2_keep = new TGeoBBox("trd_I_vert2_keep", I_width /2., I_thick /2., ( (AperYbot[0]+I_height) + (AperY[0]+I_height) ) /2.); + TGeoVolume* trd_I_vert2 = new TGeoVolume("trd_I_y12", trd_I_vert2_keep, aluminiumVolMed); + + trd_I_vert1->SetLineColor(kGreen); // kBlue); // Yellow); // kOrange); + trd_I_vert2->SetLineColor(kGreen); // kBlue); // Yellow); // kOrange); + + TGeoTranslation *ty01 = new TGeoTranslation("ty01", 0., 0., 0.); + TGeoTranslation *ty02 = new TGeoTranslation("ty02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *ty03 = new TGeoTranslation("ty03", 0., -(I_height-I_thick) /2., 0.); + + // TGeoBBox* trd_I_vert_vol1_keep = new TGeoBBox("", I_width /2., I_height /2., (BeamHeight + (AperY[0]+I_height) ) /2.); + TGeoBBox* trd_I_vert_vol1_keep = new TGeoBBox("trd_I_vert_vol1_keep", I_width /2., I_height /2., ( (AperYbot[0]+I_height) + (AperY[0]+I_height) ) /2.); + TGeoVolume* trd_I_vert_vol1 = new TGeoVolume("trd_I_y10", trd_I_vert_vol1_keep, keepVolMed); + + // set green color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_vert_vol1->SetLineColor(kGreen); + + // build I-bar trd_I_vert_vol1 + trd_I_vert_vol1->AddNode(trd_I_vert1, 1, ty01); + trd_I_vert_vol1->AddNode(trd_I_vert2, 2, ty02); + trd_I_vert_vol1->AddNode(trd_I_vert2, 3, ty03); + + // close gap to horizontal z-bars + TGeoBBox* trd_I_vert3_keep = new TGeoBBox("trd_I_vert3_keep", (I_width-I_thick)/2. /2., I_height /2. - I_thick, I_thick /2.); + TGeoVolume* trd_I_vert3 = new TGeoVolume("trd_I_y13", trd_I_vert3_keep, aluminiumVolMed); + trd_I_vert3->SetLineColor(kGreen); +// TGeoTranslation *ty04 = new TGeoTranslation("ty04", (I_thick/2. + (I_width-I_thick)/2./2.), 0., -( (AperYbot[0]+I_height) + (AperY[0]+I_height) - I_width) /2.); // top +// TGeoTranslation *ty05 = new TGeoTranslation("ty05", (I_thick/2. + (I_width-I_thick)/2./2.), 0., ( (AperYbot[0]+I_height) + (AperY[0]+I_height) - I_width) /2.); // bottom + TGeoTranslation *ty04 = new TGeoTranslation("ty04", (I_thick/2. + (I_width-I_thick)/2./2.), 0., -( zBarPosYbot[0] + zBarPosYtop[0] )/2. ); // top + TGeoTranslation *ty05 = new TGeoTranslation("ty05", (I_thick/2. + (I_width-I_thick)/2./2.), 0., ( zBarPosYbot[0] + zBarPosYtop[0] )/2. ); // bottom + trd_I_vert_vol1->AddNode(trd_I_vert3, 4, ty04); + trd_I_vert_vol1->AddNode(trd_I_vert3, 5, ty05); + + PilPosX = AperX[0]; + + TGeoCombiTrans* trd_I_vert_combi01 = new TGeoCombiTrans( (PilPosX+I_height/2.), -( (AperYbot[0]+I_height) - (AperY[0]+I_height))/2., PilPosZ[0], rotzx01); + trd_1->AddNode(trd_I_vert_vol1, 11, trd_I_vert_combi01); + TGeoCombiTrans* trd_I_vert_combi02 = new TGeoCombiTrans(-(PilPosX+I_height/2.), -( (AperYbot[0]+I_height) - (AperY[0]+I_height))/2., PilPosZ[0], rotzx01); + trd_1->AddNode(trd_I_vert_vol1, 12, trd_I_vert_combi02); + TGeoCombiTrans* trd_I_vert_combi03 = new TGeoCombiTrans( (PilPosX+I_height/2.), -( (AperYbot[0]+I_height) - (AperY[0]+I_height))/2., PilPosZ[1], rotzx02); + trd_1->AddNode(trd_I_vert_vol1, 13, trd_I_vert_combi03); + TGeoCombiTrans* trd_I_vert_combi04 = new TGeoCombiTrans(-(PilPosX+I_height/2.), -( (AperYbot[0]+I_height) - (AperY[0]+I_height))/2., PilPosZ[1], rotzx02); + trd_1->AddNode(trd_I_vert_vol1, 14, trd_I_vert_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoBBox* trd_I_vert1_keep = new TGeoBBox("trd_I_vert1_keep", I_thick /2., I_height /2. - I_thick, (BeamHeight + (AperY[1]+I_height) ) /2.); + TGeoVolume* trd_I_vert1 = new TGeoVolume("trd_I_y21", trd_I_vert1_keep, aluminiumVolMed); + TGeoBBox* trd_I_vert2_keep = new TGeoBBox("trd_I_vert2_keep", I_width /2., I_thick /2., (BeamHeight + (AperY[1]+I_height) ) /2.); + TGeoVolume* trd_I_vert2 = new TGeoVolume("trd_I_y22", trd_I_vert2_keep, aluminiumVolMed); + + trd_I_vert1->SetLineColor(kGreen); + trd_I_vert2->SetLineColor(kGreen); + + TGeoTranslation *ty01 = new TGeoTranslation("ty01", 0., 0., 0.); + TGeoTranslation *ty02 = new TGeoTranslation("ty02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *ty03 = new TGeoTranslation("ty03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_vert_vol1_keep = new TGeoBBox("trd_I_vert_vol1_keep", I_width /2., I_height /2., (BeamHeight + (AperY[1]+I_height) ) /2.); + TGeoVolume* trd_I_vert_vol1 = new TGeoVolume("trd_I_y20", trd_I_vert_vol1_keep, keepVolMed); + + // set green color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_vert_vol1->SetLineColor(kGreen); + + // build I-bar trd_I_vert_vol1 + trd_I_vert_vol1->AddNode(trd_I_vert1, 1, ty01); + trd_I_vert_vol1->AddNode(trd_I_vert2, 2, ty02); + trd_I_vert_vol1->AddNode(trd_I_vert2, 3, ty03); + + // close gap to horizontal z-bars + TGeoBBox* trd_I_vert3_keep = new TGeoBBox("trd_I_vert3_keep", (I_width-I_thick)/2. /2., I_height /2. - I_thick, I_thick /2.); + TGeoVolume* trd_I_vert3 = new TGeoVolume("trd_I_y23", trd_I_vert3_keep, aluminiumVolMed); + trd_I_vert3->SetLineColor(kGreen); + TGeoTranslation *ty04 = new TGeoTranslation("ty04", (I_thick/2. + (I_width-I_thick)/2./2.), 0., -(BeamHeight + (AperY[1]+I_height) - I_width) /2.); // top + TGeoTranslation *ty05 = new TGeoTranslation("ty05", (I_thick/2. + (I_width-I_thick)/2./2.), 0., -(BeamHeight - (AperY[1]+I_height) )/2. + zBarPosYbot[1] ); // bottom + trd_I_vert_vol1->AddNode(trd_I_vert3, 4, ty04); + trd_I_vert_vol1->AddNode(trd_I_vert3, 5, ty05); + + PilPosX = AperX[1]; + + TGeoCombiTrans* trd_I_vert_combi01 = new TGeoCombiTrans( (PilPosX+I_height/2.), -(BeamHeight - (AperY[1]+I_height))/2., PilPosZ[2], rotzx01); + trd_2->AddNode(trd_I_vert_vol1, 21, trd_I_vert_combi01); + TGeoCombiTrans* trd_I_vert_combi02 = new TGeoCombiTrans(-(PilPosX+I_height/2.), -(BeamHeight - (AperY[1]+I_height))/2., PilPosZ[2], rotzx01); + trd_2->AddNode(trd_I_vert_vol1, 22, trd_I_vert_combi02); + TGeoCombiTrans* trd_I_vert_combi03 = new TGeoCombiTrans( (PilPosX+I_height/2.), -(BeamHeight - (AperY[1]+I_height))/2., PilPosZ[3], rotzx02); + trd_2->AddNode(trd_I_vert_vol1, 23, trd_I_vert_combi03); + TGeoCombiTrans* trd_I_vert_combi04 = new TGeoCombiTrans(-(PilPosX+I_height/2.), -(BeamHeight - (AperY[1]+I_height))/2., PilPosZ[3], rotzx02); + trd_2->AddNode(trd_I_vert_vol1, 24, trd_I_vert_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoBBox* trd_I_vert1_keep = new TGeoBBox("trd_I_vert1_keep", I_thick /2., I_height /2. - I_thick, (BeamHeight + (AperY[2]+I_height) ) /2.); + TGeoVolume* trd_I_vert1 = new TGeoVolume("trd_I_y31", trd_I_vert1_keep, aluminiumVolMed); + TGeoBBox* trd_I_vert2_keep = new TGeoBBox("trd_I_vert2_keep", I_width /2., I_thick /2., (BeamHeight + (AperY[2]+I_height) ) /2.); + TGeoVolume* trd_I_vert2 = new TGeoVolume("trd_I_y32", trd_I_vert2_keep, aluminiumVolMed); + + trd_I_vert1->SetLineColor(kGreen); + trd_I_vert2->SetLineColor(kGreen); + + TGeoTranslation *ty01 = new TGeoTranslation("ty01", 0., 0., 0.); + TGeoTranslation *ty02 = new TGeoTranslation("ty02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *ty03 = new TGeoTranslation("ty03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_vert_vol1_keep = new TGeoBBox("trd_I_vert_vol1_keep", I_width /2., I_height /2., (BeamHeight + (AperY[2]+I_height) ) /2.); + TGeoVolume* trd_I_vert_vol1 = new TGeoVolume("trd_I_y30", trd_I_vert_vol1_keep, keepVolMed); + + // set green color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_vert_vol1->SetLineColor(kGreen); + + // build I-bar trd_I_vert_vol1 + trd_I_vert_vol1->AddNode(trd_I_vert1, 1, ty01); + trd_I_vert_vol1->AddNode(trd_I_vert2, 2, ty02); + trd_I_vert_vol1->AddNode(trd_I_vert2, 3, ty03); + + // close gap to horizontal z-bars + TGeoBBox* trd_I_vert3_keep = new TGeoBBox("trd_I_vert3_keep", (I_width-I_thick)/2. /2., I_height /2. - I_thick, I_thick /2.); + TGeoVolume* trd_I_vert3 = new TGeoVolume("trd_I_y33", trd_I_vert3_keep, aluminiumVolMed); + trd_I_vert3->SetLineColor(kGreen); + TGeoTranslation *ty04 = new TGeoTranslation("ty04", (I_thick/2. + (I_width-I_thick)/2./2.), 0., -(BeamHeight + (AperY[2]+I_height) - I_width) /2.); // top + TGeoTranslation *ty05 = new TGeoTranslation("ty05", (I_thick/2. + (I_width-I_thick)/2./2.), 0., -(BeamHeight - (AperY[2]+I_height) )/2. + zBarPosYbot[2] ); // bottom + trd_I_vert_vol1->AddNode(trd_I_vert3, 4, ty04); + trd_I_vert_vol1->AddNode(trd_I_vert3, 5, ty05); + + PilPosX = AperX[2]; + + TGeoCombiTrans* trd_I_vert_combi01 = new TGeoCombiTrans( (PilPosX+I_height/2.), -(BeamHeight - (AperY[2]+I_height))/2., PilPosZ[4], rotzx01); + trd_3->AddNode(trd_I_vert_vol1, 31, trd_I_vert_combi01); + TGeoCombiTrans* trd_I_vert_combi02 = new TGeoCombiTrans(-(PilPosX+I_height/2.), -(BeamHeight - (AperY[2]+I_height))/2., PilPosZ[4], rotzx01); + trd_3->AddNode(trd_I_vert_vol1, 32, trd_I_vert_combi02); + TGeoCombiTrans* trd_I_vert_combi03 = new TGeoCombiTrans( (PilPosX+I_height/2.), -(BeamHeight - (AperY[2]+I_height))/2., PilPosZ[5], rotzx02); + trd_3->AddNode(trd_I_vert_vol1, 33, trd_I_vert_combi03); + TGeoCombiTrans* trd_I_vert_combi04 = new TGeoCombiTrans(-(PilPosX+I_height/2.), -(BeamHeight - (AperY[2]+I_height))/2., PilPosZ[5], rotzx02); + trd_3->AddNode(trd_I_vert_vol1, 34, trd_I_vert_combi04); + } + + +//------------------- +// horizontal supports (X) +//------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + TGeoBBox* trd_I_hori1_keep = new TGeoBBox("trd_I_hori1_keep", I_thick /2., I_height /2. - I_thick, AperX[0]); + TGeoVolume* trd_I_hori1 = new TGeoVolume("trd_I_x11", trd_I_hori1_keep, aluminiumVolMed); + TGeoBBox* trd_I_hori2_keep = new TGeoBBox("trd_I_hori2_keep", I_width /2., I_thick /2., AperX[0]); + TGeoVolume* trd_I_hori2 = new TGeoVolume("trd_I_x12", trd_I_hori2_keep, aluminiumVolMed); + + trd_I_hori1->SetLineColor(kRed); // Yellow); + trd_I_hori2->SetLineColor(kRed); // Yellow); + + TGeoTranslation *tx01 = new TGeoTranslation("tx01", 0., 0., 0.); + TGeoTranslation *tx02 = new TGeoTranslation("tx02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *tx03 = new TGeoTranslation("tx03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_hori_vol1_keep = new TGeoBBox("trd_I_hori_vol1_keep", I_width /2., I_height /2., AperX[0]); + TGeoVolume* trd_I_hori_vol1 = new TGeoVolume("trd_I_x10", trd_I_hori_vol1_keep, keepVolMed); + + // set red color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_hori_vol1->SetLineColor(kRed); + + // build I-bar trd_I_hori_vol1 + trd_I_hori_vol1->AddNode(trd_I_hori1, 1, tx01); + trd_I_hori_vol1->AddNode(trd_I_hori2, 2, tx02); + trd_I_hori_vol1->AddNode(trd_I_hori2, 3, tx03); + + TGeoCombiTrans* trd_I_hori_combi01 = new TGeoCombiTrans(0., xBarPosYtop[0], PilPosZ[0], roty090); + trd_1->AddNode(trd_I_hori_vol1, 11, trd_I_hori_combi01); + TGeoCombiTrans* trd_I_hori_combi02 = new TGeoCombiTrans(0.,-xBarPosYbot[0], PilPosZ[0], roty090); + trd_1->AddNode(trd_I_hori_vol1, 12, trd_I_hori_combi02); + TGeoCombiTrans* trd_I_hori_combi03 = new TGeoCombiTrans(0., xBarPosYtop[0], PilPosZ[1], roty090); + trd_1->AddNode(trd_I_hori_vol1, 13, trd_I_hori_combi03); + TGeoCombiTrans* trd_I_hori_combi04 = new TGeoCombiTrans(0.,-xBarPosYbot[0], PilPosZ[1], roty090); + trd_1->AddNode(trd_I_hori_vol1, 14, trd_I_hori_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoBBox* trd_I_hori1_keep = new TGeoBBox("trd_I_hori1_keep", I_thick /2., I_height /2. - I_thick, AperX[1]); + TGeoVolume* trd_I_hori1 = new TGeoVolume("trd_I_x21", trd_I_hori1_keep, aluminiumVolMed); + TGeoBBox* trd_I_hori2_keep = new TGeoBBox("trd_I_hori2_keep", I_width /2., I_thick /2., AperX[1]); + TGeoVolume* trd_I_hori2 = new TGeoVolume("trd_I_x22", trd_I_hori2_keep, aluminiumVolMed); + + trd_I_hori1->SetLineColor(kRed); + trd_I_hori2->SetLineColor(kRed); + + TGeoTranslation *tx01 = new TGeoTranslation("tx01", 0., 0., 0.); + TGeoTranslation *tx02 = new TGeoTranslation("tx02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *tx03 = new TGeoTranslation("tx03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_hori_vol1_keep = new TGeoBBox("trd_I_hori_vol1_keep", I_width /2., I_height /2., AperX[1]); + TGeoVolume* trd_I_hori_vol1 = new TGeoVolume("trd_I_x20", trd_I_hori_vol1_keep, keepVolMed); + + // set red color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_hori_vol1->SetLineColor(kRed); + + // build I-bar trd_I_hori_vol1 + trd_I_hori_vol1->AddNode(trd_I_hori1, 1, tx01); + trd_I_hori_vol1->AddNode(trd_I_hori2, 2, tx02); + trd_I_hori_vol1->AddNode(trd_I_hori2, 3, tx03); + + TGeoCombiTrans* trd_I_hori_combi01 = new TGeoCombiTrans(0., xBarPosYtop[1], PilPosZ[2], roty090); + trd_2->AddNode(trd_I_hori_vol1, 21, trd_I_hori_combi01); + TGeoCombiTrans* trd_I_hori_combi02 = new TGeoCombiTrans(0.,-xBarPosYbot[1], PilPosZ[2], roty090); + trd_2->AddNode(trd_I_hori_vol1, 22, trd_I_hori_combi02); + TGeoCombiTrans* trd_I_hori_combi03 = new TGeoCombiTrans(0., xBarPosYtop[1], PilPosZ[3], roty090); + trd_2->AddNode(trd_I_hori_vol1, 23, trd_I_hori_combi03); + TGeoCombiTrans* trd_I_hori_combi04 = new TGeoCombiTrans(0.,-xBarPosYbot[1], PilPosZ[3], roty090); + trd_2->AddNode(trd_I_hori_vol1, 24, trd_I_hori_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoBBox* trd_I_hori1_keep = new TGeoBBox("trd_I_hori1_keep", I_thick /2., I_height /2. - I_thick, AperX[2]); + TGeoVolume* trd_I_hori1 = new TGeoVolume("trd_I_x31", trd_I_hori1_keep, aluminiumVolMed); + TGeoBBox* trd_I_hori2_keep = new TGeoBBox("trd_I_hori2_keep", I_width /2., I_thick /2., AperX[2]); + TGeoVolume* trd_I_hori2 = new TGeoVolume("trd_I_x32", trd_I_hori2_keep, aluminiumVolMed); + + trd_I_hori1->SetLineColor(kRed); + trd_I_hori2->SetLineColor(kRed); + + TGeoTranslation *tx01 = new TGeoTranslation("tx01", 0., 0., 0.); + TGeoTranslation *tx02 = new TGeoTranslation("tx02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *tx03 = new TGeoTranslation("tx03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_hori_vol1_keep = new TGeoBBox("trd_I_hori_vol1_keep", I_width /2., I_height /2., AperX[2]); + TGeoVolume* trd_I_hori_vol1 = new TGeoVolume("trd_I_x30", trd_I_hori_vol1_keep, keepVolMed); + + // set red color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_hori_vol1->SetLineColor(kRed); + + // build I-bar trd_I_hori_vol1 + trd_I_hori_vol1->AddNode(trd_I_hori1, 1, tx01); + trd_I_hori_vol1->AddNode(trd_I_hori2, 2, tx02); + trd_I_hori_vol1->AddNode(trd_I_hori2, 3, tx03); + + TGeoCombiTrans* trd_I_hori_combi01 = new TGeoCombiTrans(0., xBarPosYtop[2], PilPosZ[4], roty090); + trd_3->AddNode(trd_I_hori_vol1, 31, trd_I_hori_combi01); + TGeoCombiTrans* trd_I_hori_combi02 = new TGeoCombiTrans(0.,-xBarPosYbot[2], PilPosZ[4], roty090); + trd_3->AddNode(trd_I_hori_vol1, 32, trd_I_hori_combi02); + TGeoCombiTrans* trd_I_hori_combi03 = new TGeoCombiTrans(0., xBarPosYtop[2], PilPosZ[5], roty090); + trd_3->AddNode(trd_I_hori_vol1, 33, trd_I_hori_combi03); + TGeoCombiTrans* trd_I_hori_combi04 = new TGeoCombiTrans(0.,-xBarPosYbot[2], PilPosZ[5], roty090); + trd_3->AddNode(trd_I_hori_vol1, 34, trd_I_hori_combi04); + } + + +//------------------- +// horizontal supports (Z) +//------------------- + + // station 1 + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + TGeoBBox* trd_I_slope1_keep = new TGeoBBox("trd_I_slope1_keep", I_thick /2., I_height /2. - I_thick, (PilPosZ[1]-PilPosZ[0]-I_width)/2.); + TGeoVolume* trd_I_slope1 = new TGeoVolume("trd_I_z11", trd_I_slope1_keep, aluminiumVolMed); + TGeoBBox* trd_I_slope2_keep = new TGeoBBox("trd_I_slope2_keep", I_width /2., I_thick /2., (PilPosZ[1]-PilPosZ[0]-I_width)/2.); + TGeoVolume* trd_I_slope2 = new TGeoVolume("trd_I_z12", trd_I_slope2_keep, aluminiumVolMed); + + trd_I_slope1->SetLineColor(kYellow); + trd_I_slope2->SetLineColor(kYellow); + + TGeoTranslation *tz01 = new TGeoTranslation("tz01", 0., 0., 0.); + TGeoTranslation *tz02 = new TGeoTranslation("tz02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *tz03 = new TGeoTranslation("tz03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_slope_vol1_keep = new TGeoBBox("trd_I_slope_vol1_keep", I_width /2., I_height /2., (PilPosZ[1]-PilPosZ[0]-I_width)/2.); + TGeoVolume* trd_I_slope_vol1 = new TGeoVolume("trd_I_z10", trd_I_slope_vol1_keep, keepVolMed); + + // set yellow color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_slope_vol1->SetLineColor(kYellow); + + // build I-bar trd_I_slope_vol1 + trd_I_slope_vol1->AddNode(trd_I_slope1, 1, tz01); + trd_I_slope_vol1->AddNode(trd_I_slope2, 2, tz02); + trd_I_slope_vol1->AddNode(trd_I_slope2, 3, tz03); + + PilPosX = AperX[0]; + + TGeoCombiTrans* trd_I_slope_combi01 = new TGeoCombiTrans( (PilPosX+I_height/2.), zBarPosYtop[0], (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_I_slope_vol1, 11, trd_I_slope_combi01); + TGeoCombiTrans* trd_I_slope_combi02 = new TGeoCombiTrans(-(PilPosX+I_height/2.), zBarPosYtop[0], (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_I_slope_vol1, 12, trd_I_slope_combi02); + TGeoCombiTrans* trd_I_slope_combi03 = new TGeoCombiTrans( (PilPosX+I_height/2.),-zBarPosYbot[0], (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_I_slope_vol1, 13, trd_I_slope_combi03); + TGeoCombiTrans* trd_I_slope_combi04 = new TGeoCombiTrans(-(PilPosX+I_height/2.),-zBarPosYbot[0], (PilPosZ[0]+PilPosZ[1])/2., rotz090); + trd_1->AddNode(trd_I_slope_vol1, 14, trd_I_slope_combi04); + } + + // station 2 + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + TGeoBBox* trd_I_slope1_keep = new TGeoBBox("trd_I_slope1_keep", I_thick /2., I_height /2. - I_thick, (PilPosZ[3]-PilPosZ[2]-I_width)/2.); + TGeoVolume* trd_I_slope1 = new TGeoVolume("trd_I_z21", trd_I_slope1_keep, aluminiumVolMed); + TGeoBBox* trd_I_slope2_keep = new TGeoBBox("trd_I_slope2_keep", I_width /2., I_thick /2., (PilPosZ[3]-PilPosZ[2]-I_width)/2.); + TGeoVolume* trd_I_slope2 = new TGeoVolume("trd_I_z22", trd_I_slope2_keep, aluminiumVolMed); + + trd_I_slope1->SetLineColor(kYellow); + trd_I_slope2->SetLineColor(kYellow); + + TGeoTranslation *tz01 = new TGeoTranslation("tz01", 0., 0., 0.); + TGeoTranslation *tz02 = new TGeoTranslation("tz02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *tz03 = new TGeoTranslation("tz03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_slope_vol1_keep = new TGeoBBox("trd_I_slope_vol1_keep", I_width /2., I_height /2., (PilPosZ[3]-PilPosZ[2]-I_width)/2.); + TGeoVolume* trd_I_slope_vol1 = new TGeoVolume("trd_I_z20", trd_I_slope_vol1_keep, keepVolMed); + + // set yellow color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_slope_vol1->SetLineColor(kYellow); + + // build I-bar trd_I_slope_vol1 + trd_I_slope_vol1->AddNode(trd_I_slope1, 1, tz01); + trd_I_slope_vol1->AddNode(trd_I_slope2, 2, tz02); + trd_I_slope_vol1->AddNode(trd_I_slope2, 3, tz03); + + PilPosX = AperX[1]; + + TGeoCombiTrans* trd_I_slope_combi01 = new TGeoCombiTrans( (PilPosX+I_height/2.), zBarPosYtop[1], (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_I_slope_vol1, 21, trd_I_slope_combi01); + TGeoCombiTrans* trd_I_slope_combi02 = new TGeoCombiTrans(-(PilPosX+I_height/2.), zBarPosYtop[1], (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_I_slope_vol1, 22, trd_I_slope_combi02); + TGeoCombiTrans* trd_I_slope_combi03 = new TGeoCombiTrans( (PilPosX+I_height/2.),-zBarPosYbot[1], (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_I_slope_vol1, 23, trd_I_slope_combi03); + TGeoCombiTrans* trd_I_slope_combi04 = new TGeoCombiTrans(-(PilPosX+I_height/2.),-zBarPosYbot[1], (PilPosZ[2]+PilPosZ[3])/2., rotz090); + trd_2->AddNode(trd_I_slope_vol1, 24, trd_I_slope_combi04); + } + + // station 3 + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + TGeoBBox* trd_I_slope1_keep = new TGeoBBox("trd_I_slope1_keep", I_thick /2., I_height /2. - I_thick, (PilPosZ[5]-PilPosZ[4]-I_width)/2.); + TGeoVolume* trd_I_slope1 = new TGeoVolume("trd_I_z31", trd_I_slope1_keep, aluminiumVolMed); + TGeoBBox* trd_I_slope2_keep = new TGeoBBox("trd_I_slope2_keep", I_width /2., I_thick /2., (PilPosZ[5]-PilPosZ[4]-I_width)/2.); + TGeoVolume* trd_I_slope2 = new TGeoVolume("trd_I_z32", trd_I_slope2_keep, aluminiumVolMed); + + trd_I_slope1->SetLineColor(kYellow); + trd_I_slope2->SetLineColor(kYellow); + + TGeoTranslation *tz01 = new TGeoTranslation("tz01", 0., 0., 0.); + TGeoTranslation *tz02 = new TGeoTranslation("tz02", 0., (I_height-I_thick) /2., 0.); + TGeoTranslation *tz03 = new TGeoTranslation("tz03", 0., -(I_height-I_thick) /2., 0.); + + TGeoBBox* trd_I_slope_vol1_keep = new TGeoBBox("trd_I_slope_vol1_keep", I_width /2., I_height /2., (PilPosZ[5]-PilPosZ[4]-I_width)/2.); + TGeoVolume* trd_I_slope_vol1 = new TGeoVolume("trd_I_z30", trd_I_slope_vol1_keep, keepVolMed); + + // set yellow color for keeping volume of I profile, seen with gGeoManager->SetVisLevel(2) + trd_I_slope_vol1->SetLineColor(kYellow); + + // build I-bar trd_I_slope_vol1 + trd_I_slope_vol1->AddNode(trd_I_slope1, 1, tz01); + trd_I_slope_vol1->AddNode(trd_I_slope2, 2, tz02); + trd_I_slope_vol1->AddNode(trd_I_slope2, 3, tz03); + + PilPosX = AperX[2]; + + TGeoCombiTrans* trd_I_slope_combi01 = new TGeoCombiTrans( (PilPosX+I_height/2.), zBarPosYtop[2], (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_I_slope_vol1, 31, trd_I_slope_combi01); + TGeoCombiTrans* trd_I_slope_combi02 = new TGeoCombiTrans(-(PilPosX+I_height/2.), zBarPosYtop[2], (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_I_slope_vol1, 32, trd_I_slope_combi02); + TGeoCombiTrans* trd_I_slope_combi03 = new TGeoCombiTrans( (PilPosX+I_height/2.),-zBarPosYbot[2], (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_I_slope_vol1, 33, trd_I_slope_combi03); + TGeoCombiTrans* trd_I_slope_combi04 = new TGeoCombiTrans(-(PilPosX+I_height/2.),-zBarPosYbot[2], (PilPosZ[4]+PilPosZ[5])/2., rotz090); + trd_3->AddNode(trd_I_slope_vol1, 34, trd_I_slope_combi04); + } + + if (IncludeLabels) + { + + Int_t text_height = 40; + Int_t text_thickness = 8; + + TGeoTranslation *tr200 = new TGeoTranslation(0., (AperY[0]+I_height+ text_height/2.), PilPosZ[0]-I_width/2.+ text_thickness/2.); + TGeoTranslation *tr201 = new TGeoTranslation(0., (AperY[1]+I_height+ text_height/2.), PilPosZ[2]-I_width/2.+ text_thickness/2.); + TGeoTranslation *tr202 = new TGeoTranslation(0., (AperY[2]+I_height+ text_height/2.), PilPosZ[4]-I_width/2.+ text_thickness/2.); + + TGeoCombiTrans *tr203 = new TGeoCombiTrans(-(AperX[0]+I_height+ text_thickness/2.), (AperY[0]+I_height-I_width-text_height/2.), (PilPosZ[0]+PilPosZ[1])/2., roty090); + TGeoCombiTrans *tr204 = new TGeoCombiTrans(-(AperX[1]+I_height+ text_thickness/2.), (AperY[1]+I_height-I_width-text_height/2.), (PilPosZ[2]+PilPosZ[3])/2., roty090); + TGeoCombiTrans *tr205 = new TGeoCombiTrans(-(AperX[2]+I_height+ text_thickness/2.), (AperY[2]+I_height-I_width-text_height/2.), (PilPosZ[4]+PilPosZ[5])/2., roty090); + + TGeoCombiTrans *tr206 = new TGeoCombiTrans( (AperX[0]+I_height+ text_thickness/2.), (AperY[0]+I_height-I_width-text_height/2.), (PilPosZ[0]+PilPosZ[1])/2., roty270); + TGeoCombiTrans *tr207 = new TGeoCombiTrans( (AperX[1]+I_height+ text_thickness/2.), (AperY[1]+I_height-I_width-text_height/2.), (PilPosZ[2]+PilPosZ[3])/2., roty270); + TGeoCombiTrans *tr208 = new TGeoCombiTrans( (AperX[2]+I_height+ text_thickness/2.), (AperY[2]+I_height-I_width-text_height/2.), (PilPosZ[4]+PilPosZ[5])/2., roty270); + + TGeoVolume* trdbox1 = new TGeoVolumeAssembly("trdbox1"); // volume for TRD text (108, 40, 8) + TGeoVolume* trdbox2 = new TGeoVolumeAssembly("trdbox2"); // volume for TRD text (108, 40, 8) + TGeoVolume* trdbox3 = new TGeoVolumeAssembly("trdbox3"); // volume for TRD text (108, 40, 8) + add_trd_labels(trdbox1, trdbox2, trdbox3); + + // final placement + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + { + // trd_1->AddNode(trdbox1, 1, tr200); + trd_1->AddNode(trdbox1, 4, tr203); + trd_1->AddNode(trdbox1, 7, tr206); + } + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + { + // trd_2->AddNode(trdbox2, 2, tr201); + trd_2->AddNode(trdbox2, 5, tr204); + trd_2->AddNode(trdbox2, 8, tr207); + } + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + { + // trd_3->AddNode(trdbox3, 3, tr202); + trd_3->AddNode(trdbox3, 6, tr205); + trd_3->AddNode(trdbox3, 9, tr208); + } + } + + if (ShowLayer[0]) // if geometry contains layer 1 (1st layer of station 1) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_1, 1); + if (ShowLayer[4]) // if geometry contains layer 5 (1st layer of station 2) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_2, 2); + if (ShowLayer[8]) // if geometry contains layer 9 (1st layer of station 3) + gGeoMan->GetVolume(geoVersion)->AddNode(trd_3, 3); + +} + -- GitLab