/*------------------------------------------------------------------------------ -- This file is a part of the QLop Software -- Copyright (C) 2015, Plasma Physics Laboratory - CNRS -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -------------------------------------------------------------------------------*/ /*-- Author : Alexis Jeandet -- Mail : alexis.jeandet@member.fsf.org ----------------------------------------------------------------------------*/ #include "cassinidatafile.h" #include #include #include #include #include #include #include #include #include CassiniDataFile::CassiniDataFile(QObject *parent) : AbstractFileLoader(parent) { } CassiniDataFile::~CassiniDataFile() { } void CassiniDataFile::parseFile(const QString &fileName) { this->fileName = fileName; m_Write = false; this->start(); } void CassiniDataFile::saveFile(const QString &fileName, QLopDataList data) { this->fileName = fileName; m_Write = true; m_data = data; this->start(); } inline double __decodeVal(int ofset,unsigned char* data) { if(data[ofset]=='-') return -0.001 * (double)( (10000 * (int)(data[ofset+1] & 0x0F)) + (1000 * (int)(data[ofset+2] & 0x0F)) + (100 * (int)(data[ofset+4] & 0x0F)) + (10 * (int)(data[ofset+5] & 0x0F)) + ( (int)(data[ofset+6] & 0x0F)) ); else { if(data[ofset+1]=='-') { return -0.001 * (double)( (1000 * (int)(data[ofset+2] & 0x0F)) + (100 * (int)(data[ofset+4] & 0x0F)) + (10 * (int)(data[ofset+5] & 0x0F)) + ( (int)(data[ofset+6] & 0x0F)) ); } else { return 0.001 * (double)( (10000 * (int)(data[ofset+1] & 0x0F)) + (1000 * (int)(data[ofset+2] & 0x0F)) + (100 * (int)(data[ofset+4] & 0x0F)) + (10 * (int)(data[ofset+5] & 0x0F)) + ( (int)(data[ofset+6] & 0x0F)) ); } } } inline QDate __decodeDate(int ofset,unsigned char* data) { int y=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + (1*(data[ofset+3] & 0x0F)); int m=(10*(data[ofset+5] & 0x0F)) + (1*(data[ofset+6] & 0x0F)); int d=(10*(data[ofset+8] & 0x0F)) + (1*(data[ofset+9] & 0x0F)); return QDate(y,m,d); } inline QTime __decodeTime(int ofset,unsigned char* data) { int h=(10*(data[ofset] & 0x0F)) + (1*(data[ofset+1] & 0x0F)); int m=(10*(data[ofset+3] & 0x0F)) + (1*(data[ofset+4] & 0x0F)); int s=(10*(data[ofset+6] & 0x0F)) + (1*(data[ofset+7] & 0x0F)); int ms=(100*(data[ofset+9] & 0x0F)) + (10*(data[ofset+10] & 0x0F)) + (1*(data[ofset+11] & 0x0F)); return QTime(h,m,s,ms); } double __decodeTimeFromEpochMs(int ofset,unsigned char* data) { struct tm t; time_t t_of_day; t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)) -1900; t.tm_mon=(10*(data[ofset+5] & 0x0F)) + ((data[ofset+6] & 0x0F)); t.tm_mday=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F)); t.tm_hour=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F)); t.tm_min=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F)); t.tm_sec=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F)); int ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F)); t_of_day = mktime(&t); return (t_of_day*1000.0)+ms; } double __decodeTimeFromEpoch(int ofset,unsigned char* data) { struct tm t; time_t t_of_day; t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)) -1900; t.tm_mon=(10*(data[ofset+5] & 0x0F)) + ((data[ofset+6] & 0x0F)); t.tm_mday=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F)); t.tm_hour=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F)); t.tm_min=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F)); t.tm_sec=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F)); double ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F)); t_of_day = mktime(&t); return (double)t_of_day+((double)ms*(double)0.001); } double __decodeTimeHMSmS(int ofset,unsigned char* data) { int h,m,s; h=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F)); m=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F)); s=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F)); double ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F)); return (double)((h*3600)+(m*60)+s) + (ms*0.001); } double __decodeTimeDHMSmS(int ofset,unsigned char* data) { int d,h,m,s; d=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F)); h=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F)); m=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F)); s=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F)); double ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F)); return (double)((d*3600*24)+(h*3600)+(m*60)+s) + (ms*0.001); } double __decodeTimeFromEpochDayOnly(int ofset,unsigned char* data) { struct tm t; time_t t_of_day; // t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)) -1900; t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)); t.tm_mon=(10*(data[ofset+5] & 0x0F)) + ((data[ofset+6] & 0x0F)); t.tm_mday=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F)); t.tm_hour=0; t.tm_min=0; t.tm_sec=0; // t_of_day = mktime(&t); // return (double)t_of_day; QDateTime date(QDate(t.tm_year,t.tm_mon,1),QTime(0,0)); // date.setDate(); return (double)((date.toMSecsSinceEpoch()/1000.0)-(24*3600)); } void CassiniDataFile::run() { if(!m_Write) { readFile(); } else { writeFile(); } } void CassiniDataFile::readFile() { FILE* dataFile; dataFile = fopen(fileName.toStdString().c_str(),"r"); if(dataFile != NULL) { fseek(dataFile, 0L, SEEK_END); int FileSize=ftell(dataFile); int lineCnt = FileSize/58; int curLine=0; int lastLineUpdate=0; QVector *ch1=new QVector(lineCnt); QVector *ch2=new QVector(lineCnt); QVector *ch3=new QVector(lineCnt); QLopDataList data; QLopQCPDataVector* ch1V=new QLopQCPDataVector(); QLopQCPDataVector* ch2V=new QLopQCPDataVector(); QLopQCPDataVector* ch3V=new QLopQCPDataVector(); ch1V->data=ch1; ch2V->data=ch2; ch3V->data=ch3; ch1V->name="r"; ch2V->name="theta"; ch3V->name="phi"; ch1V->unit="nT"; ch2V->unit="nT"; ch3V->unit="nT"; data.append(ch1V); data.append(ch2V); data.append(ch3V); QElapsedTimer timr; double _x=0.0,day=0.0; char* line; QCPData data1,data2,data3; char* fileContent=(char*)malloc(FileSize); if(Q_UNLIKELY(fileContent==NULL))return; int threadIndex,numThreads=omp_get_num_threads(); int updateTriger=(lineCnt/100)/numThreads; fseek(dataFile, 0L, SEEK_SET); char* svglocale=NULL; setlocale(LC_NUMERIC,svglocale); setlocale(LC_NUMERIC, "en_US"); if(fread(fileContent,1,FileSize,dataFile)) { line = fileContent; QDateTime date; timr.start(); day=__decodeTimeFromEpochDayOnly(0,(unsigned char*)line); //#pragma omp parallel if ((FileSize > 10000000)) private(date,data1,data2,data3,_x,threadIndex,lastLineUpdate) shared(ch1,ch2,ch3,lineCnt) // { #pragma omp parallel for if ((FileSize > 1024*1024*10)) private(date,data1,data2,data3,_x,threadIndex,lastLineUpdate,curLine) shared(ch1,ch2,ch3,lineCnt,updateTriger) for(int i=0;iupdateTriger)) { lastLineUpdate=0; int test=((curLine*numThreads *100)/ (lineCnt)); emit updateProgress(omp_get_thread_num(),test); } } } //#pragma omp barrier free(fileContent); // } qDebug()<< lineCnt <<" Points loaded in "<< timr.elapsed()<<"ms"; setlocale(LC_NUMERIC,svglocale); emit dataReady(data); } } void CassiniDataFile::writeFile() { QFile dataFile(fileName); dataFile.open(QIODevice::WriteOnly); QTextStream out(&dataFile); if(dataFile.isOpen()) { if(m_data.count()==3) { QLopQCPDataVector* ch1V=(QLopQCPDataVector*)m_data.at(0); QLopQCPDataVector* ch2V=(QLopQCPDataVector*)m_data.at(1); QLopQCPDataVector* ch3V=(QLopQCPDataVector*)m_data.at(2); if(ch1V->data->count()==ch2V->data->count() && ch1V->data->count()==ch3V->data->count()) { for(int i=0;idata->count();i++) { double key = ch1V->data->at(i).key; QDateTime date = QDateTime::fromMSecsSinceEpoch(key*1000); out << date.toString(Qt::ISODate)+QString(".%1").arg(date.time().msec(),3); out << QString("%1%2%3").arg(ch1V->data->at(i).value, 11, 'f', 3).arg(ch2V->data->at(i).value, 11, 'f', 3).arg(ch3V->data->at(i).value, 11, 'f', 3); out << "\r\n"; } } dataFile.flush(); m_data.clear(); delete ch1V; delete ch2V; delete ch3V; } } }