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