/**
* \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)