#include "trial.h"
using namespace std;
Trial::Trial()
{
ready = false;
}
bool Trial::isReady()
{
return ready;
}
bool Trial::load(string filename, string &error)
{
if (parseXML(filename, error))
{
this->filename = filename;
ready = true;
return true;
}
return false;
}
int Trial::count() {
return this->cTrials.size();
}
vector<Trial::ConstrainedTrial>* Trial::inputFactory(double T, double dt, double delay) {
this->genSignal( this->inputs.begin(), T, dt, delay );
/** Find the unconstrained parameters. **/
for (vector<Input>::iterator iter=this->inputs.begin(); iter != this->inputs.end(); ++iter) {
for (map<string, Range>::iterator iter2 = iter->unconstrained.begin(); iter2 != iter->unconstrained.end(); ++iter2) {
this->unconstrained[iter2->first] = iter2->second;
}
}
return &this->cTrials;
}
void Trial::genSignal(vector<Input>::iterator inputsPos, double T, double dt, double delay) {
// Get the vector of signals from this input.
vector<Input::Signal>* thisInput = (*inputsPos).inputs(T, dt, delay);
/** BASE CASE
* We are at the last input
* Nothing is in our inputs yet, so add these on
*/
if (inputsPos+1 == this->inputs.end()) {
// If we are in the last one, just add these to the input
vector< Input::Signal >::iterator iter;
for (iter = thisInput->begin(); iter < thisInput->end(); ++iter) {
ConstrainedTrial ci;
ci.signals.push_back(*iter); // At the base case, only one input
ci.values = iter->values; // Just takes on the values from this signal.
this->cTrials.push_back(ci);
}
}
/** RECURSIVE CASE
* First, finish it for everything below
* Then create new sets of the input for each of our
* local signals.
*/
else {
genSignal(++inputsPos, T, dt, delay); // Finish up below
unsigned int steps = (int)(T/dt);
// Copy of existing inputs
vector< ConstrainedTrial > oldSignals (this->cTrials);
// We'll be replacing the existing inputs so clear them out
this->cTrials.clear();
vector< Input::Signal >::iterator newIter; // The new input signals
vector< ConstrainedTrial >::iterator oldIter; // The old combined inputs
vector<double> newValues; // New values
for (newIter = thisInput->begin(); newIter < thisInput->end(); ++newIter) {
for (oldIter = oldSignals.begin(); oldIter < oldSignals.end(); ++oldIter) {
newValues.clear();
newValues.resize(steps, 0);
for (unsigned int t = 0; t < steps; ++t) {
newValues[t] = sqrt(newIter->values[t] + oldIter->values[t]);
}
ConstrainedTrial ci(*oldIter);
ci.signals.push_back(*newIter);
ci.values = newValues;
this->cTrials.push_back(ci); // Add on the input
}
}
}
}
string Trial::toString() {
string r;
vector<Input>::iterator iter;
for ( iter = this->inputs.begin(); iter != this->inputs.end(); ++iter) {
r += "== Input ==\n" + (*iter).toString() + "\n";
}
return r;
}
bool Trial::parseXML(string filename, string &error) {
TiXmlDocument doc(filename);
if (doc.LoadFile()) {
stringstream name;
double start, end, step;
TiXmlHandle hDoc(&doc);
TiXmlElement* pElem;
TiXmlElement* pElemParam;
TiXmlHandle hRoot(0);
TiXmlHandle hInput(0);
TiXmlHandle hParam(0);
// Find Root
pElem=hDoc.FirstChildElement().Element();
if (!pElem) {
error = "Invalid root.";
return false;
}
hRoot = pElem;
// Load Each Input
pElem = hRoot.FirstChild( "input" ).Element();
for( /***/; pElem; pElem = pElem->NextSiblingElement("input")) {
Input input;
hInput = pElem;
if (strcmp(pElem->Attribute("type"), "pure") == 0) {
input.type = Input::PURE;
}
if (strcmp(pElem->Attribute("type"), "pulse") == 0) {
input.type = Input::PULSE;
}
pElem->QueryValueAttribute("ID", &input.ID);
pElemParam = hInput.FirstChild( "param" ).Element();
for ( /***/; pElemParam; pElemParam = pElemParam->NextSiblingElement( "param" )) {
hParam = pElemParam;
// Found a Parameter Element With Text
if (pElemParam->FirstChild()->Type() == TiXmlNode::TEXT) {
if (strcmp(pElemParam->Attribute("name"),"duration") == 0) {
input.duration = Range((double)atof(pElemParam->FirstChild()->Value()));
}
if (strcmp(pElemParam->Attribute("name"),"delay") == 0) {
input.delay = Range((double)atof(pElemParam->FirstChild()->Value()));
}
if (strcmp(pElemParam->Attribute("name"),"amplitude") == 0) {
input.amplitude = Range((double)atof(pElemParam->FirstChild()->Value()));
}
// Found a Parameter Element With A Range Element
} else if (pElemParam->FirstChild()->Type() == TiXmlNode::ELEMENT) {
if (strcmp(pElemParam->FirstChild()->Value(), "range") == 0) {
start = 0;
end = 0;
step = 1;
hParam.FirstChild().Element()->QueryDoubleAttribute("start", &start);
hParam.FirstChild().Element()->QueryDoubleAttribute("end", &end);
hParam.FirstChild().Element()->QueryDoubleAttribute("step", &step);
if (strcmp(pElemParam->Attribute("name"),"duration") == 0) {
input.duration = Range(start, end, step);
}
if (strcmp(pElemParam->Attribute("name"),"delay") == 0) {
input.delay = Range(start, end, step);
}
if (strcmp(pElemParam->Attribute("name"),"amplitude") == 0) {
input.amplitude = Range(start, end, step);
}
}
}
} // Parameter Loop
this->inputs.push_back(input);
} // Input Loop
return true;
} else {
error = "Unable to find file or XML syntax error.";
return false;
}
}