AstRawDark
Manage your astrophoto dark frames
 All Classes Functions Variables Enumerations Enumerator Pages
plotManager.cpp
1 /*
2  * AstRawDark
3  *
4  * Copyright (C) 2015 - Frédéric CORNU
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "plotManager.h"
21 #include "data/helpers/imageStackHelper.h"
22 
23 #ifndef QT_NO_DEBUG
24 #include <QDebug>
25 #endif
26 
27 PlotManager::PlotManager(QCustomPlot* darkTempPlot,
28  QCustomPlot* darkTempDistriPlot,
29  QCustomPlot* lightsTempPlot,
30  QCustomPlot* lightsTempDistriPlot,
31  QObject *parent)
32  : QObject(parent),
33  _darkTempEvoPlot(darkTempPlot),
34  _darkTempDistriPlot(darkTempDistriPlot),
35  _lightsTempEvoPlot(lightsTempPlot),
36  _lightsTempDistriPlot(lightsTempDistriPlot)
37 
38 {
39  setupTempEvoPlot(_darkTempEvoPlot, tr("Dark N°"), tr("Sensor temperature in °C"));
40  setupTempEvoPlot(_lightsTempEvoPlot, tr("Light N°"), tr("Sensor temperature in °C"));
41 
42  setupTempDisrtiPlot(_darkTempDistriPlot, tr("Sensor temperature in C°"), tr("Dark count"));
43  setupTempDisrtiPlot(_lightsTempDistriPlot, tr("Sensor temperature in C°"), tr("Light count"));
44 
47  this,
48  &PlotManager::on_darkModelChanged);
49 
52  this,
53  &PlotManager::on_darkScanStarted);
54 
57  this,
58  &PlotManager::on_lightsScanStarted);
59 
62  this,
63  &PlotManager::on_lightsScanDone);
64 }
65 
66 void PlotManager::on_darkModelChanged()
67 {
68  refreshDarkTempEvoGraph();
69  refreshDarkTempDistriGraph();
70 }
71 
72 void PlotManager::on_darkScanStarted()
73 {
74  clearDarkTempEvoGraph();
75  clearDarkTempDistriGraph();
76 }
77 
78 void PlotManager::on_lightsScanDone()
79 {
80  refreshLightsTempEvoGraph();
81  refreshLightsTempDistriGraph();
82 }
83 
84 void PlotManager::on_lightsScanStarted()
85 {
86  clearLightsTempEvoGraph();
87  clearLightsTempDistriGraph();
88 }
89 
90 void PlotManager::clearDarkTempEvoGraph()
91 {
92  clearPlot(_darkTempEvoPlot);
93 }
94 
95 void PlotManager::clearDarkTempDistriGraph()
96 {
97  clearPlot(_darkTempDistriPlot);
98 }
99 
100 void PlotManager::clearLightsTempEvoGraph()
101 {
102  clearPlot(_lightsTempEvoPlot);
103 }
104 
105 void PlotManager::clearLightsTempDistriGraph()
106 {
107  clearPlot(_lightsTempDistriPlot);
108 }
109 
110 void PlotManager::refreshDarkTempEvoGraph()
111 {
112  refreshTempEvoPlot(_darkTempEvoPlot, DataStore::getInstance()->getFilteredDarks());
113 }
114 
115 
116 void PlotManager::refreshDarkTempDistriGraph()
117 {
118  refreshTempDistriPlot(_darkTempDistriPlot, DataStore::getInstance()->getFilteredDarks());
119 }
120 
121 void PlotManager::refreshLightsTempEvoGraph()
122 {
123  refreshTempEvoPlot(_lightsTempEvoPlot, DataStore::getInstance()->getScannedLights());
124 }
125 
126 void PlotManager::refreshLightsTempDistriGraph()
127 {
128  refreshTempDistriPlot(_lightsTempDistriPlot, DataStore::getInstance()->getScannedLights());
129 }
130 
131 void PlotManager::setupTempEvoPlot(QCustomPlot *plot, QString xLabel, QString yLabel)
132 {
133  plot->addGraph();
134 
135  plot->xAxis->setLabel(xLabel);
136  plot->xAxis->setAutoTickStep(false);
137 
138  plot->yAxis->setLabel(yLabel);
139 }
140 
141 void PlotManager::setupTempDisrtiPlot(QCustomPlot *plot, QString xLabel, QString yLabel)
142 {
143  plot->addPlottable(new QCPBars(plot->xAxis, plot->yAxis));
144 
145  plot->xAxis->setLabel(xLabel);
146  plot->xAxis->setAutoTickStep(false);
147  plot->xAxis->setAutoSubTicks(false);
148  plot->xAxis->setTickStep(1);
149  plot->xAxis->setTickLength(0);
150  plot->xAxis->setSubTickCount(0);
151 
152  plot->yAxis->setLabel(yLabel);
153 }
154 
155 void PlotManager::refreshTempEvoPlot(QCustomPlot *plot, QList<ImageInfo> infos)
156 {
157  // we sort frames by ascending date
158  QMap<QString, ImageInfo> map;
159  foreach (ImageInfo info, infos) {
160 
161  map.insert(info.getDate(), info);
162  }
163 
164  QList<ImageInfo> data;
165  foreach ( QString date, map.keys() ) {
166 
167  data << map.value(date);
168  }
169 
170  QVector<double> x, y;
171 
172  int counter = 0;
173  int maxTemp = 0;
174 
175  foreach (ImageInfo info, data) {
176 
177  x << counter++;
178  y << info.getTemperature();
179 
180  if ( info.getTemperature() > maxTemp ) {
181 
182  maxTemp = info.getTemperature();
183  }
184  }
185 
186  plot->graph()->setData(x,y);
187 
188  // set X axis range's maximum to be the next even number after max X value
189  plot->xAxis->setRange(0, (data.count()/2)*2+2);
190  plot->yAxis->setRange(0, maxTemp + 1);
191  plot->yAxis->setTickStep(roundUp(maxTemp / 10, 5));
192 
193  int xTickStep = data.count() / 20;
194 
195  if ( xTickStep < 1 ) {
196 
197  xTickStep = 1;
198  }
199 
200  plot->xAxis->setTickStep(xTickStep);
201 
202  // ensure data visibility on small datasets
203  if ( data.count() < 5 ) {
204 
205  _darkTempEvoPlot->graph()->setScatterStyle(QCPScatterStyle::ssCross);
206 
207  } else {
208 
209  _darkTempEvoPlot->graph()->setScatterStyle(QCPScatterStyle::ssNone);
210  }
211 
212  plot->replot();
213 }
214 
215 void PlotManager::refreshTempDistriPlot(QCustomPlot *plot, QList<ImageInfo> infos)
216 {
217  QVector<double> x, y;
218 
219  QList<ImageStack*> stacks = ImageStackHelper::createStackListFromImageInfos(infos);
220 
221  int maxTemp = 0;
222  int minTemp = 200;
223 
224  int maxCount = 0;
225 
226  foreach ( ImageStack* stack, stacks ) {
227 
228  int count = stack->getSize();
229  int temperature = stack->getTemperature();
230 
231  x << temperature;
232  y << count;
233 
234  if ( maxTemp < temperature ) {
235 
236  maxTemp = temperature;
237  }
238 
239  if ( minTemp > temperature ) {
240 
241  minTemp = temperature;
242  }
243 
244  if ( maxCount < count ) {
245 
246  maxCount = count;
247  }
248  }
249 
250  static_cast<QCPBars*>(plot->plottable(0))->setData(x,y);
251 
252  // ARD-100: fix X axis when dataset is empty
253  if ( infos.count() == 0 ) {
254 
255  minTemp = 1;
256  maxTemp = 0;
257  }
258 
259  plot->xAxis->setRange(minTemp - 1, maxTemp + 1);
260  plot->yAxis->setRange(0, maxCount + 1);
261 
262  plot->yAxis->setTickStep(roundUp(maxCount / 10, 5));
263 
264  plot->replot();
265 
266  foreach ( ImageStack* stack, stacks ) { delete stack; }
267 }
268 
269 void PlotManager::clearPlot(QCustomPlot *plot)
270 {
271  if ( plot->plottableCount() ) {
272 
273  plot->plottable()->clearData();
274  plot->replot();
275  }
276 }
277 
278 int PlotManager::roundUp(int numToRound, int multiple)
279 {
280 
281  if(multiple == 0) {
282 
283  return numToRound;
284  }
285 
286  int remainder = numToRound % multiple;
287 
288  if (numToRound != 0 && remainder == 0) {
289 
290  return numToRound;
291  }
292 
293  int nRet = numToRound + multiple - remainder;
294 
295  if ( nRet < multiple ) {
296 
297  nRet = 1;
298  }
299 
300  return nRet;
301 
302 }