##// END OF EJS Templates
added quick fileName generation for data export, and fixed wrong date reading...
jeandet -
r10:63067c6877ba default
parent child
Show More
@@ -1,302 +1,306
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the QLop Software
3 3 -- Copyright (C) 2015, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 2 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@member.fsf.org
21 21 ----------------------------------------------------------------------------*/
22 22 #include "cassinidatafile.h"
23 23 #include <QFile>
24 24 #include <stdio.h>
25 25 #include <QDateTime>
26 26 #include <QVector>
27 27 #include <QProgressDialog>
28 28 #include <omp.h>
29 29 #include <QTimer>
30 30 #include <QElapsedTimer>
31 31 #include <sys/time.h>
32 32
33 33 CassiniDataFile::CassiniDataFile(QObject *parent) : AbstractFileLoader(parent)
34 34 {
35 35
36 36 }
37 37
38 38 CassiniDataFile::~CassiniDataFile()
39 39 {
40 40
41 41 }
42 42
43 43 void CassiniDataFile::parseFile(const QString &fileName)
44 44 {
45 45 this->fileName = fileName;
46 46 m_Write = false;
47 47 this->start();
48 48 }
49 49
50 50 void CassiniDataFile::saveFile(const QString &fileName, QLopDataList data)
51 51 {
52 52 this->fileName = fileName;
53 53 m_Write = true;
54 54 m_data = data;
55 55 this->start();
56 56 }
57 57
58 58 inline double __decodeVal(int ofset,unsigned char* data)
59 59 {
60 60 if(data[ofset]=='-')
61 61 return -0.001 * (double)(
62 62 (10000 * (int)(data[ofset+1] & 0x0F))
63 63 + (1000 * (int)(data[ofset+2] & 0x0F))
64 64 + (100 * (int)(data[ofset+4] & 0x0F))
65 65 + (10 * (int)(data[ofset+5] & 0x0F))
66 66 + ( (int)(data[ofset+6] & 0x0F))
67 67 );
68 68 else
69 69 {
70 70 if(data[ofset+1]=='-')
71 71 {
72 72 return -0.001 * (double)(
73 73 (1000 * (int)(data[ofset+2] & 0x0F))
74 74 + (100 * (int)(data[ofset+4] & 0x0F))
75 75 + (10 * (int)(data[ofset+5] & 0x0F))
76 76 + ( (int)(data[ofset+6] & 0x0F))
77 77 );
78 78 }
79 79 else
80 80 {
81 81 return 0.001 * (double)(
82 82 (10000 * (int)(data[ofset+1] & 0x0F))
83 83 + (1000 * (int)(data[ofset+2] & 0x0F))
84 84 + (100 * (int)(data[ofset+4] & 0x0F))
85 85 + (10 * (int)(data[ofset+5] & 0x0F))
86 86 + ( (int)(data[ofset+6] & 0x0F))
87 87 );
88 88 }
89 89 }
90 90 }
91 91
92 92 inline QDate __decodeDate(int ofset,unsigned char* data)
93 93 {
94 94 int y=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + (1*(data[ofset+3] & 0x0F));
95 95 int m=(10*(data[ofset+5] & 0x0F)) + (1*(data[ofset+6] & 0x0F));
96 96 int d=(10*(data[ofset+8] & 0x0F)) + (1*(data[ofset+9] & 0x0F));
97 97 return QDate(y,m,d);
98 98 }
99 99
100 100 inline QTime __decodeTime(int ofset,unsigned char* data)
101 101 {
102 102 int h=(10*(data[ofset] & 0x0F)) + (1*(data[ofset+1] & 0x0F));
103 103 int m=(10*(data[ofset+3] & 0x0F)) + (1*(data[ofset+4] & 0x0F));
104 104 int s=(10*(data[ofset+6] & 0x0F)) + (1*(data[ofset+7] & 0x0F));
105 105 int ms=(100*(data[ofset+9] & 0x0F)) + (10*(data[ofset+10] & 0x0F)) + (1*(data[ofset+11] & 0x0F));
106 106 return QTime(h,m,s,ms);
107 107 }
108 108
109 109 double __decodeTimeFromEpochMs(int ofset,unsigned char* data)
110 110 {
111 111 struct tm t;
112 112 time_t t_of_day;
113 113 t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)) -1900;
114 114 t.tm_mon=(10*(data[ofset+5] & 0x0F)) + ((data[ofset+6] & 0x0F));
115 115 t.tm_mday=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F));
116 116 t.tm_hour=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F));
117 117 t.tm_min=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F));
118 118 t.tm_sec=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F));
119 119 int ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F));
120 120 t_of_day = mktime(&t);
121 121 return (t_of_day*1000.0)+ms;
122 122 }
123 123
124 124 double __decodeTimeFromEpoch(int ofset,unsigned char* data)
125 125 {
126 126 struct tm t;
127 127 time_t t_of_day;
128 128 t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)) -1900;
129 129 t.tm_mon=(10*(data[ofset+5] & 0x0F)) + ((data[ofset+6] & 0x0F));
130 130 t.tm_mday=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F));
131 131 t.tm_hour=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F));
132 132 t.tm_min=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F));
133 133 t.tm_sec=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F));
134 134 double ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F));
135 135 t_of_day = mktime(&t);
136 136 return (double)t_of_day+((double)ms*(double)0.001);
137 137 }
138 138
139 139 double __decodeTimeHMSmS(int ofset,unsigned char* data)
140 140 {
141 141 int h,m,s;
142 142 h=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F));
143 143 m=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F));
144 144 s=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F));
145 145 double ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F));
146 146 return (double)((h*3600)+(m*60)+s) + (ms*0.001);
147 147 }
148 148
149 149 double __decodeTimeDHMSmS(int ofset,unsigned char* data)
150 150 {
151 151 int d,h,m,s;
152 152 d=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F));
153 153 h=(10*(data[ofset+11] & 0x0F)) + ((data[ofset+12] & 0x0F));
154 154 m=(10*(data[ofset+14] & 0x0F)) + ((data[ofset+15] & 0x0F));
155 155 s=(10*(data[ofset+17] & 0x0F)) + ((data[ofset+18] & 0x0F));
156 156 double ms=(100*(data[ofset+20] & 0x0F)) + (10*(data[ofset+21] & 0x0F)) + ((data[ofset+22] & 0x0F));
157 157 return (double)((d*3600*24)+(h*3600)+(m*60)+s) + (ms*0.001);
158 158 }
159 159
160 160 double __decodeTimeFromEpochDayOnly(int ofset,unsigned char* data)
161 161 {
162 162 struct tm t;
163 163 time_t t_of_day;
164 t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)) -1900;
164 // t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F)) -1900;
165 t.tm_year=(1000*(data[ofset] & 0x0F)) + (100*(data[ofset+1] & 0x0F)) + (10*(data[ofset+2] & 0x0F)) + ((data[ofset+3] & 0x0F));
165 166 t.tm_mon=(10*(data[ofset+5] & 0x0F)) + ((data[ofset+6] & 0x0F));
166 167 t.tm_mday=(10*(data[ofset+8] & 0x0F)) + ((data[ofset+9] & 0x0F));
167 168 t.tm_hour=0;
168 169 t.tm_min=0;
169 170 t.tm_sec=0;
170 t_of_day = mktime(&t);
171 return (double)t_of_day;
171 // t_of_day = mktime(&t);
172 // return (double)t_of_day;
173 QDateTime date(QDate(t.tm_year,t.tm_mon,1),QTime(0,0));
174 // date.setDate();
175 return (double)((date.toMSecsSinceEpoch()/1000.0)-(24*3600));
172 176 }
173 177
174 178 void CassiniDataFile::run()
175 179 {
176 180 if(!m_Write)
177 181 {
178 182 readFile();
179 183 }
180 184 else
181 185 {
182 186 writeFile();
183 187 }
184 188 }
185 189
186 190 void CassiniDataFile::readFile()
187 191 {
188 192 FILE* dataFile;
189 193 dataFile = fopen(fileName.toStdString().c_str(),"r");
190 194
191 195 if(dataFile != NULL)
192 196 {
193 197 fseek(dataFile, 0L, SEEK_END);
194 198 int FileSize=ftell(dataFile);
195 199 int lineCnt = FileSize/58;
196 200 int curLine=0;
197 201 int lastLineUpdate=0;
198 202 QVector<QCPData> *ch1=new QVector<QCPData>(lineCnt);
199 203 QVector<QCPData> *ch2=new QVector<QCPData>(lineCnt);
200 204 QVector<QCPData> *ch3=new QVector<QCPData>(lineCnt);
201 205 QLopDataList data;
202 206 QLopData* ch1V=new QLopData();
203 207 QLopData* ch2V=new QLopData();
204 208 QLopData* ch3V=new QLopData();
205 209 ch1V->data=ch1;
206 210 ch2V->data=ch2;
207 211 ch3V->data=ch3;
208 212 ch1V->name="r";
209 213 ch2V->name="theta";
210 214 ch3V->name="phi";
211 215 ch1V->unit="nT";
212 216 ch2V->unit="nT";
213 217 ch3V->unit="nT";
214 218 data.append(ch1V);
215 219 data.append(ch2V);
216 220 data.append(ch3V);
217 221 QElapsedTimer timr;
218 222
219 223 double _x=0.0,day=0.0;
220 224 char* line;
221 225 QCPData data1,data2,data3;
222 226 char* fileContent=(char*)malloc(FileSize);
223 227 if(Q_UNLIKELY(fileContent==NULL))return;
224 228 int threadIndex,numThreads=omp_get_num_threads();
225 229 int updateTriger=(lineCnt/100)/numThreads;
226 230 fseek(dataFile, 0L, SEEK_SET);
227 231 char* svglocale=NULL;
228 232 setlocale(LC_NUMERIC,svglocale);
229 233 setlocale(LC_NUMERIC, "en_US");
230 234 if(fread(fileContent,1,FileSize,dataFile))
231 235 {
232 236 line = fileContent;
233 237 QDateTime date;
234 238 timr.start();
235 239 day=__decodeTimeFromEpochDayOnly(0,(unsigned char*)line);
236 240 //#pragma omp parallel if ((FileSize > 10000000)) private(date,data1,data2,data3,_x,threadIndex,lastLineUpdate) shared(ch1,ch2,ch3,lineCnt)
237 241 // {
238 242 #pragma omp parallel for if ((FileSize > 1024*1024*10)) private(date,data1,data2,data3,_x,threadIndex,lastLineUpdate,curLine) shared(ch1,ch2,ch3,lineCnt,updateTriger)
239 243 for(int i=0;i<lineCnt;i++)
240 244 {
241 245 // _x= i;
242 246 _x= day + __decodeTimeDHMSmS((i*58),(unsigned char*)line);
243 247 // _x=__decodeTimeFromEpoch((i*58),(unsigned char*)line);
244 248 data1.key=_x;
245 249 data2.key=_x;
246 250 data3.key=_x;
247 251 data1.value=__decodeVal(((i*58)+27),(unsigned char*)line);
248 252 data2.value=__decodeVal(((i*58)+38),(unsigned char*)line);
249 253 data3.value=__decodeVal(((i*58)+49),(unsigned char*)line);
250 254 (*ch1)[i]=data1;
251 255 (*ch2)[i]=data2;
252 256 (*ch3)[i]=data3;
253 257 curLine++;
254 258 if(Q_UNLIKELY(lastLineUpdate++>updateTriger))
255 259 {
256 260 lastLineUpdate=0;
257 261 int test=((curLine*numThreads *100)/ (lineCnt));
258 262 emit updateProgress(omp_get_thread_num(),test);
259 263 }
260 264 }
261 265 }
262 266 //#pragma omp barrier
263 267 free(fileContent);
264 268 // }
265 269 qDebug()<< lineCnt <<" Points loade in "<< timr.elapsed()<<"ms";
266 270 setlocale(LC_NUMERIC,svglocale);
267 271 emit dataReady(data);
268 272 }
269 273 }
270 274
271 275 void CassiniDataFile::writeFile()
272 276 {
273 277 QFile dataFile(fileName);
274 278 dataFile.open(QIODevice::WriteOnly);
275 279 QTextStream out(&dataFile);
276 280 if(dataFile.isOpen())
277 281 {
278 282 if(m_data.count()==3)
279 283 {
280 284 QLopData* ch1V=m_data.at(0);
281 285 QLopData* ch2V=m_data.at(1);
282 286 QLopData* ch3V=m_data.at(2);
283 287 if(ch1V->data->count()==ch2V->data->count() && ch1V->data->count()==ch3V->data->count())
284 288 {
285 289 for(int i=0;i<ch1V->data->count();i++)
286 290 {
287 291 double key = ch1V->data->at(i).key;
288 292 QDateTime date = QDateTime::fromMSecsSinceEpoch(key*1000);
289 293 out << date.toString(Qt::ISODate)+QString(".%1").arg(date.time().msec(),3);
290 294 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);
291 295 out << "\r\n";
292 296 }
293 297 }
294 298 dataFile.flush();
295 299 m_data.clear();
296 300 delete ch1V;
297 301 delete ch2V;
298 302 delete ch3V;
299 303 }
300 304 }
301 305 }
302 306
@@ -1,248 +1,277
1 1 #include "cassinitools.h"
2 2 #include <qlopplots.h>
3 3 #include <QPen>
4 4 #include <QAction>
5 5 #include <fftw3.h>
6 6
7 7 CassiniTools* CassiniTools::_self=NULL;
8 8 QDockWidget* CassiniTools::m_gui=NULL;
9 9 CassiniToolsGUI* CassiniTools::m_CassiniToolsGUI=NULL;
10 10 CassiniDataFile* CassiniTools::m_dataFile=NULL;
11 11 int CassiniTools::m_defaultPlot=-1;
12 12 int CassiniTools::m_fftPlot=-1;
13 SocExplorerPlotActions* CassiniTools::ExportAction=NULL;
13 14
14 15 Qt::GlobalColor QLopColours[]= {Qt::black,
15 16 Qt::red,
16 17 Qt::blue,
17 18 Qt::green,
18 19 Qt::darkGreen,
19 20 Qt::cyan,
20 21 Qt::darkRed,
21 22 Qt::gray,
22 23 Qt::yellow,
23 24 Qt::darkBlue,
24 25 Qt::darkCyan,
25 26 Qt::magenta,
26 27 Qt::darkMagenta,
27 28 Qt::darkYellow,
28 29 Qt::darkGray,
29 30 Qt::lightGray};
30 31
31 32 int QLopColoursCount=16;
32 33
33 34 #define _INIT() if(Q_UNLIKELY(_self==NULL)){init();}
34 35
35 36 CassiniTools::CassiniTools(bool noGUI,QObject *parent) : QLopService(parent)
36 37 {
37 38 m_dataFile = new CassiniDataFile();
38 39 connect(m_dataFile,SIGNAL(dataReady(QLopDataList)),this,SLOT(dataReady(QLopDataList)));
39 40 m_serviceName="CassiniTools";
40 41 m_noGui=noGUI;
41 42 }
42 43
43 44 CassiniTools::~CassiniTools()
44 45 {
45 46 delete m_dataFile;
46 47 delete m_CassiniToolsGUI;
47 48 delete m_gui;
48 49 }
49 50
50 51 void CassiniTools::makePlot()
51 52 {
52 53 m_defaultPlot = QLopPlots::addPlot();
53 54 m_fftPlot = QLopPlots::addPlot();
54 55 SocExplorerPlot* plot=QLopPlots::getPlot(m_defaultPlot);
55 56 if(plot)
56 57 {
57 58 plot->setTitle(_self->m_serviceName + " plot");
58 59 plot->setXaxisTickLabelType(QCPAxis::ltDateTime);
59 60 plot->setXaxisDateTimeFormat("hh:mm:ss.zzz");
60 61 plot->setContextMenuPolicy(Qt::ActionsContextMenu);
61 62 SocExplorerPlotActions* action=new SocExplorerPlotActions("export view",plot->PID(),_self);
62 63 plot->addAction(action);
63 64 QObject::connect(action,SIGNAL(triggered(int)),_self,SLOT(export_view(int)));
65 ExportAction=new SocExplorerPlotActions("export view to "+QString(plot->title()).replace(".TAB","-part.TAB"),plot->PID(),_self);
66 plot->addAction(ExportAction);
67 QObject::connect(ExportAction,SIGNAL(triggered(int)),_self,SLOT(export_view_Predefined_FileName(int)));
64 68 action=new SocExplorerPlotActions("FFT of the current view",plot->PID(),_self);
65 69 plot->addAction(action);
66 70 QObject::connect(action,SIGNAL(triggered(int)),_self,SLOT(compute_fft_on_view(int)));
67 71 }
68 72 }
69 73
70 74 void CassiniTools::init(bool noGUI, QObject *parent)
71 75 {
72 76 if(Q_UNLIKELY(_self==NULL))
73 77 {
74 78 _self=new CassiniTools(noGUI,parent);
75 79 }
76 80 }
77 81
78 82 CassiniTools *CassiniTools::self()
79 83 {
80 84 _INIT();
81 85 return _self;
82 86 }
83 87
84 88 void CassiniTools::decodeFGMData(const QString &file)
85 89 {
86 90 _INIT();
87 91 m_dataFile->parseFile(file);
88 92 }
89 93
90 94 void CassiniTools::plotFile(const QString &File)
91 95 {
92 96 if(!m_dataFile->isRunning())
93 97 {
94 98 m_dataFile->parseFile(File);
95 99 // TODO fixme
96 100 SocExplorerPlot* plot = QLopPlots::getPlot(m_defaultPlot);
97 101 if(plot==NULL)
98 102 {
99 103 makePlot();
100 104 plot = QLopPlots::getPlot(m_defaultPlot);
101 105 }
102 106 if(plot)
107 {
103 108 plot->setTitle(File);
109 ExportAction->setText("export view to "+QString(File).replace(".TAB","-part.TAB"));
110 }
104 111 }
105 112 }
106 113
107 114 void CassiniTools::plot_TAB_File(const QString &fileName)
108 115 {
109 116 //TODO fix: accent not accepted
110 117 plotFile(fileName);
111 118 }
112 119
113 120 void CassiniTools::export_view(int PID)
114 121 {
115 122 SocExplorerPlot* plot = QLopPlots::getPlot(PID);
116 123 if(plot==NULL)
117 124 return;
118 125 {
119 QString fileName = QFileDialog::getSaveFileName();
126 QString fileName = plot->title();
127 fileName = QFileDialog::getSaveFileName(0,tr("Set filename"),fileName.replace(".TAB","-part.TAB"));
128 if(fileName!="")
129 {
130 QLopDataList vectors;
131 for(int i=0;i<plot->graphCount();i++)
132 {
133 QLopData* vect = new QLopData();
134 vect->data = plot->getVisibleData(i);
135 vectors.append(vect);
136 }
137 m_dataFile->saveFile(fileName,vectors);
138 }
139 }
140 }
141
142 void CassiniTools::export_view_Predefined_FileName(int PID)
143 {
144 SocExplorerPlot* plot = QLopPlots::getPlot(PID);
145 if(plot==NULL)
146 return;
147 {
148 QString fileName = QString(plot->title()).replace(".TAB","-part.TAB");
120 149 if(fileName!="")
121 150 {
122 151 QLopDataList vectors;
123 152 for(int i=0;i<plot->graphCount();i++)
124 153 {
125 154 QLopData* vect = new QLopData();
126 155 vect->data = plot->getVisibleData(i);
127 156 vectors.append(vect);
128 157 }
129 158 m_dataFile->saveFile(fileName,vectors);
130 159 }
131 160 }
132 161 }
133 162
134 163 void CassiniTools::compute_fft_on_view(int PID)
135 164 {
136 165 SocExplorerPlot* plot = QLopPlots::getPlot(PID);
137 166 if(plot==NULL)
138 167 return;
139 168 {
140 169 QLopDataList vectors;
141 170 for(int i=0;i<plot->graphCount();i++)
142 171 {
143 172 QLopData* vect = new QLopData();
144 173 vect->data = plot->getVisibleData(i);
145 174 vectors.append(vect);
146 175 }
147 176 if(vectors.count()==3)
148 177 {
149 178 QLopData* ch1V=vectors.at(0);
150 179 QLopData* ch2V=vectors.at(1);
151 180 QLopData* ch3V=vectors.at(2);
152 181 QLopData* FFTout=new QLopData();
153 182 if(ch1V->data->count()==ch2V->data->count() && ch1V->data->count()==ch3V->data->count())
154 183 {
155 184
156 185 double* in;
157 186 fftw_complex *out;
158 187 fftw_plan p;
159 188 FFTout->data = new QVector<QCPData>(ch1V->data->count()/2);
160 189 in = (double*) fftw_malloc(sizeof(double) * ch1V->data->count());
161 190 out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * ch1V->data->count());
162 191 double av=0;
163 192 for(int i=0;i<ch1V->data->count();i++)
164 193 {
165 194 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));
166 195 av = av+in[i];
167 196 }
168 197 av/=ch1V->data->count();
169 198 for(int i=0;i<ch1V->data->count();i++)
170 199 {
171 200 in[i]=in[i]-av;
172 201 }
173 202 p = fftw_plan_dft_r2c_1d(ch1V->data->count(),in, out,FFTW_ESTIMATE);
174 203 fftw_execute(p); /* repeat as needed */
175 204 fftw_destroy_plan(p);
176 205 fftw_free(in);
177 206 for(int i=0;i<ch1V->data->count()/2;i++)
178 207 {
179 208 // (*FFTout->data)[i].value=sqrt((out[i][0] * out[i][0]) + (out[i][1] * out[i][1]))/ch1V->data->count();
180 209 (*FFTout->data)[i].value=((out[i][0] * out[i][0]) + (out[i][1] * out[i][1]))/(ch1V->data->count());
181 210 (*FFTout->data)[i].key = i;
182 211 }
183 212 fftw_free(out);
184 213 SocExplorerPlot* plot = QLopPlots::getPlot(m_fftPlot);
185 214 if(plot==NULL)
186 215 return;
187 216 plot->removeAllGraphs();
188 217 plot->addGraph();
189 218 plot->setXaxisLog();
190 219 plot->setYaxisLog();
191 220 plot->setAdaptativeSampling(0,true);
192 221 QPen pen = plot->getGraphPen(0);
193 222 pen.setColor(QLopColours[0%QLopColoursCount]);
194 223 plot->setGraphPen(0,pen);
195 224 plot->setGraphData(0,FFTout->data,false);
196 225 plot->rescaleAxis();
197 226 plot->replot();
198 227
199 228 }
200 229 }
201 230 }
202 231 }
203 232
204 233 QDockWidget *CassiniTools::getGUI()
205 234 {
206 235 if(!m_noGui && (m_gui==NULL))
207 236 {
208 237 m_gui=new QDockWidget("Cassini Tools");
209 238 m_CassiniToolsGUI = new CassiniToolsGUI();
210 239 m_gui->setWidget(m_CassiniToolsGUI);
211 240 m_gui->setFeatures(QDockWidget::DockWidgetMovable|QDockWidget::DockWidgetFloatable);
212 241 }
213 242 return m_gui;
214 243 }
215 244
216 245 const QString &CassiniTools::serviceName()
217 246 {
218 247 _INIT();
219 248 return m_serviceName;
220 249 }
221 250
222 251 void CassiniTools::dataReady(QLopDataList data)
223 252 {
224 253 SocExplorerPlot* plot = QLopPlots::getPlot(m_defaultPlot);
225 254 if(plot==NULL)
226 255 {
227 256 makePlot();
228 257 plot = QLopPlots::getPlot(m_defaultPlot);
229 258 }
230 259 if(plot)
231 260 {
232 261 plot->removeAllGraphs();
233 262 for(int i=0;i<data.count();i++)
234 263 {
235 264 plot->addGraph();
236 265 plot->setAdaptativeSampling(i,true);
237 266 plot->setUseFastVector(i,true);
238 267 QPen pen = plot->getGraphPen(i);
239 268 pen.setColor(QLopColours[i%QLopColoursCount]);
240 269 plot->setGraphPen(i,pen);
241 270 plot->setGraphName(i,data.at(i)->name+"("+data.at(i)->unit+")");
242 271 plot->setGraphData(i,data.at(i)->data,false);
243 272 }
244 273 plot->rescaleAxis();
245 274 plot->replot();
246 275 }
247 276 }
248 277
@@ -1,41 +1,43
1 1 #ifndef CASSINITOOLS_H
2 2 #define CASSINITOOLS_H
3 3
4 4 #include <QObject>
5 5 #include <QWidget>
6 6 #include <qlopservice.h>
7 7 #include <cassinitoolsgui.h>
8 8 #include <cassinidatafile.h>
9 9 #include <qlopdata.h>
10 10 #include <SocExplorerPlot.h>
11 11
12 12 class CassiniTools: public QLopService
13 13 {
14 14 Q_OBJECT
15 15 private:
16 16 static CassiniTools* _self;
17 17 static QDockWidget* m_gui;
18 18 static CassiniToolsGUI* m_CassiniToolsGUI;
19 19 static CassiniDataFile* m_dataFile;
20 20 static int m_defaultPlot,m_fftPlot;
21 static SocExplorerPlotActions* ExportAction;
21 22 CassiniTools(bool noGUI=false, QObject *parent=0);
22 23 ~CassiniTools();
23 24 static void makePlot();
24 25 public:
25 26 static void init(bool noGUI=false,QObject *parent = 0);
26 27 static CassiniTools *self();
27 28 static void decodeFGMData(const QString& file);
28 29 // QLopService methodes
29 30 QDockWidget* getGUI();
30 31 const QString& serviceName();
31 32 static void plotFile(const QString &File);
32 33 public slots:
33 34 void plot_TAB_File(const QString& fileName);
34 35 void export_view(int PID);
36 void export_view_Predefined_FileName(int PID);
35 37 void compute_fft_on_view(int PID);
36 38 private slots:
37 39 void dataReady(QLopDataList data);
38 40 };
39 41
40 42 #endif // CASSINITOOLS_H
41 43
@@ -1,654 +1,669
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the QLop Software
3 3 -- Copyright (C) 2015, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 2 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@member.fsf.org
21 21 ----------------------------------------------------------------------------*/
22 22 #include "SocExplorerPlot.h"
23 23 #include <QSvgGenerator>
24 24 #include <qcpdocumentobject.h>
25 25 #include <QPdfWriter>
26 26 #include <QPrinter>
27 27
28 28 SocExplorerPlot::SocExplorerPlot(QWidget *parent) :
29 29 QWidget(parent), mRubberBand(new QRubberBand(QRubberBand::Rectangle, this))
30 30 {
31 31 this->m_plot = new QCustomPlotVect(this);
32 32 this->m_plot->setInteractions(QCP::iRangeDrag | QCP::iSelectAxes |
33 33 QCP::iSelectLegend | QCP::iSelectPlottables);
34 34 this->m_plot->axisRect()->setRangeDrag(Qt::Horizontal|Qt::Vertical);
35 35 this->m_plot->axisRect()->setRangeZoom(Qt::Horizontal|Qt::Vertical);
36 36 this->m_mainlayout = new QGridLayout(this);
37 37 this->setLayout(this->m_mainlayout);
38 38 this->m_mainlayout->addWidget(this->m_plot);
39 39 this->setMinimumSize(400,300);
40 40 this->setFocusPolicy(Qt::WheelFocus);
41 41 this->m_plot->setAttribute(Qt::WA_TransparentForMouseEvents);
42 42 this->ctrl_hold = false;
43 43 this->shift_hold = false;
44 44 this->mouse_hold = false;
45 45 this->m_plot->setNoAntialiasingOnDrag(true);
46 46 this->show();
47 47 this->m_plot->legend->setVisible(true);
48 48 }
49 49
50 50 SocExplorerPlot::~SocExplorerPlot()
51 51 {
52 52 delete mRubberBand;
53 53 }
54 54
55 55 void SocExplorerPlot::show()
56 56 {
57 57 QWidget::show();
58 58 }
59 59
60 60 void SocExplorerPlot::replot()
61 61 {
62 62 this->m_plot->replot();
63 63 }
64 64
65 65 void SocExplorerPlot::exportToSVG(const QString &fileName)
66 66 {
67 67 QSvgGenerator printer;
68 68 printer.setFileName(fileName);
69 69 QCPPainter qcpPainter;
70 70 qcpPainter.begin(&printer);
71 71 m_plot->toPainter(&qcpPainter, m_plot->width(), m_plot->height());
72 72 qcpPainter.end();
73 73 }
74 74
75 75 void SocExplorerPlot::exportToPDF(const QString &fileName)
76 76 {
77 77 QPrinter printer(QPrinter::HighResolution);
78 78 printer.setOutputFormat(QPrinter::PdfFormat);
79 79 printer.setOrientation(QPrinter::Landscape);
80 80 printer.setOutputFileName(fileName);
81 81 printer.setFullPage(true);
82 82 QCPPainter qcpPainter;
83 83 qcpPainter.begin(&printer);
84 84 m_plot->toPainter(&qcpPainter, printer.width(), printer.height());
85 85 qcpPainter.end();
86 86 }
87 87
88 88 void SocExplorerPlot::addAction(SocExplorerPlotActions *action)
89 89 {
90 90 this->m_actions.append(action);
91 91 QWidget::addAction((QAction*)action);
92 92 }
93 93
94 94 QVector<QCPData> *SocExplorerPlot::getVisibleData(int graphIndex)
95 95 {
96 96 QVector<QCPData> *visibleData=((QCPGraphVect*)m_plot->graph(graphIndex))->getVisibleData();
97 97 return visibleData;
98 98 }
99 99
100 100 void SocExplorerPlot::setTitle(QString title)
101 101 {
102 102 Q_UNUSED(title)
103 103 //this->m_plot->setTitle(title);
104 104 /*!
105 105 @todo Function borcken fixe this!
106 106 */
107 this->m_Title = title;
107 108 emit titleChanged(title);
108 109 this->repaint();
109 110 }
110 111
112 const QString &SocExplorerPlot::title()
113 {
114 return m_Title;
115 }
116
111 117 void SocExplorerPlot::setXaxisLabel(QString label)
112 118 {
113 119 this->m_plot->xAxis->setLabel(label);
114 120 this->repaint();
115 121 }
116 122
117 123 void SocExplorerPlot::setXaxisLog()
118 124 {
119 125 this->m_plot->xAxis->setScaleType(QCPAxis::stLogarithmic);
120 126 }
121 127
122 128 void SocExplorerPlot::setYaxisLabel(QString label)
123 129 {
124 130 this->m_plot->yAxis->setLabel(label);
125 131 this->repaint();
126 132 }
127 133
128 134 void SocExplorerPlot::setYaxisLog()
129 135 {
130 136 this->m_plot->yAxis->setScaleType(QCPAxis::stLogarithmic);
131 137 }
132 138
133 139 void SocExplorerPlot::setXaxisRange(double lower, double upper)
134 140 {
135 141 this->m_plot->xAxis->setRange(lower,upper);
136 142 }
137 143
138 144 void SocExplorerPlot::setYaxisRange(double lower, double upper)
139 145 {
140 146 this->m_plot->yAxis->setRange(lower,upper);
141 147 }
142 148
143 149
144 150 void SocExplorerPlot::rescaleAxis()
145 151 {
146 152 this->m_plot->rescaleAxes();
147 153 this->m_plot->replot();
148 154 }
149 155
150 156 void SocExplorerPlot::setLegendFont(QFont font)
151 157 {
152 158 this->m_plot->legend->setFont(font);
153 159 this->repaint();
154 160 }
155 161
156 162 void SocExplorerPlot::setLegendSelectedFont(QFont font)
157 163 {
158 164 this->m_plot->legend->setSelectedFont(font);
159 165 this->repaint();
160 166 }
161 167
162 168 void SocExplorerPlot::setAdaptativeSampling(int graphIndex, bool enable)
163 169 {
164 170 this->m_plot->graph(graphIndex)->setAdaptiveSampling(enable);
165 171 }
166 172
167 173 void SocExplorerPlot::setUseFastVector(int graphIndex, bool enable)
168 174 {
169 175 // TODO deprecated
170 176 // this->m_plot->graph(graphIndex)->setUseFastVectors(enable);
171 177 }
172 178
173 179 int SocExplorerPlot::addGraph()
174 180 {
175 181 this->m_plot->addGraph();
176 182 return this->m_plot->graphCount() -1;
177 183 }
178 184
179 185 bool SocExplorerPlot::removeGraph(int graphIndex)
180 186 {
181 187 return this->m_plot->removeGraph(graphIndex);
182 188 }
183 189
184 190 int SocExplorerPlot::graphCount()
185 191 {
186 192 return m_plot->graphCount();
187 193 }
188 194
189 195 void SocExplorerPlot::removeAllGraphs()
190 196 {
191 197 int graphCount=this->m_plot->graphCount();
192 198 for(int i=0;i<graphCount;i++)
193 199 {
194 200 this->m_plot->removeGraph(0);
195 201 }
196 202 }
197 203
198 204
199 205 void SocExplorerPlot::setGraphName(int graphIndex,QString name)
200 206 {
201 207 if(graphIndex<this->m_plot->graphCount())
202 208 {
203 209 this->m_plot->graph(graphIndex)->setName(name);
204 210 }
205 211 }
206 212
213 const QString &SocExplorerPlot::graphName(int graphIndex)
214 {
215 if(graphIndex<this->m_plot->graphCount())
216 {
217 return this->m_plot->graph(graphIndex)->name();
218 }
219 return "";
220 }
221
207 222
208 223 void SocExplorerPlot::setGraphData(int graphIndex, QList<QVariant> x, QList<QVariant> y)
209 224 {
210 225 if((graphIndex<this->m_plot->graphCount()) && (x.count()==y.count()) && (x.at(0).type()==QVariant::Double))
211 226 {
212 227 QVector<double> _x(x.count()), _y(y.count());
213 228 for(int i=0;i<x.count();i++)
214 229 {
215 230 /*_x[i] = x.at(i).value<double>();
216 231 _y[i] = y.at(i).value<double>();*/
217 232 _x[i] = x.at(i).toDouble();
218 233 _y[i] = y.at(i).toDouble();
219 234 }
220 235 this->m_plot->graph(graphIndex)->setData(_x,_y);
221 236 }
222 237 else
223 238 {
224 239 if((graphIndex<this->m_plot->graphCount()) && (x.count()==y.count()) && (x.at(0).type()==QVariant::DateTime))
225 240 {
226 241 QVector<double> _x(x.count()), _y(y.count());
227 242 for(int i=0;i<x.count();i++)
228 243 {
229 244 /*_x[i] = x.at(i).value<double>();
230 245 _y[i] = y.at(i).value<double>();*/
231 246 _x[i] = x.at(i).toDateTime().toMSecsSinceEpoch();
232 247 _y[i] = y.at(i).toDouble();
233 248 }
234 249 this->m_plot->graph(graphIndex)->setData(_x,_y);
235 250 this->m_plot->xAxis->setTickLabelType(QCPAxis::ltDateTime);
236 251 this->m_plot->xAxis->setDateTimeFormat("hh:mm:ss.zzz");
237 252
238 253 }
239 254 }
240 255 this->m_plot->replot();
241 256 }
242 257
243 258 void SocExplorerPlot::setGraphData(int graphIndex, QCPDataMap *data, bool copy, bool replot)
244 259 {
245 260 if((graphIndex<this->m_plot->graphCount()))// && (x.at(0).type()==QVariant::Double))
246 261 {
247 262 this->m_plot->graph(graphIndex)->setData(data,copy);
248 263 }
249 264 if(replot)
250 265 this->m_plot->replot();
251 266 }
252 267
253 268 void SocExplorerPlot::setGraphData(int graphIndex,QVector<QCPData> *data, bool replot)
254 269 {
255 270 if((graphIndex<this->m_plot->graphCount()))// && (x.at(0).type()==QVariant::Double))
256 271 {
257 272 ((QCPGraphVect*)this->m_plot->graph(graphIndex))->setData(data);
258 273 }
259 274 if(replot)
260 275 this->m_plot->replot();
261 276 }
262 277
263 278 void SocExplorerPlot::addGraphData(int graphIndex, QList<QVariant> x, QList<QVariant> y)
264 279 {
265 280 if((graphIndex<this->m_plot->graphCount()) && (x.count()==y.count()))// && (x.at(0).type()==QVariant::Double))
266 281 {
267 282 QVector<double> _x(x.count()), _y(y.count());
268 283 for(int i=0;i<x.count();i++)
269 284 {
270 285 /*_x[i] = x.at(i).value<double>();
271 286 _y[i] = y.at(i).value<double>();*/
272 287 _x[i] = x.at(i).toDouble();
273 288 _y[i] = y.at(i).toDouble();
274 289 }
275 290 this->m_plot->graph(graphIndex)->addData(_x,_y);
276 291 }
277 292 this->m_plot->replot();
278 293 }
279 294
280 295 void SocExplorerPlot::addGraphData(int graphIndex, QVariant x, QVariant y)
281 296 {
282 297 if(graphIndex<this->m_plot->graphCount())// && (x.at(0).type()==QVariant::Double))
283 298 {
284 299 this->m_plot->graph(graphIndex)->addData(x.toDouble(),y.toDouble());
285 300 }
286 301 this->m_plot->replot();
287 302 }
288 303
289 304 void SocExplorerPlot::setGraphPen(int graphIndex,QPen pen)
290 305 {
291 306 if(graphIndex<this->m_plot->graphCount())
292 307 {
293 308 this->m_plot->graph(graphIndex)->setPen(pen);
294 309 }
295 310 }
296 311
297 312 QPen SocExplorerPlot::getGraphPen(int graphIndex)
298 313 {
299 314 if(graphIndex<this->m_plot->graphCount())
300 315 {
301 316 return this->m_plot->graph(graphIndex)->pen();
302 317 }
303 318 return this->m_plot->graph()->pen();
304 319 }
305 320
306 321
307 322
308 323 void SocExplorerPlot::setGraphLineStyle(int graphIndex,QString lineStyle)
309 324 {
310 325 if(graphIndex<this->m_plot->graphCount())
311 326 {
312 327 if(!lineStyle.compare("none"))
313 328 {
314 329 this->m_plot->graph(graphIndex)->setLineStyle(QCPGraph::lsNone);
315 330 return;
316 331 }
317 332 if(!lineStyle.compare("line"))
318 333 {
319 334 this->m_plot->graph(graphIndex)->setLineStyle(QCPGraph::lsLine);
320 335 return;
321 336 }
322 337 if(!lineStyle.compare("stepleft"))
323 338 {
324 339 this->m_plot->graph(graphIndex)->setLineStyle(QCPGraph::lsStepLeft);
325 340 return;
326 341 }
327 342 if(!lineStyle.compare("stepright"))
328 343 {
329 344 this->m_plot->graph(graphIndex)->setLineStyle(QCPGraph::lsStepRight);
330 345 return;
331 346 }
332 347 if(!lineStyle.compare("stepcenter"))
333 348 {
334 349 this->m_plot->graph(graphIndex)->setLineStyle(QCPGraph::lsStepCenter);
335 350 return;
336 351 }
337 352 if(!lineStyle.compare("impulse"))
338 353 {
339 354 this->m_plot->graph(graphIndex)->setLineStyle(QCPGraph::lsImpulse);
340 355 return;
341 356 }
342 357
343 358
344 359 }
345 360 }
346 361
347 362 void SocExplorerPlot::setGraphScatterStyle(int graphIndex,QString scatterStyle)
348 363 {
349 364 if(graphIndex<this->m_plot->graphCount())
350 365 {
351 366 if(!scatterStyle.compare("none"))
352 367 {
353 368 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssNone);
354 369 return;
355 370 }
356 371 if(!scatterStyle.compare("dot"))
357 372 {
358 373 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssDot);
359 374 return;
360 375 }
361 376 if(!scatterStyle.compare("cross"))
362 377 {
363 378 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssCross);
364 379 return;
365 380 }
366 381 if(!scatterStyle.compare("plus"))
367 382 {
368 383 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssPlus);
369 384 return;
370 385 }
371 386 if(!scatterStyle.compare("circle"))
372 387 {
373 388 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssCircle);
374 389 return;
375 390 }
376 391 if(!scatterStyle.compare("disc"))
377 392 {
378 393 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssDisc);
379 394 return;
380 395 }
381 396 if(!scatterStyle.compare("square"))
382 397 {
383 398 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssSquare);
384 399 return;
385 400 }
386 401 if(!scatterStyle.compare("diamond"))
387 402 {
388 403 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssDiamond);
389 404 return;
390 405 }
391 406 if(!scatterStyle.compare("star"))
392 407 {
393 408 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssStar);
394 409 return;
395 410 }
396 411 if(!scatterStyle.compare("triangle"))
397 412 {
398 413 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssTriangle);
399 414 return;
400 415 }
401 416 if(!scatterStyle.compare("invertedtriangle"))
402 417 {
403 418 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssTriangleInverted);
404 419 return;
405 420 }
406 421 if(!scatterStyle.compare("crosssquare"))
407 422 {
408 423 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssCrossSquare);
409 424 return;
410 425 }
411 426 if(!scatterStyle.compare("plussquare"))
412 427 {
413 428 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssPlusSquare);
414 429 return;
415 430 }
416 431 if(!scatterStyle.compare("crosscircle"))
417 432 {
418 433 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssCrossCircle);
419 434 return;
420 435 }
421 436 if(!scatterStyle.compare("pluscircle"))
422 437 {
423 438 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssPlusCircle);
424 439 return;
425 440 }
426 441 if(!scatterStyle.compare("peace"))
427 442 {
428 443 this->m_plot->graph(graphIndex)->setScatterStyle(QCPScatterStyle::ssPeace);
429 444 return;
430 445 }
431 446
432 447 }
433 448 }
434 449
435 450 void SocExplorerPlot::setXaxisTickLabelType(QCPAxis::LabelType type)
436 451 {
437 452 this->m_plot->xAxis->setTickLabelType(type);
438 453 }
439 454
440 455 void SocExplorerPlot::setXaxisDateTimeFormat(const QString &format)
441 456 {
442 457 this->m_plot->xAxis->setDateTimeFormat(format);
443 458 }
444 459
445 460
446 461
447 462
448 463
449 464 void SocExplorerPlot::keyPressEvent(QKeyEvent * event)
450 465 {
451 466 switch(event->key())
452 467 {
453 468 case Qt::Key_Control:
454 469 this->ctrl_hold = true;
455 470 setCursor(Qt::CrossCursor);
456 471 break;
457 472 case Qt::Key_Shift:
458 473 this->shift_hold = true;
459 474 break;
460 475 case Qt::Key_M:
461 476 this->rescaleAxis();
462 477 break;
463 478 case Qt::Key_Left:
464 479 if(!ctrl_hold)
465 480 {
466 481 move(-0.1,Qt::Horizontal);
467 482 }
468 483 else
469 484 {
470 485 zoom(2,this->width()/2,Qt::Horizontal);
471 486 }
472 487 break;
473 488 case Qt::Key_Right:
474 489 if(!ctrl_hold)
475 490 {
476 491 move(0.1,Qt::Horizontal);
477 492 }
478 493 else
479 494 {
480 495 zoom(0.5,this->width()/2,Qt::Horizontal);
481 496 }
482 497 break;
483 498 case Qt::Key_Up:
484 499 if(!ctrl_hold)
485 500 {
486 501 move(0.1,Qt::Vertical);
487 502 }
488 503 else
489 504 {
490 505 zoom(0.5,this->height()/2,Qt::Vertical);
491 506 }
492 507 break;
493 508 case Qt::Key_Down:
494 509 if(!ctrl_hold)
495 510 {
496 511 move(-0.1,Qt::Vertical);
497 512 }
498 513 else
499 514 {
500 515 zoom(2,this->height()/2,Qt::Vertical);
501 516 }
502 517 break;
503 518 default:
504 519 QWidget::keyPressEvent(event);
505 520 break;
506 521 }
507 522 }
508 523
509 524 void SocExplorerPlot::keyReleaseEvent(QKeyEvent * event)
510 525 {
511 526 switch(event->key())
512 527 {
513 528 case Qt::Key_Control:
514 529 event->accept();
515 530 this->ctrl_hold = false;
516 531 break;
517 532 case Qt::Key_Shift:
518 533 event->accept();
519 534 this->shift_hold = false;
520 535 break;
521 536 default:
522 537 QWidget::keyReleaseEvent(event);
523 538 break;
524 539 }
525 540 setCursor(Qt::ArrowCursor);
526 541 }
527 542
528 543 void SocExplorerPlot::wheelEvent(QWheelEvent * event)
529 544 {
530 545 double factor;
531 546 double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually
532 547 if(ctrl_hold)
533 548 {
534 549 if (event->orientation()==Qt::Vertical)//mRangeZoom.testFlag(Qt::Vertical))
535 550 {
536 551 setCursor(Qt::SizeVerCursor);
537 552 factor = pow(this->m_plot->axisRect()->rangeZoomFactor(Qt::Vertical), wheelSteps);
538 553 zoom(factor,event->pos().y(),Qt::Vertical);
539 554 }
540 555 QWidget::wheelEvent(event);
541 556 return;
542 557 }
543 558 if(shift_hold)
544 559 {
545 560 if (event->orientation()==Qt::Vertical)//mRangeZoom.testFlag(Qt::Vertical))
546 561 {
547 562 setCursor(Qt::SizeHorCursor);
548 563 factor = pow(this->m_plot->axisRect()->rangeZoomFactor(Qt::Horizontal), wheelSteps);
549 564 zoom(factor,event->pos().x(),Qt::Horizontal);
550 565 }
551 566 QWidget::wheelEvent(event);
552 567 return;
553 568 }
554 569 move(wheelSteps/10,Qt::Horizontal);
555 570 QWidget::wheelEvent(event);
556 571 }
557 572
558 573
559 574
560 575
561 576 void SocExplorerPlot::mousePressEvent(QMouseEvent *event)
562 577 {
563 578 if(event->button()==Qt::LeftButton)
564 579 {
565 580 if(ctrl_hold)
566 581 {
567 582 setCursor(Qt::CrossCursor);
568 583 mOrigin = event->pos();
569 584 mRubberBand->setGeometry(QRect(mOrigin, QSize()));
570 585 mRubberBand->show();
571 586 }
572 587 else
573 588 {
574 589 setCursor(Qt::ClosedHandCursor);
575 590 mDragStart = event->pos();
576 591 this->mouse_hold = true;
577 592 DragStartHorzRange = this->m_plot->axisRect()->rangeDragAxis(Qt::Horizontal)->range();
578 593 DragStartVertRange = this->m_plot->axisRect()->rangeDragAxis(Qt::Vertical)->range();
579 594 }
580 595 }
581 596 QWidget::mousePressEvent(event);
582 597 }
583 598
584 599 void SocExplorerPlot::mouseReleaseEvent(QMouseEvent *event)
585 600 {
586 601 if(event->button()==Qt::LeftButton)
587 602 {
588 603 this->mouse_hold = false;
589 604 }
590 605 if (mRubberBand->isVisible())
591 606 {
592 607 const QRect & zoomRect = mRubberBand->geometry();
593 608 int xp1, yp1, xp2, yp2;
594 609 zoomRect.getCoords(&xp1, &yp1, &xp2, &yp2);
595 610 double x1 = this->m_plot->xAxis->pixelToCoord(xp1);
596 611 double x2 = this->m_plot->xAxis->pixelToCoord(xp2);
597 612 double y1 = this->m_plot->yAxis->pixelToCoord(yp1);
598 613 double y2 = this->m_plot->yAxis->pixelToCoord(yp2);
599 614
600 615 this->m_plot->xAxis->setRange(x1, x2);
601 616 this->m_plot->yAxis->setRange(y1, y2);
602 617
603 618 mRubberBand->hide();
604 619 this->m_plot->replot();
605 620 }
606 621 setCursor(Qt::ArrowCursor);
607 622 QWidget::mouseReleaseEvent(event);
608 623 }
609 624
610 625 void SocExplorerPlot::zoom(double factor, int center, Qt::Orientation orientation)
611 626 {
612 627 QCPAxis* axis = this->m_plot->axisRect()->rangeZoomAxis(orientation);
613 628 axis->scaleRange(factor, axis->pixelToCoord(center));
614 629 this->m_plot->replot();
615 630 }
616 631
617 632 void SocExplorerPlot::move(double factor, Qt::Orientation orientation)
618 633 {
619 634 QCPAxis* axis = this->m_plot->axisRect()->rangeDragAxis(orientation);
620 635 double rg = (axis->range().upper - axis->range().lower)*(factor);
621 636 axis->setRange(axis->range().lower+(rg), axis->range().upper+(rg));
622 637 this->m_plot->replot();
623 638 }
624 639
625 640
626 641 void SocExplorerPlot::mouseMoveEvent(QMouseEvent *event)
627 642 {
628 643 if(mouse_hold)
629 644 {
630 645 QCPAxis* Haxis = this->m_plot->axisRect()->rangeDragAxis(Qt::Horizontal);
631 646 QCPAxis* Vaxis = this->m_plot->axisRect()->rangeDragAxis(Qt::Vertical);
632 647 double diff = Haxis->pixelToCoord(mDragStart.x()) - Haxis->pixelToCoord(event->pos().x());
633 648 Haxis->setRange(DragStartHorzRange.lower+diff, DragStartHorzRange.upper+diff);
634 649 diff = Vaxis->pixelToCoord(mDragStart.y()) - Vaxis->pixelToCoord(event->pos().y());
635 650 Vaxis->setRange(DragStartVertRange.lower+diff, DragStartVertRange.upper+diff);
636 651 this->m_plot->replot();
637 652 }
638 653 if (mRubberBand->isVisible())
639 654 {
640 655 mRubberBand->setGeometry(QRect(mOrigin, event->pos()).normalized());
641 656 }
642 657 QWidget::mouseMoveEvent(event);
643 658 }
644 659
645 660
646 661
647 662
648 663
649 664
650 665
651 666
652 667
653 668
654 669
@@ -1,131 +1,134
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the QLop Software
3 3 -- Copyright (C) 2015, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 2 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@member.fsf.org
21 21 ----------------------------------------------------------------------------*/
22 22 #ifndef SOCEXPLORERPLOT_H
23 23 #define SOCEXPLORERPLOT_H
24 24
25 25 #include <QWidget>
26 26 #include <QGridLayout>
27 27 #include <qcustomplot.h>
28 28 #include <qcustomplotvect.h>
29 29 #include <QRubberBand>
30 30 #include <QPoint>
31 31
32 32 class SocExplorerPlotActions : public QAction
33 33 {
34 34 Q_OBJECT
35 35 public:
36 36 SocExplorerPlotActions(const QString &text,int PID,QObject* parent=0)
37 37 :QAction(text,parent)
38 38 {
39 39 setPID(PID);
40 40 connect(this,SIGNAL(triggered()),this,SLOT(trigger()));
41 41 }
42 42 SocExplorerPlotActions(const QIcon &icon, const QString &text,int PID, QObject* parent)
43 43 :QAction(icon,text,parent)
44 44 {
45 45 setPID(PID);
46 46 connect(this,SIGNAL(triggered()),this,SLOT(trigger()));
47 47 }
48 48 ~SocExplorerPlotActions(){}
49 49 void setPID(int PID){this->m_PID=PID;}
50 50 int PID(){return m_PID;}
51 51 private slots:
52 52 void trigger(){emit triggered(m_PID);}
53 53 signals:
54 54 void triggered(int PID);
55 55 private:
56 56 int m_PID;
57 57 };
58 58
59 59 class SocExplorerPlot : public QWidget
60 60 {
61 61 Q_OBJECT
62 62 public:
63 63 explicit SocExplorerPlot(QWidget *parent = 0);
64 64 ~SocExplorerPlot();
65 65 void setTitle(QString title);
66 const QString& title();
66 67 void setXaxisLabel(QString label);
67 68 void setXaxisLog();
68 69 void setXaxisRange(double lower, double upper);
69 70 void setYaxisLabel(QString label);
70 71 void setYaxisLog();
71 72 void setYaxisRange(double lower, double upper);
72 73 void rescaleAxis();
73 74 void setLegendFont(QFont font);
74 75 void setLegendSelectedFont(QFont font);
75 76 void setAdaptativeSampling(int graphIndex,bool enable);
76 77 void setUseFastVector(int graphIndex,bool enable);
77 78 int addGraph();
78 79 bool removeGraph(int graphIndex);
79 80 int graphCount();
80 81 void removeAllGraphs();
81 82 void setGraphName(int graphIndex,QString name);
83 const QString& graphName(int graphIndex);
82 84 void setGraphData(int graphIndex, QList<QVariant> x, QList<QVariant> y);
83 85 void setGraphData(int graphIndex, QCPDataMap* data,bool copy = true,bool replot=true);
84 86 void setGraphData(int graphIndex, QVector<QCPData> *data, bool replot);
85 87 void addGraphData(int graphIndex, QList<QVariant> x, QList<QVariant> y);
86 88 void addGraphData(int graphIndex, QVariant x, QVariant y);
87 89 void setGraphPen(int graphIndex,QPen pen);
88 90 QPen getGraphPen(int graphIndex);
89 91 void setGraphLineStyle(int graphIndex,QString lineStyle);
90 92 void setGraphScatterStyle(int graphIndex,QString scatterStyle);
91 93 void setXaxisTickLabelType(QCPAxis::LabelType type);
92 94 void setXaxisDateTimeFormat(const QString &format);
93 95 void show();
94 96 void replot();
95 97 void exportToSVG(const QString& fileName);
96 98 void exportToPDF(const QString& fileName);
97 99 void addAction(SocExplorerPlotActions* action);
98 100 int PID(){return m_PID;}
99 101 void setPID(int PID){m_PID = PID;}
100 102 QVector<QCPData>* getVisibleData(int graphIndex);
101 103 signals:
102 104 void titleChanged(const QString& newTitle);
103 105 public slots:
104 106
105 107 protected:
106 108 void keyPressEvent(QKeyEvent *);
107 109 void keyReleaseEvent(QKeyEvent *);
108 110 void wheelEvent(QWheelEvent *);
109 111 void mousePressEvent(QMouseEvent *);
110 112 void mouseMoveEvent(QMouseEvent *);
111 113 void mouseReleaseEvent(QMouseEvent *);
112 114
113 115 private:
114 116 void zoom(double factor, int center, Qt::Orientation orientation);
115 117 void move(double factor, Qt::Orientation orientation);
116 118 QCustomPlotVect* m_plot;
117 119 QGridLayout* m_mainlayout;
118 120 bool ctrl_hold;
119 121 bool shift_hold;
120 122 bool mouse_hold;
121 123 QCPRange DragStartHorzRange;
122 124 QCPRange DragStartVertRange;
123 125 QPoint mDragStart;
124 126 bool mZoomMode;
125 127 QRubberBand * mRubberBand;
126 128 QPoint mOrigin;
127 129 QList<SocExplorerPlotActions*> m_actions;
130 QString m_Title;
128 131 int m_PID;
129 132 };
130 133
131 134 #endif // SOCEXPLORERPLOT_H
General Comments 0
You need to be logged in to leave comments. Login now