m_supportedFileTypes << "*.ch";
}
-DataFilesLoader::ReturnCode DataFilesLoader::loadSingleRun(const QDir& path, std::vector<struct HPCS_MeasuredData*>& loadedData)
+DataFilesLoader::ReturnCode DataFilesLoader::loadSingleRun(const QDir& path, std::vector<struct HPCS_MeasuredData* >& loadedData)
{
ReturnCode ret = ReturnCode::SUCCESS;
QMessageBox::warning(nullptr, "Error reading file '" + s + "'", errDesc);
hpcs_free(mdata);
- ret = ReturnCode::E_READ_ERROR;
- break;
}
}
Logger::log(Logger::Level::DEBUG, ME_SENDER_STR, QString::number(loadedData.size()) + " files were found and successfully parsed");
- return ret;
+ return ReturnCode::SUCCESS;
}
Signal::TimeValuePair stvp(md->data[idx].time, md->data[idx].value);
values.push_back(stvp);
}
- _s = std::shared_ptr<Signal>(new Signal(eqp, res, samplingRate, yu, md->dad_wavelength_msr, md->dad_wavelength_ref, values));
+ _s = std::shared_ptr<Signal>(new Signal(eqp, res, samplingRate, yu, md->dad_wavelength_msr.wavelength, md->dad_wavelength_msr.interval,
+ md->dad_wavelength_ref.wavelength, md->dad_wavelength_ref.interval, values));
if (!date.isValid()) {
llog->log(Logger::WARNING, ME_SENDER_STR, QString("Date ") + date.toString() + QString("is invalid."));
swp->setDataTableModel(ctrl->dataTableModel());
swp->setIntegrationTableModel(ctrl->integrationTableModel());
if (ctrl->signal()->resource() == Signal::Resource::CE_DAD)
- swp->setTypeText(ctrl->signal()->resourceAsString() + " Sig: " + QString::number(ctrl->signal()->wavelengthAbsorbed()) + " nm, Ref: " +
- QString::number(ctrl->signal()->wavelengthReference()) + " nm");
+ swp->setTypeText(ctrl->signal()->resourceAsString() + " Sig: " + QString::number(ctrl->signal()->wavelengthMeasured().wavelength) + " nm, Ref: " +
+ QString::number(ctrl->signal()->wavelengthReference().wavelength) + " nm");
else
swp->setTypeText(ctrl->signal()->resourceAsString());
swp->setXUnits(ctrl->signal()->xunitAsString());
*/
+#include "helpers.h"
#include "gui/graphview.h"
#include "logger.h"
#include <QtGui/QPainter>
case Qt::LeftButton:
switch (m_mouseMode) {
case GraphView::MouseMode::CROSSHAIR:
- if (m_graphCtrlMode == GraphControlModes::ZOOM) {
+ switch (m_graphCtrlMode) {
+ case GraphControlModes::ZOOM:
m_zoomRectStartXPix = ev->x();
m_zoomRectStartYPix = ev->y();
m_zoomRectLastXPix = ev->x();
m_zoomRectLastYPix = ev->y();
eraseCrosshair(true);
m_mouseMode = GraphView::MouseMode::ZOOM;
- } else if (m_graphCtrlMode == GraphControlModes::INTEGRATE) {
+ break;
+ case GraphControlModes::INTEGRATE_BASELINE:
+ m_integrateStartBLYPix = relToYPix(m_controller->valueToRel(m_controller->getXYValues(xPixToRel(ev->x())).second));
+ m_integrateStopBLYPix = m_integrateStartBLYPix;
+ case GraphControlModes::INTEGRATE_INTERSECT:
m_integrateStartXPix = ev->x();
m_integrateStartYPix = ev->y();
m_integrateStopXPix = ev->x();
break;
case GraphView::MouseMode::INTEGRATE:
PeakDrawData pdData = m_controller->integratePeak(xPixToRel(m_integrateStartXPix), yPixToRel(m_integrateStartYPix),
- xPixToRel(m_integrateStopXPix), yPixToRel(m_integrateStopYPix));
+ xPixToRel(m_integrateStopXPix), yPixToRel(m_integrateStopYPix), m_integrationType);
eraseIntegrationBaseline(true);
QRegion reg = renderPeak(pdData, m_background);
copyPixmapRegion(reg, m_background, m_pixmap);
reg = eraseIntegrationBaseline();
+ if (m_integrationType == IntegrationType::BASELINE) {
+ m_integrateStopBLYPix = relToYPix(m_controller->valueToRel(m_controller->getXYValues(xPixToRel(x)).second));
+
+ p.begin(m_pixmap);
+ p.setPen(Qt::black);
+ p.drawLine(m_integrateStartXPix, m_integrateStartYPix, m_integrateStartXPix, m_integrateStartBLYPix);
+ p.drawLine(x, y, x, m_integrateStopBLYPix);
+ p.end();
+ reg += QRect(m_integrateStartXPix, m_integrateStopXPix, m_integrateStartXPix, m_integrateStopBLYPix);
+ reg += QRect(x, y, x, m_integrateStopBLYPix);
+ }
+
if (m_integrateStartXPix > m_integrateStopXPix) {
lstartX = (m_integrateStopXPix > 1) ? m_integrateStopXPix - 1 : 0;
lstopX = (m_integrateStartXPix < dwidth()-1) ? m_integrateStartXPix + 1 : dwidth()-1;
p.drawLine(m_integrateStartXPix, m_integrateStartYPix, x, y);
p.end();
+
+
reg += QRect(lstartX, lstartY, lstopX, lstopY);
m_integrateStopXPix = x;
if (m_integrateStartXPix < 0)
return QRegion();
+ if (m_integrationType == IntegrationType::BASELINE) {
+ int top, bottom, left, right;
+ top = Helpers::minof(m_integrateStartYPix, m_integrateStopYPix, m_integrateStartBLYPix, m_integrateStopBLYPix);
+ bottom = Helpers::maxof(m_integrateStartYPix, m_integrateStopYPix, m_integrateStartBLYPix, m_integrateStopBLYPix);
+ left = std::min(m_integrateStartXPix, m_integrateStopXPix);
+ right = std::max(m_integrateStartXPix, m_integrateStopXPix);
+
+ p.begin(m_pixmap);
+ p.drawPixmap(left, top, *m_background, left, top, right - left+1, bottom - top+1);
+ //p.drawPixmap(lstartX, lstartY, *m_background, lstartX, lstartY, lstopX - lstartX+1, lstopY - lstartY+1); //FIXME: +1 should not be needed!
+ /*p.begin(m_pixmap);
+ p.setPen(Qt::yellow);
+ p.drawLine(m_integrateStartXPix, m_integrateStartYPix, m_integrateStartXPix, m_integrateStartBLYPix);
+ p.drawLine(x, y, x, m_integrateStopBLYPix);
+ p.end();*/
+ reg += QRect(left, top, right - left+1, bottom - top+1);
+ p.end();
+ }
+
p.begin(m_pixmap);
if (m_integrateStartXPix > m_integrateStopXPix) {
lstartX = (m_integrateStopXPix > 1) ? m_integrateStopXPix - 1 : 0;
p.drawPixmap(lstartX, lstartY, *m_background, lstartX, lstartY, lstopX - lstartX+1, lstopY - lstartY+1); //FIXME: +1 should not be needed!
p.end();
- reg = QRect(lstartX, lstartY, lstopX - lstartX +1, lstopY - lstartY + 1);
+ reg += QRect(lstartX, lstartY, lstopX - lstartX +1, lstopY - lstartY + 1);
if (apply)
update(reg);
int m_graphCrosshairXPix;
int m_graphCrosshairYPix;
/* Integration baseline */
+ IntegrationType m_integrationType;
+ int m_integrateStartBLYPix;
+ int m_integrateStopBLYPix;
int m_integrateStartXPix;
int m_integrateStartYPix;
int m_integrateStopXPix;
void onCtxMenuZoomOut();
public slots:
- void onControlModeChanged(GraphControlModes mode) { m_graphCtrlMode = mode; }
+ void onControlModeChanged(GraphControlModes mode)
+ { m_graphCtrlMode = mode;
+ if (mode == GraphControlModes::INTEGRATE_BASELINE) m_integrationType = IntegrationType::BASELINE;
+ else if (mode == GraphControlModes::INTEGRATE_INTERSECT) m_integrationType = IntegrationType::INTERSECTION;
+ }
signals:
void crosshairValuesUpdated(const double time, const double value);
#endif
{
/* Controls panel */
- connect(ui->qpb_integrate, SIGNAL(pressed()), this, SLOT(onIntegrateSelected()));
+ connect(ui->qpb_integrateBaseline, SIGNAL(pressed()), this, SLOT(onIntegrateBaselineSelected()));
+ connect(ui->qpb_integrateIntersect, SIGNAL(pressed()), this, SLOT(onIntegrateIntersectSelected()));
connect(ui->qpb_zoom, SIGNAL(pressed()), this, SLOT(onZoomSelected()));
/* DATA menu */
/* Public slots */
void MainWindow::onAddToDashboard(SignalView* sw)
{
- if (ui->qpb_integrate->isChecked())
- sw->m_graphView->onControlModeChanged(GraphControlModes::INTEGRATE);
+ if (ui->qpb_integrateBaseline->isChecked())
+ sw->m_graphView->onControlModeChanged(GraphControlModes::INTEGRATE_BASELINE);
+ else if(ui->qpb_integrateIntersect->isChecked())
+ sw->m_graphView->onControlModeChanged(GraphControlModes::INTEGRATE_INTERSECT);
else if(ui->qpb_zoom->isChecked())
sw->m_graphView->onControlModeChanged(GraphControlModes::ZOOM);
aa.exec();
}
-void MainWindow::onIntegrateSelected()
+void MainWindow::onIntegrateBaselineSelected()
{
- emit controlModeChanged(GraphControlModes::INTEGRATE);
+ emit controlModeChanged(GraphControlModes::INTEGRATE_BASELINE);
}
+
+void MainWindow::onIntegrateIntersectSelected()
+{
+ emit controlModeChanged(GraphControlModes::INTEGRATE_INTERSECT);
+}
+
void MainWindow::onLoadSequence()
{
m_loadDataFileDialog->setWindowTitle("Load sequence");
void onExportGraphToImage() { emit exportGraphToImage(); }
void onExportPeaks() { emit exportPeaks(); }
void onExportRawData() { emit exportRawData(); }
- void onIntegrateSelected();
+ void onIntegrateBaselineSelected();
+ void onIntegrateIntersectSelected();
void onLoadSequence();
void onLoadSingleRun();
void onSaveChanges() { emit saveChanges(); }
</widget>
</item>
<item row="0" column="1">
- <widget class="QPushButton" name="qpb_integrate">
+ <widget class="QPushButton" name="qpb_integrateIntersect">
<property name="text">
- <string>Integrate</string>
+ <string>Integrate by intersection</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="autoExclusive">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QPushButton" name="qpb_integrateBaseline">
+ <property name="text">
+ <string>Integrate by baseline</string>
</property>
<property name="checkable">
<bool>true</bool>
return name.mid(dotIdx+1).toLower();
}
+ template <typename T> static T maxof(T n, ...)
+ {
+ T idx;
+ T val, largest;
+ va_list vl;
+ va_start(vl, n);
+ largest = va_arg(vl, T);
+ for (idx = 1; idx < n; idx++) {
+ val = va_arg(vl, T);
+ largest = (largest > val) ? largest : val;
+ }
+ va_end(vl);
+ return largest;
+ }
+
+ template <typename T> static T minof(T n, ...)
+ {
+ T idx;
+ T val, largest;
+ va_list vl;
+ va_start(vl, n);
+ largest = va_arg(vl, T);
+ for (idx = 1; idx < n; idx++) {
+ val = va_arg(vl, T);
+ largest = (largest < val) ? largest : val;
+ }
+ va_end(vl);
+ return largest;
+ }
+
};
#endif // MATHHELPERS_H
const QString IntegratedPeak::KEY_FROMIDX("fromIdx");
const QString IntegratedPeak::KEY_FROMTIME("fromTime");
const QString IntegratedPeak::KEY_FROMY("fromY");
+const QString IntegratedPeak::KEY_ITYPE("itype");
const QString IntegratedPeak::KEY_PEAKIDX("peakIdx");
const QString IntegratedPeak::KEY_PEAKTIME("peakTime");
const QString IntegratedPeak::KEY_PEAKY("peakY");
IntegratedPeak::IntegratedPeak(IntegratedPeak::Type type, double auc, size_t peakIdx, double peakTime, double peakY,
size_t fromIdx, size_t toIdx, double fromTime, double toTime, double fromY, double toY,
- double relBlSlope, double relBlQ, QObject* parent) :
+ double relBlSlope, double relBlQ, IntegrationType itype, QObject* parent) :
QObject(parent),
JSONSerializable(),
m_auc(auc),
m_fromIdx(fromIdx),
m_fromTime(fromTime),
m_fromY(fromY),
+ m_itype(itype),
m_peakIdx(peakIdx),
m_peakTime(peakTime),
m_peakY(peakY),
if (!jso.contains(KEY_FROMY))
return false;
m_fromY = jso.value(KEY_FROMY).toDouble();
+ if (!jso.contains(KEY_ITYPE))
+ m_itype = IntegrationType::INTERSECTION;
+ m_itype = jso.value(KEY_ITYPE).toBool() ? IntegrationType::BASELINE : IntegrationType::INTERSECTION;
if (!jso.contains(KEY_PEAKIDX))
return false;
jso.insert(KEY_FROMIDX, QJsonValue(static_cast<qint64>(m_fromIdx)));
jso.insert(KEY_FROMTIME, QJsonValue(m_fromTime));
jso.insert(KEY_FROMY, QJsonValue(m_fromY));
+ jso.insert(KEY_ITYPE, QJsonValue( (m_itype == IntegrationType::BASELINE) ? true : false) );
jso.insert(KEY_PEAKIDX, QJsonValue(static_cast<qint64>(m_peakIdx)));
jso.insert(KEY_PEAKTIME, QJsonValue(m_peakTime));
jso.insert(KEY_PEAKY, QJsonValue(m_peakY));
#include "jsonserializable.h"
#include <QtCore/QObject>
+enum class IntegrationType {
+ NONE,
+ INTERSECTION,
+ BASELINE
+};
+
class IntegratedPeak : public QObject, public JSONSerializable
{
Q_OBJECT
explicit IntegratedPeak() : m_type(Type::INVALID) {}
explicit IntegratedPeak(Type type, double auc, size_t peakIdx, double peakTime, double peakY, size_t fromIdx, size_t toIdx, double fromTime, double toTime,
- double fromY, double toY, double relBlSlope, double relBlQ, QObject* parent = nullptr);
+ double fromY, double toY, double relBlSlope, double relBlQ, IntegrationType itype, QObject* parent = nullptr);
double auc() const { return m_auc; }
double baselineSlope() const;
size_t fromIdx() const { return m_fromIdx; }
double fromY() const { return m_fromY; }
double fromTime() const { return m_fromTime;}
double height() const;
+ IntegrationType itype() const { return m_itype; }
size_t peakIdx() const { return m_peakIdx; }
double peakTime() const { return m_peakTime; }
double peakY() const { return m_peakY; }
size_t m_fromIdx;
double m_fromTime;
double m_fromY;
+ IntegrationType m_itype;
size_t m_peakIdx;
double m_peakTime;
double m_peakY;
static const QString KEY_FROMIDX;
static const QString KEY_FROMTIME;
static const QString KEY_FROMY;
+ static const QString KEY_ITYPE;
static const QString KEY_PEAKIDX;
static const QString KEY_PEAKTIME;
static const QString KEY_PEAKY;
}
Integrator::ReturnCode Integrator::integrate(size_t startIdx, size_t stopIdx, double startY, double stopY, IntegratedPeakSPtr& peak,
- double relBlSlope, double relBlQ)
+ double relBlSlope, double relBlQ, IntegrationType itype)
{
- size_t peakValueIdx;
- size_t startIntersIdx, stopIntersIdx;
- size_t i;
- double auc = 0.0;
double slope;
- double startYVal, stopYVal;
- bool expectDownward;
- IntegratedPeak::Type peakType;
+ bool down;
if (startIdx > m_signal->valuesCount()-1) {
Logger::log(Logger::Level::ERROR, ME_SENDER_STR, "Invalid startIdx value " + QString::number(startIdx));
}
slope = (stopY - startY) / static_cast<double>(stopIdx - startIdx);
- /* Try to find first intersection */
- if (startY < m_signal->valueAt(startIdx)) {
- expectDownward = true;
- //qDebug() << "Expecting downward peak";
- } else {
- expectDownward = false;
- //qDebug() << "Expecting upward peak";
+
+ switch (itype) {
+ case IntegrationType::INTERSECTION: {
+ if (startY < m_signal->valueAt(startIdx))
+ down = true;
+ else
+ down = false;
+ ReturnCode ret = findIntersections(startIdx, startY, stopIdx, stopY, down, slope);
+ if (ret != ReturnCode::SUCCESS)
+ return ret;
+ break;
}
+ default:
+ if (startY > m_signal->valueAt(startIdx))
+ down = true;
+ else down = false;
+ break;
+ }
+
+ return integrateInternal(startIdx, startY, stopIdx, stopY, down, slope, peak, relBlSlope, relBlQ, itype);
+}
+
+Integrator::ReturnCode Integrator::findIntersections(size_t& startIdx, double& startY, size_t& stopIdx, double& stopY, bool& down, const double slope)
+{
+ size_t origStartIdx = startIdx;
+ size_t i;
+
+ /* Try to find first intersection */
for (i = startIdx; i <= stopIdx; i++) {
double value = m_signal->valueAt(i);
- double blY = slope * static_cast<double>(i - startIdx) + startY;
+ double blY = slope * static_cast<double>(i - origStartIdx) + startY;
- if (expectDownward && blY > value) { /* Found first intersection */
- startIntersIdx = i;
- startYVal = blY;
+ if (down && blY > value) { /* Found first intersection */
+ startIdx = i;
+ startY = blY;
break;
- } else if (!expectDownward && blY < value) { /* Found first intersection */
- startIntersIdx = i;
- startYVal = blY;
+ } else if (!down && blY < value) { /* Found first intersection */
+ startIdx = i;
+ startY = blY;
break;
}
}
/* Try to find second intersection */
for (; i <= stopIdx; i++) {
double value = m_signal->valueAt(i);
- double blY = slope * static_cast<double>(i - startIdx) + startY;
+ double blY = slope * static_cast<double>(i - origStartIdx) + startY;
- if (expectDownward && blY < value) {
- stopIntersIdx = i;
- stopYVal = blY;
+ if (down && blY < value) {
+ stopIdx = i;
+ stopY = blY;
break;
- } else if (!expectDownward && blY > value) {
- stopIntersIdx = i;
- stopYVal = blY;
+ } else if (!down && blY > value) {
+ stopIdx = i;
+ stopY = blY;
break;
}
}
return ReturnCode::E_NO_SECOND_INTERSECT;
}
+ return ReturnCode::SUCCESS;
+}
+
+Integrator::ReturnCode Integrator::integrateInternal(const size_t startIdx, const double startY, const size_t stopIdx, const double stopY,
+ const bool down, const double slope, IntegratedPeakSPtr& peak,
+ double relBlSlope, double relBlQ, IntegrationType itype)
+{
+ double auc = 0.0;
+ size_t peakValueIdx = startIdx;
+ IntegratedPeak::Type peakType;
+
/* Integrate */
- peakValueIdx = startIntersIdx;
- for (i = startIntersIdx+1; i < stopIntersIdx; i++) {
- double blXA = slope * (i - startIntersIdx) + startY;
- double blXB = slope * (i - startIntersIdx) + startY;
+ for (size_t i = startIdx+1; i < stopIdx; i++) {
+ double blXA = slope * (i - startIdx) + startY;
+ double blXB = slope * (i - startIdx) + startY;
double valA = m_signal->valueAt(i-1);
double valB = m_signal->valueAt(i);
double tA = m_signal->timeAt(i-1);
double avgH = (valB + valA)/2 - (blXB + blXA)/2;
double area = avgH * (tB - tA);
auc += area;
- if (expectDownward && valB < m_signal->valueAt(peakValueIdx)) peakValueIdx = i;
- else if (!expectDownward && valB > m_signal->valueAt(peakValueIdx)) peakValueIdx = i;
+ if (down && valB < m_signal->valueAt(peakValueIdx)) peakValueIdx = i;
+ else if (!down && valB > m_signal->valueAt(peakValueIdx)) peakValueIdx = i;
//qDebug() << area << auc;
}
/* Convert AUC to positive and seconds */
auc = fabs(auc) * 60;
/* Add peak to list */
- if (expectDownward) peakType = IntegratedPeak::Type::VALLEY;
+ if (down) peakType = IntegratedPeak::Type::VALLEY;
else peakType = IntegratedPeak::Type::PEAK;
- /*qDebug("Peak integrated");
- qDebug() << "SXC" << fromX << "SYC" << fromY << "EXC" << toX << "EYC" << toY << "Slope" << slope;
- qDebug() << "1st(X, Y, vY)" << startIntersIdx << m_signal->valueAt(startIntersIdx) << startYVal;
- qDebug() << "2nd(X, Y, vY)" << stopIntersIdx << m_signal->valueAt(stopIntersIdx) << stopYVal;
- qDebug("---");*/
+ qDebug("Peak integrated");
+ //qDebug() << "SXC" << fromX << "SYC" << fromY << "EXC" << toX << "EYC" << toY << "Slope" << slope;
+ qDebug() << "1st(X, Y, vY)" << startIdx << m_signal->valueAt(startIdx) << startY;
+ qDebug() << "2nd(X, Y, vY)" << stopIdx << m_signal->valueAt(stopIdx) << stopY;
+ qDebug("---");
peak = std::shared_ptr<IntegratedPeak>(new IntegratedPeak(peakType, auc, peakValueIdx, m_signal->timeAt(peakValueIdx), m_signal->valueAt(peakValueIdx),
- startIntersIdx, stopIntersIdx, m_signal->timeAt(startIntersIdx), m_signal->timeAt(stopIntersIdx),
- startYVal, stopYVal, relBlSlope, relBlQ));
+ startIdx, stopIdx, m_signal->timeAt(startIdx), m_signal->timeAt(stopIdx),
+ startY, stopY, relBlSlope, relBlQ, itype));
emit addingPeak(m_peakCount);
addPeakToMap(peak);
emit peakAdded();
PeakList allPeaks();
IntegratedPeakCSPtr deletePeak(size_t idx);
ReturnCode integrate(size_t startIdx, size_t stopIdx, double startY, double stopY, std::shared_ptr<IntegratedPeak>& peak,
- double relBlSlope, double relBlQ);
+ double relBlSlope, double relBlQ, IntegrationType itype);
IntegratedPeakCSPtr peakByLinearIdx(const size_t idx);
- //std::multimap<size_t, std::shared_ptr<IntegratedPeak>>::const_iterator peaksCBegin() const { return m_peaks.cbegin(); }
- //std::multimap<size_t, std::shared_ptr<IntegratedPeak>>::const_iterator peaksCEnd() const { return m_peaks.cend(); }
size_t peakCount() const { return m_peakCount; }
private:
void addPeakToMap(IntegratedPeakCSPtr peak);
+ ReturnCode findIntersections(size_t& startIdx, double& startY, size_t& stopIdx, double& stopY, bool& down, const double slope);
+ ReturnCode integrateInternal(const size_t startIdx, const double startY, const size_t stopIdx, const double stopY, const bool down,
+ const double slope, IntegratedPeakSPtr& peak, double relBlSlope, double relBlQ, const IntegrationType itype);
size_t m_peakCount;
PeakMap m_peakMap;
enum class GraphControlModes {
ZOOM,
- INTEGRATE
+ INTEGRATE_INTERSECT,
+ INTEGRATE_BASELINE
};
Q_DECLARE_METATYPE(GraphControlModes);
const QString Signal::MILLIVOLTS_SI("mV");
const QString Signal::WATTS_SI("W");
-Signal::Signal(const Equipment equipment, const Resource resource, const double samplingRate, const YUnit yunit, uint16_t wavelengthAbs, uint16_t wavelengthRef,
+Signal::Signal(const Equipment equipment, const Resource resource, const double samplingRate, const YUnit yunit,
+ const uint16_t wlMsr, const uint16_t wlMsrInt, const uint16_t wlRef, const uint16_t wlRefInt,
const std::vector<TimeValuePair>& values, QObject* parent) :
QObject(parent),
m_equipment(equipment),
m_resource(resource),
m_samplingRate(samplingRate),
m_values(values),
- m_wavelengthAbs(wavelengthAbs),
- m_wavelengthRef(wavelengthRef),
+ m_wavelengthMeasured(wlMsr),
+ m_wavelengthMeasuredInterval(wlMsrInt),
+ m_wavelengthReference(wlRef),
+ m_wavelengthReferenceInterval(wlRefInt),
m_xunit(XUnit::MINUTE),
m_yunit(yunit)
{
{
QString name = resourceAsString();
if (m_resource == Resource::CE_DAD)
- name += "_SIG" + QString::number(m_wavelengthAbs) + "_REF" + QString::number(m_wavelengthRef);
+ name += "_SIG" + QString::number(m_wavelengthMeasured) + "/" + QString::number(m_wavelengthMeasuredInterval) + "_REF" +
+ QString::number(m_wavelengthReference) + "/" + QString::number(m_wavelengthReferenceInterval);
return name;
}
MILLIVOLTS,
WATTS
};
+ struct Wavelength {
+ Wavelength (uint16_t w, uint16_t i) : wavelength(w), interval(i) {}
+ uint16_t wavelength;
+ uint16_t interval;
+ };
- explicit Signal(const Equipment equipment, const Resource resource, const double samplingRate, const YUnit yunit, const uint16_t wavelengthAbs,
- const uint16_t wavelengthRef, const std::vector<TimeValuePair>& values, QObject* parent = nullptr);
+ explicit Signal(const Equipment equipment, const Resource resource, const double samplingRate, const YUnit yunit, const uint16_t wlMsr,
+ const uint16_t wlMsrInt, const uint16_t wlRef, const uint16_t wlRefInt,
+ const std::vector<TimeValuePair>& values, QObject* parent = nullptr);
uint count() const { return m_values.size(); }
QString descriptiveName() const;
Equipment equipment() const { return m_equipment; }
std::vector<TimeValuePair>::const_iterator pairsBegin() const { return m_values.cbegin(); }
size_t valuesCount() const { return m_values.size(); }
std::vector<TimeValuePair>::const_iterator pairsEnd() const { return m_values.cend(); }
- uint16_t wavelengthAbsorbed() const { return m_wavelengthAbs; }
- uint16_t wavelengthReference() const { return m_wavelengthRef; }
+ Wavelength wavelengthMeasured() const { return Wavelength(m_wavelengthMeasured, m_wavelengthMeasuredInterval); }
+ Wavelength wavelengthReference() const { return Wavelength(m_wavelengthReference, m_wavelengthReferenceInterval); }
XUnit xunit() const { return m_xunit; }
QString xunitAsString() const;
YUnit yunit() const { return m_yunit; }
const Resource m_resource;
const double m_samplingRate;
const std::vector<TimeValuePair> m_values;
- const uint16_t m_wavelengthAbs;
- const uint16_t m_wavelengthRef;
+ const uint16_t m_wavelengthMeasured;
+ const uint16_t m_wavelengthMeasuredInterval;
+ const uint16_t m_wavelengthReference;
+ const uint16_t m_wavelengthReferenceInterval;
const XUnit m_xunit;
const YUnit m_yunit;
return std::pair<double, double>(m_signal->timeAt(idx), m_signal->valueAt(idx+1));
}
-PeakDrawData SignalController::integratePeak(const double fromX, const double fromY, const double toX, const double toY)
+PeakDrawData SignalController::integratePeak(const double fromX, const double fromY, const double toX, const double toY,
+ const IntegrationType itype)
{
size_t fromIdx, toIdx;
double fromVal, toVal;
fromVal = relToValue(fromY);
toVal = relToValue(toY);
- ret = m_integrator->integrate(fromIdx, toIdx, fromVal, toVal, peak, relBlSlope, relBlQ);
+ ret = m_integrator->integrate(fromIdx, toIdx, fromVal, toVal, peak, relBlSlope, relBlQ, itype);
switch (ret) {
case Integrator::ReturnCode::SUCCESS:
double fromY = m_signal->valueAt(peak->fromIdx());
double toY = m_signal->valueAt(peak->toIdx());
+ switch (peak->itype()) {
+ case IntegrationType::INTERSECTION:
+ fromY = m_signal->valueAt(peak->fromIdx());
+ toY = m_signal->valueAt(peak->toIdx());
+ break;
+ case IntegrationType::BASELINE:
+ fromY = peak->fromY();
+ toY = peak->toY();
+ break;
+ }
+
//qDebug() << __QFUNC__ << beforeFromY << fromY
// << beforeToY << toY;
//qDebug() << m_signal->timeAt(peak->fromIdx() - 0) << m_signal->timeAt(peak->fromIdx() + 1) << peak->fromTime();
idxToRel(peak->toIdx()), valueToRel(toY), idxToRel(peak->toIdx()-1), valueToRel(beforeToY),
peak->relBlSlope(), peak->relBlQ(),
idxToRel(peak->peakIdx()), valueToRel(m_signal->valueAt(peak->peakIdx())),
- peak->peakTime(), peak->auc());
+ peak->peakTime(), peak->auc(), peak->itype(),
+ valueToRel(m_signal->valueAt(peak->fromIdx())), valueToRel(m_signal->valueAt(peak->toIdx())));
}
double SignalController::idxToRel(const size_t idx)
struct PeakDrawData {
PeakDrawData() : fromX(0), fromY(0), toX(0), toY(0), beforeFromX(0), beforeFromY(0), beforeToX(0),
- beforeToY(0), blSlope(0), blQ(0), peakX(0), peakY(0), auc(0), time(0) {}
+ beforeToY(0), blSlope(0), blQ(0), peakX(0), peakY(0), auc(0), time(0), itype(IntegrationType::NONE),
+ blFromY(0), blToY(0) {}
PeakDrawData(const double fromX, const double fromY, const double beforeFromX, const double beforeFromY,
const double toX, const double toY, const double beforeToX, const double beforeToY,
const double blSlope, const double blQ,
- const double peakX, const double peakY, const double auc, const double time) :
+ const double peakX, const double peakY, const double auc, const double time,
+ const IntegrationType itype, const double blFromY, const double blToY) :
fromX(fromX), fromY(fromY), toX(toX), toY(toY),
beforeFromX(beforeFromX), beforeFromY(beforeFromY), beforeToX(beforeToX), beforeToY(beforeToY),
blSlope(blSlope), blQ(blQ),
- peakX(peakX), peakY(peakY), auc(auc), time(time) {}
+ peakX(peakX), peakY(peakY), auc(auc), time(time), itype(itype), blFromY(blFromY), blToY(blToY) {}
const double fromX, fromY, toX, toY;
const double beforeFromX, beforeFromY, beforeToX, beforeToY;
const double blSlope, blQ;
const double peakX, peakY;
const double auc, time;
+ const IntegrationType itype;
+ const double blFromY, blToY;
};
struct RulerDrawData {
double toXAbs() const { return m_signal->timeAt(m_signal->count()-1); }
double fromYAbs() const { return m_signal->valueAt(0); }
double toYAbs() const { return m_signal->valueAt(m_signal->count()-1); }
- PeakDrawData integratePeak(const double fromX, const double fromY, const double toX, const double toY);
+ PeakDrawData integratePeak(const double fromX, const double fromY, const double toX, const double toY, const IntegrationType itype);
IntegrationTableModel* integrationTableModel() { return m_integTblModel;}
void setGUIViewport(const double fromX, const double fromY, const double toX, const double toY);
virtual QJsonValue serialize() const;
const QString SignalDrawer::ME_SENDER_STR("SignalDrawer");
const int SignalDrawer::AXIS_LABEL_BORDER_OFFSET(2);
-const int SignalDrawer::AXIS_LABEL_SCALE_OFFSET(2);
+const int SignalDrawer::AXIS_LABEL_SCALE_OFFSET(3);
const int SignalDrawer::SCALE_MARGIN_TIME(16);
const int SignalDrawer::SCALE_MARGIN_VALUE(48);
QRegion SignalDrawer::erasePeak(const PeakDrawData& pd)
{
- //QPainter p;
QFont font("arial", 10);
QFontMetrics fm(font);
QString aucText, timeText;
QRegion peakReg;
int tTextHeight, tTextWidth, aTextWidth;
- int fromXPix, fromYPix;
- int toXPix, toYPix;
+ int fromXPix;
+ int toXPix;
int peakX, peakY;
int beginXPix, endXPix;
if (pd.auc == 0)
return QRect();
- fromXPix = relToXPix(pd.fromX); fromYPix = relToYPix(pd.fromY);
- toXPix = relToXPix(pd.toX); toYPix = relToYPix(pd.toY);
+ fromXPix = relToXPix(pd.fromX);
+ toXPix = relToXPix(pd.toX);
peakX = relToXPix(pd.peakX); peakY = relToYPix(pd.peakY);
aucText = m_locale.toString(pd.auc, 'f', 4);
timeText = m_locale.toString(pd.time, 'f', 4);
else
endXPix = toXPix;
- peakReg = QRect(beginXPix, 0, endXPix - beginXPix, m_height);
+ peakReg = QRect(beginXPix, 0, endXPix - beginXPix + 1, m_height);
if (peakReg.intersects(m_xAxisLabelRect)) {
peakReg += m_xAxisLabelRect;
}
if (pd.auc == 0)
return QRect();
- /* Psycho: Calculate precise position of the beginning and end of the baseline */
- double fromSlope = (pd.fromY - pd.beforeFromY) / (pd.fromX - pd.beforeFromX);
- double toSlope = (pd.toY - pd.beforeToY) / (pd.toX - pd.beforeToX);
- double qf = pd.beforeFromY - fromSlope * pd.beforeFromX;
- double qt = pd.beforeToY - toSlope * pd.beforeToX;
- double precFromX = linesIntersection(fromSlope, qf, pd.blSlope, pd.blQ);
- double precToX = linesIntersection(toSlope, qt, pd.blSlope, pd.blQ);
- double precFromY = precFromX * pd.blSlope + pd.blQ;
- double precToY = precToX * pd.blSlope + pd.blQ;
-
- /*qDebug() << __QFUNC__ << "idxStep" << pd.idxStep;
- qDebug() << __QFUNC__ << "blSlope" << pd.blSlope << "blQ" << pd.blQ;
- qDebug() << __QFUNC__ << "fromSlope" << fromSlope;
- qDebug() << __QFUNC__ << "qf" << qf << "qt" << qt;
- qDebug() << __QFUNC__ << precFromX << pd.beforeFromX;
- qDebug() << __QFUNC__ << precFromY << pd.beforeFromY;*/
-
- fromXPix = relToXPix(precFromX); fromYPix = relToYPix(precFromY);
- toXPix = relToXPix(precToX); toYPix = relToYPix(precToY);
+ switch (pd.itype) {
+ case IntegrationType::INTERSECTION:
+ {
+ /* Psycho: Calculate precise position of the beginning and end of the baseline */
+ double fromSlope = (pd.fromY - pd.beforeFromY) / (pd.fromX - pd.beforeFromX);
+ double toSlope = (pd.toY - pd.beforeToY) / (pd.toX - pd.beforeToX);
+ double qf = pd.beforeFromY - fromSlope * pd.beforeFromX;
+ double qt = pd.beforeToY - toSlope * pd.beforeToX;
+ double precFromX = linesIntersection(fromSlope, qf, pd.blSlope, pd.blQ);
+ double precToX = linesIntersection(toSlope, qt, pd.blSlope, pd.blQ);
+ double precFromY = precFromX * pd.blSlope + pd.blQ;
+ double precToY = precToX * pd.blSlope + pd.blQ;
+
+ fromXPix = relToXPix(precFromX); fromYPix = relToYPix(precFromY);
+ toXPix = relToXPix(precToX); toYPix = relToYPix(precToY);
+ }
+ break;
+ default:
+ fromXPix = relToXPix(pd.fromX); fromYPix = relToYPix(pd.fromY);
+ toXPix = relToXPix(pd.toX); toYPix = relToYPix(pd.toY);
+ break;
+ }
+
peakX = relToXPix(pd.peakX); peakY = relToYPix(pd.peakY);
aucText = m_locale.toString(pd.auc, 'f', 4);
timeText = QString("A:") + m_locale.toString(pd.time, 'f', 4);
p.begin(target);
p.setPen(Qt::red);
p.drawLine(fromXPix, fromYPix, toXPix, toYPix);
+ if (pd.itype == IntegrationType::BASELINE) {
+ p.drawLine(fromXPix, fromYPix, fromXPix, relToYPix(pd.blFromY));
+ p.drawLine(toXPix, toYPix, toXPix, relToYPix(pd.blToY));
+ }
/* Draw AREA and TIME caption */
p.setFont(font);
else
endXPix = toXPix;
- peakReg = QRect(beginXPix, 0, endXPix - beginXPix, m_height);
+ peakReg = QRect(beginXPix, 0, endXPix - beginXPix + 1, m_height);
p.end();
if (peakReg.intersects(m_xAxisLabelRect)) {