1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
10 #include <anna/statistics/Engine.hpp>
11 #include <anna/statistics/internal/sccs.hpp>
12 #include <anna/core/mt/Guard.hpp>
13 #include <anna/core/functions.hpp>
14 #include <anna/xml/xml.hpp>
21 using namespace anna::statistics;
24 //******************************************************************************
25 //----------------------------------------------------------------------- Engine
26 //******************************************************************************
28 //------------------------------------------------------------------------------
29 //------------------------------------------------------------- Engine::Engine()
30 //------------------------------------------------------------------------------
32 statistics::sccs::activate();
34 a_sequence_concept_id = 0;
38 //------------------------------------------------------------------------------
39 //------------------------------------------------------------ Engine::~Engine()
40 //------------------------------------------------------------------------------
42 for (_accumulator_map_it it = a_accumulators.begin(); it != a_accumulators.end(); it++)
47 //------------------------------------------------------------------------------
48 //--------------------------------------------------------- Engine::addConcept()
49 //------------------------------------------------------------------------------
50 int Engine::addConcept(const std::string & description, const std::string & unit, const bool & integerNatureSample) throw() {
51 a_sequence_concept_id++;
52 _concept_identification_t aux;
53 aux.SampleFile = ""; // sample dump disabled by default for new concepts
54 aux.Description = description;
56 aux.IntegerNatureSample = integerNatureSample;
57 a_concept_identification_map[a_sequence_concept_id] = aux;
58 return (a_sequence_concept_id);
62 //------------------------------------------------------------------------------
63 //--------------------------------------------------------- Engine::getConcept()
64 //------------------------------------------------------------------------------
65 bool Engine::getConcept(const int & id, std::string & description, std::string & unit, bool & integerNatureSample) const throw() {
66 _concept_identification_map_iter it = a_concept_identification_map.find(id);
68 if(it == a_concept_identification_map.end()) return false;
70 description = (*it).second.Description;
71 unit = (*it).second.Unit;
72 integerNatureSample = (*it).second.IntegerNatureSample;
77 //------------------------------------------------------------------------------
78 //---------------------------------------------------- Engine::enableSampleLog()
79 //------------------------------------------------------------------------------
80 bool Engine::enableSampleLog(const int & id, const char *sampleFileName) throw() {
81 _concept_identification_map_nc_iter it;
82 std::string providedName = sampleFileName ? sampleFileName : "sample";
83 std::string *SampleFile_ptr;
84 std::string realName = "";
87 it = a_concept_identification_map.find(id);
89 if(it == a_concept_identification_map.end()) return false;
91 if(providedName != "") realName = anna::functions::asString("%s.%d.csv", providedName.c_str(), id);
94 SampleFile_ptr = &((*it).second.SampleFile);
95 *SampleFile_ptr = realName;
100 _concept_identification_map_nc_iter it_min(a_concept_identification_map.begin());
101 _concept_identification_map_nc_iter it_max(a_concept_identification_map.end());
103 for(it = it_min; it != it_max; it++) {
106 if(providedName != "") realName = anna::functions::asString("%s.%d.csv", providedName.c_str(), (*it).first);
108 SampleFile_ptr = &((*it).second.SampleFile);
109 *SampleFile_ptr = realName;
116 //------------------------------------------------------------------------------
117 //--------------------------------------------------- Engine::disableSampleLog()
118 //------------------------------------------------------------------------------
119 bool Engine::disableSampleLog(const int & id) throw() {
120 _concept_identification_map_nc_iter it = a_concept_identification_map.find(id);
122 if(it == a_concept_identification_map.end()) return false;
125 std::string *SampleFile_ptr = &((*it).second.SampleFile);
126 *SampleFile_ptr = "";
131 //------------------------------------------------------------------------------
132 //--------------------------------------------------- Engine::disableSampleLog()
133 //------------------------------------------------------------------------------
134 bool Engine::logSample(const int & conceptId, const anna::Millisecond & unixTimestamp, const double & value) const throw() {
135 anna::Guard guard(a_mutex);
137 _concept_identification_map_iter it = a_concept_identification_map.find(conceptId);
139 if(it == a_concept_identification_map.end()) return false;
141 std::string target = (*it).second.SampleFile;
143 if(target != "") { // enabled
144 std::ofstream out(target.c_str(), std::ifstream::out | std::ifstream::app);
145 // Write and close (quiza no deberia cerrar cada vez...)
146 std::string log = anna::functions::asString(unixTimestamp);
148 log += anna::functions::asString(value, (*it).second.IntegerNatureSample ? "%.0f" : "%e");
150 out.write(log.c_str(), log.size());
158 //------------------------------------------------------------------------------
159 //-------------------------------------------------- Engine::createAccumulator()
160 //------------------------------------------------------------------------------
161 Accumulator *Engine::createAccumulator(const std::string &name) throw(anna::RuntimeException) {
162 Accumulator *result = getAccumulator(name);
165 throw anna::RuntimeException(anna::functions::asString("Cannot register another accumulator with the same name: %s", name.c_str()), ANNA_FILE_LOCATION);
167 result = new Accumulator(name);
168 a_accumulators[name] = result;
172 Accumulator* Engine::getAccumulator(const std::string &name) throw() {
173 Accumulator *result = NULL;
175 _accumulator_map_nc_it it = a_accumulators.find(name);
176 if (it != a_accumulators.end())
183 //------------------------------------------------------------------------------
184 //----------------------------------------------------------- Engine::asString()
185 //------------------------------------------------------------------------------
186 std::string Engine::asString(void) const throw() {
188 _concept_identification_map_iter iter;
189 _concept_identification_map_iter iter_min(a_concept_identification_map.begin());
190 _concept_identification_map_iter iter_max(a_concept_identification_map.end());
191 trace = "\n=============================";
192 trace += "\nStatistic Engine Information";
193 trace += "\n============================";
196 trace += "\nWARNING: engine is disabled !";
198 if(a_concept_identification_map.size() == 0) {
199 trace += "\nNo concepts found (empty map)";
203 trace += "\nNumber of elements (registered concepts) = "; trace += anna::functions::asString(a_concept_identification_map.size());
205 for(iter = iter_min; iter != iter_max; iter++) {
207 trace += "\n Concept id: "; trace += anna::functions::asString((*iter).first);
209 if((*iter).second.SampleFile != "") trace += "\n Sample file: "; trace += (*iter).second.SampleFile;
211 trace += "\n Description: "; trace += (*iter).second.Description;
212 trace += "\n Unit: "; trace += (*iter).second.Unit;
213 trace += "\n Integer Nature Sample: "; trace += (*iter).second.IntegerNatureSample ? "yes" : "no";
219 trace += "\nNumber of accumulators= "; trace += anna::functions::asString(a_accumulators.size());
220 for (_accumulator_map_it it = a_accumulators.begin(); it != a_accumulators.end(); it++) {
222 trace += it->second->asString();
229 //------------------------------------------------------------------------------
230 //-------------------------------------------------------------- Engine::asXML()
231 //------------------------------------------------------------------------------
232 anna::xml::Node* Engine::asXML(anna::xml::Node* parent, const int & numberOfDecimals) const throw() {
233 anna::xml::Node* result = parent->createChild("anna.statistics.Engine");
234 _concept_identification_map_iter iter;
235 _concept_identification_map_iter iter_min(a_concept_identification_map.begin());
236 _concept_identification_map_iter iter_max(a_concept_identification_map.end());
237 int size = a_concept_identification_map.size();
238 result->createAttribute("State", enabled() ? "Enabled" : "Disabled");
239 anna::xml::Node* registeredConcepts = result->createChild("ConceptsList");
240 registeredConcepts->createAttribute("Size", (size > 0) ? anna::functions::asString(size) : "No concepts found (empty map)");
242 for(iter = iter_min; iter != iter_max; iter++) {
243 anna::xml::Node* concept = registeredConcepts->createChild("Concept");
244 concept->createAttribute("Id", anna::functions::asString((*iter).first));
246 if((*iter).second.SampleFile != "") concept->createAttribute("SampleFile", (*iter).second.SampleFile);
248 concept->createAttribute("Description", (*iter).second.Description);
249 concept->createAttribute("Unit", (*iter).second.Unit);
250 concept->createAttribute("IntegerNatureSample", (*iter).second.IntegerNatureSample ? "yes" : "no");
254 anna::xml::Node* accumulators = result->createChild("anna.statistics.Accumulators");
255 accumulators->createAttribute("RegisteredAccumulators", a_accumulators.size());
256 for (_accumulator_map_it it = a_accumulators.begin(); it != a_accumulators.end(); it++)
257 it->second->asXML(accumulators);