MtuFormat.cpp
Go to the documentation of this file.00001 #include "MtuFormat.h"
00002 #include "FatalException.h"
00003 #include <iostream>
00004 #include <algorithm>
00005 #include <boost/date_time/gregorian/gregorian_types.hpp>
00006 #include <boost/date_time/posix_time/posix_time.hpp>
00007 #include <boost/cast.hpp>
00008 #include <time.h>
00009
00010 using namespace std;
00011 namespace gplib
00012 {
00013 const char tagsize = 32;
00014
00015 MtuFormat::MtuFormat()
00016 {
00017 }
00018
00019 MtuFormat::~MtuFormat()
00020 {
00021 }
00022
00023 void MtuFormat::ReadValue(TimeSeriesComponent &CurrChannel, char *pos)
00024 {
00025 unsigned char byte1, byte2, byte3;
00026 int datavalue;
00027
00028 byte1 = *pos;
00029 byte2 = *(pos + 1);
00030 byte3 = *(pos + 2);
00031 datavalue = ByteToInt(byte1, byte2, byte3);
00032 CurrChannel.GetData().push_back(datavalue);
00033 }
00034
00035 int MtuFormat::ByteToInt(unsigned char first, unsigned char second,
00036 unsigned char last)
00037 {
00038 const char highbit = 0x80;
00039 int value;
00040 if (last & highbit)
00041 {
00042 last = ~last;
00043 second = ~second;
00044 first = ~first;
00045 value = -(last * 65536 + second * 256 + first + 1);
00046 }
00047 else
00048 value = last * 65536 + second * 256 + first;
00049 return (value);
00050 }
00051
00052 void MtuFormat::ReadRecord(ifstream &infile)
00053 {
00054 unsigned char CurrentTag[tagsize];
00055 int recordlength;
00056
00057 char *buffer;
00058 char *currentbyte;
00059
00060 infile.read((char *) CurrentTag, tagsize);
00061 if (infile.good())
00062 {
00063 startsec = CurrentTag[0];
00064 startmin = CurrentTag[1];
00065 starthr = CurrentTag[2];
00066 startday = CurrentTag[3];
00067 startmonth = CurrentTag[4];
00068 startyear = CurrentTag[5];
00069 startdow = CurrentTag[6];
00070 startcentury = CurrentTag[7];
00071 serialnumber = CurrentTag[9] * 256 + CurrentTag[8];
00072 nscans = CurrentTag[11] * 256 + CurrentTag[10];
00073 nchannels = CurrentTag[12];
00074 taglength = CurrentTag[13];
00075 status = CurrentTag[14];
00076 saturationflags = CurrentTag[15];
00077 futurereserved = CurrentTag[16];
00078 samplelength = CurrentTag[17];
00079 sampledenom = boost::numeric_cast<double>(CurrentTag[19] * 256
00080 + CurrentTag[18]);
00081 sampleunit = CurrentTag[20];
00082 clockstatus = CurrentTag[21];
00083 clockerror = 16777216 * CurrentTag[25] + 65536 * CurrentTag[24]
00084 + 256 * CurrentTag[23] + CurrentTag[22];
00085 for (int i = 0; i < 6; ++i)
00086 reserved[i] = CurrentTag[i + 26];
00087 switch (sampleunit)
00088 {
00089 case 0:
00090 sampleenum = 1.0;
00091 break;
00092 case 1:
00093 sampleenum = 60.0;
00094 break;
00095 case '2':
00096 sampleenum = 3600.0;
00097 break;
00098 case '3':
00099 sampleenum = 3600.0 * 24.0;
00100 break;
00101 }
00102 const double samplerate = sampledenom / sampleenum;
00103 Hx.SetSamplerate(samplerate);
00104 Hy.SetSamplerate(samplerate);
00105 Hz.SetSamplerate(samplerate);
00106 Ex.SetSamplerate(samplerate);
00107 Ey.SetSamplerate(samplerate);
00108 recordlength = nscans * nchannels;
00109
00110 TimeSeries::ttime basetime(boost::gregorian::date(startcentury
00111 * 100 + startyear, startmonth, startday),
00112 boost::posix_time::time_duration(starthr, startmin, startsec));
00113
00114 buffer = new char[recordlength * samplelength];
00115 infile.read(buffer, recordlength * samplelength);
00116 currentbyte = buffer;
00117 for (int i = 0; i < nscans; ++i)
00118 {
00119 t.push_back(basetime + boost::posix_time::microseconds(
00120 boost::numeric_cast<unsigned int>(i * 1000000.0
00121 / samplerate)));
00122 ReadValue(Ex, currentbyte);
00123 currentbyte += samplelength;
00124 ReadValue(Ey, currentbyte);
00125 currentbyte += samplelength;
00126 ReadValue(Hx, currentbyte);
00127 currentbyte += samplelength;
00128 ReadValue(Hy, currentbyte);
00129 currentbyte += samplelength;
00130 ReadValue(Hz, currentbyte);
00131 currentbyte += samplelength;
00132 }
00133 delete[] buffer;
00134 }
00135 }
00136
00137 void MtuFormat::GetData(const std::string filename)
00138 {
00139 ifstream infile(filename.c_str(), ios::binary);
00140 if (infile)
00141 {
00142 while (infile.good())
00143 {
00144 ReadRecord(infile);
00145 }
00146 }
00147 else
00148 {
00149 throw FatalException("Infile does not exist: " + filename);
00150 }
00151 }
00152
00153 void MtuFormat::GetData()
00154 {
00155
00156 }
00157
00158 void MtuFormat::MakeGood()
00159 {
00160 status = 0;
00161 saturationflags = 0;
00162 }
00163
00164 void MtuFormat::WriteNum(double number, ofstream &outfile)
00165 {
00166 unsigned char high;
00167 unsigned char middle;
00168 unsigned char low;
00169 char buffer[3];
00170 unsigned int intnumber;
00171 if (number >= 0)
00172 intnumber = int(abs(floor(number)));
00173 else
00174 intnumber = ~int(abs(floor(number))) + 1;
00175 high = intnumber / 65536;
00176 middle = (intnumber % 65536) / 256;
00177 low = intnumber % 256;
00178
00179 buffer[0] = low;
00180 buffer[1] = middle;
00181 buffer[2] = high;
00182 outfile.write(buffer, 3);
00183 }
00184
00185 void MtuFormat::UpDateHeader(unsigned char *&header, const int firstscan)
00186 {
00187 tm currtime = boost::posix_time::to_tm(t.at(firstscan));
00188 header[0] = boost::numeric_cast<char>(currtime.tm_sec);
00189 header[1] = boost::numeric_cast<char>(currtime.tm_min);
00190 header[2] = boost::numeric_cast<char>(currtime.tm_hour);
00191 boost::gregorian::greg_year_month_day currdate =
00192 t.at(firstscan).date().year_month_day();
00193 header[3] = boost::numeric_cast<char>(currdate.day.as_number());
00194 header[4] = boost::numeric_cast<char>(currdate.month.as_number());
00195 header[5] = boost::numeric_cast<char>(currdate.year % 100);
00196 header[6] = boost::numeric_cast<char>(currtime.tm_wday);
00197 header[7] = boost::numeric_cast<char>(currdate.year / 100);
00198 }
00199
00200 void MtuFormat::WriteData(const std::string filename)
00201 {
00202
00203 int nrecords = 0;
00204 int firstscan = 0;
00205 unsigned char *header = new unsigned char[tagsize];
00206
00207 header[8] = serialnumber % 256;
00208 header[9] = serialnumber / 256;
00209 header[10] = nscans % 256;
00210 header[11] = nscans / 256;
00211 header[12] = nchannels;
00212 header[13] = taglength;
00213 header[14] = status;
00214 header[15] = saturationflags;
00215 header[16] = futurereserved;
00216 header[17] = samplelength;
00217 header[18] = boost::numeric_cast<unsigned int>(sampledenom) % 256;
00218 header[19] = boost::numeric_cast<unsigned int>(sampledenom) / 256;
00219 header[20] = sampleunit;
00220 header[21] = clockstatus;
00221 header[22] = clockerror % 256;
00222 header[23] = (clockerror % 65536) / 256;
00223 header[24] = (clockerror % 16777216) / 65536;
00224 header[25] = clockerror / 16777216;
00225 for (int i = 0; i < 6; ++i)
00226 header[i + 26] = reserved[i];
00227 nrecords = Size() / nscans;
00228
00229 ofstream outfile(filename.c_str());
00230 for (int i = 0; i < nrecords; ++i)
00231 {
00232 UpDateHeader(header, firstscan);
00233 outfile.write((char *) header, tagsize);
00234 for (int j = 0; j < nscans; ++j)
00235 {
00236
00237 WriteNum(Ex.GetData().at(firstscan + j), outfile);
00238 WriteNum(Ey.GetData().at(firstscan + j), outfile);
00239 WriteNum(Hx.GetData().at(firstscan + j), outfile);
00240 WriteNum(Hy.GetData().at(firstscan + j), outfile);
00241 WriteNum(Hz.GetData().at(firstscan + j), outfile);
00242 }
00243 firstscan += nscans;
00244
00245 }
00246 }
00247
00248 MtuFormat& MtuFormat::operator=(MtuFormat &source)
00249 {
00250 if (this != &source)
00251 {
00252 this->TimeSeries::operator=(source);
00253 }
00254 return *this;
00255 }
00256
00257 MtuFormat& MtuFormat::operator=(TimeSeries &source)
00258 {
00259 this->TimeSeries::operator=(source);
00260 return *this;
00261 }
00262 }