00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "ArffFileSink.h"
00020
00021 #include <fstream>
00022 #include <iomanip>
00023
00024
00025 using std::ostringstream;
00026 using std::ofstream;
00027 using std::ios_base;
00028 using std::endl;
00029 using std::vector;
00030 using std::fixed;
00031 using std::setprecision;
00032
00033
00034 using namespace Marsyas;
00035
00036 ArffFileSink::ArffFileSink(mrs_string name) : MarSystem("ArffFileSink", name)
00037 {
00038 os_ = NULL;
00039 filename_ = "";
00040 decimationCounter = 0;
00041 addControls();
00042 }
00043
00044 ArffFileSink::ArffFileSink(const ArffFileSink& a) : MarSystem(a)
00045 {
00046 os_ = NULL;
00047 filename_ = "";
00048 decimationCounter = 0;
00049
00052 ctrl_floatPrecision_ = getControl("mrs_natural/floatPrecision");
00053 ctrl_decimationFactor_ = getControl("mrs_natural/decimationFactor");
00054 ctrl_filename_ = getControl("mrs_string/filename");
00055 }
00056
00057
00058 ArffFileSink::~ArffFileSink()
00059 {
00060 closeOutput();
00061 }
00062
00063 MarSystem*
00064 ArffFileSink::clone() const
00065 {
00066 return new ArffFileSink(*this);
00067 }
00068
00069 void
00070 ArffFileSink::addControls()
00071 {
00073 addControl("mrs_natural/floatPrecision", 6, ctrl_floatPrecision_);
00074 addControl("mrs_natural/decimationFactor", 1, ctrl_decimationFactor_);
00075 addControl("mrs_string/filename", "data.arff", ctrl_filename_);
00076 }
00077
00078 void
00079 ArffFileSink::myUpdate(MarControlPtr sender)
00080 {
00082 MarSystem::myUpdate(sender);
00083
00084
00085 floatPrecision_ = ctrl_floatPrecision_->to<mrs_natural>();
00086 decimationFactor_ = ctrl_decimationFactor_->to<mrs_natural>();
00087
00088 decimationFactor_ = decimationFactor_ == 0 ? 1 : decimationFactor_;
00089
00090 decimationCounter = 0;
00091
00092 }
00093
00095 void
00096 ArffFileSink::closeOutput()
00097 {
00098 if (os_ != NULL)
00099 {
00100 os_->flush();
00101 os_->close();
00102 delete os_;
00103 }
00104 filename_ = "";
00105 }
00106
00108 void
00109 ArffFileSink::prepareOutput()
00110 {
00111
00112
00113 if (filename_ != ctrl_filename_->to<mrs_string>())
00114 {
00115
00116 closeOutput();
00117
00118 filename_ = ctrl_filename_->to<mrs_string>();
00119 os_ = new ofstream;
00120 os_->open(filename_.c_str());
00121 if (os_->fail()) {
00122
00123
00124 ostringstream oss;
00125 oss << "[Error in " << __FILE__ << ":" << __LINE__ << "] "
00126 << "could not open file '" << filename_ << "' for writing.";
00127 throw ios_base::failure(oss.str());
00128 }
00129
00130 writeArffHeader();
00131 }
00132 }
00133
00134
00135 void
00136 ArffFileSink::writeArffHeader()
00137 {
00138
00139 (*os_) << "% ARFF file Created by Marsyas (ArffFileSink)" << endl;
00140 (*os_) << "@relation " << filename_ << endl;
00141
00142
00143
00144 mrs_string onObsNames = ctrl_onObsNames_->to<mrs_string>();
00145 vector<mrs_string> attributeNames = stringSplit(onObsNames, ",");
00146 const mrs_natural onObservations = ctrl_onObservations_->to<mrs_natural>();
00147
00148 for (mrs_natural i = 0; i < onObservations; ++i)
00149 {
00150 if (i < (mrs_natural)attributeNames.size() && !attributeNames[i].empty())
00151 {
00152 (*os_ ) << "@attribute " << attributeNames[i] << " real" << endl;
00153 }
00154 else
00155 {
00156 (*os_ ) << "@attribute " << "untitled" << i << " real" << endl;
00157 }
00158 }
00159
00160
00161 (*os_) << "\n@data" << endl;
00162 }
00163
00164 void
00165 ArffFileSink::myProcess(realvec& in, realvec& out)
00166 {
00167 mrs_natural o,t;
00168
00169 prepareOutput();
00170
00171
00172 for (t = 0; t < inSamples_; t++)
00173 {
00174 for (o = 0; o < inObservations_; o++)
00175 {
00176 out(o, t) = in(o, t);
00177 }
00178 }
00179
00180 if (!ctrl_mute_->isTrue()) {
00181
00182 for (t = 0; t < inSamples_; t++)
00183 {
00184 if (decimationCounter % decimationFactor_ == 0)
00185 {
00186 for (o = 0; o < inObservations_; o++)
00187 {
00188 (*os_) << fixed << setprecision(floatPrecision_) << out(o, t);
00189 if (o < inObservations_ - 1)
00190 {
00191 (*os_) << ",";
00192 }
00193 }
00194 (*os_) << endl;
00195 }
00196 decimationCounter ++;
00197 }
00198 }
00199 }