solar-scores
Version:
Compute scores for solar decathlon competition - Cali 2015
225 lines (196 loc) • 6.41 kB
JavaScript
;
const utils = require('../utils');
const points = require('../points');
const baseScore = require('../baseScore');
const moment = require('moment');
const waterMax = 1550;//In litters.
class Water extends baseScore {
constructor(options) {
super(options);
}
setData(tsv, group) {
this.tsv = tsv;
this.group = group;
}
getScore(asOfDate) {
var tsv = this.tsv;
var group = this.group;
var elapsedPercentage = utils.getElapsedFraction('Water', asOfDate);
let latest = this.getConsumption();
let maxConsumption = waterMax * elapsedPercentage;
if(!latest.data[group] || latest.data[group] > maxConsumption) {
return {
points: 0,
projected: 0,
max: points.Water,
maxUntilNow: elapsedPercentage * points.Water
};
}
let minConsumption = Number.MAX_VALUE;
maxConsumption = 0;
for(var key in latest.data) {
if(latest.data[key]<waterMax) {
if (latest.data[key] < minConsumption) {
minConsumption = latest.data[key];
}
if (latest.data[key] > maxConsumption) {
maxConsumption = latest.data[key];
}
}
}
let scoringFunction = utils.getSingleScoringFunction(minConsumption, maxConsumption);
let score = scoringFunction(latest.data[group]);
//DO NOT REPORT PARTIAL POINTS!!!
elapsedPercentage = elapsedPercentage>=1?1:0;
return {
points: score * points.Water * elapsedPercentage,
max: points.Water,
maxUntilNow: points.Water * elapsedPercentage,
projected: score * points.Water
};
//var water = getDayData(tsv, group);
//return doWater(water,group);
}
getConsumption() {
return this.getConsumptions()[0] || {};
}
getConsumptions() {
if(!this.tsv) return [];
var r = parseData(this.tsv);
r = utils.filterByEpoch(r, 'Water');
r.sort((a, b) => b.epoch - a.epoch);
return r;
}
}
function parseData(tsv) {
var result = [];
var data = csvTable(tsv, '\t');
var header = data[0];
var column = 2;
while(column < header.length) {
let i = column - 2;
var entry = {};
entry.epoch = new Date(header[column]+' 12:00:00 GMT-0500').getTime();
entry.data = {};
for(let i=1; i<data.length; i++) {
var el = data[i][column];
if(el.endsWith('\r')) {
el = el.slice(0, el.length - 1);
}
el = +el;
entry.data[data[i][0]] = el;
}
result[i] = entry;
column++;
}
return result;
}
// ==== Unused ===== //
/**
* Row 0 contains the current day date
* @param input
* @returns {*}
*/
function getDayData(input){
var data = csvTable(input,"\t");
var today = new Date().getTime(); //getDateDDMMYYYY();
var header = data[0];
var column = 2;
var minDiff = Number.MAX_SAFE_INTEGER;
while(column<header.length){
var columnDate = new Date(header[column]+' 12:00:00 GMT-0500').getTime();
if(Math.abs(today-columnDate)<minDiff){
column++;
minDiff = Math.abs(today-columnDate);
}
else{
column--;
break;
}
}
if(column>=header.length){
return null;
}
var result = new Array(data.length-1);
for(var i=1;i<data.length;i++){
result[i-1]={id:data[i][0],value:Number(data[i][column]),date:header[column]};
}
var table = new Array();
table.push(result);
for(var k=2;k<=column-1;k++){
var row = new Array(data.length-1);
for(var i=1;i<data.length;i++){
row[i-1]={id:data[i][0],value:Number(data[i][k]),date:header[k]};
}
table.push(row);
}
return table;
}
function doWater(water, group){
var score = waterScoreDay(water, group, new Date(),0);
delete score.day;
var perDay = new Array(water.length-1);
for(var i=1;i<water.length;i++){
perDay[i-1]=waterScoreDay(water, group, new Date(water[i][0].date+' 12:00:00 GMT-0500'),i);
}
score.perDay = perDay;
return score;
}
function waterScoreDay(water, group, today, column){
//TODO Change the dates to the competition dates
var dayStart = new Date('2015-11-25 12:00:00 GMT-0500');
var dayEnd = new Date('2015-12-5 12:00:00 GMT-0500');
//var today = new Date(last);//Date(getDateDDMMYYYY()+ " 12:00:00 GMT-0500");
var maxPoints = 10; // Set this parameter
var min = 9999999;
var max = 0;
for(var i=0;i<water[column].length;i++) {
var value = water[column][i].value;
if (value < waterMax) {
if (value > max) {
max = value;
}
if (value < min) {
min = value;
}
}
}
//console.log(max + " " + min);
var elapsedPercentaje= moment.duration(moment(today).diff(dayStart)).asDays()/
moment.duration(moment(dayEnd).diff(dayStart)).asDays();
if(elapsedPercentaje>=1)
elapsedPercentaje = 1;
else
elapsedPercentaje = 0;
var result;
for(var i=0;i<water[column].length;i++) {
if(water[column][i].id == group){
var value = water[column][i].value;
result = {max: maxPoints, day:water[column][i].date};
if (value < waterMax) {
var linearScore = (value-max)/(min-max);
result.points = elapsedPercentaje*maxPoints*linearScore;
result.maxUntilNow = elapsedPercentaje*maxPoints;
result.projected = maxPoints*linearScore;
}
else{
result.points = 0;
result.maxUntilNow = 0;
result.projected = 0;
}
}
}
return result;
}
function csvTable(csv,delimiter){
var lines=csv.split("\n");
var result = [];
var headers=lines[0].replace("\r","").split(delimiter);
result.push(headers);
for(var i=1;i<lines.length;i++){
var currentline=lines[i].split(delimiter);
result.push(currentline);
}
return result;
}
module.exports = Water;