#include #include #include #include #include #include #include #include #include #include #include "IGeomVisitor.hxx" #include "ICDCGeom.hxx" #include #include #include #include namespace COMET { /// For information see the discription of the base class 'IGeomVisitor' class ICDCGeomVisitor: public COMET::IGeomVisitor { public: explicit ICDCGeomVisitor(COMET::ICDCGeom* geom) { fCDCGeom = geom; } bool VisitNode(int d, const std::string& name, const TGeoNode* node); const TGeoNode *GetCDC(int id) { return fCDCWireVolumes[id].second;} const COMET::ICDCGeom::IGeoNodeList_t& GetCDCWireVolumes(void) { return fCDCWireVolumes;} COMET::ICDCGeom::IGeoNodeList_t fSenseLayers; /// List of TGeoNode for sense layers, int key is the size of this node (to be replaced to the layer Id) COMET::ICDCGeom::IGeoNodeList_t fSenseWires; /// List of TGeoNode for sense wires, int key is the size of this node (to be replaced to the wire Id) COMET::ICDCGeom::IGeoNodeList_t fFieldWires; /// List of TGeoNode for field wires, int key is the size of this node (to be replaced to the wire Id) std::map CDCNames; /// This save all paths of volumes we want to pass to the RecPack. private: COMET::ICDCGeom* fCDCGeom; COMET::ICDCGeom::IGeoNodeList_t fCDCWireVolumes; }; }; bool COMET::ICDCGeomVisitor::VisitNode(int, const std::string& name, const TGeoNode* node) { //COMETLog("COMET::ICDCGeomVisitor::VisitNode, visiting :" << name); /// If the node isn't in the Detector Solenoid, skip this node. if (name.find("/DetectorSolenoid") == std::string::npos) return true; /// If the node isn't in the CyDet, skip this node. if (name.find("/CylindricalDetector") == std::string::npos) return true; /// If the node isn't in the CDC, skip this node. if (name.find("/CylindricalDriftChamber") == std::string::npos) return true; /// If the node isn't in the CDC sense layer, skip this node. if (name.find("/CDCSenseLayer") == std::string::npos) return true; int nodeID = -1; int index = CDCNames.size(); CDCNames[index] = name; gGeoManager->cd(name.c_str()); nodeID = gGeoManager->GetCurrentNodeId(); std::pair tmp(nodeID,node); if ( name.find("SenseWire") == std::string::npos && name.find("FieldWire") == std::string::npos) { // Layer index = fSenseLayers.size(); fSenseLayers[index] = tmp; } else { //index = fCDCWireVolumes.size(); //fCDCWireVolumes[index] = tmp; if ( name.find("SenseWire") != std::string::npos ) { // Sense wire index = fSenseWires.size(); fSenseWires[index] = tmp; index = fCDCWireVolumes.size(); fCDCWireVolumes[index] = tmp; } else if ( name.find("FieldWire") != std::string::npos ) { // Field wire index = fFieldWires.size(); fFieldWires[index] = tmp; } } return true; } COMET::ICDCGeom::ICDCGeom() :IGeomBase() ,fCDCWireManager(NULL) ,fWireDiameter(0.03*unit::mm) { COMETNamedTrace("2","COMET::ICDCGeom::ICDCGeom()"); fWireMap.resize(kMaxNumLayers, std::vector(kMaxNumWires, -999)); } COMET::ICDCGeom::~ICDCGeom() { Clear(); } void COMET::ICDCGeom::Fill() { COMETNamedTrace("2","COMET::ICDCGeom::Fill()"); fCDCWireManager = new COMET::ICDCWireManager(); ICDCGeomVisitor visitor(this); visitor.VisitGeometry(); fCDCWireVolumes = visitor.GetCDCWireVolumes(); fSenseLayers = visitor.fSenseLayers; fSenseWires = visitor.fSenseWires; fFieldWires = visitor.fFieldWires; // New information needed by oaRecPack. The path names will be saved during the search. for (unsigned int i=0; i< visitor.CDCNames.size();i++) { COMET::IGeomModuleBase* myModule = new IGeomModuleBase(visitor.CDCNames[i]); double x0 = 20*unit::meter; myModule->SetX0(x0); fModules.push_back(myModule); } BuildWireMap(); fCDCWireManager->Init(fWireMap); } void COMET::ICDCGeom::ls(const char *opt) { COMETInfo( "// --------------------------------------------------------------------- "); COMETInfo( "// CDC geometry "); COMETInfo( "// --------------------------------------------------------------------- "); COMETInfo( "// Number of Layers = " << GetNumberOfLayers()); COMETInfo( "// Number of SenseWires = " << GetNumberOfWires()); COMETInfo( "// --------------------------------------------------------------------- "); if ( strcmp(opt,"VERBOSE") ) return ; } void COMET::ICDCGeom::Clear(void) { if (fCDCWireManager != NULL) { delete fCDCWireManager; } std::vector::iterator modules_it = fModules.begin(); std::vector::iterator modules_end = fModules.end(); for ( ; modules_it != modules_end; ++modules_it) { if (*modules_it) delete (*modules_it); } fModules.clear(); } /// Get the list of wires in a layer bool COMET::ICDCGeom::GetWiresInLayer(const int& layer, std::vector& list) { // check if illegal layer is used if (layer>=GetNumberOfLayers() || layer<0) return false; int offset = 0; for (int i=0;i=0 && layer<=kMaxNumLayers && wire>=0 && wire<=kMaxNumWires) { if (fWireMap.at(layer).at(wire)>=0) return fWireMap.at(layer).at(wire); else return -1; } else { return -1; } } TGeoNode* COMET::ICDCGeom::GeomIdToModuleNode(const COMET::IGeometryId& id) const { int wire = GeomIdToWire(id); int node = GeomIdToNodeId(id); return fCDCWireManager->ChannelToModuleNode(node,wire); } bool COMET::ICDCGeom::GeomIdToGlobalPosition(const COMET::IGeometryId& id , TVector3& global) const { int wire = GeomIdToWire(id); int node = GeomIdToNodeId(id); if (node == -1 || wire == -1) return false; bool ok = fCDCWireManager->ChannelToGlobalPosition(wire,global); return ok; } bool COMET::ICDCGeom::GlobalPositionToGeomId(const TVector3& global, COMET::IGeometryId& id) const { if (!COMET::IOADatabase::Get().GeomId().GetGeometryId(global.X(), global.Y(), global.Z(), id)) return false; if (!COMET::GeomId::CDC::IsCDC(id)) return false; /* int layer = COMET::GeomId::CDC::GetLayerId(geomId); int wire = COMET::GeomId::CDC::GetWireId(geomId); */ int channel = -1; int node = -1; if (!fCDCWireManager->GlobalPositionToChannel(global, channel)) return false; return ChannelToGeomId(node, channel, id); } int COMET::ICDCGeom::GeomIdToWire(const COMET::IGeometryId& id) const { int wire = -1, sense = -1, active = -1; if (COMET::GeomId::CDC::IsActiveSenseWire(id)) { wire = COMET::GeomId::CDC::GetWireId(id, sense, active); if (sense>0 && active>0) return wire/2; // this is an active sense wire else return -1; } else { return -1; } } int COMET::ICDCGeom::GeomIdToLayer(const COMET::IGeometryId& id) const { if (COMET::GeomId::CDC::IsCDC(id)) { /// all CDC volumes should have layer id for now. return COMET::GeomId::CDC::GetLayerId(id); } else { return -1; } } int COMET::ICDCGeom::GeomIdToCell(const COMET::IGeometryId& id) const { int layer = GeomIdToLayer(id); int wire = GeomIdToWire(id); if (layer<0 || wire<0) return -1; return (wire-fCDCWireManager->GetFirstWireIndexAt(layer)); } bool COMET::ICDCGeom::GetGeometryInfo(const COMET::IGeometryId& id, int& layer, int& wire) const { wire = GeomIdToWire(id); if (wire == -1) return false; layer = GeomIdToLayer(id); return true; } void COMET::ICDCGeom::BuildWireMap() { COMETNamedTrace("2","COMET::ICDCGeom::BuildWireMap"); IGeoNodeList_t nodes = GetCDCWireVolumes(); IGeoNodeList_t::iterator it; std::vector< bool > used(kMaxNumWires, false); bool found = false; for(it = nodes.begin(); it != nodes.end(); it++){ int node_id = (*it).second.first; COMET::IOADatabase::Get().Geometry()->CdNode(node_id); TString path = COMET::IOADatabase::Get().Geometry()->GetPath(); found = false; if (!path.Contains("SenseWire")) continue; for (int iwire = 0; iwire < kMaxNumWires; iwire++) { if (used[iwire]) continue; for (int ilayer = 0; ilayer < kMaxNumLayers; ilayer++) { char slayer[256]; sprintf(slayer, "/CDCSenseLayer_%d_0", ilayer); if (!path.Contains(slayer)) continue; char swire[256]; sprintf(swire, "/SenseWire_%d_0", iwire); if (path.Contains(swire)) { if (iwire%2==1) fWireMap[ilayer][iwire] = node_id; // active wire COMETInfo(path); COMETInfo(" CDC LAYER = " << slayer << ", WIRE = " << swire << " --> " << node_id); used[iwire] = true; found = true; break; } } if (found) break; } } }