diff --git a/core/detectors/trd/CbmTrdBaseLinkDef.h b/core/detectors/trd/CbmTrdBaseLinkDef.h index b191955c756627426a19492ff9aa83d9f7b5aa10..de7338445de2b72f902c0c9603a439aa5dec465f 100644 --- a/core/detectors/trd/CbmTrdBaseLinkDef.h +++ b/core/detectors/trd/CbmTrdBaseLinkDef.h @@ -27,6 +27,7 @@ #pragma link C++ class cbm::trd::geo::ChamberBuilder::Volume + ; #pragma link C++ class cbm::trd::geo::ChamberBuilder::BackPanel + ; #pragma link C++ class cbm::trd::geo::ChamberBuilder::FEB + ; +#pragma link C++ class cbm::trd::geo::ChamberBuilder::AUX + ; #pragma link C++ class cbm::trd::geo::SetupManager + ; #pragma link C++ class cbm::trd::geo::Setup + ; #pragma link C++ class cbm::trd::geo::Setup::Module + ; diff --git a/core/detectors/trd/CbmTrdGeoFactory.cxx b/core/detectors/trd/CbmTrdGeoFactory.cxx index 1c79aaf66087b453ec1972d224d2682ffa9df0ef..827991474cf7e70e6c063112885530268690ef9d 100644 --- a/core/detectors/trd/CbmTrdGeoFactory.cxx +++ b/core/detectors/trd/CbmTrdGeoFactory.cxx @@ -27,8 +27,8 @@ using namespace cbm::trd; using namespace cbm::trd::geo; -const char* ChamberBuilder::Component::fgName[(int) ChamberBuilder::eGeoPart::kNparts] = {"Radiator", "Window", - "Volume", "BackPanel", "FEB"}; +const char* ChamberBuilder::Component::fgName[(int) ChamberBuilder::eGeoPart::kNparts] = { + "Radiator", "Window", "Volume", "BackPanel", "FEB", "AUX"}; //________________________________________________________________________________________ const TGeoMedium* cbm::trd::geo::GetMaterial(const char* mname) { @@ -170,13 +170,17 @@ ChamberBuilder::ChamberBuilder(int typ) : FairTask(Form("module%d", typ)) fComponent[(int) eGeoPart::kVolume] = new Volume; fComponent[(int) eGeoPart::kBackPanel] = new BackPanel; fComponent[(int) eGeoPart::kFEB] = nullptr; + fComponent[(int) eGeoPart::kAUX] = nullptr; } //________________________________________________________________________________________ InitStatus ChamberBuilder::Init() { if (HasRadiator()) fComponent[(int) eGeoPart::kRadiator] = new Radiator; - if (HasFEB()) fComponent[(int) eGeoPart::kFEB] = new FEB; + if (HasFEB()) { + fComponent[(int) eGeoPart::kFEB] = new FEB; + fComponent[(int) eGeoPart::kAUX] = new AUX; + } switch (fChmbTyp) { case 1: LOG(info) << "Init for TRD2D."; @@ -224,23 +228,17 @@ void ChamberBuilder::Exec(Option_t*) int idx(0); double vh[(int) eGeoPart::kNparts]; bool kAdd(true); - double hOffset(0.), hTot(0.); + double hTot(0.); for (auto icomp : fComponent) { if (!icomp) continue; vh[idx] = icomp->GetHeight(); hTot += vh[idx]; if (kAdd) { - if (idx == (int) eGeoPart::kVolume) { - hOffset += vh[idx] / 2; - kAdd = false; - } - else - hOffset += vh[idx]; + if (idx == (int) eGeoPart::kVolume) kAdd = false; } idx++; } // add global z offset - hOffset = hTot / 2; fVol = new TGeoVolume(Form("module%d", fChmbTyp), new TGeoBBox("", sizeX / 2, sizeY / 2, hTot / 2), cbm::trd::geo::GetMaterial("air")); fVol->SetLineColor(kGreen); @@ -256,7 +254,8 @@ void ChamberBuilder::Exec(Option_t*) switch (idx) { case (int) eGeoPart::kFEB: { // special case for feb multiple placement. // FEB characteristics and identification stored in geometry - auto vFeb = new TGeoVolume(icomp->GetName(), new TGeoBBox("", sizeX / 2, sizeY / 2, vh[idx] / 2)); + auto vFeb = + new TGeoVolume("FEB", new TGeoBBox("", sizeX / 2, sizeY / 2, vh[idx] / 2), cbm::trd::geo::GetMaterial("air")); for (int ifeb(0), jfeb(0); ifeb < Nfebs; ifeb++) { infoFeb.id = ifeb; infoFeb.superId = 0; // gDB.GetFebId(imod, ifeb); @@ -499,6 +498,12 @@ InitStatus ChamberBuilder::BackPanel::Init() } } fHeight += hHC; + // supports for electronics + TGeoBBox* faspro_fy = new TGeoBBox("faspro_fy", 1.0 / 2, 0.5 + 0.5 * sizeY, 0.5 * ChamberBuilder::FEB::FASPRO_zspace); + TGeoVolume* vol_faspro_fy = + new TGeoVolume("faspro_fy", faspro_fy, cbm::trd::geo::GetMaterial("TRDG10") /*frameVolMed*/); + vol_faspro_fy->SetLineColor(kViolet + 2); // vol_faspro_fy->SetTransparency(50); + fHeight += ChamberBuilder::FEB::FASPRO_zspace; // framex auto xoutBd = @@ -526,13 +531,14 @@ InitStatus ChamberBuilder::BackPanel::Init() vol_bkp_yout->SetLineColor(kViolet + 2); // Add up all components - fVol = new TGeoVolume(GetName(), new TGeoBBox("", bkp_size_x / 2, bkp_size_y / 2, fHeight / 2), + float height(fHeight); + fVol = new TGeoVolume(GetName(), new TGeoBBox("", bkp_size_x / 2, bkp_size_y / 2, height / 2), cbm::trd::geo::GetMaterial("air")); fVol->SetLineColor(kOrange); fVol->SetTransparency(50); double x, y; - fHeight = -fHeight / 2 + 0.5 * pp_pads_thickness; + fHeight = -height / 2 + 0.5 * pp_pads_thickness; fVol->AddNode(vol_pp, 1, new TGeoTranslation("", 0., 0., fHeight)); fHeight += 0.5 * (pp_pads_thickness + pp_pcb_thickness); fVol->AddNode(vol_pp_PCB, 1, new TGeoTranslation("", 0., 0., fHeight)); @@ -554,19 +560,33 @@ InitStatus ChamberBuilder::BackPanel::Init() fy_mat = new TGeoHMatrix(""); (*fy_mat) = (*fy_rot) * (*fy_tra); fVol->AddNode(vol_bkp_xout, 2, fy_mat); - fHeight += 0.5 * hHC; + fHeight += 0.5 * (hHC + ChamberBuilder::FEB::FASPRO_zspace); + + int cFeb(0); + for (int ifeb(0); ifeb < Nfebs; ifeb++) { + if (ifeb % 5 != 0) continue; + // add support + fVol->AddNode( + vol_faspro_fy, cFeb, + new TGeoTranslation("", feb_pos[ifeb][0] - 0.5 * (ChamberBuilder::FEB::FASPRO_length + 0.2), 0., fHeight)); + cFeb++; + } + fVol->AddNode( + vol_faspro_fy, cFeb, + new TGeoTranslation("", feb_pos[Nfebs - 1][0] + 0.5 * (ChamberBuilder::FEB::FASPRO_length + 0.2), 0., fHeight)); + + fHeight += 0.5 * ChamberBuilder::FEB::FASPRO_zspace; fHeight *= 2; + return kSUCCESS; } //________________________________________________________________________________________ -ChamberBuilder::FEB::FEB() : Component("FEB") { ; } +ChamberBuilder::FEB::FEB() : Component("FASPRO") { ; } InitStatus ChamberBuilder::FEB::Init() { // Create the FASPRO FEBs out of all CU/PCB layers - fHeight = FASPRO_zspace; - TString scu = "", spcb = ""; TGeoTranslation* tr(nullptr); double FASPRO_thickness(0.); @@ -605,7 +625,7 @@ InitStatus ChamberBuilder::FEB::Init() cbm::trd::geo::GetMaterial("TRDG10") /*febVolMed*/); // the FEB made of PCB vol_faspro_pcb->SetLineColor(kGreen + 3); //vol_faspro_pcb->SetTransparency(50); - fHeight += FASPRO_thickness; + fHeight = FASPRO_thickness; // create FASP ASIC auto fasp = new TGeoBBox("fasp", FASP_x / 2., FASP_y / 2., FASP_z / 2.); @@ -637,16 +657,18 @@ InitStatus ChamberBuilder::FEB::Init() // FEB family FASPRO // FEB type v1 (12 FASPs) int fType = 1; - fVol = new TGeoVolumeAssembly(Form("%s1%d", GetName(), fType)); + fVol = new TGeoVolume(Form("%s1%d", GetName(), fType), + new TGeoBBox("", FASPRO_length / 2., FASPRO_width / 2., fHeight / 2.), + cbm::trd::geo::GetMaterial("air")); fVol->SetLineColor(kGreen); fVol->SetTransparency(50); // Add up all components - fHeight = -0.5 * fHeight + FASPRO_zspace; + fHeight = -0.5 * fHeight; fVol->AddNode(vol_faspro_cu, 1, new TGeoTranslation("", 0., 0., fHeight)); fVol->AddNode(vol_faspro_pcb, 1, new TGeoTranslation("", 0., 0., fHeight)); // add FASPs on the back side of the FEB - info_t infoAsic; + //info_t infoAsic; for (int ifasp(0), jfasp(0); ifasp < faspFeb[fType].nasic; ifasp++) { vol_fasp->SetTitle(Form("%x", 0xff /*gDB->GetASICMask*/)); // if ((jfasp = WriteAsicInfo(&infoAsic)) < 0) continue; @@ -672,6 +694,101 @@ InitStatus ChamberBuilder::FEB::Init() new TGeoTranslation("", ConnBRG_pos[iconn][0], ConnBRG_pos[iconn][1], fHeight + ConnBRG_z / 2)); fHeight += ConnBRG_z; fHeight *= 2; + + return kSUCCESS; +} + + +//________________________________________________________________________________________ +ChamberBuilder::AUX::AUX() : Component("AUX") { ; } + +InitStatus ChamberBuilder::AUX::Init() +{ + // create BRIDGE Coonector (see also FEB::Init()) + auto connBrg = new TGeoBBox("connBrg", ChamberBuilder::FEB::ConnBRG_x / 2., ChamberBuilder::FEB::ConnBRG_y / 2., + ChamberBuilder::FEB::ConnBRG_z / 2.); + auto vol_conn_brg = new TGeoVolume("connBrg", connBrg, cbm::trd::geo::GetMaterial("polypropylene")); + vol_conn_brg->SetLineColor(kYellow + 2); + + // GA01 board - create + float ga01_z = ChamberBuilder::FEB::ConnBRG_z + GA01_z + SATAz; + TGeoBBox* ga01_bd = new TGeoBBox("ga01_bd", GA01_x / 2., GA01_y / 2., GA01_z / 2.); + TGeoVolume* vol_ga01_bd = new TGeoVolume("ga01_bd", ga01_bd, cbm::trd::geo::GetMaterial("TRDG10")); + vol_ga01_bd->SetLineColor(kGreen + 7); + // GA01 board - create SATA connectors + TGeoBBox* sata_conn = new TGeoBBox("sata_conn", 0.5 * SATAx, 0.5 * SATAy, 0.5 * SATAz); + TGeoVolume* vol_conn_sata = new TGeoVolume("sata_conn", sata_conn, cbm::trd::geo::GetMaterial("TRDG10")); + vol_conn_sata->SetLineColor(kGray + 2); + // GA01 board - assembly + TGeoVolumeAssembly* ga01 = new TGeoVolumeAssembly("GA01"); + ga01->AddNode(vol_ga01_bd, 1, new TGeoTranslation("", 0., 0., 0.5 * ga01_z - SATAz - 0.5 * GA01_z)); + Float_t sataConnPosX[] = {2, 1.2, -1.}, sataConnPosY[] = {0, 1.5, 1}; + for (Int_t ic(-2); ic <= 2; ic++) { + ga01->AddNode(vol_conn_sata, ic + 2, + new TGeoTranslation("", sataConnPosX[abs(ic)], (ic > 0 ? 1 : -1) * sataConnPosY[abs(ic)], + 0.5 * ga01_z - 0.5 * SATAz)); + } + ga01->AddNode(vol_conn_brg, 1, + new TGeoTranslation("", -0.5 * GA01_x + ChamberBuilder::FEB::ConnBRG_x, 0, + -0.5 * ga01_z + 0.5 * ChamberBuilder::FEB::ConnBRG_z)); + + // Board to Board (B2B) - create + TGeoBBox* b2b_bd = new TGeoBBox("b2b_bd", B2B_y / 2., B2B_x / 2., B2B_z / 2.); + TGeoVolume* vol_b2b_bd = new TGeoVolume("b2b_bd", b2b_bd, cbm::trd::geo::GetMaterial("TRDG10")); + vol_b2b_bd->SetLineColor(kGreen + 7); + // B2B board - assembly + float b2b_z = B2B_z + ChamberBuilder::FEB::ConnBRG_z; + TGeoVolumeAssembly* b2b = new TGeoVolumeAssembly("B2B"); + b2b->AddNode(vol_b2b_bd, 1, new TGeoTranslation("", 0., 0., 0.5 * b2b_z - 0.5 * B2B_z)); + b2b->AddNode(vol_conn_brg, 1, new TGeoTranslation("", -0.6, 0., -0.5 * b2b_z + 0.5 * ChamberBuilder::FEB::ConnBRG_z)); + b2b->AddNode(vol_conn_brg, 2, new TGeoTranslation("", +0.6, 0., -0.5 * b2b_z + 0.5 * ChamberBuilder::FEB::ConnBRG_z)); + // VTTX Board - create + float vttx_z = VTTX_z + ChamberBuilder::FEB::ConnBRG_z; + new TGeoBBox("vttx_bd0", VTTX_y / 2., VTTX_x / 2., VTTX_z / 2.); + new TGeoBBox("vttx_bd1", VTTX_y1 / 2. + 0.01, VTTX_x1 / 2. + 0.01, VTTX_z / 2. + 0.01); + auto tr = new TGeoTranslation("t_vttx_bd1", -0.5 * (VTTX_y - VTTX_y1), 0.5 * (VTTX_x - VTTX_x1), 0.); + tr->RegisterYourself(); + new TGeoBBox("vttx_bd2", VTTX_y2 / 2. + 0.01, VTTX_x2 / 2. + 0.01, VTTX_z / 2. + 0.01); + tr = new TGeoTranslation("t_vttx_bd2", -0.5 * (VTTX_y - VTTX_y2), 0.5 * (VTTX_x - VTTX_x2) - VTTX_x1, 0.); + tr->RegisterYourself(); + auto vttx_bd = new TGeoCompositeShape("vttx_bd", "vttx_bd0 - vttx_bd1:t_vttx_bd1 - vttx_bd2:t_vttx_bd2"); + TGeoVolume* vol_vttx_bd = new TGeoVolume("vttx_bd", vttx_bd, cbm::trd::geo::GetMaterial("TRDG10")); + vol_vttx_bd->SetLineColor(kGreen + 7); + // VTTX board - assembly + TGeoVolumeAssembly* vttx = new TGeoVolumeAssembly("VTTX"); + vttx->AddNode(vol_vttx_bd, 1, new TGeoTranslation("", 0., 0., 0.5 * vttx_z - 0.5 * VTTX_z)); + vttx->AddNode(vol_conn_brg, 1, + new TGeoTranslation("", 0.5 * VTTX_y - ChamberBuilder::FEB::ConnBRG_x, 0., + -0.5 * vttx_z + 0.5 * ChamberBuilder::FEB::ConnBRG_z)); + + fHeight = ChamberBuilder::FEB::ConnBRG_z + SATAz + GA01_z; + + // Init volume: + // FEB - AUX family FASPRO type v1 (12 FASPs) + fVol = + new TGeoVolume(GetName(), new TGeoBBox("", sizeX / 2, sizeY / 2, fHeight / 2.), cbm::trd::geo::GetMaterial("air")); + fVol->SetLineColor(kGreen); + fVol->SetTransparency(50); + + int cFeb(0); + for (int ifeb(0), ib2b(0), ivttx(0); ifeb < Nfebs; ifeb++) { + cFeb = ifeb % 3; + + if (cFeb > 0) // add B2B boards + fVol->AddNode(b2b, ib2b++, + new TGeoTranslation("", feb_pos[ifeb][0] - 0.5 * (ChamberBuilder::FEB::FASPRO_length + 0.2), + feb_pos[ifeb][1], -0.5 * fHeight + 0.5 * b2b_z)); + if (cFeb > 1) // add VTTX boards + fVol->AddNode(vttx, ivttx++, + new TGeoTranslation( + "", feb_pos[ifeb][0] + 0.5 * (ChamberBuilder::FEB::FASPRO_length + 0.2) - 0.5 * VTTX_y - 0.1, + feb_pos[ifeb][1], -0.5 * fHeight + 0.5 * vttx_z)); + } + fVol->AddNode( + ga01, 1, + new TGeoTranslation("", feb_pos[0][0] - 0.5 * (ChamberBuilder::FEB::FASPRO_length + 0.2) + 0.5 * GA01_y + 0.05, + feb_pos[0][1], -0.5 * fHeight + 0.5 * ga01_z)); + return kSUCCESS; } @@ -697,4 +814,5 @@ ClassImp(cbm::trd::geo::ChamberBuilder::Window) ClassImp(cbm::trd::geo::ChamberBuilder::Volume) ClassImp(cbm::trd::geo::ChamberBuilder::BackPanel) ClassImp(cbm::trd::geo::ChamberBuilder::FEB) +ClassImp(cbm::trd::geo::ChamberBuilder::AUX) /* clang-format on */ diff --git a/core/detectors/trd/CbmTrdGeoFactory.h b/core/detectors/trd/CbmTrdGeoFactory.h index 8daa2d047409e698dbee0d2a51c06e7f9510d1bc..a2e816674bfad2aa1b3f9cc82052c7a8ccbe7af2 100644 --- a/core/detectors/trd/CbmTrdGeoFactory.h +++ b/core/detectors/trd/CbmTrdGeoFactory.h @@ -100,6 +100,7 @@ namespace cbm::trd::geo kVolume, kBackPanel, kFEB, + kAUX, kNparts }; enum eConfig @@ -114,6 +115,7 @@ namespace cbm::trd::geo class Volume; class BackPanel; class FEB; + class AUX; /** \brief Constructor for the chamber. Adds all elements according to config. * \param[in] typ TRD chamber type [1, 3, 5, 7]. **/ @@ -143,9 +145,9 @@ namespace cbm::trd::geo short fChmbTyp = 1; //! chamber type [1, 3, 5, 7] array<Component*, (int) eGeoPart::kNparts> fComponent = {}; //! list of chamber component builders static const int Nfebs = faspFeb[1].nmax; - const double feb_pos[Nfebs][2] = {{-18, -21.6}, {0, -21.6}, {18, -21.6}, {-18, -10.8}, {0, -10.8}, - {18, -10.8}, {-18, 0.0}, {0, 0.0}, {18, 0.0}, {-18, +10.8}, - {0, +10.8}, {18, +10.8}, {-18, +21.6}, {0, +21.6}, {18, +21.6}}; + static constexpr double feb_pos[Nfebs][2] = {{-18, -21.6}, {0, -21.6}, {18, -21.6}, {-18, -10.8}, {0, -10.8}, + {18, -10.8}, {-18, 0.0}, {0, 0.0}, {18, 0.0}, {-18, +10.8}, + {0, +10.8}, {18, +10.8}, {-18, +21.6}, {0, +21.6}, {18, +21.6}}; TGeoVolume* fVol = nullptr; //! the geo volume itself ClassDef(ChamberBuilder, 1) // Manager of the TRD support structure }; @@ -284,6 +286,37 @@ namespace cbm::trd::geo ClassDef(ChamberBuilder::BackPanel, 1) // Model for the TRD back panel }; + /** \brief Inner class describing the geometry of the TRD AUXILIARY boards (FEE): + **/ + class ChamberBuilder::AUX : public ChamberBuilder::Component { + public: + /** \brief Constructor. + **/ + AUX(); + /** \brief Init task **/ + virtual InitStatus Init(); + + private: + AUX(const AUX&); + // ADD AUXILIARY BOARDS + const double GA01_x = 5.; // length of LV FEBs in cm + const double GA01_y = 5.1; // width of LV FEBs in cm + const double GA01_z = 0.2; + const double B2B_x = 4.8; // length of B2B board in cm + const double B2B_y = 2.3; // width of B2B board in cm + const double B2B_z = 0.16; + const double VTTX_x = 10.6; // length of VTTX board in cm + const double VTTX_y = 5.0; // width of VTTX board in cm + const double VTTX_z = 0.16; + const double VTTX_x1 = 4.3; // length of VTTX large subtraction cm + const double VTTX_y1 = 3.9; // width of VTTX large subtraction cm + const double VTTX_x2 = 5.3; // length of VTTX small subtraction cm + const double VTTX_y2 = 0.94; // width of VTTX small subtraction cm + const double SATAx = 0.7; // width of a SATA connector on GA01 + const double SATAy = 1.7; // length of a SATA connector on GA01 + const double SATAz = 0.8; // height of a SATA connector on GA01 + ClassDef(ChamberBuilder::AUX, 1) // Model for auxiliary TRD FEBs layer + }; /** \brief Inner class describing the geometry of the TRD Front End Electronics (FEE): **/ class ChamberBuilder::FEB : public ChamberBuilder::Component { @@ -294,6 +327,15 @@ namespace cbm::trd::geo /** \brief Init task **/ virtual InitStatus Init(); + // Connector reused by FEB-AUX component of 2D + static constexpr double ConnBRG_x = 0.5; //! + static constexpr double ConnBRG_y = 4.58; //! + static constexpr double ConnBRG_z = 0.658; //! + static constexpr double ConnBRG_pos[2][2] = {{-8.4, 0}, {+8.4, 0}}; + + static constexpr double FASPRO_zspace = 1.0; //! gap size between boards + static constexpr double FASPRO_length = 17.8; //! length of FASP FEBs in cm + static constexpr double FASPRO_width = 10.6; //! width of FASP FEBs in cm private: FEB(const FEB&); //ChamberBuilder::FEB operator=(const FEB&); @@ -312,18 +354,13 @@ namespace cbm::trd::geo const double ConnFC_x = 2.37; //! const double ConnFC_y = 0.535; //! const double ConnFC_z = 0.266; //! - const double ConnBRG_x = 0.5; //! - const double ConnBRG_y = 4.58; //! - const double ConnBRG_z = 0.658; //! static const int FASPRO_Nly = 18; //! static const int FASPRO_Nfasp = 12; //! static const int FASPRO_Nadc = 6; //! static const int FASPRO_Nfpga = 3; //! static const int FASPRO_Ndcdc = 3; //! - const double FASPRO_zspace = 1.0; //! gap size between boards - const double FASPRO_length = 17.8; //! length of FASP FEBs in cm - const double FASPRO_width = 10.6; //! width of FASP FEBs in cm + const double FASPRO_hole_x = 2.2; //! const double FASPRO_hole_y = 0.4; //! const double FASPRO_ly_cu[FASPRO_Nly][2] = { // FASPRO(Cu) layer thickness [um] and covarage [%] @@ -344,7 +381,6 @@ namespace cbm::trd::geo const double DCDC_pos[FASPRO_Ndcdc][2] = {{-3, 0.1}, {3, -1.2}, {2.89, 0.1}}; const double ConnFC_pos[FASPRO_Nfasp][2] = {{-6, -4.9}, {-6, -2.9}, {-6, 2.9}, {-6, 4.9}, {0, -4.9}, {0, -2.9}, {0, 2.9}, {0, 4.9}, {+6, -4.9}, {+6, -2.9}, {+6, 2.9}, {+6, 4.9}}; - const double ConnBRG_pos[2][2] = {{-8.4, 0}, {+8.4, 0}}; ClassDef(ChamberBuilder::FEB, 1) // Model for the TRD FEB geometry };