|
|
/*------------------------------------------------------------------------------
|
|
|
-- 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 "themisdatafile.h"
|
|
|
#include <QFile>
|
|
|
#include <stdio.h>
|
|
|
#include <QDateTime>
|
|
|
#include <QVector>
|
|
|
#include <QProgressDialog>
|
|
|
#include <omp.h>
|
|
|
#include <QTimer>
|
|
|
#include <QElapsedTimer>
|
|
|
#include <time.h>
|
|
|
|
|
|
ThemisDataFile::ThemisDataFile(QObject *parent) : QThread(parent)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
ThemisDataFile::~ThemisDataFile()
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
void ThemisDataFile::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));
|
|
|
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+(ms*0.001);
|
|
|
}
|
|
|
void ThemisDataFile::run()
|
|
|
{
|
|
|
FILE* dataFile;
|
|
|
dataFile = fopen(fileName.toStdString().c_str(),"r");
|
|
|
QCPDataMap *ch1=new QCPDataMap();
|
|
|
QCPDataMap *ch2=new QCPDataMap();
|
|
|
QCPDataMap *ch3=new QCPDataMap();
|
|
|
QElapsedTimer timr;
|
|
|
|
|
|
double _x=0.0;
|
|
|
char* line;
|
|
|
QCPData data1,data2,data3;
|
|
|
if(dataFile != NULL)
|
|
|
{
|
|
|
fseek(dataFile, 0L, SEEK_END);
|
|
|
int FileSize=ftell(dataFile);
|
|
|
int lineCnt = FileSize/58;
|
|
|
int curLine=0;
|
|
|
int lastLineUpdate=0;
|
|
|
int threadIndex,numThreads=omp_get_num_threads();
|
|
|
char* fileContent=(char*)malloc(FileSize);
|
|
|
if(Q_UNLIKELY(fileContent==NULL))return;
|
|
|
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;
|
|
|
if(FileSize > 10000000)
|
|
|
{
|
|
|
lineCnt/=numThreads;
|
|
|
}
|
|
|
QDateTime date;
|
|
|
timr.start();
|
|
|
#pragma omp parallel if ((FileSize > 10000000)) private(date,data1,data2,data3,_x,threadIndex,lastLineUpdate) shared(ch1,ch2,ch3,lineCnt)
|
|
|
{
|
|
|
threadIndex = omp_get_thread_num();
|
|
|
#pragma omp for
|
|
|
for(int i=0;i<(FileSize/(58));i++)
|
|
|
{
|
|
|
_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);
|
|
|
#pragma omp critical
|
|
|
{
|
|
|
ch1->insertMulti(_x,data1);
|
|
|
ch2->insertMulti(_x,data2);
|
|
|
ch3->insertMulti(_x,data3);
|
|
|
}
|
|
|
curLine++;
|
|
|
if(lastLineUpdate++>8000)
|
|
|
{
|
|
|
lastLineUpdate=0;
|
|
|
int test=(curLine *100/ (lineCnt));
|
|
|
emit updateProgress(threadIndex,test);
|
|
|
}
|
|
|
}
|
|
|
#pragma omp barrier
|
|
|
}
|
|
|
free(fileContent);
|
|
|
|
|
|
}
|
|
|
|
|
|
qDebug()<<timr.elapsed();
|
|
|
setlocale(LC_NUMERIC,svglocale);
|
|
|
emit dataReady(ch1,ch2,ch3);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|