#include #include #include #include #include #include "ICOMETLog.hxx" #include "ISMRDGeom.hxx" #include "TGeoManager.h" #include "TGeoBBox.h" #include "IOADatabase.hxx" #include "IGeomIdManager.hxx" COMET::ISMRDGeom::ISMRDGeom(const char* mothervolname, const char* layername, const char* barname) : IGeomBase(), fMotherVol(mothervolname), fLayerName(layername), fBarName(barname){ } COMET::ISMRDGeom::~ISMRDGeom() {} const COMET::IScintBarGeom& COMET::ISMRDGeom::GetBar(COMET::IGeometryId geomId) const { std::map::const_iterator s = fBarList.find(geomId); if (s == fBarList.end()) { COMETSevere("bar not found!!!!"); throw COMET::ENoSuchSMRDBarGeom(); } return *((s->second)); } const COMET::ISMRDGeom::BarMap& COMET::ISMRDGeom::GetBars() const { return fBarList; } void COMET::ISMRDGeom::ls(const char*) { COMETInfo("||| Module path keywords :"<::iterator b = fBarList.begin(); b != fBarList.end(); ++b){ if (!(*b).second->GetOrientation()){ ++cntx; cntxr += (*b).second->GetNumOfSensors(); } else if ((*b).second->GetOrientation() != 0){ ++cnty; cntyr += (*b).second->GetNumOfSensors(); } } COMETInfo(" tot bars : "<CdTop(); FindModuleBars(); } bool COMET::ISMRDGeom::IsInLeftClam(COMET::IHandle hit) { //int nodeId = hit->GetGeoNodeId(); //gGeoManager->CdNode(nodeId); //std::string path = gGeoManager->GetPath(); std::string path = hit->GetGeomId().GetName(); if(path.find("LeftClam") !=std::string::npos) return true; return false; } bool COMET::ISMRDGeom::IsInRightClam(COMET::IHandle hit) { //int nodeId = hit->GetGeoNodeId(); //gGeoManager->CdNode(nodeId); //std::string path = gGeoManager->GetPath(); std::string path = hit->GetGeomId().GetName(); if(path.find("RightClam") !=std::string::npos) return true; return false; } bool COMET::ISMRDGeom::IsSMRDArm(COMET::IHandle hit) { //int nodeId = hit->GetGeoNodeId(); //gGeoManager->CdNode(nodeId); //std::string path = gGeoManager->GetPath(); std::string path = hit->GetGeomId().GetName(); if(path.find("MRDArm") !=std::string::npos) return true; return false; } bool COMET::ISMRDGeom::IsSMRDSide(COMET::IHandle hit) { //int nodeId = hit->GetGeoNodeId(); //gGeoManager->CdNode(nodeId); //std::string path = gGeoManager->GetPath(); std::string path = hit->GetGeomId().GetName(); if(path.find("MRDSide") !=std::string::npos) return true; return false; } bool COMET::ISMRDGeom::IsSMRDTop(COMET::IHandle hit) { //int nodeId = hit->GetGeoNodeId(); //gGeoManager->CdNode(nodeId); COMET::IOADatabase::Get().GeomId().CdId(hit->GetGeomId()); double local[3] = {0,0,0}; double master[3] = {0,0,0}; gGeoManager->LocalToMaster(local,master); TVector3 node_position = TVector3(master); std::string path = gGeoManager->GetPath(); if(node_position.Y()>0 && (path.find("MRD") !=std::string::npos)) return true; return false; } bool COMET::ISMRDGeom::IsSMRDBottom(COMET::IHandle hit) { //int nodeId = hit->GetGeoNodeId(); //gGeoManager->CdNode(nodeId); COMET::IOADatabase::Get().GeomId().CdId(hit->GetGeomId()); double local[3] = {0,0,0}; double master[3] = {0,0,0}; gGeoManager->LocalToMaster(local,master); TVector3 node_position = TVector3(master); std::string path = gGeoManager->GetPath(); if(node_position.Y()<0 && (path.find("MRD") !=std::string::npos)) return true; return false; } bool COMET::ISMRDGeom::IsSMRDTopWall(COMET::IHandle hit) { //[TW] //int nodeId = hit->GetGeoNodeId(); //gGeoManager->CdNode(nodeId); //std::string path = gGeoManager->GetPath(); COMET::IOADatabase::Get().GeomId().CdId(hit->GetGeomId()); double local[3] = {0,0,0}; double master[3] = {0,0,0}; gGeoManager->LocalToMaster(local,master); TVector3 node_position = TVector3(master); std::string path = gGeoManager->GetPath(); if(node_position.Y()>0 && (path.find("MRDArm") !=std::string::npos)) return true; return false; } bool COMET::ISMRDGeom::IsSMRDBottomWall(COMET::IHandle hit) { //[TW] //int nodeId = hit->GetGeoNodeId(); //gGeoManager->CdNode(nodeId); //std::string path = gGeoManager->GetPath(); COMET::IOADatabase::Get().GeomId().CdId(hit->GetGeomId()); double local[3] = {0,0,0}; double master[3] = {0,0,0}; gGeoManager->LocalToMaster(local,master); TVector3 node_position = TVector3(master); std::string path = gGeoManager->GetPath(); if(node_position.Y()<0 && (path.find("MRDArm") !=std::string::npos)) return true; return false; } bool COMET::ISMRDGeom::IsSMRDLeftWall(COMET::IHandle hit) { //[TW] //int nodeId = hit->GetGeoNodeId(); //gGeoManager->CdNode(nodeId); //std::string path = gGeoManager->GetPath(); COMET::IOADatabase::Get().GeomId().CdId(hit->GetGeomId()); double local[3] = {0,0,0}; double master[3] = {0,0,0}; gGeoManager->LocalToMaster(local,master); TVector3 node_position = TVector3(master); std::string path = gGeoManager->GetPath(); if(node_position.X()>0 && (path.find("MRDSide") !=std::string::npos)) return true; return false; } bool COMET::ISMRDGeom::IsSMRDRightWall(COMET::IHandle hit) { //[TW] //int nodeId = hit->GetGeoNodeId(); //gGeoManager->CdNode(nodeId); //std::string path = gGeoManager->GetPath(); COMET::IOADatabase::Get().GeomId().CdId(hit->GetGeomId()); double local[3] = {0,0,0}; double master[3] = {0,0,0}; gGeoManager->LocalToMaster(local,master); TVector3 node_position = TVector3(master); std::string path = gGeoManager->GetPath(); if(node_position.X()<0 && (path.find("MRDSide") !=std::string::npos)) return true; return false; } int COMET::ISMRDGeom::GetYokeRingNumber(COMET::IHandle hit) { //Use Clark's naming convention to get the yoke number //Convention: 'name:XYZ', where name=MRDArm,MRDSide; X-yoke, Y-layer (ring), Z-slot (module) //X = 0,1,...,7 //Y = 0,1,...,5 //Z = 0,1,...,7 //[TW] COMET::IGeometryId geomId = hit->GetGeomId(); int YokeRingNumber = -9999; //Get path of this node std::string name = geomId.GetName(); // Get the information from the path std::istringstream in; if (name.find("MRDArm:")!=std::string::npos || name.find("MRDSide:")!=std::string::npos) { unsigned colon = name.find(":"); in.str(name.substr(colon+1,3)); in >> YokeRingNumber; //slot = yoke % 10; //layer = (yoke/10) % 10; YokeRingNumber = YokeRingNumber/100; } //Convention: yoke = 1,2,...,8 is used. YokeRingNumber++; return YokeRingNumber; } int COMET::ISMRDGeom::GetMagnetYokeNumber(COMET::IHandle hit) { //Use Clark's naming convention to get the yoke number //Convention: 'name:XYZ', where name=MRDArm,MRDSide; X-yoke, Y-layer (ring), Z-slot (module) //X = 0,1,...,7 //Y = 0,1,...,5 //Z = 0,1,...,7 //[TW] COMET::IGeometryId geomId = hit->GetGeomId(); int MagnetYokeNumber = -9999; std::string name = geomId.GetName(); // Get the information from the path std::istringstream in; if (name.find("MRDArm:")!=std::string::npos || name.find("MRDSide:")!=std::string::npos) { unsigned colon = name.find(":"); in.str(name.substr(colon+1,3)); in >> MagnetYokeNumber; //slot = yoke % 10; //layer = (yoke/10) % 10; MagnetYokeNumber = MagnetYokeNumber/100; } //Convention: yoke = 1,2,...,8 is used. MagnetYokeNumber++; //For the rhs side add 8 to yoke number if(name.find("RightClam") !=std::string::npos) MagnetYokeNumber+=8; return MagnetYokeNumber; } int COMET::ISMRDGeom::GetSMRDRingNumber(COMET::IHandle hit) { //Use Clark's naming convention to get the yoke number //Convention: 'name:XYZ', where name=MRDArm,MRDSide; X-yoke, Y-layer (ring), Z-slot (module) //X = 0,1,...,7 //Y = 0,1,...,5 //Z = 0,1,...,7 //[TW] COMET::IGeometryId geomId = hit->GetGeomId(); int RingNumber = -9999; int yoke; std::string name = geomId.GetName(); // Get the information from the path std::istringstream in; if (name.find("MRDArm:")!=std::string::npos || name.find("MRDSide:")!=std::string::npos) { unsigned colon = name.find(":"); in.str(name.substr(colon+1,3)); in >> yoke; RingNumber = (yoke/10) % 10; //slot = yoke % 10; //MagnetYokeNumber = MagnetYokeNumber/100; } RingNumber++; return RingNumber; } int COMET::ISMRDGeom::GetSMRDTowerNumber(COMET::IHandle hit) { //Use Clark's naming convention to get the yoke number //Convention: name:XYZ, where name=MRDArm,MRDSide; X-yoke, Y-layer (ring), Z-slot (module) //X = 0,1,...,7 //Y = 0,1,...,5 //Z = 0,1,...,7 //[TW] //Slot corresponds to SMRD module: //Slots are numbered clockwise when viewed from the target. //LeftClam: 0,1 - bottom MRDArm slots; 2,3,4,5 - MRDSide slots; 6,7 - MRDArm top slots //RightClam: 0,1 - top MRDArm slots; 2,3,4,5 - MRDSide slots; 6,7 - MRDArm bottom slots //In this function the previous convention is used: tower no.1 is in left-top. //[TW] int slot = -9999; int yoke; COMET::IGeometryId geomId = hit->GetGeomId(); std::string name = geomId.GetName(); bool isLeftClam = IsInLeftClam(hit); bool isRightClam = IsInRightClam(hit); // Get the information from the path std::istringstream in; if (name.find("MRDArm:")!=std::string::npos || name.find("MRDSide:")!=std::string::npos) { unsigned colon = name.find(":"); in.str(name.substr(colon+1,3)); in >> yoke; slot = yoke % 10; } if(isLeftClam){ //Convention: // 6 -> 1,7 -> 2 if(slot>=6) slot-=5; else// 0 -> 11,1 -> 12,3 -> 13,4 -> 14,5 -> 15 slot+=11; } else if(isRightClam){ // 0 -> 3, 1 -> 4, 2 -> 5,... slot+=3; } return slot; } int COMET::ISMRDGeom::GetSMRDScintNumber(COMET::IHandle hit) { //Return the number of the SMRD scintillator(counter) in single wall and in single yoke. //For vertically oriented counters (MRDSide) we have 20 counters and for horizontally oriented 16. //Use Clark's naming convention to get the yoke number //Convention: name:XYZ, where name=MRDArm,MRDSide; X-yoke, Y-layer (ring), Z-slot (module) //X = 0,1,...,7 //Y = 0,1,...,5 //Z = 0,1,...,7 //[TW] //Slot corresponds to SMRD module: //Slots are numbered clockwise when viewed from the target. //LeftClam: 0,1 - bottom MRDArm slots; 2,3,4,5 - MRDSide slots; 6,7 - MRDArm top slots //RightClam: 0,1 - top MRDArm slots; 2,3,4,5 - MRDSide slots; 6,7 - MRDArm bottom slots int yoke; int slot = -999; int bar = -999; int ScintNumber = -999; COMET::IGeometryId geomId = hit->GetGeomId(); std::string name = geomId.GetName(); std::size_t mrdside = name.find("MRDSide"); std::size_t mrdarm = name.find("MRDArm"); // Get the information from the path std::istringstream in; if (name.find("MRDArm:")!=std::string::npos || name.find("MRDSide:")!=std::string::npos) { unsigned colon = name.find(":"); in.str(name.substr(colon+1,3)); in >> yoke; slot = yoke % 10; } if(mrdside != std::string::npos){ //Get bar number std::size_t barpos = name.find("Bar_"); if(barpos !=std::string::npos){ in.clear(); in.str(name.substr(barpos+4,1)); in >> bar; } //For MRDSide decrease by 2 to have module numbers 0-3 slot-=2; //ScintNumber is slot number times bar number ScintNumber = slot*5 + bar; } else if (mrdarm != std::string::npos) { //MRDArm case... std::size_t barpos = name.find("Bar_"); if(barpos !=std::string::npos){ in.clear(); in.str(name.substr(barpos+4,1)); in >> bar; } //We need to modify it in this way: 6 -> 0,7 -> 1 if(slot > 1) slot-=6; else //0 -> 2,1 -> 3 slot+=2; ScintNumber = slot*4 + bar; } return ScintNumber; } int COMET::ISMRDGeom::GetSMRDBarNumber(COMET::IHandle hit) { //Use Clark's naming convention to get the yoke number //Convention: name:XYZ, where name=MRDArm,MRDSide; X-yoke, Y-layer (ring), Z-slot (module) //X = 0,1,...,7 //Y = 0,1,...,5 //Z = 0,1,...,7 //[TW] int BarNumber = -999; COMET::IGeometryId geomId = hit->GetGeomId(); std::string name = geomId.GetName(); std::size_t mrd = name.find("MRD"); std::istringstream in; if(mrd != std::string::npos){ //Get bar number std::size_t barpos = name.find("Bar_"); if(barpos !=std::string::npos){ in.clear(); in.str(name.substr(barpos+4,1)); in >> BarNumber; } } return BarNumber; } bool COMET::ISMRDGeom::IsSMRD(COMET::IHandle hit){ //Horizontal counters. We always have 3 layers. if(IsSMRDArm(hit) && GetSMRDRingNumber(hit)>0 && GetSMRDRingNumber(hit)<=3 ) return true; //Vertical counters. if(IsSMRDSide(hit)){ //Yokes 1-5: we have 3 layers. if(GetYokeRingNumber(hit)>=1 && GetYokeRingNumber(hit)<=5 && GetSMRDRingNumber(hit)>=1 && GetSMRDRingNumber(hit)<=3 ) return true; //Yoke 6: we have 4 layers. if(GetYokeRingNumber(hit)==6 && GetSMRDRingNumber(hit)>=1 && GetSMRDRingNumber(hit)<=4 ) return true; //Yoke 7,8: we have 6 layers. if(GetYokeRingNumber(hit)>=7 && GetYokeRingNumber(hit)<=8 && GetSMRDRingNumber(hit)<=6 ) return true; } return false; } Bool_t COMET::ISMRDGeom::FindModuleBars() { std::string thePath(gGeoManager->GetPath()); // considered here for now that for detector // that specify X and Y in volume name the bar orientation // is set accordingly and except the ECAL which is // particular, all other scintillator detectors have // their photosensors on the + side and if not specified // then it is considered that the path corresponds to the // which has 2 end readout for all modules. COMET::IScintBarGeom* bar = NULL; if (thePath.find(fMotherVol)!=std::string::npos && thePath.find(fLayerName)!=std::string::npos && thePath.find(fBarName)!=std::string::npos) { //Int_t bnode = gGeoManager->GetCurrentNodeId(); COMET::IGeometryId geomId; COMET::IOADatabase::Get().GeomId().FindGeometryId(geomId); if (thePath.find("X")!=std::string::npos) { bar = new COMET::IScintBarGeom(geomId, 0, 1); } else if (thePath.find("Y")!=std::string::npos) { bar = new COMET::IScintBarGeom(geomId, 1, 1); } else { bar = new COMET::IScintBarGeom(geomId, 0, 2); } fBarList[geomId] = bar; gGeoManager->CdUp(); return kTRUE; } if (gGeoManager->GetCurrentNode()->GetNdaughters()>0) { for (int i=0;iGetCurrentNode()->GetNdaughters();i++) { gGeoManager->CdDown(i); FindModuleBars(); } } gGeoManager->CdUp(); return kTRUE; }