1 #include "DDaceXMLHandler.h"
2 #include <cstdlib>
3 #include <cstring>
4 #include <iostream>
5 #include <hash_set>
6 #include "UniformDistribution.h"
7 #include "NormalDistribution.h"
8 #include "DDaceLHSampler.h"
9 #include "DDaceRandomSampler.h"
10 #include "DDaceOASampler.h"
11 #include "DDaceFactorialSampler.h"
12 #include "DDaceUserInputSampler.h"
13 #include "SmartPtr.h"
14 #include "DDaceRunStatus.h"
15 
16 using namespace std;
17 
18 struct eqstr
19 {
operator ()eqstr20   bool operator()(const std::string s1, const string s2) const
21   {
22     return s1.compare(s2) == 0;
23   }
24 };
25 
26 std::hash_set<std::string, hash<string>, eqstr> DDaceXMLHandler::samplerTypes_;
27 
28 
DDaceXMLHandler()29 DDaceXMLHandler::DDaceXMLHandler()
30   : samplerName_("null"), samplerParams_(), varNames_(), varDist_(),
31     outputNames_(), archiveFilename_("ddaceArchive"), currentTag_(-1),
32     charStr_(), pts_(), results_(), status_(),isSamplePt_(false),
33     isSampleResult_(false), isArchiveFile_(false), getPtsComplete_(false)
34 {
35   try
36     {
37       if (samplerTypes_.size()==0)
38 	{
39 	  samplerTypes_.insert("Random", "blah");
40 	  samplerTypes_.insert("LatinHypercube", "blah");
41 	  samplerTypes_.insert("OrthogonalArray", "blah");
42 	  samplerTypes_.insert("Factorial", "blah");
43 	  samplerTypes_.insert("UserInputSampler", "blah");
44 
45 	}
46     }
47   catch(std::exception& e)
48     {
49 	std::cerr << e.what();
50     }
51 }
52 
53 
54 
createObject()55 DDace DDaceXMLHandler::createObject()
56 {
57   try
58     {
59       DDaceSampler sampler = createSampler();
60       DDace ddaceObj(sampler, varNames_, outputNames_, archiveFilename_);
61 
62       // Through the process of creating ddaceObj, the pts_ have been
63       // created:
64 
65       getPtsComplete_ = true;
66       // if we are reading from an archive file, then we need to
67       // store the pts_, results_, and status_ values in the DDace
68       // object.  Otherwise, these will be given default values
69       // with the above creation of the ddaceObj, and will be
70       // filled in as the runs are completed.
71       if(isArchiveFile_)
72 	{
73 	  if(getPtsComplete_)
74 	    {
75 	      for (int i=0; i<pts_.length(); i++)
76 		{
77 		  ddaceObj.storeFunctionValue(pts_[i], results_[i]);
78 		  ddaceObj.recordRunStatus(pts_[i], status_[i]);
79 		}
80 	    }
81 	}
82       return ddaceObj;
83     }
84   catch(std::exception& e)
85     {
86 	std::cerr << "An error occurred: " << e.what();
87     }
88   return DDace(); // -Wall
89 }
90 
createSampler() const91 DDaceSampler DDaceXMLHandler::createSampler() const
92 {
93   try
94     {
95       DDaceSampler sampler;
96 
97       if (samplerParams_.containsKey("seed"))
98 	{
99 	  int seed = atoi(samplerParams_.get("seed"));
100 	  DistributionBase::setSeed(seed);
101 	}
102 
103       if (samplerName_ == "Random")
104 	{
105 	  int nSamples = atoi(samplerParams_.get("samples"));
106 	  sampler = DDaceRandomSampler(nSamples, varDist_);
107 	}
108       else if (samplerName_ == "LatinHypercube")
109 	{
110 	  int nSamples = atoi(samplerParams_.get("samples"));
111 	  int nReps = atoi(samplerParams_.get("replications"));
112 	  bool noise = false;
113 	  if (samplerParams_.containsKey("perturb"))
114 	    {
115 	      noise = atob(samplerParams_.get("perturb"));
116 	    }
117 	  sampler = DDaceLHSampler(nSamples, nReps, noise, varDist_);
118 	}
119       else if (samplerName_ == "OrthogonalArray")
120 	{
121 	  int nSamples = atoi(samplerParams_.get("samples"));
122 	  bool noise = false;
123 	  if (samplerParams_.containsKey("perturb"))
124 	    {
125 	      noise = atob(samplerParams_.get("perturb"));
126 	    }
127 	  sampler = DDaceOASampler(nSamples, noise, varDist_);
128 	}
129       else if (samplerName_ == "Factorial")
130 	{
131 	  int nSamples = atoi(samplerParams_.get("samples"));
132 	  int nReps = atoi(samplerParams_.get("symbols"));
133 	  bool noise = false;
134 	  if (samplerParams_.containsKey("perturb"))
135 	    {
136 	      noise = atob(samplerParams_.get("perturb"));
137 	    }
138 	  sampler = DDaceFactorialSampler(nSamples, nReps, noise, varDist_);
139 	}
140       else if (samplerName_ == "UserInputSampler")
141 	{
142 	  std::string filename = samplerParams_.get("filename");
143 	  sampler = DDaceUserInputSampler(filename);
144 	}
145       else
146 	{
147 	  throw runtime_error("unrecognized sampler type in DDaceXMLHandler::createSampler()");
148 	}
149       return sampler;
150     }
151   catch(std::exception& e)
152     {
153 	cerr << "In DDaceXMLHandler::createSampler(): " << e.what() << endl;
154     }
155 
156   return DDaceSampler();
157 }
158 
getVarNames() const159 Array<std::string> DDaceXMLHandler::getVarNames() const
160 {
161   return varNames_;
162 }
163 
getOutputNames() const164 Array<std::string> DDaceXMLHandler::getOutputNames() const
165 {
166   return outputNames_;
167 }
168 
startElement(const std::string & name,const Hashtable & attributes)169 void DDaceXMLHandler::startElement(const std::string& name,
170 				   const Hashtable& attributes)
171 {
172   try
173     {
174       if (samplerTypes_.containsKey(name))
175 	{
176 	  samplerParams_ = attributes;
177 	  samplerName_ = name;
178 
179 	  int samples = atoi(attributes.get("samples"));
180 	  pts_.resize(samples);
181 	  results_.resize(samples);
182 	  status_.resize(samples);
183 	  // give default values to elements of status_
184 	  for(int j=0; j < samples; j++)
185 	    status_[j] = DDaceRunNotStarted;
186 	}
187       else if (name == "Variable")
188 	{
189 	  varNames_.append(attributes.get("name"));
190 
191 	  if (attributes.containsKey("distribution")
192 	      && attributes.get("distribution") != "uniform")
193 	    {
194 	      std::string distType = attributes.get("distribution");
195 	      if (distType == "normal")
196 		{
197 		  if (attributes.containsKey("mean")
198 		      && attributes.containsKey("sigma"))
199 		    {
200 		      double mean = atof(attributes.get("mean"));
201 		      double sigma = atof(attributes.get("sigma"));
202 		      double nDev = atof(attributes.get("cutoff"));
203 		      varDist_.append(NormalDistribution(Mean(mean),
204 							 StdDeviation(sigma),
205 							 nDev));
206 		    }
207 		  else if (attributes.containsKey("upper") && attributes.containsKey("lower"))
208 		    {
209 		      double lower = atof(attributes.get("lower"));
210 		      double upper = atof(attributes.get("upper"));
211 		      if (attributes.containsKey("nDev"))
212 			{
213 			  double nDev = atof(attributes.get("cutoff"));
214 			  varDist_.append(NormalDistribution(lower, upper, nDev));
215 			}
216 		      else
217 			{
218 			  varDist_.append(NormalDistribution(lower, upper));
219 			}
220 		    }
221 		  else
222 		    {
223 		      ExceptionBase::raise("invalid xml specification of normally distributed variable");
224 		    }
225 		}
226 	      else
227 		{
228 		  ExceptionBase::raise("unrecognized xml specification of distribution type");
229 		}
230 	    }
231 	  else if ( samplerName_ == "UserInputSampler" )
232 	    {
233 	      // no distribution information required for UserInputSampler
234 	    }
235 	  else /* uniform distribution */
236 	    {
237 	      double lower = atof(attributes.get("lower"));
238 	      double upper = atof(attributes.get("upper"));
239 	      varDist_.append(UniformDistribution(lower, upper));
240 
241 	    }
242 	}
243       else if (name == "Archive")
244 	{
245 	  archiveFilename_ = attributes.get("name");
246 	}
247       else if (name == "Output")
248 	{
249 	  outputNames_.append(attributes.get("name"));
250 	}
251       else if (name == "Sample")
252 	{
253 	  currentTag_ = atoi(attributes.get("tag"));
254 	}
255       else if (name == "SamplePoint")
256 	{
257 	  isSamplePt_ = true;
258 	  charStr_ = "";
259 	}
260       else if (name == "SampleResult")
261 	{
262 	  isArchiveFile_ = true;
263 	  if (currentTag_ == -1)
264 	    ExceptionBase::raise("Index tag corresponding to current "
265 				 "sample is -1.");
266 	  String statusString = attributes.get("status");
267 	  if (statusString == "Run OK")
268 	    status_[currentTag_] = DDaceRunOK;
269 	  else if (statusString == "Run failed")
270 	    status_[currentTag_] = DDaceRunFailed;
271 	  else if (statusString == "Post processing failed")
272 	    status_[currentTag_] = DDacePostProcFailed;
273 	  else if (statusString == "Run not started")
274 	    status_[currentTag_] = DDaceRunNotStarted;
275 	  else if (statusString == "Run pending")
276 	    status_[currentTag_] = DDaceRunPending;
277 	  else
278 	    ExceptionBase::raise("unrecognized sample status inside "
279 				 "SampleResult for "
280 				 "DDaceXMLHandler::startElement()");
281 	  isSampleResult_ = true;
282 	  charStr_= "";
283 	}
284     }
285   catch(ExceptionBase& e)
286     {
287       e.trace("in DDaceXMLHandler::startElement( tag = " + name + ")");
288     }
289 }
290 
characters(const String & chars,const unsigned int length)291 void DDaceXMLHandler::characters(const String& chars,
292 				 const unsigned int length)
293 {
294 
295   if(isSamplePt_ || isSampleResult_)
296     charStr_ += chars;
297 }
298 
endElement(const String & name)299 void DDaceXMLHandler::endElement(const String& name )
300 {
301   if (name == "SamplePoint")
302     {
303       if (currentTag_ == -1)
304 	ExceptionBase::raise("Index tag corresponding to current "
305 			     "sample is -1.");
306       Array<double> tempPt;
307       Array<String> charStrLines = StrUtils::splitIntoLines(charStr_);
308       tempPt.resize(charStrLines.length());
309       for(int i=0; i < charStrLines.length(); i++)
310 	tempPt[i] = atof(charStrLines[i]);
311       DDaceSamplePoint point(currentTag_, tempPt);
312       pts_[currentTag_] = point;
313 
314       // reset these variables as we exit the SamplePoint block...
315       isSamplePt_ = false;
316       charStr_="";
317     }
318   if (name == "SampleResult")
319     {
320       if (currentTag_ == -1)
321 				ExceptionBase::raise("Index tag corresponding to current "
322 														 "sample is -1.");
323       Array<String> charStrLines = StrUtils::splitIntoLines(charStr_);
324       results_[currentTag_].resize(charStrLines.length());
325       for(int i=0; i < charStrLines.length(); i++)
326 	results_[currentTag_][i] = atof(charStrLines[i]);
327 
328       // reset these variables as we exit the SamplePoint block...
329       isSampleResult_ = false;
330       charStr_="";
331     }
332   if (name == "Results")
333     {
334       // if we've reached the end of the Results section, and
335       // the currentTag_ is one less than the number of pts_,
336       // we've read in all (and the appropriate number) of the
337       // pts_ values from the archive file.
338       if(currentTag_ == (pts_.length() - 1))
339 	getPtsComplete_ = true;
340     }
341 }
342 
343 
344 
345