IntervalItem::refresh()

Computes the metrics for an interval and creates a temporary
ridefile locally so you don't have to.

.. previous design should have pushed this into the
   class instead of performing it in RideItem

.. now there should be no reason to create a ridefile
   during interval discovery.
This commit is contained in:
Mark Liversedge
2015-05-04 18:17:33 +01:00
parent 90c053f09f
commit 8a3e35b880
6 changed files with 69 additions and 52 deletions

View File

@@ -18,6 +18,8 @@
#include "IntervalItem.h"
#include "RideFile.h"
#include "Context.h"
#include "Athlete.h"
IntervalItem::IntervalItem(const RideFile *ride, QString name, double start, double stop,
double startKM, double stopKM, int displaySequence,
@@ -48,6 +50,60 @@ IntervalItem::setFrom(IntervalItem &other)
*this = other;
}
void
IntervalItem::refresh()
{
// don't open on our account - we should be called with a ride available
RideFile *f = rideItem_->ride_;
if (!f) return;
// create a temporary ride
RideFile intervalRide(f);
for (int i = f->intervalBeginSecs(start); i>= 0 &&i < f->dataPoints().size(); ++i) {
// iterate
const RideFilePoint *p = f->dataPoints()[i];
if (p->secs > stop) break;
// append all values
intervalRide.appendPoint(p->secs, p->cad, p->hr, p->km, p->kph, p->nm,
p->watts, p->alt, p->lon, p->lat, p->headwind,
p->slope, p->temp, p->lrbalance,
p->lte, p->rte, p->lps, p->rps,
p->lpco, p->rpco, p->lppb, p->rppb, p->lppe, p->rppe, p->lpppb, p->rpppb, p->lpppe, p->rpppe,
p->smo2, p->thb, p->rvert, p->rcad, p->rcontact, 0);
// copy derived data
RideFilePoint *l = intervalRide.dataPoints().last();
l->np = p->np;
l->xp = p->xp;
l->apower = p->apower;
}
// we created a blank ride (?)
if (intervalRide.dataPoints().size() == 0) return;
// ok, lets collect the metrics
const RideMetricFactory &factory = RideMetricFactory::instance();
QHash<QString,RideMetricPtr> computed= RideMetric::computeMetrics(rideItem_->context, &intervalRide, rideItem_->context->athlete->zones(),
rideItem_->context->athlete->hrZones(), factory.allMetrics());
// pack the metrics away and clean up if needed
metrics_.fill(0, factory.metricCount());
// snaffle away all the computed values into the array
QHashIterator<QString, RideMetricPtr> i(computed);
while (i.hasNext()) {
i.next();
metrics_[i.value()->index()] = i.value()->value();
}
// clean any bad values
for(int j=0; j<factory.metricCount(); j++)
if (std::isinf(metrics_[j]) || std::isnan(metrics_[j]))
metrics_[j] = 0.00f;
}
/*----------------------------------------------------------------------
* Edit Interval dialog
*--------------------------------------------------------------------*/

View File

@@ -55,6 +55,7 @@ class IntervalItem : public QTreeWidgetItem
QColor color; // color to use on plots that differentiate by color
// precomputed metrics
void refresh();
QVector<double> metrics_;
QVector<double> &metrics() { return metrics_; }

View File

@@ -369,9 +369,15 @@ struct ComparePointSecs {
int
RideFile::intervalBegin(const RideFileInterval &interval) const
{
return intervalBeginSecs(interval.start);
}
int
RideFile::intervalBeginSecs(const double secs) const
{
RideFilePoint p;
p.secs = interval.start;
p.secs = secs;
QVector<RideFilePoint*>::const_iterator i = std::lower_bound(
dataPoints_.begin(), dataPoints_.end(), &p, ComparePointSecs());
if (i == dataPoints_.end())

View File

@@ -260,6 +260,7 @@ class RideFile : public QObject // QObject to emit signals
void clearIntervals();
void fillInIntervals();
int intervalBegin(const RideFileInterval &interval) const;
int intervalBeginSecs(const double secs) const;
// Working with CAIBRATIONS
const QList<RideFileCalibration> &calibrations() const { return calibrations_; }

View File

@@ -555,9 +555,6 @@ RideItem::updateIntervals()
// add those automatically for HR and Power where those
// data series are present
// get metric factory
const RideMetricFactory &factory = RideMetricFactory::instance();
// ride start and end
RideFilePoint *begin = f->dataPoints().first();
RideFilePoint *end = f->dataPoints().last();
@@ -575,6 +572,7 @@ RideItem::updateIntervals()
entire->rideItem_ = this;
intervals_ << entire;
int count = 1;
foreach(RideFileInterval interval, f->intervals()) {
// skip peaks, they're autodiscovered now
@@ -589,37 +587,6 @@ RideItem::updateIntervals()
// skip empty backward intervals
if (interval.start >= interval.stop) continue;
// create a temporary ride
RideFile intervalRide(f);
int count = 1;
for (int i = f->intervalBegin(interval); i>= 0 &&i < f->dataPoints().size(); ++i) {
// iterate
const RideFilePoint *p = f->dataPoints()[i];
if (p->secs > interval.stop) break;
// append all values
intervalRide.appendPoint(p->secs, p->cad, p->hr, p->km, p->kph, p->nm,
p->watts, p->alt, p->lon, p->lat, p->headwind,
p->slope, p->temp, p->lrbalance,
p->lte, p->rte, p->lps, p->rps,
p->lpco, p->rpco, p->lppb, p->rppb, p->lppe, p->rppe, p->lpppb, p->rpppb, p->lpppe, p->rpppe,
p->smo2, p->thb, p->rvert, p->rcad, p->rcontact, 0);
// copy derived data
RideFilePoint *l = intervalRide.dataPoints().last();
l->np = p->np;
l->xp = p->xp;
l->apower = p->apower;
}
// we created a blank ride (?)
if (intervalRide.dataPoints().size() == 0) continue;
// ok, lets collect the metrics
QHash<QString,RideMetricPtr> computed= RideMetric::computeMetrics(context, &intervalRide, context->athlete->zones(),
context->athlete->hrZones(), factory.allMetrics());
// create a new interval item
IntervalItem *intervalItem = new IntervalItem(f, interval.name,
interval.start, interval.stop,
@@ -627,25 +594,10 @@ RideItem::updateIntervals()
f->timeToDistance(interval.stop),
count++, // sequence defaults to count
RideFileInterval::USER);
intervalItem->rideItem_ = this;
intervalItem->rideItem_ = this; // XXX will go when we refactor and be passed instead of ridefile
intervalItem->refresh(); // XXX will get called in constructore when refactor
intervals_ << intervalItem;
// pack the metrics away and clean up if needed
intervalItem->metrics_.fill(0, factory.metricCount());
// snaffle away all the computed values into the array
QHashIterator<QString, RideMetricPtr> i(computed);
while (i.hasNext()) {
i.next();
intervalItem->metrics_[i.value()->index()] = i.value()->value();
}
// clean any bad values
for(int j=0; j<factory.metricCount(); j++)
if (std::isinf(metrics_[j]) || std::isnan(metrics_[j]))
intervalItem->metrics_[j] = 0.00f;
// debug
//qDebug()<<"interval:"<<interval.name<<interval.start<<interval.stop<<"f:"<<begin->secs<<end->secs;
}

View File

@@ -47,6 +47,7 @@ class RideItem : public QObject
friend class ::RideCache;
friend class ::RideCacheModel;
friend class ::IntervalItem;
// ridefile
RideFile *ride_;