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)); //convert boost time to old c-style struct
00188         header[0] = boost::numeric_cast<char>(currtime.tm_sec); // read out seconds part
00189         header[1] = boost::numeric_cast<char>(currtime.tm_min); //boost::numeric_cast takes care of type conversion
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(); //convert date
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); // this is the day of week (between 0 and 6)
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   }

Generated on Tue May 4 16:52:14 2010 for GPLIB++ by  doxygen 1.5.8