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());
102 for(it = it_min; it != it_max; it++) {
104 if(providedName != "") realName = anna::functions::asString("%s.%d.csv", providedName.c_str(), (*it).first);
105 SampleFile_ptr = &((*it).second.SampleFile);
106 *SampleFile_ptr = realName;
113 //------------------------------------------------------------------------------
114 //--------------------------------------------------- Engine::disableSampleLog()
115 //------------------------------------------------------------------------------
116 bool Engine::disableSampleLog(const int & id) throw() {
119 _concept_identification_map_nc_iter it = a_concept_identification_map.find(id);
121 if(it == a_concept_identification_map.end()) return false;
124 std::string *SampleFile_ptr = &((*it).second.SampleFile);
125 *SampleFile_ptr = "";
130 return enableSampleLog(id /* -1 */, "");
134 //------------------------------------------------------------------------------
135 //--------------------------------------------------- Engine::disableSampleLog()
136 //------------------------------------------------------------------------------
137 bool Engine::logSample(const int & conceptId, const anna::Millisecond & unixTimestamp, const double & value) const throw() {
138 anna::Guard guard(a_mutex);
140 _concept_identification_map_iter it = a_concept_identification_map.find(conceptId);
142 if(it == a_concept_identification_map.end()) return false;
144 std::string target = (*it).second.SampleFile;
146 if(target != "") { // enabled
147 std::ofstream out(target.c_str(), std::ifstream::out | std::ifstream::app);
148 // Write and close (quiza no deberia cerrar cada vez...)
149 std::string log = anna::functions::asString(unixTimestamp);
151 log += anna::functions::asString(value, (*it).second.IntegerNatureSample ? "%.0f" : "%e");
153 out.write(log.c_str(), log.size());
161 //------------------------------------------------------------------------------
162 //-------------------------------------------------- Engine::createAccumulator()
163 //------------------------------------------------------------------------------
164 Accumulator *Engine::createAccumulator(const std::string &name) throw(anna::RuntimeException) {
165 Accumulator *result = getAccumulator(name);
168 throw anna::RuntimeException(anna::functions::asString("Cannot register another accumulator with the same name: %s", name.c_str()), ANNA_FILE_LOCATION);
170 result = new Accumulator(name);
171 a_accumulators[name] = result;
175 Accumulator* Engine::getAccumulator(const std::string &name) throw() {
176 Accumulator *result = NULL;
178 _accumulator_map_nc_it it = a_accumulators.find(name);
179 if (it != a_accumulators.end())
186 //------------------------------------------------------------------------------
187 //----------------------------------------------------------- Engine::asString()
188 //------------------------------------------------------------------------------
189 std::string Engine::asString(void) const throw() {
191 _concept_identification_map_iter iter;
192 _concept_identification_map_iter iter_min(a_concept_identification_map.begin());
193 _concept_identification_map_iter iter_max(a_concept_identification_map.end());
194 trace = "\n=============================";
195 trace += "\nStatistic Engine Information";
196 trace += "\n============================";
199 trace += "\nWARNING: engine is disabled !";
201 if(a_concept_identification_map.size() == 0) {
202 trace += "\nNo concepts found (empty map)";
206 trace += "\nNumber of elements (registered concepts) = "; trace += anna::functions::asString(a_concept_identification_map.size());
208 for(iter = iter_min; iter != iter_max; iter++) {
210 trace += "\n Concept id: "; trace += anna::functions::asString((*iter).first);
212 if((*iter).second.SampleFile != "") trace += "\n Sample file: "; trace += (*iter).second.SampleFile;
214 trace += "\n Description: "; trace += (*iter).second.Description;
215 trace += "\n Unit: "; trace += (*iter).second.Unit;
216 trace += "\n Integer Nature Sample: "; trace += (*iter).second.IntegerNatureSample ? "yes" : "no";
222 trace += "\nNumber of accumulators= "; trace += anna::functions::asString(a_accumulators.size());
223 for (_accumulator_map_it it = a_accumulators.begin(); it != a_accumulators.end(); it++) {
225 trace += it->second->asString();
232 //------------------------------------------------------------------------------
233 //-------------------------------------------------------------- Engine::asXML()
234 //------------------------------------------------------------------------------
235 anna::xml::Node* Engine::asXML(anna::xml::Node* parent, const int & numberOfDecimals) const throw() {
236 anna::xml::Node* result = parent->createChild("anna.statistics.Engine");
237 _concept_identification_map_iter iter;
238 _concept_identification_map_iter iter_min(a_concept_identification_map.begin());
239 _concept_identification_map_iter iter_max(a_concept_identification_map.end());
240 int size = a_concept_identification_map.size();
241 result->createAttribute("State", enabled() ? "Enabled" : "Disabled");
242 anna::xml::Node* registeredConcepts = result->createChild("ConceptsList");
243 registeredConcepts->createAttribute("Size", (size > 0) ? anna::functions::asString(size) : "No concepts found (empty map)");
245 for(iter = iter_min; iter != iter_max; iter++) {
246 anna::xml::Node* concept = registeredConcepts->createChild("Concept");
247 concept->createAttribute("Id", anna::functions::asString((*iter).first));
249 if((*iter).second.SampleFile != "") concept->createAttribute("SampleFile", (*iter).second.SampleFile);
251 concept->createAttribute("Description", (*iter).second.Description);
252 concept->createAttribute("Unit", (*iter).second.Unit);
253 concept->createAttribute("IntegerNatureSample", (*iter).second.IntegerNatureSample ? "yes" : "no");
257 anna::xml::Node* accumulators = result->createChild("anna.statistics.Accumulators");
258 accumulators->createAttribute("RegisteredAccumulators", a_accumulators.size());
259 for (_accumulator_map_it it = a_accumulators.begin(); it != a_accumulators.end(); it++)
260 it->second->asXML(accumulators);