|
||||
File indexing completed on 2025-01-18 10:17:34
0001 0002 // Copyright 2007-2025, Jefferson Science Associates, LLC. 0003 // Subject to the terms in the LICENSE file found in the top-level directory. 0004 0005 #pragma once 0006 0007 #include <map> 0008 #include <string> 0009 #include <sstream> 0010 #include <vector> 0011 using std::map; 0012 using std::string; 0013 using std::stringstream; 0014 using std::vector; 0015 0016 0017 /// JGeometry is a virtual base class used to define the interface by 0018 /// which geometry information can be obtained in JANA. 0019 /// Implementing this base class allows the JANA end user to be 0020 /// agnostic as to the details of how the geometry info is stored. 0021 /// The geometry can be stored in a database or any number of file 0022 /// formats. The files can be stored locally, or on the network 0023 /// somewhere. 0024 /// 0025 /// The primary advantage here is that it allows one to work with 0026 /// local files, but then easily switch to a remote source method 0027 /// when appropriate without requiring modifications to the end 0028 /// user code. 0029 /// 0030 /// On the user side they will call one of the Get(...) methods which all get 0031 /// translated into a call of one of the two vitural methods: 0032 /// 0033 /// virtual bool Get(string namepath, string &sval, map<string, string> &where)=0; 0034 /// virtual bool Get(string namepath, map<string, string> &svals, map<string, string> &where)=0; 0035 /// 0036 /// These two virtual methods along with one to get a list of the available 0037 /// namepaths are the only things that need to be implemented 0038 /// in a concrete subclass of JGeometry. 0039 /// 0040 /// A geometry element is specified by its <i>namepath</i> and an optional 0041 /// set of qualifiers (the <i>where</i> argument). The <i>namepath</i> 0042 /// is a hierarchal list of elements separated by forward slashes(/) 0043 /// analogous to a path on a unix filesystem. This path is always assumed 0044 /// to be relative to the <i>url</i> specified in the constructor. So, 0045 /// for instance, suppose one kept the geometry in a set XML files on the 0046 /// local filesystem and wished to access information from the file 0047 /// 0048 /// <tt>/home/joe/calib/geom_Oct10_2017.xml</tt> 0049 /// 0050 /// One would specify the <i>url</i> as: 0051 /// 0052 /// file:///home/joe/calib/geom_Oct10_2017.xml 0053 /// 0054 /// and then the namepath could be specified as the string: 0055 /// 0056 /// "TOF/bar/X_Y_Z" 0057 /// 0058 /// which would indicate the attribute <i>"X_Y_Z"</i> of the 0059 /// subtag <i>"bar"</i> of the tag <i>"TOF"</i> in the file 0060 /// <i>"/home/joe/calib/geom_Oct10_2017.xml"</i> 0061 0062 class JGeometry{ 0063 public: 0064 JGeometry(string url, int run, string context="default"){ 0065 this->url = url; 0066 this->run_requested = run; 0067 this->context = context; 0068 } 0069 virtual ~JGeometry(){} 0070 virtual const char* className(void){return static_className();} 0071 static const char* static_className(void){return "JGeometry";} 0072 0073 typedef enum{ 0074 // Used to specify which (if any) attributes should be included in 0075 // the values obtained through GetXPaths(). 0076 attr_level_none = 0, // Don't include any attributes. Only node names. 0077 attr_level_last = 1, // Include the attributes for the last node only. 0078 attr_level_all = 2 // Include attributes for all nodes. 0079 }ATTR_LEVEL_t; 0080 0081 void SetVerbose(int newval){ verbose = newval; } 0082 0083 // Virtual methods called through base class 0084 virtual bool Get(string xpath, string &sval)=0; 0085 virtual bool Get(string xpath, map<string, string> &svals)=0; 0086 virtual bool GetMultiple(string xpath, vector<string> &vsval)=0; 0087 virtual bool GetMultiple(string xpath, vector<map<string, string> >&vsvals)=0; 0088 virtual void GetXPaths(vector<string> &xpaths, ATTR_LEVEL_t level=attr_level_last, const string &filter="")=0; 0089 virtual string GetChecksum(void) const {return string("not supported");} 0090 0091 // Templated methods that can return more useful forms 0092 template<class T> bool Get(string xpath, T &val); 0093 template<class T> bool Get(string xpath, vector<T> &vals, string delimiter=" "); 0094 template<class T> bool Get(string xpath, map<string,T> &vals); 0095 template<class T> bool GetMultiple(string xpath, vector<T> &vval); 0096 template<class T> bool GetMultiple(string xpath, vector<vector<T> > &vvals, string delimiter=" "); 0097 template<class T> bool GetMultiple(string xpath, vector<map<string,T> > &vvals); 0098 0099 const int& GetRunRequested(void) const {return run_requested;} 0100 const int& GetRunFound(void) const {return run_found;} 0101 const int& GetRunMin(void) const {return run_min;} 0102 const int& GetRunMax(void) const {return run_max;} 0103 const string& GetContext(void) const {return context;} 0104 const string& GetURL(void) const {return url;} 0105 0106 protected: 0107 int run_min; 0108 int run_max; 0109 int run_found; 0110 0111 int verbose=1; 0112 0113 private: 0114 JGeometry(){} // Don't allow trivial constructor 0115 0116 int run_requested; 0117 string context; 0118 string url; 0119 map<string,string> anywhere; // an empty map means no constraints 0120 0121 }; 0122 0123 0124 //------------- 0125 // Get (single version) 0126 //------------- 0127 template<class T> 0128 bool JGeometry::Get(string xpath, T &val) 0129 { 0130 /// Templated method used to get a single geometry element. 0131 /// 0132 /// This method will get the specified geometry element in the form of 0133 /// a string using the virtual (non-templated) Get(...) method. It will 0134 /// then convert the string into the data type on which <i>val</i> is 0135 /// based. It does this using the stringstream 0136 /// class so T is restricted to the types stringstream understands (int, float, 0137 /// double, string, ...). 0138 /// 0139 /// If no element of the specified name is found, a value 0140 /// of boolean "false" is returned. A value of "true" is 0141 /// returned upon success. 0142 0143 // Get values in the form of a string 0144 string sval; 0145 bool res = Get(xpath, sval); 0146 if(!res)return res; 0147 0148 // Convert the string to type "T" and copy it into val. 0149 // Use stringstream to convert from a string to type "T" 0150 stringstream ss(sval); 0151 ss >> val; 0152 0153 return res; 0154 } 0155 0156 //------------- 0157 // Get (vector version) 0158 //------------- 0159 template<class T> 0160 bool JGeometry::Get(string xpath, vector<T> &vals, string delimiter) 0161 { 0162 /// Templated method used to get a set of values from a geometry attribute. 0163 /// 0164 /// This method can be used to get a list of values (possibly only one) 0165 /// from a single geometry attribute specified by xpath. The attribute 0166 /// is obtained as a string using the non-templated Get(...) method 0167 /// and the string broken into tokens separated by the delimiter 0168 /// (which defaults to a single white space). Each 0169 /// token is then converted into type T using the stringstream class 0170 /// so T is restricted to the types stringstream understands (int, float, 0171 /// double, string, ...). 0172 /// 0173 /// If no element of the specified name is found, a value 0174 /// of boolean "false" is returned. A value of "true" is 0175 /// returned upon success. 0176 0177 // Get values in the form of strings 0178 vals.clear(); 0179 string svals; 0180 bool res = Get(xpath, svals); 0181 if(!res)return res; 0182 0183 string::size_type pos_start = svals.find_first_not_of(delimiter,0); 0184 while(pos_start != string::npos){ 0185 string::size_type pos_end = svals.find_first_of(delimiter, pos_start); 0186 if(pos_end==string::npos)pos_end=svals.size(); 0187 0188 T v; 0189 string val = svals.substr(pos_start, pos_end-pos_start); 0190 stringstream ss(val); 0191 ss >> v; 0192 vals.push_back(v); 0193 0194 pos_start = svals.find_first_not_of(delimiter, pos_end); 0195 } 0196 0197 return res; 0198 } 0199 0200 //------------- 0201 // Get (map version) 0202 //------------- 0203 template<class T> 0204 bool JGeometry::Get(string xpath, map<string,T> &vals) 0205 { 0206 /// Templated method used to get a set of geometry attributes. 0207 /// 0208 /// This method can be used to get a list of all attributes for 0209 /// a given xpath. The attributes are copied into the <i>vals</i> 0210 /// map with the attribute name as the key and the attribute 0211 /// value as the value. This relies on the non-templated, virtual 0212 /// Get(string, map<string,string>&) method to first get the values 0213 /// in the form of strings. It converts them using the stringstream 0214 /// class so T is restricted to the types it understands (int, float, 0215 /// double, string, ...). 0216 /// 0217 /// If no element of the specified name is found, a value 0218 /// of boolean "false" is returned. A value of "true" is 0219 /// returned upon success. 0220 0221 // Get values in the form of strings 0222 map<string, string> svals; 0223 bool res = Get(xpath, svals); 0224 0225 // Loop over values, converting the strings to type "T" and 0226 // copying them into the vals map. 0227 vals.clear(); 0228 map<string,string>::const_iterator iter; 0229 for(iter=svals.begin(); iter!=svals.end(); ++iter){ 0230 // Use stringstream to convert from a string to type "T" 0231 T v; 0232 stringstream ss(iter->second); 0233 ss >> v; 0234 vals[iter->first] = v; 0235 } 0236 0237 return res; 0238 } 0239 0240 0241 //------------- 0242 // GetMultiple (single version) 0243 //------------- 0244 template<class T> 0245 bool JGeometry::GetMultiple(string xpath, vector<T> &vval) 0246 { 0247 /// Templated method used to get multiple entries satisfying a single xpath. 0248 /// 0249 /// This method will get the specified geometry element in the form of 0250 /// a string using the virtual (non-templated) Get(...) method. It will 0251 /// then convert the string into the data type on which <i>val</i> is 0252 /// based. It does this using the stringstream 0253 /// class so T is restricted to the types stringstream understands (int, float, 0254 /// double, string, ...). 0255 /// 0256 /// This differs from the similar Get() method in that the geometry tree 0257 /// will be searched for all nodes satisfying the given xpath and all 0258 /// all values will be copied into the container provided. In Get(), only 0259 /// the first node encountered that satisfies the xpath will be copied. 0260 /// 0261 /// If no element of the specified name is found, a value 0262 /// of boolean "false" is returned. A value of "true" is 0263 /// returned upon success. 0264 0265 // Get values in the form of a string 0266 vector<string> vsval; 0267 bool res = GetMultiple(xpath, vsval); 0268 if(!res)return res; 0269 0270 // Convert the string to type "T" and copy it into val. 0271 // Use stringstream to convert from a string to type "T" 0272 for(unsigned int i=0; i<vsval.size(); i++){ 0273 stringstream ss(vsval[i]); 0274 T val; 0275 ss >> val; 0276 vval.push_back(val); 0277 } 0278 0279 return res; 0280 } 0281 0282 //------------- 0283 // GetMultiple (vector version) 0284 //------------- 0285 template<class T> 0286 bool JGeometry::GetMultiple(string xpath, vector<vector<T> > &vvals, string delimiter) 0287 { 0288 /// Templated method used to get a set of values from a geometry attribute. 0289 /// 0290 /// This method can be used to get a list of values (possibly only one) 0291 /// from a single geometry attribute specified by xpath. The attribute 0292 /// is obtained as a string using the non-templated Get(...) method 0293 /// and the string broken into tokens separated by the delimiter 0294 /// (which defaults to a single white space). Each 0295 /// token is then converted into type T using the stringstream class 0296 /// so T is restricted to the types stringstream understands (int, float, 0297 /// double, string, ...). 0298 /// 0299 /// If no element of the specified name is found, a value 0300 /// of boolean "false" is returned. A value of "true" is 0301 /// returned upon success. 0302 0303 // Get values in the form of strings 0304 vvals.clear(); 0305 vector<string> vsvals; 0306 bool res = GetMultiple(xpath, vsvals); 0307 if(!res)return res; 0308 0309 for(unsigned int i=0; i<vsvals.size(); i++){ 0310 string &svals = vsvals[i]; 0311 0312 string::size_type pos_start = svals.find_first_not_of(delimiter,0); 0313 vector<T> vals; 0314 while(pos_start != string::npos){ 0315 string::size_type pos_end = svals.find_first_of(delimiter, pos_start); 0316 if(pos_end==string::npos)pos_end=svals.size(); 0317 0318 T v; 0319 string val = svals.substr(pos_start, pos_end-pos_start); 0320 stringstream ss(val); 0321 ss >> v; 0322 vals.push_back(v); 0323 0324 pos_start = svals.find_first_not_of(delimiter, pos_end); 0325 } 0326 0327 vvals.push_back(vals); 0328 } 0329 0330 return res; 0331 } 0332 0333 //------------- 0334 // GetMultiple (map version) 0335 //------------- 0336 template<class T> 0337 bool JGeometry::GetMultiple(string xpath, vector<map<string,T> > &vvals) 0338 { 0339 /// Templated method used to get a set of geometry attributes. 0340 /// 0341 /// This method can be used to get a list of all attributes for 0342 /// a given xpath. The attributes are copied into the <i>vals</i> 0343 /// map with the attribute name as the key and the attribute 0344 /// value as the value. This relies on the non-templated, virtual 0345 /// Get(string, map<string,string>&) method to first get the values 0346 /// in the form of strings. It converts them using the stringstream 0347 /// class so T is restricted to the types it understands (int, float, 0348 /// double, string, ...). 0349 /// 0350 /// If no element of the specified name is found, a value 0351 /// of boolean "false" is returned. A value of "true" is 0352 /// returned upon success. 0353 0354 // Get values in the form of strings 0355 vector<map<string, string> > vsvals; 0356 bool res = GetMultiple(xpath, vsvals); 0357 0358 // Loop over values, converting the strings to type "T" and 0359 // copying them into the vals map. 0360 vvals.clear(); 0361 0362 for(unsigned int i=0; i<vsvals.size(); i++){ 0363 map<string,string> &svals = vsvals[i]; 0364 0365 map<string,T> vals; 0366 map<string,string>::const_iterator iter; 0367 for(iter=svals.begin(); iter!=svals.end(); ++iter){ 0368 // Use stringstream to convert from a string to type "T" 0369 T v; 0370 stringstream ss(iter->second); 0371 ss >> v; 0372 vals[iter->first] = v; 0373 } 0374 0375 vvals.push_back(vals); 0376 } 0377 0378 return res; 0379 } 0380
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |