JANA
|
00001 // $Id$ 00002 // 00003 // File: JGeometry.h 00004 // Created: Fri Jul 6 16:24:24 EDT 2007 00005 // Creator: davidl (on Darwin fwing-dhcp61.jlab.org 8.10.1 i386) 00006 // 00007 00008 #ifndef _JGeometry_ 00009 #define _JGeometry_ 00010 00011 #include "jerror.h" 00012 00013 #include <map> 00014 #include <string> 00015 #include <sstream> 00016 #include <vector> 00017 using std::map; 00018 using std::string; 00019 using std::stringstream; 00020 using std::vector; 00021 00022 // Place everything in JANA namespace 00023 namespace jana{ 00024 00025 /// JGeometry is a virtual base class used to define the interface by 00026 /// which geometry information can be obtained in JANA. 00027 /// Implementing this base class allows the JANA end user to be 00028 /// agnostic as to the details of how the geometry info is stored. 00029 /// The geometry can be stored in a database or any number of file 00030 /// formats. The files can be stored locally, or on the network 00031 /// somewhere. 00032 /// 00033 /// The primary advantage here is that it allows one to work with 00034 /// local files, but then easily switch to a remote source method 00035 /// when appropriate without requiring modifications to the end 00036 /// user code. 00037 /// 00038 /// On the user side they will call one of the Get(...) methods which all get 00039 /// translated into a call of one of the two vitural methods: 00040 /// 00041 /// virtual bool Get(string namepath, string &sval, map<string, string> &where)=0; 00042 /// virtual bool Get(string namepath, map<string, string> &svals, map<string, string> &where)=0; 00043 /// 00044 /// These two virtual methods along with one to get a list of the available 00045 /// namepaths are the only things that need to be implemented 00046 /// in a concrete subclass of JGeometry. 00047 /// 00048 /// A geometry element is specified by its <i>namepath</i> and an optional 00049 /// set of qualifiers (the <i>where</i> argument). The <i>namepath</i> 00050 /// is a hierarchal list of elements separated by forward slashes(/) 00051 /// analogous to a path on a unix filesystem. This path is always assumed 00052 /// to be relative to the <i>url</i> specified in the constructor. So, 00053 /// for instance, suppose one kept the geometry in a set XML files on the 00054 /// local filesystem and wished to access information from the file 00055 /// 00056 /// <tt>/home/joe/calib/geom_Oct10_2017.xml</tt> 00057 /// 00058 /// One would specify the <i>url</i> as: 00059 /// 00060 /// file:///home/joe/calib/geom_Oct10_2017.xml 00061 /// 00062 /// and then the namepath could be specified as the string: 00063 /// 00064 /// "TOF/bar/X_Y_Z" 00065 /// 00066 /// which would indicate the attribute <i>"X_Y_Z"</i> of the 00067 /// subtag <i>"bar"</i> of the tag <i>"TOF"</i> in the file 00068 /// <i>"/home/joe/calib/geom_Oct10_2017.xml"</i> 00069 00070 class JGeometry{ 00071 public: 00072 JGeometry(string url, int run, string context="default"){ 00073 this->url = url; 00074 this->run_requested = run; 00075 this->context = context; 00076 } 00077 virtual ~JGeometry(){} 00078 virtual const char* className(void){return static_className();} 00079 static const char* static_className(void){return "JGeometry";} 00080 00081 typedef enum{ 00082 // Used to specify which (if any) attributes should be included in 00083 // the values obtained through GetXPaths(). 00084 attr_level_none = 0, // Don't include any attributes. Only node names. 00085 attr_level_last = 1, // Include the attributes for the last node only. 00086 attr_level_all = 2 // Include attributes for all nodes. 00087 }ATTR_LEVEL_t; 00088 00089 // Virtual methods called through base class 00090 virtual bool Get(string xpath, string &sval)=0; 00091 virtual bool Get(string xpath, map<string, string> &svals)=0; 00092 virtual bool GetMultiple(string xpath, vector<string> &vsval)=0; 00093 virtual bool GetMultiple(string xpath, vector<map<string, string> >&vsvals)=0; 00094 virtual void GetXPaths(vector<string> &xpaths, ATTR_LEVEL_t level=attr_level_last, const string &filter="")=0; 00095 00096 // Templated methods that can return more useful forms 00097 template<class T> bool Get(string xpath, T &val); 00098 template<class T> bool Get(string xpath, vector<T> &vals, string delimiter=" "); 00099 template<class T> bool Get(string xpath, map<string,T> &vals); 00100 template<class T> bool GetMultiple(string xpath, vector<T> &vval); 00101 template<class T> bool GetMultiple(string xpath, vector<vector<T> > &vvals, string delimiter=" "); 00102 template<class T> bool GetMultiple(string xpath, vector<map<string,T> > &vvals); 00103 00104 const int& GetRunRequested(void) const {return run_requested;} 00105 const int& GetRunFound(void) const {return run_found;} 00106 const int& GetRunMin(void) const {return run_min;} 00107 const int& GetRunMax(void) const {return run_max;} 00108 const string& GetContext(void) const {return context;} 00109 const string& GetURL(void) const {return url;} 00110 00111 protected: 00112 int run_min; 00113 int run_max; 00114 int run_found; 00115 00116 private: 00117 JGeometry(){} // Don't allow trivial constructor 00118 00119 int run_requested; 00120 string context; 00121 string url; 00122 map<string,string> anywhere; // an empty map means no constraints 00123 00124 }; 00125 00126 00127 //------------- 00128 // Get (single version) 00129 //------------- 00130 template<class T> 00131 bool JGeometry::Get(string xpath, T &val) 00132 { 00133 /// Templated method used to get a single geometry element. 00134 /// 00135 /// This method will get the specified geometry element in the form of 00136 /// a string using the virtual (non-templated) Get(...) method. It will 00137 /// then convert the string into the data type on which <i>val</i> is 00138 /// based. It does this using the stringstream 00139 /// class so T is restricted to the types stringstream understands (int, float, 00140 /// double, string, ...). 00141 /// 00142 /// If no element of the specified name is found, a value 00143 /// of boolean "false" is returned. A value of "true" is 00144 /// returned upon success. 00145 00146 // Get values in the form of a string 00147 string sval; 00148 bool res = Get(xpath, sval); 00149 if(!res)return res; 00150 00151 // Convert the string to type "T" and copy it into val. 00152 // Use stringstream to convert from a string to type "T" 00153 stringstream ss(sval); 00154 ss >> val; 00155 00156 return res; 00157 } 00158 00159 //------------- 00160 // Get (vector version) 00161 //------------- 00162 template<class T> 00163 bool JGeometry::Get(string xpath, vector<T> &vals, string delimiter) 00164 { 00165 /// Templated method used to get a set of values from a geometry attribute. 00166 /// 00167 /// This method can be used to get a list of values (possibly only one) 00168 /// from a single geometry attribute specified by xpath. The attribute 00169 /// is obtained as a string using the non-templated Get(...) method 00170 /// and the string broken into tokens separated by the delimiter 00171 /// (which defaults to a single white space). Each 00172 /// token is then converted into type T using the stringstream class 00173 /// so T is restricted to the types stringstream understands (int, float, 00174 /// double, string, ...). 00175 /// 00176 /// If no element of the specified name is found, a value 00177 /// of boolean "false" is returned. A value of "true" is 00178 /// returned upon success. 00179 00180 // Get values in the form of strings 00181 vals.clear(); 00182 string svals; 00183 bool res = Get(xpath, svals); 00184 if(!res)return res; 00185 00186 string::size_type pos_start = svals.find_first_not_of(delimiter,0); 00187 while(pos_start != string::npos){ 00188 string::size_type pos_end = svals.find_first_of(delimiter, pos_start); 00189 if(pos_end==string::npos)pos_end=svals.size(); 00190 00191 T v; 00192 string val = svals.substr(pos_start, pos_end-pos_start); 00193 stringstream ss(val); 00194 ss >> v; 00195 vals.push_back(v); 00196 00197 pos_start = svals.find_first_not_of(delimiter, pos_end); 00198 } 00199 00200 return res; 00201 } 00202 00203 //------------- 00204 // Get (map version) 00205 //------------- 00206 template<class T> 00207 bool JGeometry::Get(string xpath, map<string,T> &vals) 00208 { 00209 /// Templated method used to get a set of geometry attributes. 00210 /// 00211 /// This method can be used to get a list of all attributes for 00212 /// a given xpath. The attributes are copied into the <i>vals</i> 00213 /// map with the attribute name as the key and the attribute 00214 /// value as the value. This relies on the non-templated, virtual 00215 /// Get(string, map<string,string>&) method to first get the values 00216 /// in the form of strings. It converts them using the stringstream 00217 /// class so T is restricted to the types it understands (int, float, 00218 /// double, string, ...). 00219 /// 00220 /// If no element of the specified name is found, a value 00221 /// of boolean "false" is returned. A value of "true" is 00222 /// returned upon success. 00223 00224 // Get values in the form of strings 00225 map<string, string> svals; 00226 bool res = Get(xpath, svals); 00227 00228 // Loop over values, converting the strings to type "T" and 00229 // copying them into the vals map. 00230 vals.clear(); 00231 map<string,string>::const_iterator iter; 00232 for(iter=svals.begin(); iter!=svals.end(); ++iter){ 00233 // Use stringstream to convert from a string to type "T" 00234 T v; 00235 stringstream ss(iter->second); 00236 ss >> v; 00237 vals[iter->first] = v; 00238 } 00239 00240 return res; 00241 } 00242 00243 00244 //------------- 00245 // GetMultiple (single version) 00246 //------------- 00247 template<class T> 00248 bool JGeometry::GetMultiple(string xpath, vector<T> &vval) 00249 { 00250 /// Templated method used to get multiple entries satisfying a single xpath. 00251 /// 00252 /// This method will get the specified geometry element in the form of 00253 /// a string using the virtual (non-templated) Get(...) method. It will 00254 /// then convert the string into the data type on which <i>val</i> is 00255 /// based. It does this using the stringstream 00256 /// class so T is restricted to the types stringstream understands (int, float, 00257 /// double, string, ...). 00258 /// 00259 /// This differs from the similar Get() method in that the geometry tree 00260 /// will be searched for all nodes satisfying the given xpath and all 00261 /// all values will be copied into the container provided. In Get(), only 00262 /// the first node encountered that satisfies the xpath will be copied. 00263 /// 00264 /// If no element of the specified name is found, a value 00265 /// of boolean "false" is returned. A value of "true" is 00266 /// returned upon success. 00267 00268 // Get values in the form of a string 00269 vector<string> vsval; 00270 bool res = GetMultiple(xpath, vsval); 00271 if(!res)return res; 00272 00273 // Convert the string to type "T" and copy it into val. 00274 // Use stringstream to convert from a string to type "T" 00275 for(unsigned int i=0; i<vsval.size(); i++){ 00276 stringstream ss(vsval[i]); 00277 T val; 00278 ss >> val; 00279 vval.push_back(val); 00280 } 00281 00282 return res; 00283 } 00284 00285 //------------- 00286 // GetMultiple (vector version) 00287 //------------- 00288 template<class T> 00289 bool JGeometry::GetMultiple(string xpath, vector<vector<T> > &vvals, string delimiter) 00290 { 00291 /// Templated method used to get a set of values from a geometry attribute. 00292 /// 00293 /// This method can be used to get a list of values (possibly only one) 00294 /// from a single geometry attribute specified by xpath. The attribute 00295 /// is obtained as a string using the non-templated Get(...) method 00296 /// and the string broken into tokens separated by the delimiter 00297 /// (which defaults to a single white space). Each 00298 /// token is then converted into type T using the stringstream class 00299 /// so T is restricted to the types stringstream understands (int, float, 00300 /// double, string, ...). 00301 /// 00302 /// If no element of the specified name is found, a value 00303 /// of boolean "false" is returned. A value of "true" is 00304 /// returned upon success. 00305 00306 // Get values in the form of strings 00307 vvals.clear(); 00308 vector<string> vsvals; 00309 bool res = GetMultiple(xpath, vsvals); 00310 if(!res)return res; 00311 00312 for(unsigned int i=0; i<vsvals.size(); i++){ 00313 string &svals = vsvals[i]; 00314 00315 string::size_type pos_start = svals.find_first_not_of(delimiter,0); 00316 vector<T> vals; 00317 while(pos_start != string::npos){ 00318 string::size_type pos_end = svals.find_first_of(delimiter, pos_start); 00319 if(pos_end==string::npos)pos_end=svals.size(); 00320 00321 T v; 00322 string val = svals.substr(pos_start, pos_end-pos_start); 00323 stringstream ss(val); 00324 ss >> v; 00325 vals.push_back(v); 00326 00327 pos_start = svals.find_first_not_of(delimiter, pos_end); 00328 } 00329 00330 vvals.push_back(vals); 00331 } 00332 00333 return res; 00334 } 00335 00336 //------------- 00337 // GetMultiple (map version) 00338 //------------- 00339 template<class T> 00340 bool JGeometry::GetMultiple(string xpath, vector<map<string,T> > &vvals) 00341 { 00342 /// Templated method used to get a set of geometry attributes. 00343 /// 00344 /// This method can be used to get a list of all attributes for 00345 /// a given xpath. The attributes are copied into the <i>vals</i> 00346 /// map with the attribute name as the key and the attribute 00347 /// value as the value. This relies on the non-templated, virtual 00348 /// Get(string, map<string,string>&) method to first get the values 00349 /// in the form of strings. It converts them using the stringstream 00350 /// class so T is restricted to the types it understands (int, float, 00351 /// double, string, ...). 00352 /// 00353 /// If no element of the specified name is found, a value 00354 /// of boolean "false" is returned. A value of "true" is 00355 /// returned upon success. 00356 00357 // Get values in the form of strings 00358 vector<map<string, string> > vsvals; 00359 bool res = GetMultiple(xpath, vsvals); 00360 00361 // Loop over values, converting the strings to type "T" and 00362 // copying them into the vals map. 00363 vvals.clear(); 00364 00365 for(unsigned int i=0; i<vsvals.size(); i++){ 00366 map<string,string> &svals = vsvals[i]; 00367 00368 map<string,T> vals; 00369 map<string,string>::const_iterator iter; 00370 for(iter=svals.begin(); iter!=svals.end(); ++iter){ 00371 // Use stringstream to convert from a string to type "T" 00372 T v; 00373 stringstream ss(iter->second); 00374 ss >> v; 00375 vals[iter->first] = v; 00376 } 00377 00378 vvals.push_back(vals); 00379 } 00380 00381 return res; 00382 } 00383 00384 } // Close JANA namespace 00385 00386 #endif // _JGeometry_