Back to home page

EIC code displayed by LXR

 
 

    


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