/*------------------------------------------------------------------------------ -- 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 "cassinitools.h" #include #include #include #include #include #include CassiniTools* CassiniTools::_self=NULL; QDockWidget* CassiniTools::m_gui=NULL; CassiniToolsGUI* CassiniTools::m_CassiniToolsGUI=NULL; CassiniDataFile* CassiniTools::m_dataFile=NULL; int CassiniTools::m_defaultPlot=-1; int CassiniTools::m_fftPlot=-1; SocExplorerPlotActions* CassiniTools::ExportAction=NULL; Qt::GlobalColor QLopColours[]= {Qt::black, Qt::red, Qt::blue, Qt::green, Qt::darkGreen, Qt::cyan, Qt::darkRed, Qt::gray, Qt::yellow, Qt::darkBlue, Qt::darkCyan, Qt::magenta, Qt::darkMagenta, Qt::darkYellow, Qt::darkGray, Qt::lightGray}; int QLopColoursCount=16; #define _INIT() if(Q_UNLIKELY(_self==NULL)){init();} CassiniTools::CassiniTools(bool noGUI,QObject *parent) : QLopService(parent) { m_dataFile = new CassiniDataFile(); connect(m_dataFile,SIGNAL(dataReady(QLopDataList)),this,SLOT(dataReady(QLopDataList))); connect(m_dataFile,SIGNAL(fileWritten()),this,SLOT(fileWritten())); m_serviceName="CassiniTools"; m_noGui=noGUI; fftw_init_threads(); } CassiniTools::~CassiniTools() { delete m_dataFile; delete m_CassiniToolsGUI; delete m_gui; } void CassiniTools::makePlot() { m_defaultPlot = QLopPlots::addPlot(); m_fftPlot = QLopPlots::addPlot(); SocExplorerPlot* plot=QLopPlots::getPlot(m_defaultPlot); if(plot) { plot->setTitle(_self->m_serviceName + " plot"); plot->setXaxisTickLabelType(QCPAxis::ltDateTime); plot->setXaxisDateTimeFormat("hh:mm:ss.zzz"); plot->setContextMenuPolicy(Qt::ActionsContextMenu); SocExplorerPlotActions* action=new SocExplorerPlotActions("export view",plot->PID(),_self); plot->addAction(action); QObject::connect(action,SIGNAL(triggered(int)),_self,SLOT(export_view(int))); QString fileName = QString(plot->title()).replace(".TAB",""); fileName = generateFileName(fileName,".TAB"); ExportAction=new SocExplorerPlotActions("export view to "+fileName,plot->PID(),_self); plot->addAction(ExportAction); QObject::connect(ExportAction,SIGNAL(triggered(int)),_self,SLOT(export_view_Predefined_FileName(int))); action=new SocExplorerPlotActions("FFT of the current view",plot->PID(),_self); plot->addAction(action); QObject::connect(action,SIGNAL(triggered(int)),_self,SLOT(compute_fft_on_view(int))); } } void CassiniTools::init(bool noGUI, QObject *parent) { if(Q_UNLIKELY(_self==NULL)) { _self=new CassiniTools(noGUI,parent); } } CassiniTools *CassiniTools::self() { _INIT(); return _self; } void CassiniTools::decodeFGMData(const QString &file) { _INIT(); m_dataFile->parseFile(file); } void CassiniTools::plotFile(const QString &File) { if(!m_dataFile->isRunning()) { m_dataFile->parseFile(File); // TODO fixme SocExplorerPlot* plot = QLopPlots::getPlot(m_defaultPlot); if(plot==NULL) { makePlot(); plot = QLopPlots::getPlot(m_defaultPlot); } if(plot) { plot->setTitle(File); QString fileName = QString(File).replace(".TAB","-part"); fileName = generateFileName(fileName,".TAB"); ExportAction->setText("export view to "+fileName); } } } void CassiniTools::plot_TAB_File(const QString &fileName) { //TODO fix: accent not accepted plotFile(fileName); } void CassiniTools::export_view(int PID) { SocExplorerPlot* plot = QLopPlots::getPlot(PID); if(plot==NULL) return; { QString fileName = plot->title(); fileName = QFileDialog::getSaveFileName(0,tr("Set filename"),fileName.replace(".TAB","-part.TAB")); if(fileName!="") { QLopDataList vectors; for(int i=0;igraphCount();i++) { QLopQCPDataVector* vect = new QLopQCPDataVector(); vect->data = plot->getVisibleData(i); vectors.append(vect); } m_dataFile->saveFile(fileName,vectors); } } } void CassiniTools::export_view_Predefined_FileName(int PID) { SocExplorerPlot* plot = QLopPlots::getPlot(PID); if(plot==NULL) return; { QString fileName = QString(plot->title()).replace(".TAB","-part"); fileName = generateFileName(fileName,".TAB"); if(fileName!="") { QLopDataList vectors; for(int i=0;igraphCount();i++) { QLopQCPDataVector* vect = new QLopQCPDataVector(); vect->data = plot->getVisibleData(i); vectors.append(vect); } m_dataFile->saveFile(fileName,vectors); } } } void CassiniTools::compute_fft_on_view(int PID) { QElapsedTimer timr; SocExplorerPlot* plot = QLopPlots::getPlot(PID); if(plot==NULL) return; { timr.start(); QLopDataList vectors; for(int i=0;igraphCount();i++) { QLopQCPDataVector* vect = new QLopQCPDataVector(); vect->data = plot->getVisibleData(i); vectors.append(vect); } if(vectors.count()==3) { QLopQCPDataVector* ch1V=(QLopQCPDataVector*)vectors.at(0); QLopQCPDataVector* ch2V=(QLopQCPDataVector*)vectors.at(1); QLopQCPDataVector* ch3V=(QLopQCPDataVector*)vectors.at(2); QLopQCPDataVector* FFTout=new QLopQCPDataVector(); if(ch1V->data->count()==ch2V->data->count() && ch1V->data->count()==ch3V->data->count()) { double* in; fftw_complex *out; fftw_plan p; FFTout->data = new QVector(ch1V->data->count()/2); in = (double*) fftw_malloc(sizeof(double) * ch1V->data->count()); out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * ch1V->data->count()); double av=0; for(int i=0;idata->count();i++) { in[i]=sqrt((ch1V->data->at(i).value*ch1V->data->at(i).value) + (ch2V->data->at(i).value*ch2V->data->at(i).value) + (ch3V->data->at(i).value*ch3V->data->at(i).value)); av = av+in[i]; } av/=ch1V->data->count(); for(int i=0;idata->count();i++) { in[i]=in[i]-av; } fftw_plan_with_nthreads(4); p = fftw_plan_dft_r2c_1d(ch1V->data->count(),in, out,FFTW_ESTIMATE); fftw_execute(p); /* repeat as needed */ fftw_destroy_plan(p); fftw_free(in); for(int i=0;idata->count()/2;i++) { // (*FFTout->data)[i].value=sqrt((out[i][0] * out[i][0]) + (out[i][1] * out[i][1]))/ch1V->data->count(); (*FFTout->data)[i].value=((out[i][0] * out[i][0]) + (out[i][1] * out[i][1]))/(ch1V->data->count()); (*FFTout->data)[i].key = i; } fftw_free(out); SocExplorerPlot* plot = QLopPlots::getPlot(m_fftPlot); if(plot==NULL) return; plot->removeAllGraphs(); plot->addGraph(); plot->setXaxisLog(); plot->setYaxisLog(); plot->setAdaptativeSampling(0,true); QPen pen = plot->getGraphPen(0); pen.setColor(QLopColours[0%QLopColoursCount]); plot->setGraphPen(0,pen); plot->setGraphData(0,FFTout->data,false); plot->rescaleAxis(); plot->replot(); qDebug()<< ch1V->data->count() <<" Points loaded in "<< timr.elapsed()<<"ms"; } } } } QString CassiniTools::generateFileName(const QString &baseName, const QString &extension) { QString fileName = baseName+extension; int i=0; while(QFile::exists(fileName)) { fileName = baseName+QString::number(i++)+extension; } return fileName; } QDockWidget *CassiniTools::getGUI() { if(!m_noGui && (m_gui==NULL)) { m_gui=new QDockWidget("Cassini Tools"); m_CassiniToolsGUI = new CassiniToolsGUI(); m_gui->setWidget(m_CassiniToolsGUI); m_gui->setFeatures(QDockWidget::DockWidgetMovable|QDockWidget::DockWidgetFloatable); } return m_gui; } const QString &CassiniTools::serviceName() { _INIT(); return m_serviceName; } void CassiniTools::dataReady(QLopDataList data) { static QLopDataList prevData=QLopDataList(); SocExplorerPlot* plot = QLopPlots::getPlot(m_defaultPlot); if(plot==NULL) { makePlot(); plot = QLopPlots::getPlot(m_defaultPlot); } if(plot) { QLopDataBase::removeData(prevData); plot->removeAllGraphs(); // QLopDataBase::re for(int i=0;iaddGraph(); plot->setAdaptativeSampling(i,true); plot->setUseFastVector(i,true); QPen pen = plot->getGraphPen(i); pen.setColor(QLopColours[i%QLopColoursCount]); plot->setGraphPen(i,pen); plot->setGraphName(i,data.at(i)->name+"("+data.at(i)->unit+")"); plot->setGraphData(i,((QLopQCPDataVector*)data.at(i))->data,false); } plot->rescaleAxis(); plot->replot(); prevData = data; QLopDataBase::addData(data); } } void CassiniTools::fileWritten() { SocExplorerPlot* plot = QLopPlots::getPlot(m_defaultPlot); if(plot==NULL) { makePlot(); plot = QLopPlots::getPlot(m_defaultPlot); } if(plot) { QString fileName = QString(plot->title()).replace(".TAB","-part"); fileName = generateFileName(fileName,".TAB"); ExportAction->setText("export view to "+fileName); } }