// $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(const DVector3 &pos,const DVector3 &mom, 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,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(const DVector3 &pos, 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,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 "<r_z; double phi0; vectorrot; // Extract data from the XML if(!Get(ncopy_s.str(), ncopy)) return false; if(!Get(r_z_s.str(), r_z)) return false; if(!Get(phi0_s.str(), phi0)) return false; if(!Get(rot_s.str(), rot)) return false; // Angular quantities const double deg2rad=M_PI/180.; double dphi=2*M_PI/double(ncopy); phi0*=deg2rad; // Extract data from close-packed straws const double EPS=1e-4; bool close_packed=false; double rotX=0.,rotY=0.,stereo=0.; vectordelta_xyz; if (r_z[0]ring=ring; w->straw=i+1; w->phi=phi; if (close_packed){ w->origin.SetX(delta_xyz[0]); w->origin.SetY(delta_xyz[1]); w->origin.RotateZ(phi); } else{ w->origin.SetX(r_z[0]*cos(phi)); w->origin.SetY(r_z[0]*sin(phi)); } // Here, we need to define a coordinate system for the wire // in which the wire runs along one axis. We call the directions // of the axes in this coordinate system s,t, and u with // the wire running in the "u" direction. The "s" direction // will be defined by the direction pointing from the beamline // to the midpoint of the wire. w->udir.SetXYZ(0.0, 0.0,1.0); if (close_packed){ w->udir.RotateX(rotX); w->udir.RotateY(rotY); w->udir.RotateZ(phi); w->stereo = (rotX<0?-1.:1.)*w->udir.Angle(DVector3(0,0,1)); } else{ w->stereo=stereo; w->udir.RotateX(stereo); w->udir.RotateZ(phi); } stereowires.push_back(w); } return true; } /// Extract the axial wire data from the XML bool DGeometry::GetCDCAxialWires(unsigned int ring,vector &axialwires) const{ stringstream ncopy_s,phi0_s,r_z_s; // Create search strings for the number of straws and the straw geometrical properties ncopy_s << "//mposPhi[@volume='CDCstrawShort']/@ncopy/ring[@value='" << ring << "']"; phi0_s << "//mposPhi[@volume='CDCstrawShort']/@Phi0/ring[@value='" << ring << "']"; r_z_s << "//mposPhi[@volume='CDCstrawShort']/@R_Z/ring[@value='" << ring << "']"; unsigned int ncopy; double phi0; vectorr_z; // Extract the data from the XML if(!Get(ncopy_s.str(), ncopy)) return false; if(!Get(phi0_s.str(), phi0)) return false; if(!Get(r_z_s.str(), r_z)) return false; // Angular quantities double dphi=2*M_PI/double(ncopy); phi0*=M_PI/180.; // Loop over the number of straws for (unsigned int i=0;iring=ring; w->straw=i+1; w->origin.SetX(r_z[0]*cos(phi)); w->origin.SetY(r_z[0]*sin(phi)); w->phi=phi; w->stereo=0.; // Here, we need to define a coordinate system for the wire // in which the wire runs along one axis. We call the directions // of the axes in this coordinate system s,t, and u with // the wire running in the "u" direction. The "s" direction // will be defined by the direction pointing from the beamline // to the midpoint of the wire. w->udir.SetXYZ(0.0, 0.0,1.0); w->udir.RotateZ(phi); axialwires.push_back(w); } return true; } //--------------------------------- // GetCDCWires //--------------------------------- bool DGeometry::GetCDCWires(vector >&cdcwires) const{ vectorcdc_origin; vectorcdc_length; Get("//posXYZ[@volume='CentralDC']/@X_Y_Z",cdc_origin); Get("//tubs[@name='STRW']/@Rio_Z",cdc_length); double zmin=cdc_origin[2]; double zmax=zmin+cdc_length[2]; double zcenter=0.5*(zmin+zmax); double L=zmax-zmin; // First axial layer for (unsigned int ring=1;ring<5;ring++){ vectorstraws; if (!GetCDCAxialWires(ring,straws)) return false; cdcwires.push_back(straws); } string longwireflags[16]={"","B12","","B14","","B16","","B18","","B22","","B24","","B26","","B28"}; // First set of stereo layers for (unsigned int i=0;i<8;i++){ vectorstraws; if (!GetCDCStereoWires(i+5,longwireflags[i],straws)) return false; cdcwires.push_back(straws); } // Second axial layer for (unsigned int ring=13;ring<17;ring++){ vectorstraws; if (!GetCDCAxialWires(ring,straws)) return false; cdcwires.push_back(straws); } // Second set of stereo layers for (unsigned int i=8;i<16;i++){ vectorstraws; if (!GetCDCStereoWires(i+9,longwireflags[i],straws)) return false; cdcwires.push_back(straws); } // Third axial layer for (unsigned int ring=25;ring<29;ring++){ vectorstraws; if (!GetCDCAxialWires(ring,straws)) return false; cdcwires.push_back(straws); } // Calculate wire lengths and compute "s" and "t" direction vectors (orthogonal to "u") for (unsigned int i=0;iL=L/cos(w->stereo); w->origin.SetZ(zcenter); // With the addition of close-packed stereo wires, the vector connecting // the center of the wire to the beamline ("s" direction) is not necessarily // perpendicular to the beamline. By definition, we want the "s" direction // to be perpendicular to the wire direction "u" and pointing at the beamline. // // NOTE: This extensive comment is here because the result, when implmented // below caused a WORSE residual distribution in the close-packed stereo // layers. Owing to lack of time currently to track the issue down (most // likely in DReferenceTrajectory) I'm commenting out the "correct" calculation // of s, but leaving this comment so the issue can be revisited later. This // error leads to around 100 micron errors in the C.P.S. wires, but they // are completely washed out when the position smearing of 150 microns is applied // making the error unnoticable except when position smearing is not applied. // // April 2, 2009 D.L. // // Here is how this is calculated -- We define a vector equation with 2 unknowns // Z and S: // // Zz + Ss = W // // where: z = unit vector in z direction // s = unit vector in "s" direction // W = vector pointing to center of wire in lab coordinates // // Rearranging, we get: // // s = (W - Zz)/S // // Since s must be perpendicular to u, we take a dot product of s and u // and set it equal to zero to determine Z: // // u.s = 0 = u.(W - Zz)/S => u.W = Zu.z // // or // // Z = u.W/u.z // // Thus, the s direction is just given by (W - (u.W/u.z)z) // //w->sdir=w->origin-DVector3(0,0,w->origin.Z()); w->sdir = w->origin - DVector3(0.0, 0.0, w->udir.Dot(w->origin)/w->udir.Z()); // see above comments w->sdir.SetMag(1.0); w->tdir = w->udir.Cross(w->sdir); w->tdir.SetMag(1.0); // This isn't really needed } } return true; } //--------------------------------- // GetFDCWires //--------------------------------- bool DGeometry::GetFDCWires(vector >&fdcwires) const{ // Get geometrical information from database vectorz_wires; vectorstereo_angles; if(!GetFDCZ(z_wires)) return false; if(!GetFDCStereo(stereo_angles)) return false; for(int layer=1; layer<=FDC_NUM_LAYERS; layer++){ double angle=-stereo_angles[layer-1]*M_PI/180.; vectortemp; for(int wire=1; wire<=WIRES_PER_PLANE; wire++){ DFDCWire *w = new DFDCWire; w->layer = layer; w->wire = wire; w->angle = angle; // find coordinates of center of wire in rotated system float u = U_OF_WIRE_ZERO + WIRE_SPACING*(float)(wire-1); // Rotate coordinates into lab system and set the wire's origin // Note that the FDC measures "angle" such that angle=0 // corresponds to the anode wire in the vertical direction // (i.e. at phi=90 degrees). float x = u*sin(angle + M_PI/2.0); float y = u*cos(angle + M_PI/2.0); w->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++){ // if (chamber==4) forwardDC_chamber[package-1][chamber-1][2]+=15.0; 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; }