Changed LICENSE. Now referenced to web site and file on project root directory
[anna.git] / source / statistics / Engine.cpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
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 //
7
8
9 // Local
10 #include <anna/statistics/Engine.hpp>
11 #include <anna/statistics/internal/sccs.hpp>
12
13 #include <anna/core/functions.hpp>
14 #include <anna/xml/xml.hpp>
15
16 // Std
17 #include <iostream>
18 #include <fstream>
19
20
21 using namespace anna::statistics;
22
23
24 //******************************************************************************
25 //----------------------------------------------------------------------- Engine
26 //******************************************************************************
27 Engine::Engine() {
28   statistics::sccs::activate();
29   a_enabled = false;
30   a_sequence_concept_id = 0;
31 }
32
33
34 //------------------------------------------------------------------------------
35 //--------------------------------------------------------- Engine::addConcept()
36 //------------------------------------------------------------------------------
37 int Engine::addConcept(const std::string & description, const std::string & unit, const bool & integerNatureSample) throw() {
38   a_sequence_concept_id++;
39   _concept_identification_t aux;
40   aux.SampleFile = ""; // sample dump disabled by default for new concepts
41   aux.Description = description;
42   aux.Unit = unit;
43   aux.IntegerNatureSample = integerNatureSample;
44   a_concept_identification_map[a_sequence_concept_id] = aux;
45   return (a_sequence_concept_id);
46 }
47
48
49 //------------------------------------------------------------------------------
50 //--------------------------------------------------------- Engine::getConcept()
51 //------------------------------------------------------------------------------
52 bool Engine::getConcept(const int & id, std::string & description, std::string & unit, bool & integerNatureSample) const throw() {
53   _concept_identification_map_iter it = a_concept_identification_map.find(id);
54
55   if(it == a_concept_identification_map.end()) return false;
56
57   description = (*it).second.Description;
58   unit = (*it).second.Unit;
59   integerNatureSample = (*it).second.IntegerNatureSample;
60   return (true);
61 }
62
63
64 //------------------------------------------------------------------------------
65 //---------------------------------------------------- Engine::enableSampleLog()
66 //------------------------------------------------------------------------------
67 bool Engine::enableSampleLog(const int & id, const char *sampleFileName) throw() {
68   _concept_identification_map_nc_iter it;
69   std::string providedName = sampleFileName ? sampleFileName : "sample";
70   std::string *SampleFile_ptr;
71   std::string realName = "";
72
73   if(id != -1) {
74     it = a_concept_identification_map.find(id);
75
76     if(it == a_concept_identification_map.end()) return false;
77
78     if(providedName != "") realName = anna::functions::asString("%s.%d.csv", providedName.c_str(), id);
79
80     // Assignment
81     SampleFile_ptr = &((*it).second.SampleFile);
82     *SampleFile_ptr = realName;
83     return true;
84   }
85
86   // For all concepts:
87   _concept_identification_map_nc_iter it_min(a_concept_identification_map.begin());
88   _concept_identification_map_nc_iter it_max(a_concept_identification_map.end());
89
90   for(it = it_min; it != it_max; it++) {
91     realName = "";
92
93     if(providedName != "") realName = anna::functions::asString("%s.%d.csv", providedName.c_str(), (*it).first);
94
95     SampleFile_ptr = &((*it).second.SampleFile);
96     *SampleFile_ptr = realName;
97   }
98
99   return true;
100 }
101
102
103 //------------------------------------------------------------------------------
104 //--------------------------------------------------- Engine::disableSampleLog()
105 //------------------------------------------------------------------------------
106 bool Engine::disableSampleLog(const int & id) throw() {
107   _concept_identification_map_nc_iter it = a_concept_identification_map.find(id);
108
109   if(it == a_concept_identification_map.end()) return false;
110
111   // Access to map
112   std::string *SampleFile_ptr = &((*it).second.SampleFile);
113   *SampleFile_ptr = "";
114   return true;
115 }
116
117
118 //------------------------------------------------------------------------------
119 //--------------------------------------------------- Engine::disableSampleLog()
120 //------------------------------------------------------------------------------
121 bool Engine::logSample(const int & conceptId, const anna::Millisecond & unixTimestamp, const double & value) const throw() {
122   _concept_identification_map_iter it = a_concept_identification_map.find(conceptId);
123
124   if(it == a_concept_identification_map.end()) return false;
125
126   std::string target = (*it).second.SampleFile;
127
128   if(target != "") {  // enabled
129     std::ofstream out(target.c_str(), std::ifstream::out | std::ifstream::app);
130     // Write and close (quiza no deberia cerrar cada vez...)
131     std::string log = anna::functions::asString(unixTimestamp);
132     log += ",";
133     log += anna::functions::asString(value, (*it).second.IntegerNatureSample ? "%.0f" : "%e");
134     log += "\n";
135     out.write(log.c_str(), log.size());
136     out.close();
137   }
138
139   return true;
140 }
141
142 //------------------------------------------------------------------------------
143 //----------------------------------------------------------- Engine::asString()
144 //------------------------------------------------------------------------------
145 std::string Engine::asString(void) const throw() {
146   std::string trace;
147   _concept_identification_map_iter iter;
148   _concept_identification_map_iter iter_min(a_concept_identification_map.begin());
149   _concept_identification_map_iter iter_max(a_concept_identification_map.end());
150   trace =  "\n=============================";
151   trace +=  "\nStatistic Engine Information";
152   trace +=  "\n============================";
153
154   if(!enabled())
155     trace +=  "\nWARNING: engine is disabled !";
156
157   if(a_concept_identification_map.size() == 0) {
158     trace += "\nNo concepts found (empty map)";
159     return trace;
160   }
161
162   trace += "\nNumber of elements (registered concepts) = "; trace += anna::functions::asString(a_concept_identification_map.size());
163
164   for(iter = iter_min; iter != iter_max; iter++) {
165     trace += "\n";
166     trace += "\n   Concept id:            "; trace += anna::functions::asString((*iter).first);
167
168     if((*iter).second.SampleFile != "") trace += "\n   Sample file:           "; trace += (*iter).second.SampleFile;
169
170     trace += "\n   Description:           "; trace += (*iter).second.Description;
171     trace += "\n   Unit:                  "; trace += (*iter).second.Unit;
172     trace += "\n   Integer Nature Sample: "; trace += (*iter).second.IntegerNatureSample ? "yes" : "no";
173   }
174
175   trace += "\n";
176   return (trace);
177 }
178
179
180 //------------------------------------------------------------------------------
181 //-------------------------------------------------------------- Engine::asXML()
182 //------------------------------------------------------------------------------
183 anna::xml::Node* Engine::asXML(anna::xml::Node* parent, const int & numberOfDecimals) const throw() {
184   anna::xml::Node* result = parent->createChild("anna.statistics.Engine");
185   _concept_identification_map_iter iter;
186   _concept_identification_map_iter iter_min(a_concept_identification_map.begin());
187   _concept_identification_map_iter iter_max(a_concept_identification_map.end());
188   int size = a_concept_identification_map.size();
189   result->createAttribute("State", enabled() ? "Enabled" : "Disabled");
190   anna::xml::Node* registeredConcepts = result->createChild("ConceptsList");
191   registeredConcepts->createAttribute("Size", (size > 0) ? anna::functions::asString(size) : "No concepts found (empty map)");
192
193   for(iter = iter_min; iter != iter_max; iter++) {
194     anna::xml::Node* concept = registeredConcepts->createChild("Concept");
195     concept->createAttribute("Id", anna::functions::asString((*iter).first));
196
197     if((*iter).second.SampleFile != "") concept->createAttribute("SampleFile", (*iter).second.SampleFile);
198
199     concept->createAttribute("Description", (*iter).second.Description);
200     concept->createAttribute("Unit", (*iter).second.Unit);
201     concept->createAttribute("IntegerNatureSample", (*iter).second.IntegerNatureSample ? "yes" : "no");
202   }
203
204   return result;
205 }
206