JANA
JGeometry.h
Go to the documentation of this file.
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines