|
|
/*------------------------------------------------------------------------------
|
|
|
-- 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);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|