00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "boost/spirit/core.hpp"
00012
00013
00014 #include "DDLMap.h"
00015 #include "DDLElementRegistry.h"
00016
00017
00018 #include "DetectorDescription/Core/interface/DDMap.h"
00019 #include "DetectorDescription/Base/interface/DDdebug.h"
00020 #include "DetectorDescription/Base/interface/DDException.h"
00021 #include "CLHEP/Units/SystemOfUnits.h"
00022 #include "DetectorDescription/ExprAlgo/interface/ExprEvalSingleton.h"
00023
00024 #include <map>
00025 #include <string>
00026
00027 using namespace boost::spirit;
00028
00029
00030 DDLMap::DDLMap()
00031 {
00032 }
00033
00034 DDLMap::~DDLMap()
00035 {
00036 }
00037
00038 template <typename ScannerT> struct Mapper::definition
00039 {
00040 definition(Mapper const& self)
00041 {
00042 mapSet
00043 = ppair[MapPair()]
00044 >> *((',' >> ppair)[MapPair()])
00045 ;
00046
00047 ppair
00048 = name
00049 >> ch_p('=') >> value
00050 ;
00051
00052 name
00053 = (alpha_p >> *alnum_p)[MapMakeName()]
00054 ;
00055
00056 value
00057 = (+(anychar_p - ','))[MapMakeDouble()]
00058 ;
00059
00060 }
00061
00062 rule<ScannerT> mapSet, ppair, name, value;
00063
00064 rule<ScannerT> const&
00065 start() const { return mapSet; }
00066 };
00067
00068
00069 void MapPair::operator() (char const* str, char const* end) const
00070 {
00071 DDLMap* myDDLMap = dynamic_cast < DDLMap* > (DDLElementRegistry::instance()->getElement("Map"));
00072 myDDLMap->do_pair(str, end);
00073 }
00074
00075 void MapMakeName::operator() (char const* str, char const* end) const
00076 {
00077 DDLMap* myDDLMap = dynamic_cast < DDLMap* > (DDLElementRegistry::instance()->getElement("Map"));
00078 myDDLMap->do_makeName(str, end);
00079 }
00080
00081 void MapMakeDouble::operator() (char const* str, char const* end)const
00082 {
00083 DDLMap* myDDLMap = dynamic_cast < DDLMap* > (DDLElementRegistry::instance()->getElement("Map"));
00084 myDDLMap->do_makeDouble(str, end);
00085 }
00086
00087 void DDLMap::preProcessElement (const std::string& name, const std::string& nmspace)
00088 {
00089 pName = "";
00090 pMap.clear() ;
00091
00092 pDouble = 0.0;
00093 pNameSpace = nmspace;
00094 }
00095
00096 void DDLMap::processElement (const std::string& name, const std::string& nmspace)
00097 {
00098 DCOUT_V('P', "DDLMap::processElement started");
00099
00100 std::string tTextToParse = getText();
00101 DDXMLAttribute atts = getAttributeSet();
00102 std::string tName = atts.find("name")->second;
00103
00104 if (tTextToParse.size() == 0)
00105 {
00106 errorOut("No std::string to parse!");
00107 }
00108
00109
00110 if (atts.find("type") != atts.end() && atts.find("type")->second == "string")
00111 {
00112 errorOut("Map of type std::string is not supported yet.");
00113 }
00114
00115 Mapper mapGrammar;
00116
00117 pMap.clear();
00118
00119 parse_info<> info = boost::spirit::parse(tTextToParse.c_str(), mapGrammar >> end_p, space_p);
00120 if (!info.full)
00121 {
00122 errorOut("Does not conform to name=value, name=value... etc. of ddl Map element.");
00123 }
00124
00125 if (parent() == "Algorithm" || parent() == "SpecPar")
00126 {
00127 pMapMap[tName] = pMap;
00128 }
00129 else if (parent() == "ConstantsSection" || parent() == "DDDefinition")
00130 {
00131 dd_map_type * tMap = new dd_map_type;
00132 for (std::map<std::string, double>::const_iterator it = pMap.begin(); it != pMap.end(); ++it)
00133 {
00134 (*tMap)[it->first] = it->second;
00135 }
00136 DDMap m ( getDDName(pNameSpace) , tMap);
00137
00138 pMapMap.clear();
00139 }
00140
00141 std::string nEntries = atts.find("nEntries")->second;
00142 if (pMap.size() !=
00143 size_t(ExprEvalSingleton::instance().eval(pNameSpace, nEntries)))
00144 {
00145 errorOut("Number of entries found in Map text does not match number in attribute nEntries.");
00146 }
00147 clear();
00148
00149 DCOUT_V('P', "DDLMap::processElement completed");
00150 }
00151
00152 void DDLMap::do_pair(char const* str, char const* end)
00153 {
00154 pMap[pName] = pDouble;
00155 }
00156
00157 void DDLMap::do_makeName(char const* str, char const* end)
00158 {
00159 pName = std::string(str, end);
00160 }
00161
00162 void DDLMap::do_makeDouble(char const* str, char const* end)
00163 {
00164 std::string ts(str, end);
00165 pDouble = ExprEvalSingleton::instance().eval(pNameSpace, ts);
00166 }
00167
00168 void DDLMap::errorOut(const char* str)
00169 {
00170 std::string msg("\nDDLMap: Failed to parse the following: \n");
00171 msg+= std::string(str);
00172 msg+="\n as a Map element (comma separated list of name=value).";
00173 throwError(msg);
00174 }
00175
00176 ReadMapType< std::map<std::string,double> > & DDLMap::getMapOfMaps()
00177 {
00178 return pMapMap;
00179 }