1 // ANNA - Anna is Not Nothingness Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // http://redmine.teslayout.com/projects/anna-suite
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
38 #include <anna/statistics/Engine.hpp>
39 #include <anna/statistics/internal/sccs.hpp>
41 #include <anna/core/functions.hpp>
42 #include <anna/xml/xml.hpp>
49 using namespace anna::statistics;
52 //******************************************************************************
53 //----------------------------------------------------------------------- Engine
54 //******************************************************************************
56 statistics::sccs::activate();
58 a_sequence_concept_id = 0;
62 //------------------------------------------------------------------------------
63 //--------------------------------------------------------- Engine::addConcept()
64 //------------------------------------------------------------------------------
65 int Engine::addConcept(const std::string & description, const std::string & unit, const bool & integerNatureSample) throw() {
66 a_sequence_concept_id++;
67 _concept_identification_t aux;
68 aux.SampleFile = ""; // sample dump disabled by default for new concepts
69 aux.Description = description;
71 aux.IntegerNatureSample = integerNatureSample;
72 a_concept_identification_map[a_sequence_concept_id] = aux;
73 return (a_sequence_concept_id);
77 //------------------------------------------------------------------------------
78 //--------------------------------------------------------- Engine::getConcept()
79 //------------------------------------------------------------------------------
80 bool Engine::getConcept(const int & id, std::string & description, std::string & unit, bool & integerNatureSample) const throw() {
81 _concept_identification_map_iter it = a_concept_identification_map.find(id);
83 if(it == a_concept_identification_map.end()) return false;
85 description = (*it).second.Description;
86 unit = (*it).second.Unit;
87 integerNatureSample = (*it).second.IntegerNatureSample;
92 //------------------------------------------------------------------------------
93 //---------------------------------------------------- Engine::enableSampleLog()
94 //------------------------------------------------------------------------------
95 bool Engine::enableSampleLog(const int & id, const char *sampleFileName) throw() {
96 _concept_identification_map_nc_iter it;
97 std::string providedName = sampleFileName ? sampleFileName : "sample";
98 std::string *SampleFile_ptr;
99 std::string realName = "";
102 it = a_concept_identification_map.find(id);
104 if(it == a_concept_identification_map.end()) return false;
106 if(providedName != "") realName = anna::functions::asString("%s.%d.csv", providedName.c_str(), id);
109 SampleFile_ptr = &((*it).second.SampleFile);
110 *SampleFile_ptr = realName;
115 _concept_identification_map_nc_iter it_min(a_concept_identification_map.begin());
116 _concept_identification_map_nc_iter it_max(a_concept_identification_map.end());
118 for(it = it_min; it != it_max; it++) {
121 if(providedName != "") realName = anna::functions::asString("%s.%d.csv", providedName.c_str(), (*it).first);
123 SampleFile_ptr = &((*it).second.SampleFile);
124 *SampleFile_ptr = realName;
131 //------------------------------------------------------------------------------
132 //--------------------------------------------------- Engine::disableSampleLog()
133 //------------------------------------------------------------------------------
134 bool Engine::disableSampleLog(const int & id) throw() {
135 _concept_identification_map_nc_iter it = a_concept_identification_map.find(id);
137 if(it == a_concept_identification_map.end()) return false;
140 std::string *SampleFile_ptr = &((*it).second.SampleFile);
141 *SampleFile_ptr = "";
146 //------------------------------------------------------------------------------
147 //--------------------------------------------------- Engine::disableSampleLog()
148 //------------------------------------------------------------------------------
149 bool Engine::logSample(const int & conceptId, const anna::Millisecond & unixTimestamp, const double & value) const throw() {
150 _concept_identification_map_iter it = a_concept_identification_map.find(conceptId);
152 if(it == a_concept_identification_map.end()) return false;
154 std::string target = (*it).second.SampleFile;
156 if(target != "") { // enabled
157 std::ofstream out(target.c_str(), std::ifstream::out | std::ifstream::app);
158 // Write and close (quiza no deberia cerrar cada vez...)
159 std::string log = anna::functions::asString(unixTimestamp);
161 log += anna::functions::asString(value, (*it).second.IntegerNatureSample ? "%.0f" : "%e");
163 out.write(log.c_str(), log.size());
170 //------------------------------------------------------------------------------
171 //----------------------------------------------------------- Engine::asString()
172 //------------------------------------------------------------------------------
173 std::string Engine::asString(void) const throw() {
175 _concept_identification_map_iter iter;
176 _concept_identification_map_iter iter_min(a_concept_identification_map.begin());
177 _concept_identification_map_iter iter_max(a_concept_identification_map.end());
178 trace = "\n=============================";
179 trace += "\nStatistic Engine Information";
180 trace += "\n============================";
183 trace += "\nWARNING: engine is disabled !";
185 if(a_concept_identification_map.size() == 0) {
186 trace += "\nNo concepts found (empty map)";
190 trace += "\nNumber of elements (registered concepts) = "; trace += anna::functions::asString(a_concept_identification_map.size());
192 for(iter = iter_min; iter != iter_max; iter++) {
194 trace += "\n Concept id: "; trace += anna::functions::asString((*iter).first);
196 if((*iter).second.SampleFile != "") trace += "\n Sample file: "; trace += (*iter).second.SampleFile;
198 trace += "\n Description: "; trace += (*iter).second.Description;
199 trace += "\n Unit: "; trace += (*iter).second.Unit;
200 trace += "\n Integer Nature Sample: "; trace += (*iter).second.IntegerNatureSample ? "yes" : "no";
208 //------------------------------------------------------------------------------
209 //-------------------------------------------------------------- Engine::asXML()
210 //------------------------------------------------------------------------------
211 anna::xml::Node* Engine::asXML(anna::xml::Node* parent, const int & numberOfDecimals) const throw() {
212 anna::xml::Node* result = parent->createChild("anna.statistics.Engine");
213 _concept_identification_map_iter iter;
214 _concept_identification_map_iter iter_min(a_concept_identification_map.begin());
215 _concept_identification_map_iter iter_max(a_concept_identification_map.end());
216 int size = a_concept_identification_map.size();
217 result->createAttribute("State", enabled() ? "Enabled" : "Disabled");
218 anna::xml::Node* registeredConcepts = result->createChild("ConceptsList");
219 registeredConcepts->createAttribute("Size", (size > 0) ? anna::functions::asString(size) : "No concepts found (empty map)");
221 for(iter = iter_min; iter != iter_max; iter++) {
222 anna::xml::Node* concept = registeredConcepts->createChild("Concept");
223 concept->createAttribute("Id", anna::functions::asString((*iter).first));
225 if((*iter).second.SampleFile != "") concept->createAttribute("SampleFile", (*iter).second.SampleFile);
227 concept->createAttribute("Description", (*iter).second.Description);
228 concept->createAttribute("Unit", (*iter).second.Unit);
229 concept->createAttribute("IntegerNatureSample", (*iter).second.IntegerNatureSample ? "yes" : "no");