/** * \file CbmMvdGeoHandler.cxx * \author Philipp Sitzmann * \brief addapted from TrdGeoHandler by Florian Uhlig */ #include "CbmMvdGeoHandler.h" #include "FairLogger.h" #include "TGeoVolume.h" #include "TGeoBBox.h" #include "TGeoNode.h" #include "TGeoManager.h" #include "TGeoMatrix.h" #include "TVirtualMC.h" #include #include #include #include using std::cout; using std::endl; using std::string; using std::atoi; //-------------------------------------------------------------------------- CbmMvdGeoHandler::CbmMvdGeoHandler() : TObject(), fDetector(NULL), fStationPar(NULL), fStationMap(), fIsSimulation(kFALSE), fGeoPathHash(), //! fCurrentVolume(), //! fVolumeShape(), //! fGlobal(), //! Global center of volume fGlobalMatrix(), //! fLayerId(-1), //! fModuleId(-1), //! fModuleType(-1), //! fStation(-1), //! StationID fMother(""), fGeoTyp(), fVolId(), fStationNumber(-1), fWidth(0.), fHeight(0.), fRadLength(0.), fBeamwidth(0.), fBeamheight(0.), fThickness(0.), fXres(0.), fYres(0.), fStationName(""), fDetectorName(""), fSectorName(""), fQuadrantName(""), fSensorHolding(""), fSensorName(""), fnodeName("") { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- CbmMvdGeoHandler::~CbmMvdGeoHandler() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void CbmMvdGeoHandler::Init(Bool_t isSimulation) { fIsSimulation = isSimulation; GetPipe(); GetGeometryTyp(); if(!isSimulation) { fStationPar = new CbmMvdStationPar(); switch (fGeoTyp) { case FourStation: case FourStationShift: fStationPar->SetNofStations(4); break; case ThreeStation: fStationPar->SetNofStations(3); break; case MiniCbm: fStationPar->SetNofStations(2); break; default: fStationPar->SetNofStations(0); } fStationPar->Init(); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- Int_t CbmMvdGeoHandler::GetSensorAddress() { // In the simulation we can not rely on the TGeoManager information // In the simulation we get the correct information only from gMC return 1; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- Int_t CbmMvdGeoHandler::GetSensorAddress(const TString& path) { if (fGeoPathHash != path.Hash()) { NavigateTo(path); } return GetSensorAddress(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- Double_t CbmMvdGeoHandler::GetSizeX( const TString& path) { if (fGeoPathHash != path.Hash()) { NavigateTo(path); } return fVolumeShape->GetDX(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- Double_t CbmMvdGeoHandler::GetSizeY( const TString& path) { if (fGeoPathHash != path.Hash()) { NavigateTo(path); } return fVolumeShape->GetDY(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- Double_t CbmMvdGeoHandler::GetSizeZ( const TString& path) { if (fGeoPathHash != path.Hash()) { NavigateTo(path); } return fVolumeShape->GetDZ(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- Double_t CbmMvdGeoHandler::GetZ( const TString& path) { if (fGeoPathHash != path.Hash()) { NavigateTo(path); } return fGlobal[2]; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- Double_t CbmMvdGeoHandler::GetY( const TString& path) { if (fGeoPathHash != path.Hash()) { NavigateTo(path); } return fGlobal[1]; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- Double_t CbmMvdGeoHandler::GetX( const TString& path) { if (fGeoPathHash != path.Hash()) { NavigateTo(path); } return fGlobal[0]; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- Int_t CbmMvdGeoHandler::GetStation( const TString& path) { if (fGeoPathHash != path.Hash()) { NavigateTo(path); } return fStation; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void CbmMvdGeoHandler::NavigateTo( const TString& path) { // cout << "path : " << path.Data() << endl; if (fIsSimulation) { LOG(FATAL) << "This method is not supported in simulation mode" << FairLogger::endl; } else { gGeoManager->cd(path.Data()); fGeoPathHash = path.Hash(); fCurrentVolume = gGeoManager->GetCurrentVolume(); TString name = fCurrentVolume->GetName(); //cout << endl << "this volume is " << name << endl; fVolumeShape = (TGeoBBox*)fCurrentVolume->GetShape(); Double_t local[3] = {0., 0., 0.}; // Local center of volume gGeoManager->LocalToMaster(local, fGlobal); fGlobalMatrix = gGeoManager->GetCurrentMatrix(); if(name.Contains("S0")) fStationNumber = 0; else if(name.Contains("S1")) fStationNumber = 1; else if(name.Contains("S2")) fStationNumber = 2; else if(name.Contains("S3")) fStationNumber = 3; else LOG(FATAL) << "couldn't find Station in volume name, something seems fishy " << FairLogger::endl; local[0] = fVolumeShape->GetDX(); local[1] = fVolumeShape->GetDY(); Double_t fGlobalMax[3]; gGeoManager->LocalToMaster(local, fGlobalMax); local[0] = -1*fVolumeShape->GetDX(); local[1] = -1*fVolumeShape->GetDY(); Double_t fGlobalMin[3]; gGeoManager->LocalToMaster(local, fGlobalMin); if(fGlobalMax[0] > fGlobalMin[0]){fWidth = fGlobalMax[0]; fBeamwidth = fGlobalMin[0];}else {fWidth = fGlobalMin[0]; fBeamwidth = fGlobalMax[0];} if(fGlobalMax[1] > fGlobalMin[1]){fHeight = fGlobalMax[1]; fBeamheight = fGlobalMin[1];}else {fHeight = fGlobalMin[1]; fBeamheight = fGlobalMax[1];} // TODO: hard coded numbers, find other way only for Mvd_v14a / v14b if(fStationNumber == 0) fRadLength = 0.24; else if(fStationNumber == 1) fRadLength = 0.31; else if(fStationNumber == 2) fRadLength = 0.47; else fRadLength = 0.49; fXres = 3.8; // TODO: pixelSizeX / sqrt{12} fYres = 3.8; // TODO: pixelSizeY / sqrt{12} } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void CbmMvdGeoHandler::GetPipe() { TString pipeName = "pipevac1"; Int_t pipeID; TGeoNode* pipeNode; TString motherName; fMother = "cave_1/pipevac1_0"; if (!gGeoManager->CheckPath(fMother.Data())) { pipeID = gGeoManager->GetUID(pipeName); pipeNode = gGeoManager->GetNode(pipeID); gGeoManager->CdTop(); gGeoManager->CdDown(0); motherName=gGeoManager->GetPath(); fMother = motherName; fMother += "/"; fMother += pipeName; fMother += "_0"; gGeoManager->CdTop(); } else fMother = "cave_1/pipevac1_0"; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void CbmMvdGeoHandler::GetGeometryTyp() { if ( gGeoManager->CheckPath(fMother + "/Beamtimeosetupoobgnum_0")) { cout << endl << "Found Beamtimesetup" << endl; fGeoTyp = beamtest; } else if (gGeoManager->CheckPath(fMother + "/MVDoMistraloquero012oStationo150umodigi_0")) { LOG(INFO) << "Found MVD with 3 Stations" << FairLogger::endl; fGeoTyp = ThreeStation; } else if (gGeoManager->CheckPath(fMother + "/MVDo0123ohoFPCoextoHSoSo0123_0")) { LOG(INFO) << "Found MVD with 4 Stations" << FairLogger::endl; fGeoTyp = FourStation; fDetectorName = "/MVDo0123ohoFPCoextoHSoSo0123_0"; } else if (gGeoManager->CheckPath(fMother + "/MVDo1123ohoFPCoextoHSoSo1123_0")) { LOG(INFO) << "Found shifted MVD with 4 Stations" << FairLogger::endl; fGeoTyp = FourStationShift; fDetectorName = "/MVDo1123ohoFPCoextoHSoSo1123_0"; } else if (gGeoManager->CheckPath(fMother + "/MVDomCBM_0")) { LOG(INFO) << "Found mCBM MVD configuration" << FairLogger::endl; fDetectorName = "/MVDomCBM_0"; fGeoTyp = MiniCbm; } else if (gGeoManager->CheckPath(fMother + "/MVDomCBMorotated_0")) { LOG(INFO) << "Found mCBM MVD rotated configuration" << FairLogger::endl; fDetectorName = "/MVDomCBMorotated_0"; fGeoTyp = MiniCbm; } else { cout << endl << "Try standard Geometry" << endl; fGeoTyp = Default; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void CbmMvdGeoHandler::Fill() { if(fIsSimulation) FillStationMap(); else FillDetector(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void CbmMvdGeoHandler::FillDetector() { if(fGeoTyp == Default) LOG(FATAL) << "Using old Geometry files within the new Digitizer is not supported, " << "please use CbmMvdDigitizeL if you want to use this Geometry" << FairLogger::endl; if(fGeoTyp == FourStation || fGeoTyp == FourStationShift) { fDetector = CbmMvdDetector::Instance(); if(!fDetector) LOG(FATAL) << "GeometryHandler couldn't find a valid Detector" << FairLogger::endl; fDetector->SetParameterFile(fStationPar); Int_t iStation = 0; for(Int_t StatNr = 0; StatNr < 4; StatNr++) { if(StatNr == 0 && fGeoTyp == FourStation) fStationName = "/MVDo0ohoFPCoHSoS_1"; else fStationName = Form("/MVDo%iohoFPCoextoHSoS_1",StatNr); for(Int_t QuadNr = 0; QuadNr < 4; QuadNr++) { if(StatNr == 0 && fGeoTyp == 4) fQuadrantName = Form("/St0Q%iohoFPC_1", QuadNr); else fQuadrantName = Form("/St%iQ%iohoFPCoext_1",StatNr, QuadNr); for(Int_t Layer = 0; Layer < 2; Layer++) { for(Int_t SensNr = 0; SensNr < 50; SensNr++) { fSensorHolding = Form("/MVD-S%i-Q%i-L%i-C%02i-P0oPartAss_1", StatNr, QuadNr, Layer, SensNr); fSensorName = Form("MVD-S%i-Q%i-L%i-C%02i-P0", StatNr, QuadNr, Layer, SensNr); fVolId = gGeoManager->GetUID(fSensorName); if(fVolId > -1) for(Int_t SegmentNr = 0; SegmentNr < 50; SegmentNr++) { fSectorName = Form("/S%iQ%iS%i_1", StatNr, QuadNr, SegmentNr); fnodeName = fMother + fDetectorName + fStationName + fQuadrantName + fSectorName + fSensorHolding + "/" + fSensorName + "_1"; //cout << endl << "looking for " << fnodeName << endl; Bool_t nodeFound = gGeoManager->CheckPath(fnodeName.Data()); if(nodeFound) { fDetector->AddSensor(fSensorName, fSensorName, fnodeName, new CbmMvdMimosa26AHR, iStation, fVolId, 0.0, StatNr); iStation++; FillParameter(); } } } } } } } else if(fGeoTyp == MiniCbm) { fDetector = CbmMvdDetector::Instance(); if(!fDetector) LOG(FATAL) << "GeometryHandler couldn't find a valid mCBM Detector" << FairLogger::endl; fDetector->SetParameterFile(fStationPar); Int_t iStation = 0; for(Int_t StatNr = 0; StatNr < 2; StatNr++) { fStationName = Form("/MVDomCBMoS%i_1",StatNr); for(Int_t Layer = 0; Layer < 2; Layer++) { for(Int_t SensNr = 0; SensNr < 50; SensNr++) { fQuadrantName = Form("/MVD-S%i-Q0-L%i-C%02i_1",StatNr, Layer, SensNr); fSensorHolding = Form("/MVD-S%i-Q0-L%i-C%02i-P0oPartAss_1", StatNr, Layer, SensNr); fSensorName = Form("MVD-S%i-Q0-L%i-C%02i-P0", StatNr, Layer, SensNr); fVolId = gGeoManager->GetUID(fSensorName); if(fVolId > -1) { fnodeName = fMother + fDetectorName + fStationName + fQuadrantName + fSensorHolding + "/" + fSensorName + "_1"; Bool_t nodeFound = gGeoManager->CheckPath(fnodeName.Data()); if(nodeFound) { fDetector->AddSensor(fSensorName, fSensorName, fnodeName, new CbmMvdMimosa26AHR, iStation, fVolId, 0.0, StatNr); iStation++; FillParameter(); } } } } } } else { LOG(FATAL) << "Tried to load an unsupported MVD Geometry" << FairLogger::endl; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void CbmMvdGeoHandler::FillParameter() { if (fGeoPathHash != fnodeName.Hash()) { NavigateTo(fnodeName); } fStationPar->SetZPosition(fStationNumber, fGlobal[2]); fStationPar->SetWidth(fStationNumber, fWidth); fStationPar->SetHeight(fStationNumber, fHeight); fStationPar->SetThickness(fStationNumber, fGlobal[2]); fStationPar->SetXRes(fStationNumber, fXres); fStationPar->SetYRes(fStationNumber, fYres); fStationPar->SetRadLength(fStationNumber, fRadLength); if(fBeamheight > 0)fStationPar->SetBeamHeight(fStationNumber, fBeamheight); if(fBeamwidth > 0)fStationPar->SetBeamWidth(fStationNumber, fBeamwidth); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void CbmMvdGeoHandler::PrintGeoParameter() { fStationPar->Print(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void CbmMvdGeoHandler::FillStationMap() { if(fGeoTyp == FourStation || fGeoTyp == FourStationShift) { Int_t iStation = 0; for(Int_t StatNr = 0; StatNr < 4; StatNr++) { if(StatNr == 0 && fGeoTyp == FourStation) fStationName = "/MVDo0ohoFPCoHSoS_1"; else fStationName = Form("/MVDo%iohoFPCoextoHSoS_1",StatNr); for(Int_t QuadNr = 0; QuadNr < 4; QuadNr++) { if(StatNr == 0 && fGeoTyp == 4) fQuadrantName = Form("/St0Q%iohoFPC_1", QuadNr); else fQuadrantName = Form("/St%iQ%iohoFPCoext_1",StatNr, QuadNr); for(Int_t Layer = 0; Layer < 2; Layer++) { for(Int_t SensNr = 0; SensNr < 50; SensNr++) { fSensorHolding = Form("/MVD-S%i-Q%i-L%i-C%02i-P0oPartAss_1", StatNr, QuadNr, Layer, SensNr); fSensorName = Form("MVD-S%i-Q%i-L%i-C%02i-P0", StatNr, QuadNr, Layer, SensNr); fVolId = gGeoManager->GetUID(fSensorName); if(fVolId > -1) for(Int_t SegmentNr = 0; SegmentNr < 50; SegmentNr++) { fSectorName = Form("/S%iQ%iS%i_1", StatNr, QuadNr, SegmentNr); fnodeName = fMother + fDetectorName + fStationName + fQuadrantName + fSectorName + fSensorHolding + "/" + fSensorName + "_1"; //cout << endl << "looking for " << fnodeName << endl; Bool_t nodeFound = gGeoManager->CheckPath(fnodeName.Data()); if(nodeFound) { fStationMap[fVolId] = iStation; iStation++; } } } } } } } else if(fGeoTyp == Default) { Int_t iStation = 1; Int_t volId = -1; do { TString volName = Form("mvdstation%02i", iStation); volId = gGeoManager->GetUID(volName); if (volId > -1 ) { fStationMap[volId] = iStation; LOG(INFO) << GetName() << "::ConstructAsciiGeometry: " << "Station No. " << iStation << ", volume ID " << volId << ", volume name " << volName << FairLogger::endl; iStation++; } } while ( volId > -1 ); } else if(fGeoTyp == MiniCbm) { Int_t iStation = 0; for(Int_t StatNr = 0; StatNr < 2; StatNr++) { fStationName = Form("/MVDomCBMoS%i_1",StatNr); for(Int_t Layer = 0; Layer < 2; Layer++) { for(Int_t SensNr = 0; SensNr < 50; SensNr++) { fQuadrantName = Form("/MVD-S%i-Q0-L%i-C%02i_1",StatNr, Layer, SensNr); fSensorHolding = Form("/MVD-S%i-Q0-L%i-C%02i-P0oPartAss_1", StatNr, Layer, SensNr); fSensorName = Form("MVD-S%i-Q0-L%i-C%02i-P0", StatNr, Layer, SensNr); //cout << endl << "try to find: " << fSensorName << endl; fVolId = gGeoManager->GetUID(fSensorName); if(fVolId > -1) { fnodeName = fMother + fDetectorName + fStationName + fQuadrantName + fSensorHolding + "/" + fSensorName + "_1"; //cout << endl << "sensorfound check for node " << fnodeName << endl; Bool_t nodeFound = gGeoManager->CheckPath(fnodeName.Data()); if(nodeFound) { //cout << endl << "node found " << fnodeName << endl; fStationMap[fVolId] = iStation; iStation++; } } } } } } else LOG(FATAL) << "You tried to use an unsoported Geometry" << FairLogger::endl; } //-------------------------------------------------------------------------- ClassImp(CbmMvdGeoHandler)