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