##// END OF EJS Templates
added quick fileName generation for data export, and fixed wrong date reading...
added quick fileName generation for data export, and fixed wrong date reading on cassini data files.

File last commit:

r10:63067c6877ba default
r10:63067c6877ba default
Show More
cassinidatafile.cpp
306 lines | 11.1 KiB | text/x-c | CppLexer
/*------------------------------------------------------------------------------
-- 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;
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<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);
}
}
void CassiniDataFile::writeFile()
{
QFile dataFile(fileName);
dataFile.open(QIODevice::WriteOnly);
QTextStream out(&dataFile);
if(dataFile.isOpen())
{
if(m_data.count()==3)
{
QLopData* ch1V=m_data.at(0);
QLopData* ch2V=m_data.at(1);
QLopData* ch3V=m_data.at(2);
if(ch1V->data->count()==ch2V->data->count() && ch1V->data->count()==ch3V->data->count())
{
for(int i=0;i<ch1V->data->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;
}
}
}