Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

Constants.cxx

Go to the documentation of this file.
00001 // $Header: /nfs/slac/g/glast/ground/cvs/xmlUtil/src/Constants.cxx,v 1.9 2002/09/13 23:33:59 jrb Exp $
00002 
00003 #include <string>
00004 #include <dom/DOMString.hpp>
00005 #include <dom/DOM_Node.hpp>
00006 #include <dom/DOM_NodeList.hpp>
00007 #include <dom/DOM_TreeWalker.hpp>
00008 #include "xmlUtil/Constants.h"
00009 #include "xmlUtil/Arith.h"
00010 #include "xml/Dom.h"
00011 #include <vector>
00012 
00013 namespace {
00014   // Put a local utility in the unnamed namespace
00015 
00016 /* For each <prim>
00017     if it's of type "length"
00018      if units are not "mm" then convert to "mm"
00019 
00020    for each <primEnergy>
00021       Make a <prim> node with same name, value fields to replace it.
00022       Convert GeV to MeV
00023 
00024    For diagnostics, digits in return value are calculated as follows:
00025            1's place (1)  -- was a <prim>
00026               1000 place  -- was a <primEnergy>
00027        10000 place  -- required conversion
00028       100000 place  -- unknown unit; couldn't convert
00029 */
00030 
00031   int normPrim(DOM_Element elt, std::vector<DOM_Element>& save) {
00032     int ret = 0;
00033     //    if (!(elt.getNodeName()).equals(DOMString("prim"))) return ret;
00034     if ((elt.getNodeName()).equals(DOMString("prim"))) {
00035     
00036       ret += 1;
00037       DOMString valueString = DOMString("value");
00038 
00039       // Check for int.  If we've got one, round it.
00040       // Check if we're supposed to be an int.  If so, coerce
00041       // m_number to be nearby int in case of round-off error 
00042       if (DOMString("int").equals(elt.getAttribute("type"))) {
00043         // If we're not already a perfect int, attempt to fix
00044         // so that we round the right way.
00045         // Otherwise, leave well enough alone
00046         
00047         double   origValueDbl =
00048           atof(xml::Dom::transToChar(elt.getAttribute(valueString)));
00049         int origValueInt = 
00050           atoi(xml::Dom::transToChar(elt.getAttribute(valueString)));
00051         double   intified = origValueInt;
00052         if (intified != origValueDbl) { 
00053           // put back properly rounded int
00054           double fixup = 0.5;
00055           if (origValueDbl < 0) fixup = -fixup;
00056           origValueDbl += fixup;
00057           int newValue = origValueDbl;
00058           xml::Dom::addAttribute(elt, valueString, newValue);
00059         }
00060       }
00061 
00062       // Found a prim, but we don't have to convert since it's not a length
00063       if (!(elt.getAttribute(DOMString("uType"))).equals("length")) return ret;
00064     
00065       //      ret += 1000;
00066       DOMString uLength = DOMString("unitLength");
00067     
00068       DOMString units = elt.getAttribute(uLength);
00069       if (units.equals(DOMString("mm"))) return ret;
00070     
00071       double scale, value;
00072       if (units.equals(DOMString("cm"))) {
00073         ret += 10000;
00074         scale = 10;
00075       }
00076       else if (units.equals(DOMString("m"))) {
00077         ret += 10000;
00078         scale = 1000;
00079       }
00080       else return (100000 + ret);          // should never happen
00081     
00082       value = atof(xml::Dom::transToChar(elt.getAttribute(valueString)));
00083       value *= scale;
00084       xml::Dom::addAttribute(elt, valueString, value);
00085       elt.setAttribute(uLength, DOMString("mm"));
00086     
00087       //      return ret;
00088     }
00089     else if ((elt.getNodeName()).equals(DOMString("primEnergy"))) {
00090       save.push_back(elt);
00091       ret += 1000;
00092     }
00093     return ret;
00094   }                 // end of utility normPrim
00095 
00096   void handleEnergies(std::vector<DOM_Element> saved) {
00097     // Make a new <prim> node to replace it; meanwhile convert
00098     // GeV to MeV if necessary
00099     std::vector<DOM_Element>::const_iterator eltIt;
00100     for (eltIt = saved.begin(); eltIt != saved.end(); eltIt++) {
00101       DOM_Element elt = *eltIt;
00102       DOM_Document doc = elt.getOwnerDocument();
00103       DOM_Element  prim = doc.createElement("prim");
00104       prim.setAttribute("name", elt.getAttribute("name"));
00105       prim.setAttribute("type", "double");
00106       prim.setAttribute("uType", "energy");
00107       prim.setAttribute("unitEnergy", "MeV");
00108       double energy = atof(xml::Dom::transToChar(elt.getAttribute("value")));
00109       if ((DOMString("GeV")).equals(elt.getAttribute("units")) ) {
00110         energy *= 1000;
00111       }
00112       xml::Dom::addAttribute(prim, "value", energy);
00113       elt.normalize();
00114       DOM_Node textChild = elt.getFirstChild();
00115       prim.appendChild(textChild);
00116       //      elt.removeChild(textChild);
00117       DOM_Node parent = elt.getParentNode();
00118       DOM_Node oldChild =  parent.replaceChild(prim, elt);
00119     }
00120   }
00121 }   // end of anonymous namespace
00122 
00123 namespace xmlUtil {
00124 
00125   Constants::Constants(DOM_Document doc) : m_doc(doc) {
00126     DOM_NodeList list = m_doc.getElementsByTagName("constants");
00127 
00128     m_constants = (list.getLength() > 0) ? 
00129        static_cast<const DOM_Element &> (list.item(0)) : DOM_Element();
00130   }
00131 
00132   void Constants::normalizePrimary()
00133   {
00134     // find <primary>
00135     if (m_constants == DOM_Node()) return;
00136 
00137     DOM_NodeList primarys = m_constants.getElementsByTagName("primary");
00138 
00139     // must be precisely one <primary> element
00140     DOM_Node curNode = primarys.item(0);
00141     DOM_Element primary = static_cast<DOM_Element &>(curNode);
00142     if (primary.getAttribute("normalized").equals(DOMString("true"))) return;
00143 
00144     // Make a DOMTreeWalker which returns only elements
00145     unsigned long whatToShow = 1 << (DOM_Node::ELEMENT_NODE -1);
00146     
00147     DOM_TreeWalker walker = 
00148       m_doc.createTreeWalker(curNode, whatToShow, 0, 0);
00149     
00150     // Diagnostic -- number of <prim>s seen
00151     int count = 0;
00152     std::vector<DOM_Element> energyElts;
00153     while (curNode != DOM_Node() ) {
00154       count += normPrim(static_cast<DOM_Element &> (curNode), energyElts);
00155       curNode = walker.nextNode();
00156     }
00157     handleEnergies(energyElts);
00158 
00159     primary.setAttribute("normalized", "true");
00160     //    std::cout << "Results of normalizePrim: " << count << std::endl;
00161     //    return (count < 100000);
00162   }
00163  
00164   // Remove children of evaluated constants
00165   void Constants::pruneConstants(bool keepNotes) { 
00166 
00167     if (m_constants == DOM_Node()) return;
00168 
00169     DOM_Element curConst;
00170     
00171     // For each derCategory, prune each const child
00172     DOM_NodeList cats = m_constants.getElementsByTagName("derCategory");
00173     int nCats = cats.getLength();
00174     int iCat;
00175     
00176     for (iCat = 0; iCat < nCats; iCat++) {
00177       DOM_Node catNode = cats.item(iCat);
00178       DOM_Element& curCat = static_cast<DOM_Element&> (catNode);
00179       curConst = xml::Dom::findFirstChildByName(curCat, "const" );
00180       
00181       while (curConst != DOM_Element()) {
00182         if (keepNotes) { // tread more carefully
00183           DOM_Element child = xml::Dom::getFirstChildElement(curConst);
00184           if (child != DOM_Element() ) {
00185             if ((child.getTagName()).equals(DOMString("notes"))) {
00186               child = xml::Dom::getSiblingElement(child);
00187               if (child != DOM_Element()) {
00188                 xml::Dom::prune(child);
00189                 (child.getParentNode()).removeChild(child);
00190               }
00191             }
00192             else {
00193               xml::Dom::prune(curConst);  // remove all its children
00194             }
00195           }
00196         }
00197         else {  // remove all its children
00198           xml::Dom::prune(curConst);  
00199         }
00200         curConst = xml::Dom::getSiblingElement(curConst);
00201       }
00202     }
00203   }
00204 
00207   void Constants::evalConstants() {
00208     if (m_constants == DOM_Node()) return;
00209     DOM_Element derived = 
00210       xml::Dom::findFirstChildByName(m_constants, "derived"); 
00211     if (derived == DOM_Element()) return; 
00212     if ((derived.getAttribute("evaluated")).equals(DOMString("true"))) return;
00213 
00214     DOM_Element curConst;
00215 
00216     DOM_NodeList cats = m_doc.getElementsByTagName("derCategory");
00217     int nCats = cats.getLength();
00218     int iCat;
00219     
00220     for (iCat = 0; iCat < nCats; iCat++) {
00221       DOM_Node catNode = cats.item(iCat);
00222       DOM_Element& curCat = static_cast<DOM_Element&> (catNode); 
00223       curConst = xml::Dom::findFirstChildByName(curCat, "const" );
00224       
00225       while (curConst != DOM_Element()) {
00226         Arith curArith(curConst);
00227         double evalValue = curArith.evaluate();
00228         curArith.saveValue();
00229         
00230         curConst = xml::Dom::getSiblingElement(curConst);
00231       }
00232     }
00233     derived.setAttribute("evaluated", "true");
00234   }
00235 
00236 
00237 }
00238 

Generated on Wed Oct 16 14:02:47 2002 by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001