cassinidatafile.cpp
249 lines
| 9.1 KiB
| text/x-c
|
CppLexer
r5 | /*------------------------------------------------------------------------------ | |||
-- 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 <QFile> | ||||
#include <stdio.h> | ||||
#include <QDateTime> | ||||
#include <QVector> | ||||
#include <QProgressDialog> | ||||
#include <omp.h> | ||||
#include <QTimer> | ||||
#include <QElapsedTimer> | ||||
#include <sys/time.h> | ||||
CassiniDataFile::CassiniDataFile(QObject *parent) : AbstractFileLoader(parent) | ||||
{ | ||||
} | ||||
CassiniDataFile::~CassiniDataFile() | ||||
{ | ||||
} | ||||
void CassiniDataFile::parseFile(const QString &fileName) | ||||
{ | ||||
this->fileName = fileName; | ||||
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_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; | ||||
} | ||||
void CassiniDataFile::run() | ||||
{ | ||||
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<QCPData> *ch1=new QVector<QCPData>(lineCnt); | ||||
QVector<QCPData> *ch2=new QVector<QCPData>(lineCnt); | ||||
QVector<QCPData> *ch3=new QVector<QCPData>(lineCnt); | ||||
QLopDataList data; | ||||
QLopData* ch1V=new QLopData(); | ||||
QLopData* ch2V=new QLopData(); | ||||
QLopData* ch3V=new QLopData(); | ||||
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;i<lineCnt;i++) | ||||
{ | ||||
// _x= i; | ||||
_x= day + __decodeTimeDHMSmS((i*58),(unsigned char*)line); | ||||
// _x=__decodeTimeFromEpoch((i*58),(unsigned char*)line); | ||||
data1.key=_x; | ||||
data2.key=_x; | ||||
data3.key=_x; | ||||
data1.value=__decodeVal(((i*58)+27),(unsigned char*)line); | ||||
data2.value=__decodeVal(((i*58)+38),(unsigned char*)line); | ||||
data3.value=__decodeVal(((i*58)+49),(unsigned char*)line); | ||||
(*ch1)[i]=data1; | ||||
(*ch2)[i]=data2; | ||||
(*ch3)[i]=data3; | ||||
curLine++; | ||||
if(Q_UNLIKELY(lastLineUpdate++>updateTriger)) | ||||
{ | ||||
lastLineUpdate=0; | ||||
int test=((curLine*numThreads *100)/ (lineCnt)); | ||||
emit updateProgress(omp_get_thread_num(),test); | ||||
} | ||||
} | ||||
} | ||||
//#pragma omp barrier | ||||
free(fileContent); | ||||
// } | ||||
qDebug()<< lineCnt <<" Points loade in "<< timr.elapsed()<<"ms"; | ||||
setlocale(LC_NUMERIC,svglocale); | ||||
emit dataReady(data); | ||||
} | ||||
} | ||||