00001 #include <iostream>
00002 #include <fstream>
00003 #include <cstdlib>
00004 #include <string>
00005 #include "ppftypes.hpp"
00006 #include "ppfdatatype.hpp"
00007
00008 using namespace std;
00009
00010 namespace ppf
00011 {
00012 datatype::datatype()
00013 {
00014 xunit = "";
00015 tunit = "";
00016 dataunit = "";
00017 comment = "";
00018 userdtstatus = 0;
00019 sysddastatus = 0;
00020 sysdtstatus = 0;
00021 }
00022
00023 datatype::datatype(string filename)
00024 {
00025 this->readLocal(filename);
00026 }
00027
00028
00029 void datatype::readLocal(string filename)
00030 {
00031 const string header = "PPFLDF";
00032 const short majorver = 1;
00033 const short minorver = 0;
00034 ifstream file;
00035 short tempsi;
00036 int tempi;
00037 char tempca[24];
00038 string tempst;
00039
00040
00041 file.open(filename.c_str(), ios::binary);
00042
00043
00044 if(!file.is_open()) throw ppf_error("Could not open specified local PPF file.");
00045
00046
00047 file.read(tempca, 6);
00048 tempst.assign(tempca, 6);
00049 if (tempst != header)
00050 {
00051 file.close();
00052 throw ppf_error("Specified file is not a local PPF file.");
00053 }
00054 file.read((char*) &tempsi, sizeof(short));
00055 if (tempsi != majorver)
00056 {
00057 file.close();
00058 throw ppf_error("The version number of the specified local PPF file is not supported.");
00059 }
00060 file.read((char*) &tempsi, sizeof(short));
00061 if (tempsi != minorver)
00062 {
00063 file.close();
00064 throw ppf_error("The version number of the specified local PPF file is not supported.");
00065 }
00066
00067
00068 file.read(tempca, 8);
00069 tunit.assign(tempca, 8);
00070
00071
00072 file.read(tempca, 8);
00073 xunit.assign(tempca, 8);
00074
00075
00076 file.read(tempca, 8);
00077 dataunit.assign(tempca, 8);
00078
00079
00080 file.read(tempca, 24);
00081 comment.assign(tempca, 24);
00082
00083
00084 file.read((char*) &tempi, sizeof(int));
00085 userdtstatus = tempi;
00086 file.read((char*) &tempi, sizeof(int));
00087 sysddastatus = tempi;
00088 file.read((char*) &tempi, sizeof(int));
00089 sysdtstatus = tempi;
00090
00091
00092 file.read((char*) &tempi, sizeof(int));
00093 t.resize(tempi);
00094 data.resize(tempi);
00095 file.read((char*) &tempi, sizeof(int));
00096 x.resize(tempi);
00097 for(int i=0;i<data.size();i++) data[i].resize(tempi);
00098
00099
00100 for(int i=0;i<t.size();i++) file.read((char*) &t[i], sizeof(float));
00101 for(int i=0;i<x.size();i++) file.read((char*) &x[i], sizeof(float));
00102 for(int i=0;i<t.size();i++) for(int j=0;j<x.size();j++) file.read((char*) &data[i][j], sizeof(float));
00103
00104
00105 file.close();
00106 }
00107
00108
00109 void datatype::writeLocal(string filename)
00110 {
00111 const string header = "PPFLDF";
00112 const short majorver = 1;
00113 const short minorver = 0;
00114 ofstream file;
00115 int temp;
00116
00117
00118 file.open(filename.c_str(), ios::binary);
00119
00120
00121 if(!file.is_open()) throw ppf_error("The local PPF file could not be created.");
00122
00123
00124 file.write(header.c_str(), 6);
00125 file.write((char*) &majorver, sizeof(short));
00126 file.write((char*) &minorver, sizeof(short));
00127
00128
00129 if (tunit.size() != 8) tunit.resize(8);
00130 file.write(tunit.c_str(), 8);
00131
00132
00133 if (xunit.size() != 8) xunit.resize(8);
00134 file.write(xunit.c_str(), 8);
00135
00136
00137 if (dataunit.size() != 8) dataunit.resize(8);
00138 file.write(dataunit.c_str(), 8);
00139
00140
00141 if (comment.size() != 24) comment.resize(24);
00142 file.write(comment.c_str(), 24);
00143
00144
00145 file.write((char*) &userdtstatus, sizeof(int));
00146 file.write((char*) &sysddastatus, sizeof(int));
00147 file.write((char*) &sysdtstatus, sizeof(int));
00148
00149
00150 temp = t.size();
00151 file.write((char*) &temp, sizeof(int));
00152 temp = x.size();
00153 file.write((char*) &temp, sizeof(int));
00154
00155
00156 for(int i=0;i<t.size();i++) file.write((char*) &t[i], sizeof(float));
00157 for(int i=0;i<x.size();i++) file.write((char*) &x[i], sizeof(float));
00158 for(int i=0;i<t.size();i++) for(int j=0;j<x.size();j++) file.write((char*) &data[i][j], sizeof(float));
00159
00160
00161 file.close();
00162 }
00163
00164 int datatype::getTDim()
00165 {
00166 return t.size();
00167 }
00168
00169 int datatype::getXDim()
00170 {
00171 return x.size();
00172 }
00173
00174 string datatype::getTUnit()
00175 {
00176 return tunit;
00177 }
00178
00179 string datatype::getXUnit()
00180 {
00181 return xunit;
00182 }
00183
00184 string datatype::getDataUnit()
00185 {
00186 return dataunit;
00187 }
00188
00189 string datatype::getComment()
00190 {
00191 return comment;
00192 }
00193
00194 int datatype::getUserDTStatus()
00195 {
00196 return userdtstatus;
00197 }
00198
00199 int datatype::getSysDDAStatus()
00200 {
00201 return sysddastatus;
00202 }
00203
00204 int datatype::getSysDTStatus()
00205 {
00206 return sysdtstatus;
00207 }
00208
00209 float datatype::getT(int It)
00210 {
00211 return t[It];
00212 }
00213
00214 float datatype::getX(int Ix)
00215 {
00216 return x[Ix];
00217 }
00218
00219 float datatype::getDataIt(int It)
00220 {
00221 return data[It][0];
00222 }
00223
00224 float datatype::getDataIx(int Ix)
00225 {
00226 return data[0][Ix];
00227 }
00228
00229 float datatype::getDataItIx(int It, int Ix)
00230 {
00231 return data[It][Ix];
00232 }
00233
00234 int datatype::getIt(float t)
00235 {
00236 int Ilower, Iupper;
00237
00238
00239 findNearest(this->t, 0, this->t.size()-1, t, Ilower, Iupper);
00240 if (Ilower == Iupper) return Ilower;
00241 if ((this->t[Iupper] - t) <= (t - this->t[Ilower])) return Iupper;
00242 else return Ilower;
00243 }
00244
00245 int datatype::getIx(float x)
00246 {
00247 int Ilower, Iupper;
00248
00249
00250 findNearest(this->x, 0, this->x.size()-1, x, Ilower, Iupper);
00251 if (Ilower == Iupper) return Ilower;
00252 if ((this->x[Iupper] - x) <= (x - this->x[Ilower])) return Iupper;
00253 else return Ilower;
00254 }
00255
00256 float datatype::getDataT(float t)
00257 {
00258 return getDataT(t, ppf::linear);
00259 }
00260
00261 float datatype::getDataT(float t, processflag flag)
00262 {
00263 float ta, v;
00264
00265 getDataTIx(t, 0, flag, ta, v);
00266 return v;
00267 }
00268
00269 coord datatype::getDataCT(float t, processflag flag)
00270 {
00271 float ta, v;
00272 coord c;
00273
00274 getDataTIx(t, 0, flag, ta, v);
00275 c.t = ta;
00276 c.x = x[0];
00277 c.d = v;
00278 return c;
00279 }
00280
00281 float datatype::getDataX(float x)
00282 {
00283 return getDataX(x, ppf::linear);
00284 }
00285
00286 float datatype::getDataX(float x, processflag flag)
00287 {
00288 float xa, v;
00289
00290 getDataItX(0, x, flag, xa, v);
00291 return v;
00292 }
00293
00294 coord datatype::getDataCX(float x, processflag flag)
00295 {
00296 float xa, v;
00297 coord c;
00298
00299 getDataItX(0, x, flag, xa, v);
00300 c.t = t[0];
00301 c.x = xa;
00302 c.d = v;
00303 return c;
00304 }
00305
00306 float datatype::getDataTIx(float t, long Ix)
00307 {
00308 return getDataTIx(t, Ix, ppf::linear);
00309 }
00310
00311 float datatype::getDataTIx(float t, long Ix, processflag t_flag)
00312 {
00313 float ta, v;
00314
00315 getDataTIx(t, Ix, t_flag, ta, v);
00316 return v;
00317 }
00318
00319 coord datatype::getDataCTIx(float t, long Ix, processflag t_flag)
00320 {
00321 float ta, v;
00322 coord c;
00323
00324 getDataTIx(t, Ix, t_flag, ta, v);
00325 c.t = ta;
00326 c.x = x[Ix];
00327 c.d = v;
00328 return c;
00329 }
00330
00331 float datatype::getDataItX(long It, float x)
00332 {
00333 return getDataItX(It, x, ppf::linear);
00334 }
00335
00336 float datatype::getDataItX(long It, float x, processflag x_flag)
00337 {
00338 float xa, v;
00339
00340 getDataItX(It, x, x_flag, xa, v);
00341 return v;
00342 }
00343
00344 coord datatype::getDataCItX(long It, float x, processflag x_flag)
00345 {
00346 float xa, v;
00347 coord c;
00348
00349 getDataItX(It, x, x_flag, xa, v);
00350 c.t = t[It];
00351 c.x = xa;
00352 c.d = v;
00353 return c;
00354 }
00355
00356 float datatype::getDataTX(float t, float x)
00357 {
00358 return getDataTX(t, x, ppf::linear, ppf::linear);
00359 }
00360
00361 float datatype::getDataTX(float t, float x, processflag t_flag, processflag x_flag)
00362 {
00363 float ta ,xa, v;
00364
00365 getDataTX(t, x, t_flag, x_flag, ta, xa, v);
00366 return v;
00367 }
00368
00369 coord datatype::getDataCTX(float t, float x, processflag t_flag, processflag x_flag)
00370 {
00371 float ta ,xa, v;
00372 coord c;
00373
00374 getDataTX(t, x, t_flag, x_flag, ta, xa, v);
00375 c.t = ta;
00376 c.x = xa;
00377 c.d = v;
00378 return c;
00379 }
00380
00381 void datatype::setT(int It, float v)
00382 {
00383 t[It] = v;
00384 }
00385
00386 void datatype::setX(int Ix, float v)
00387 {
00388 x[Ix] = v;
00389 }
00390
00391 void datatype::setDataIt(int It, float v)
00392 {
00393 data[It][0] = v;
00394 }
00395
00396 void datatype::setDataIx(int Ix, float v)
00397 {
00398 data[0][Ix] = v;
00399 }
00400
00401 void datatype::setDataItIx(int It, int Ix, float v)
00402 {
00403 data[It][Ix] = v;
00404 }
00405
00406 void datatype::findNearest(vector<float> &v, int Imin, int Imax, float f, int &Ilower, int &Iupper)
00407 {
00408
00409
00410 int t, b, m;
00411
00412
00413 if (v[Imin] < v[Imax])
00414 {
00415
00416 if (f <= v[Imin])
00417 {
00418 Ilower = Iupper = Imin;
00419 return;
00420 }
00421 if (f >= v[Imax])
00422 {
00423 Ilower = Iupper = Imax;
00424 return;
00425 }
00426
00427
00428 t = Imax;
00429 b = Imin;
00430 while(t != (b+1))
00431 {
00432
00433 m = b + (t-b)/2;
00434
00435
00436 if (v[m] == f)
00437 {
00438 Ilower = Iupper = m;
00439 return;
00440 }
00441 if (v[m] < f) b = m;
00442 else t = m;
00443 }
00444
00445
00446 Ilower = b;
00447 Iupper = t;
00448 }
00449 else
00450 {
00451
00452 if (f >= v[Imin])
00453 {
00454 Ilower = Iupper = Imin;
00455 return;
00456 }
00457 if (f <= v[Imax])
00458 {
00459 Ilower = Iupper = Imax;
00460 return;
00461 }
00462
00463
00464 t = Imax;
00465 b = Imin;
00466 while(t != (b+1))
00467 {
00468
00469 m = b + (t-b)/2;
00470
00471
00472 if (v[m] == f)
00473 {
00474 Ilower = Iupper = m;
00475 return;
00476 }
00477 if (v[m] > f) b = m;
00478 else t = m;
00479 }
00480
00481
00482 Ilower = t;
00483 Iupper = b;
00484 }
00485 }
00486
00487 double datatype::interpolateLinear(double p1, double v1, double p2, double v2, double pt)
00488 {
00489 return (v1 + ((v2-v1)/(p2-p1))*(pt-p1));
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499 void datatype::getDataTIx(float t, long Ix, processflag t_flag, float &ta, float &v)
00500 {
00501 int Ilower, Iupper;
00502
00503 if(t_flag == ppf::nearest)
00504 {
00505
00506 findNearest(this->t, 0, this->t.size()-1, t, Ilower, Iupper);
00507 if (Ilower == Iupper)
00508 {
00509 ta = this->t[Ilower];
00510 v = this->data[Ilower][Ix];
00511 }
00512 else if ((this->t[Iupper] - t) <= (t - this->t[Ilower]))
00513 {
00514 ta = this->t[Iupper];
00515 v = this->data[Iupper][Ix];
00516 }
00517 else
00518 {
00519 ta = this->t[Ilower];
00520 v = this->data[Ilower][Ix];
00521 }
00522 }
00523 else if(t_flag == ppf::linear)
00524 {
00525
00526 findNearest(this->t, 0, this->t.size()-1, t, Ilower, Iupper);
00527 if (Ilower == Iupper)
00528 {
00529
00530 ta = this->t[Ilower];
00531 v = this->data[Ilower][Ix];
00532 }
00533 else
00534 {
00535
00536 ta = t;
00537 v = interpolateLinear(this->t[Ilower], this->data[Ilower][Ix], this->t[Iupper], this->data[Iupper][Ix], t);
00538 }
00539 }
00540
00541
00542
00543
00544 else throw ppf_error("Invalid process flag.");
00545 }
00546
00547 void datatype::getDataItX(long It, float x, processflag x_flag, float &xa, float &v)
00548 {
00549 int Ilower, Iupper;
00550
00551 if(x_flag == ppf::nearest)
00552 {
00553
00554 findNearest(this->x, 0, this->x.size()-1, x, Ilower, Iupper);
00555 if (Ilower == Iupper)
00556 {
00557 xa = this->x[Ilower];
00558 v = this->data[It][Ilower];
00559 }
00560 else if ((this->x[Iupper] - x) <= (x - this->x[Ilower]))
00561 {
00562 xa = this->x[Iupper];
00563 v = this->data[It][Iupper];
00564 }
00565 else
00566 {
00567 xa = this->x[Ilower];
00568 v = this->data[It][Ilower];
00569 }
00570 }
00571 else if(x_flag == ppf::linear)
00572 {
00573
00574 findNearest(this->x, 0, this->x.size()-1, x, Ilower, Iupper);
00575 if (Ilower == Iupper)
00576 {
00577
00578 xa = this->x[Ilower];
00579 v = this->data[It][Ilower];
00580 }
00581 else
00582 {
00583
00584 xa = x;
00585 v = interpolateLinear(this->x[Ilower], this->data[It][Ilower], this->x[Iupper], this->data[It][Iupper], x);
00586 }
00587 }
00588
00589
00590
00591
00592 else throw ppf_error("Invalid process flag.");
00593 }
00594
00595 void datatype::getDataTX(float t, float x, processflag t_flag, processflag x_flag, float &ta, float &xa, float &v)
00596 {
00597 int Ilower, Iupper;
00598
00599 if(x_flag == ppf::nearest)
00600 {
00601
00602 findNearest(this->x, 0, this->x.size()-1, x, Ilower, Iupper);
00603 if (Ilower == Iupper)
00604 {
00605
00606 xa = this->x[Ilower];
00607 getDataTIx(t, Ilower, t_flag, ta, v);
00608 }
00609 else if ((this->x[Iupper] - x) <= (x - this->x[Ilower]))
00610 {
00611
00612 xa = this->x[Iupper];
00613 getDataTIx(t, Iupper, t_flag, ta, v);
00614 }
00615 else
00616 {
00617
00618 xa = this->x[Ilower];
00619 getDataTIx(t, Ilower, t_flag, ta, v);
00620 }
00621 }
00622 else if (x_flag == ppf::linear)
00623 {
00624
00625 findNearest(this->x, 0, this->x.size()-1, x, Ilower, Iupper);
00626 if (Ilower == Iupper)
00627 {
00628
00629 xa = this->x[Ilower];
00630 getDataTIx(t, Ilower, t_flag, ta, v);
00631 }
00632 else
00633 {
00634 float tl, tu, vl, vu;
00635
00636
00637 getDataTIx(t, Ilower, t_flag, tl, vl);
00638 getDataTIx(t, Iupper, t_flag, tu, vu);
00639
00640
00641 xa = x;
00642 ta = tl;
00643 v = interpolateLinear(this->x[Ilower], vl, this->x[Iupper], vu, x);
00644 }
00645 }
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 else throw ppf_error("Invalid process flag.");
00658
00659 }
00660
00661 datatype::~datatype()
00662 {
00663 }
00664 };