// $Id$ // // File: DGeometry.cc // Created: Thu Apr 3 08:43:06 EDT 2008 // Creator: davidl (on Darwin swire-d95.jlab.org 8.11.1 i386) // #include using namespace std; #include "DGeometry.h" #include #include "FDC/DFDCWire.h" #include "FDC/DFDCGeometry.h" #include using namespace std; //--------------------------------- // DGeometry (Constructor) //--------------------------------- DGeometry::DGeometry(JGeometry *jgeom, DApplication *dapp, unsigned int runnumber) { this->jgeom = jgeom; this->dapp = dapp; this->bfield = dapp->GetBfield(); JCalibration *jcalib = dapp->GetJCalibration(runnumber); if(!jcalib){ _DBG_<<"ERROR: Unable to get JCalibration object!"< material_maps; vector namepaths; jcalib->GetListOfNamepaths(namepaths); vector material_namepaths; for(unsigned int i=0; iGetNr()*mat->GetNz()); } //cout<GetLorentzDeflections(); } //--------------------------------- // FindNodes //--------------------------------- void DGeometry::FindNodes(string xpath, vector &matched_xpaths) const { /// Find all nodes that match the specified xpath and return them as /// fully parsed lists of the nodes and attributes. /// /// The matched_xpaths variable has 4 levels of STL containers nested /// together! The node_t data type contains 2 of them and represents /// a single tag with the "first" member being the tag name /// and the "second" member being a map of all of the attributes /// of that tag along with their values. /// /// The xpathparsed_t data type is a STL vector of node_t objects /// that comprises a complete xpath. The data type of matched_xpaths /// is a STL vector if xpathparsed_t objects and so comprises a /// list of complete xpaths. /// We do this by calling the GetXPaths() method of JGeometry to get /// a list of all xpaths. Then we pass all of those in to /// JGeometryXML::ParseXPath() to get a parsed list for each. This /// is compared to the parsed values of the xpath passed to us /// (also parsed by JGeometryXML::ParseXPath()) to find matches. // Make sure matched_xpaths is empty matched_xpaths.clear(); // Cast JGeometry into a JGeometryXML JGeometryXML *jgeomxml = dynamic_cast(jgeom); // Parse our target xpath xpathparsed_t target; string unused_string; unsigned int unused_int; jgeomxml->ParseXPath(xpath, target, unused_string, unused_int); // Get all xpaths for current geometry source vector allxpaths; jgeom->GetXPaths(allxpaths, JGeometry::attr_level_all); // Loop over xpaths for(unsigned int i=0; iFindMatALT1(pos,KrhoZ_overA, rhoZ_overA,LnI,X0); if(err==NOERROR){ // We found the material map containing this point. If a non-NULL // pointer was passed in for s_to_boundary, then search through all // material maps above and including this one to find the estimated // distance to the nearest boundary the swimmer should step to. Maps // after this one would only be considered outside of this one so // there is no need to check them. if(s_to_boundary==NULL)return NOERROR; // User doesn't want distance to boundary *s_to_boundary = 1.0E6; for(unsigned int j=0; j<=i; j++){ double s = materialmaps[j]->EstimatedDistanceToBoundary(pos, mom); if(s<*s_to_boundary)*s_to_boundary = s; } return NOERROR; } } return RESOURCE_UNAVAILABLE; } //--------------------------------- // FindMatKalman - Kalman filter needs slightly different set of parms. //--------------------------------- jerror_t DGeometry::FindMatKalman(DVector3 &pos, DVector3 &mom,double &Z, double &KrhoZ_overA, double &rhoZ_overA, double &LnI, double &chi2c_factor,double &chi2a_factor,double &chi2a_corr, unsigned int &last_index, double *s_to_boundary) const { //last_index=0; for(unsigned int i=last_index; iFindMatKalman(pos,Z,KrhoZ_overA, rhoZ_overA,LnI,chi2c_factor,chi2a_factor,chi2a_corr); if(err==NOERROR){ if(i==materialmaps.size()-1) last_index=0; else last_index=i; if(s_to_boundary==NULL)return NOERROR; // User doesn't want distance to boundary *s_to_boundary = 1.0E6; // If we are in the main mother volume, search through all the maps for // the nearest boundary if(last_index==0){ for(unsigned int j=0; jEstimatedDistanceToBoundary(pos, mom); if(s<*s_to_boundary){ *s_to_boundary = s; } } } else{ // otherwise, we found the material map containing this point. double s = materialmaps[last_index]->EstimatedDistanceToBoundary(pos, mom); if(s<*s_to_boundary)*s_to_boundary = s; } return NOERROR; } } return RESOURCE_UNAVAILABLE; } //--------------------------------- jerror_t DGeometry::FindMatKalman(DVector3 &pos,double &Z, double &KrhoZ_overA, double &rhoZ_overA, double &LnI, double &chi2c_factor, double &chi2a_factor, double &chi2a_corr, unsigned int &last_index) const { //last_index=0; for(unsigned int i=last_index; iFindMatKalman(pos,Z,KrhoZ_overA, rhoZ_overA,LnI,chi2c_factor,chi2a_factor,chi2a_corr); if(err==NOERROR){ if(i==materialmaps.size()-1) last_index=0; else last_index=i; return err; } } return RESOURCE_UNAVAILABLE; } //--------------------------------- // FindMat //--------------------------------- jerror_t DGeometry::FindMat(DVector3 &pos, double &rhoZ_overA, double &rhoZ_overA_logI, double &RadLen) const { for(unsigned int i=0; iFindMat(pos, rhoZ_overA, rhoZ_overA_logI, RadLen); if(err==NOERROR)return NOERROR; } return RESOURCE_UNAVAILABLE; } //--------------------------------- // FindMat //--------------------------------- jerror_t DGeometry::FindMat(DVector3 &pos, double &density, double &A, double &Z, double &RadLen) const { for(unsigned int i=0; iFindMat(pos, density, A, Z, RadLen); if(err==NOERROR)return NOERROR; } return RESOURCE_UNAVAILABLE; } //--------------------------------- // FindMatNode //--------------------------------- //const DMaterialMap::MaterialNode* DGeometry::FindMatNode(DVector3 &pos) const //{ // //} //--------------------------------- // FindDMaterialMap //--------------------------------- const DMaterialMap* DGeometry::FindDMaterialMap(DVector3 &pos) const { for(unsigned int i=0; iIsInMap(pos))return map; } return NULL; } //==================================================================== // Convenience Methods // // Below are defined some methods to make it easy to extract certain // key values about the GlueX detector geometry from the XML source. // Note that one can still use the generic Get(string xpath, ...) // methods. This just packages some of them up for convenience. // // The one real gotcha here is that these methods must be kept // in sync with the XML structure by hand. If volumes are renamed // or their location within the hierachy is modified, then these // routines will need to be modified as well. That, or course, is // also true if you are using the generic Get(...) methods. // // What these methods are useful for is when minor changes are made // to the XML (such as the locations of the FDC packages) they // are automatically reflected here. //==================================================================== //--------------------------------- // GetDMaterial //--------------------------------- const DMaterial* DGeometry::GetDMaterial(string name) { /// Get a pointer to the DMaterial object with the specified name. // Only fill materials member when one is actually requested // and then, only fill it once. if(materials.size()==0)GetMaterials(); for(unsigned int i=0; iGetName() == name)return materials[i]; } //_DBG_<<"No material \""< xpaths; jgeom->GetXPaths(xpaths, JGeometry::attr_level_all, filter); // Look for xpaths that have "/materials[" in them for(unsigned int i=0; itoString(); } //=========== composites =========== filter = "//materials/composite[@name]"; // Get list of all xpaths jgeom->GetXPaths(xpaths, JGeometry::attr_level_all, filter); // Look for xpaths that have "/materials[" in them for(unsigned int i=0; itoString(); } } //--------------------------------- // GetCompositeMaterial //--------------------------------- bool DGeometry::GetCompositeMaterial(const string &name, double &density, double &radlen) { // Get list of all xpaths with "addmaterial" and "fractionmass" char filter[512]; sprintf(filter,"//materials/composite[@name='%s']/addmaterial/fractionmass[@fraction]", name.c_str()); vector xpaths; jgeom->GetXPaths(xpaths, JGeometry::attr_level_all, filter); // Loop over components of this composite _DBG_<<"Components for compsite "<origin.SetXYZ(x,y,z_wires[layer-1]); // Length of wire is set by active radius w->L = 2.0*sqrt(pow(FDC_ACTIVE_RADIUS,2.0) - u*u); // Set directions of wire's coordinate system with "udir" // along wire. w->udir.SetXYZ(sin(angle),cos(angle),0.0); // "s" points in direction from beamline to midpoint of // wire. This happens to be the same direction as "origin" w->sdir = w->origin; w->sdir.SetMag(1.0); w->tdir = w->udir.Cross(w->sdir); w->tdir.SetMag(1.0); // This isn't really needed temp.push_back(w); } fdcwires.push_back(temp); } return true; } //--------------------------------- // GetFDCZ //--------------------------------- bool DGeometry::GetFDCZ(vector &z_wires) const { // The FDC geometry is defined as 4 packages, each containing 2 // "module"s and each of those containing 3 "chambers". The modules // are placed as multiple copies in Z using mposZ, but none of the // others are (???). // // This method is currently hardwired to assume 4 packages and // 3 chambers. (The number of modules is discovered via the // "ncopy" attribute of mposZ.) vector ForwardDC; vector forwardDC; vector forwardDC_package[4]; vector forwardDC_module[4]; vector forwardDC_chamber[4][6]; if(!Get("//section/composition/posXYZ[@volume='ForwardDC']/@X_Y_Z", ForwardDC)) return false; if(!Get("//composition[@name='ForwardDC']/posXYZ[@volume='forwardDC']/@X_Y_Z", forwardDC)) return false; if(!Get("//posXYZ[@volume='forwardDC_package_1']/@X_Y_Z", forwardDC_package[0])) return false; if(!Get("//posXYZ[@volume='forwardDC_package_2']/@X_Y_Z", forwardDC_package[1])) return false; if(!Get("//posXYZ[@volume='forwardDC_package_3']/@X_Y_Z", forwardDC_package[2])) return false; if(!Get("//posXYZ[@volume='forwardDC_package_4']/@X_Y_Z", forwardDC_package[3])) return false; if(!Get("//posXYZ[@volume='forwardDC_module_1']/@X_Y_Z", forwardDC_module[0])) return false; if(!Get("//posXYZ[@volume='forwardDC_module_2']/@X_Y_Z", forwardDC_module[1])) return false; if(!Get("//posXYZ[@volume='forwardDC_module_3']/@X_Y_Z", forwardDC_module[2])) return false; if(!Get("//posXYZ[@volume='forwardDC_module_4']/@X_Y_Z", forwardDC_module[3])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@X_Y_Z/layer[@value='1']", forwardDC_chamber[0][0])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@X_Y_Z/layer[@value='2']", forwardDC_chamber[0][1])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@X_Y_Z/layer[@value='3']", forwardDC_chamber[0][2])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@X_Y_Z/layer[@value='4']", forwardDC_chamber[0][3])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@X_Y_Z/layer[@value='5']", forwardDC_chamber[0][4])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@X_Y_Z/layer[@value='6']", forwardDC_chamber[0][5])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@X_Y_Z/layer[@value='1']", forwardDC_chamber[1][0])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@X_Y_Z/layer[@value='2']", forwardDC_chamber[1][1])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@X_Y_Z/layer[@value='3']", forwardDC_chamber[1][2])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@X_Y_Z/layer[@value='4']", forwardDC_chamber[1][3])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@X_Y_Z/layer[@value='5']", forwardDC_chamber[1][4])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@X_Y_Z/layer[@value='6']", forwardDC_chamber[1][5])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@X_Y_Z/layer[@value='1']", forwardDC_chamber[2][0])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@X_Y_Z/layer[@value='2']", forwardDC_chamber[2][1])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@X_Y_Z/layer[@value='3']", forwardDC_chamber[2][2])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@X_Y_Z/layer[@value='4']", forwardDC_chamber[2][3])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@X_Y_Z/layer[@value='5']", forwardDC_chamber[2][4])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@X_Y_Z/layer[@value='6']", forwardDC_chamber[2][5])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@X_Y_Z/layer[@value='1']", forwardDC_chamber[3][0])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@X_Y_Z/layer[@value='2']", forwardDC_chamber[3][1])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@X_Y_Z/layer[@value='3']", forwardDC_chamber[3][2])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@X_Y_Z/layer[@value='4']", forwardDC_chamber[3][3])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@X_Y_Z/layer[@value='5']", forwardDC_chamber[3][4])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@X_Y_Z/layer[@value='6']", forwardDC_chamber[3][5])) return false; // Offset due to global FDC envelopes double zfdc = ForwardDC[2] + forwardDC[2]; // Loop over packages for(int package=1; package<=4; package++){ double z_package = forwardDC_package[package-1][2]; // Each "package" has 1 "module" which is currently positioned at 0,0,0 but // that could in principle change so we add the module z-offset double z_module = forwardDC_module[package-1][2]; // Loop over chambers in this module for(int chamber=1; chamber<=6; chamber++){ double z_chamber = forwardDC_chamber[package-1][chamber-1][2]; double z = zfdc + z_package + z_module + z_chamber; z_wires.push_back(z); } } return true; } //--------------------------------- // GetFDCStereo //--------------------------------- bool DGeometry::GetFDCStereo(vector &stereo_angles) const { // The FDC geometry is defined as 4 packages, each containing 2 // "module"s and each of those containing 3 "chambers". The modules // are placed as multiple copies in Z using mposZ, but none of the // others are (???). // // This method is currently hardwired to assume 4 packages and // 3 chambers. (The number of modules is discovered via the // "ncopy" attribute of mposZ.) // // Stereo angles are assumed to be rotated purely about the z-axis // and the units are not specified, but the XML currently uses degrees. vector forwardDC_module[4]; vector forwardDC_chamber[4][6]; if(!Get("//posXYZ[@volume='forwardDC_module_1']/@X_Y_Z", forwardDC_module[0])) return false; if(!Get("//posXYZ[@volume='forwardDC_module_2']/@X_Y_Z", forwardDC_module[1])) return false; if(!Get("//posXYZ[@volume='forwardDC_module_3']/@X_Y_Z", forwardDC_module[2])) return false; if(!Get("//posXYZ[@volume='forwardDC_module_4']/@X_Y_Z", forwardDC_module[3])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@rot/layer[@value='1']", forwardDC_chamber[0][0])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@rot/layer[@value='2']", forwardDC_chamber[0][1])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@rot/layer[@value='3']", forwardDC_chamber[0][2])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@rot/layer[@value='4']", forwardDC_chamber[0][3])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@rot/layer[@value='5']", forwardDC_chamber[0][4])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_1']/@rot/layer[@value='6']", forwardDC_chamber[0][5])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@rot/layer[@value='1']", forwardDC_chamber[1][0])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@rot/layer[@value='2']", forwardDC_chamber[1][1])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@rot/layer[@value='3']", forwardDC_chamber[1][2])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@rot/layer[@value='4']", forwardDC_chamber[1][3])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@rot/layer[@value='5']", forwardDC_chamber[1][4])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_2']/@rot/layer[@value='6']", forwardDC_chamber[1][5])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@rot/layer[@value='1']", forwardDC_chamber[2][0])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@rot/layer[@value='2']", forwardDC_chamber[2][1])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@rot/layer[@value='3']", forwardDC_chamber[2][2])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@rot/layer[@value='4']", forwardDC_chamber[2][3])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@rot/layer[@value='5']", forwardDC_chamber[2][4])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_3']/@rot/layer[@value='6']", forwardDC_chamber[2][5])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@rot/layer[@value='1']", forwardDC_chamber[3][0])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@rot/layer[@value='2']", forwardDC_chamber[3][1])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@rot/layer[@value='3']", forwardDC_chamber[3][2])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@rot/layer[@value='4']", forwardDC_chamber[3][3])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@rot/layer[@value='5']", forwardDC_chamber[3][4])) return false; if(!Get("//posXYZ[@volume='forwardDC_chamber_4']/@rot/layer[@value='6']", forwardDC_chamber[3][5])) return false; // Loop over packages for(int package=1; package<=4; package++){ // Loop over chambers for(int chamber=1; chamber<=6; chamber++){ stereo_angles.push_back(forwardDC_chamber[package-1][chamber-1][2]); } } return true; } //--------------------------------- // GetFDCRmin //--------------------------------- bool DGeometry::GetFDCRmin(vector &rmin_packages) const { vector FDA[4]; if(!Get("//section[@name='ForwardDC']/tubs[@name='FDA1']/@Rio_Z", FDA[0])) return false; if(!Get("//section[@name='ForwardDC']/tubs[@name='FDA2']/@Rio_Z", FDA[1])) return false; if(!Get("//section[@name='ForwardDC']/tubs[@name='FDA3']/@Rio_Z", FDA[2])) return false; if(!Get("//section[@name='ForwardDC']/tubs[@name='FDA4']/@Rio_Z", FDA[3])) return false; rmin_packages.push_back(FDA[0][0]); rmin_packages.push_back(FDA[1][0]); rmin_packages.push_back(FDA[2][0]); rmin_packages.push_back(FDA[3][0]); return true; } //--------------------------------- // GetFDCRmax //--------------------------------- bool DGeometry::GetFDCRmax(double &rmax_active_fdc) const { // We assume that all packages have the same outer radius of the // active area. vector FDA1; bool good = Get("//section[@name='ForwardDC']/tubs[@name='FDA1']/@Rio_Z", FDA1); if(!good){ _DBG_<<"Unable to retrieve FDC Rmax values."< Rio_Z; bool good = Get("//section[@name='CentralDC']/tubs[@name='STRW']/@Rio_Z", Rio_Z); cdc_axial_length = Rio_Z[2]; if(!good){ _DBG_<<"Unable to retrieve CDC axial wire length"< &cdc_stereo) const { return false; } //--------------------------------- // GetCDCRmid //--------------------------------- bool DGeometry::GetCDCRmid(vector &cdc_rmid) const { return false; } //--------------------------------- // GetCDCNwires //--------------------------------- bool DGeometry::GetCDCNwires(vector &cdc_nwires) const { return false; } //--------------------------------- // GetCDCEndplate //--------------------------------- bool DGeometry::GetCDCEndplate(double &z,double &dz,double &rmin,double &rmax) const{ vectorcdc_origin; vectorcdc_center; vectorcdc_endplate_pos; vectorcdc_endplate_dim; if(!Get("//posXYZ[@volume='CentralDC'/@X_Y_Z",cdc_origin)) return false; if(!Get("//posXYZ[@volume='centralDC_option-1']/@X_Y_Z",cdc_center)) return false; if(!Get("//posXYZ[@volume='CDPD']/@X_Y_Z",cdc_endplate_pos)) return false; if(!Get("//tubs[@name='CDPD']/@Rio_Z",cdc_endplate_dim)) return false; if(cdc_origin.size()<3){ _DBG_<<"cdc_origin.size()<3 !"< ForwardEMcalpos; bool good = Get("//section/composition/posXYZ[@volume='ForwardEMcal']/@X_Y_Z", ForwardEMcalpos); if(!good){ _DBG_<<"Unable to retrieve ForwardEMcal position."< &z_tof) const { vector ForwardTOF; vector forwardTOF[2]; vector FTOC; if(!Get("//section/composition/posXYZ[@volume='ForwardTOF']/@X_Y_Z", ForwardTOF)) return false; if(!Get("//composition[@name='ForwardTOF']/posXYZ[@volume='forwardTOF']/@X_Y_Z/plane[@value='0']", forwardTOF[0])) return false; if(!Get("//composition[@name='ForwardTOF']/posXYZ[@volume='forwardTOF']/@X_Y_Z/plane[@value='1']", forwardTOF[1])) return false; if(!Get("//box[@name='FTOC' and sensitive='true']/@X_Y_Z", FTOC)) return false; z_tof.push_back(ForwardTOF[2] + forwardTOF[0][2] - FTOC[2]/2.0); z_tof.push_back(ForwardTOF[2] + forwardTOF[1][2] - FTOC[2]/2.0); return true; } //--------------------------------- // GetTargetZ //--------------------------------- bool DGeometry::GetTargetZ(double &z_target) const { vector xyz_vessel; vector xyz_target; vector xyz_detector; z_target=0.; if(!Get("//composition[@name='targetVessel']/posXYZ[@volume='targetTube']/@X_Y_Z", xyz_vessel)) return false; if(!Get("//composition[@name='Target']/posXYZ[@volume='targetVessel']/@X_Y_Z", xyz_target)) return false; if(!Get("//composition[@name='GlueXdetector']/posXYZ[@volume='Target']/@X_Y_Z", xyz_detector)) return false; z_target = xyz_vessel[2] + xyz_target[2] + xyz_detector[2]; return true; } //--------------------------------- // GetTargetLength //--------------------------------- bool DGeometry::GetTargetLength(double &target_length) const { vector Rio_Z; bool good = Get("//section[@name='Target']/tubs[@name='LIH2']/@Rio_Z", Rio_Z); target_length = good ? Rio_Z[2]:0.0; return good; }