Files
GoldenCheetah/src/MetricAggregator.cpp
2009-12-10 10:16:58 -08:00

166 lines
5.4 KiB
C++

/*
* Copyright (c) 2009 Justin F. Knotzke (jknotzke@shampoo.ca)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "MetricAggregator.h"
#include "DBAccess.h"
#include "RideFile.h"
#include "Zones.h"
#include "Settings.h"
#include "RideItem.h"
#include "RideMetric.h"
#include "TimeUtils.h"
#include <assert.h>
#include <math.h>
#include <QtXml/QtXml>
MetricAggregator::MetricAggregator()
{
}
void MetricAggregator::aggregateRides(QDir home, const Zones *zones)
{
qDebug() << QDateTime::currentDateTime();
DBAccess *dbaccess = new DBAccess(home);
dbaccess->dropMetricTable();
dbaccess->createDatabase();
QRegExp rx = RideFileFactory::instance().rideFileRegExp();
QStringList errors;
QStringListIterator i(RideFileFactory::instance().listRideFiles(home));
while (i.hasNext()) {
QString name = i.next();
QFile file(home.absolutePath() + "/" + name);
RideFile *ride = RideFileFactory::instance().openRideFile(file, errors);
importRide(home, zones, ride, name, dbaccess);
}
dbaccess->closeConnection();
delete dbaccess;
qDebug() << QDateTime::currentDateTime();
}
bool MetricAggregator::importRide(QDir path, const Zones *zones, RideFile *ride, QString fileName, DBAccess *dbaccess)
{
SummaryMetrics *summaryMetric = new SummaryMetrics();
QFile file(path.absolutePath() + "/" + fileName);
QRegExp rx = RideFileFactory::instance().rideFileRegExp();
if (!rx.exactMatch(fileName)) {
fprintf(stderr, "bad name: %s\n", fileName.toAscii().constData());
assert(false);
return false;
}
summaryMetric->setFileName(fileName);
assert(rx.numCaptures() == 7);
QDate date(rx.cap(1).toInt(), rx.cap(2).toInt(),rx.cap(3).toInt());
QTime time(rx.cap(4).toInt(), rx.cap(5).toInt(),rx.cap(6).toInt());
QDateTime dateTime(date, time);
summaryMetric->setRideDate(dateTime);
int zone_range = zones->whichRange(dateTime.date());
const RideMetricFactory &factory = RideMetricFactory::instance();
QSet<QString> todo;
for (int i = 0; i < factory.metricCount(); ++i)
todo.insert(factory.metricName(i));
while (!todo.empty()) {
QMutableSetIterator<QString> i(todo);
later:
while (i.hasNext()) {
const QString &name = i.next();
const QVector<QString> &deps = factory.dependencies(name);
for (int j = 0; j < deps.size(); ++j)
if (!metrics.contains(deps[j]))
goto later;
RideMetric *metric = factory.newMetric(name);
metric->compute(ride, zones, zone_range, metrics);
metrics.insert(name, metric);
i.remove();
double value = metric->value(true);
if(name == "workout_time")
summaryMetric->setWorkoutTime(value);
else if(name == "average_cad")
summaryMetric->setCadence(value);
else if(name == "total_distance")
summaryMetric->setDistance(value);
else if(name == "skiba_xpower")
summaryMetric->setXPower(value);
else if(name == "average_speed")
summaryMetric->setSpeed(value);
else if(name == "total_work")
summaryMetric->setTotalWork(value);
else if(name == "average_power")
summaryMetric->setWatts(value);
else if(name == "time_riding")
summaryMetric->setRideTime(value);
else if(name == "average_hr")
summaryMetric->setHeartRate(value);
else if(name == "skiba_relative_intensity")
summaryMetric->setRelativeIntensity(value);
else if(name == "skiba_bike_score")
summaryMetric->setBikeScore(value);
}
}
dbaccess->importRide(summaryMetric);
delete summaryMetric;
return true;
}
void MetricAggregator::scanForMissing(QDir home, const Zones *zones)
{
QStringList errors;
DBAccess *dbaccess = new DBAccess(home);
QStringList filenames = dbaccess->getAllFileNames();
QRegExp rx = RideFileFactory::instance().rideFileRegExp();
QStringListIterator i(RideFileFactory::instance().listRideFiles(home));
while (i.hasNext()) {
QString name = i.next();
if(!filenames.contains(name))
{
qDebug() << "Found missing file: " << name;
QFile file(home.absolutePath() + "/" + name);
RideFile *ride = RideFileFactory::instance().openRideFile(file, errors);
importRide(home, zones, ride, name, dbaccess);
}
}
dbaccess->closeConnection();
delete dbaccess;
}
void MetricAggregator::resetMetricTable(QDir home)
{
DBAccess dbAccess(home);
dbAccess.dropMetricTable();
}