blob: 80ff251c46066c7f742eb98e663ea3f239b7e826 [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright (c) 2015 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<link rel="import" href="/tracing/base/statistics.html">
<link rel="import" href="/tracing/extras/rail/rail_interaction_record.html">
<script>
'use strict';
tr.exportTo('tr.e.rail', function() {
function RAILScore(opt_irs, opt_rangeOfInterest) {
this.interactionRecords_ = [];
if (opt_irs)
this.interactionRecords_.push.apply(this.interactionRecords_, opt_irs);
this.rangeOfInterest_ = opt_rangeOfInterest;
if (!this.rangeOfInterest_ || this.rangeOfInterest_.isEmpty)
this.rangeOfInterest_ = tr.b.Range.fromExplicitRange(
-Number.MAX_VALUE, Number.MAX_VALUE);
};
RAILScore.prototype = {
get interactionRecords() {
return this.interactionRecords_;
},
get overallScore() {
// The design of this algorithm is discussed here: https://goo.gl/Cc0H1z
// TODO(benjhayden): Make doc public and remove below comment?
// Until the doc is made public, this is basically a weighted average,
// where the weights are tunable. The weights are recommended to be higher
// for lower scores, so that lower scores will bring down the overallScore
// more than higher scores bring it up. The optional fields provide an
// opportunity to customize the tunable parameters based on IR type,
// duration, etc. The continuity and monotonicity of the weighting
// function are also important characteristics. The weighting function is
// not composed of meaningful sub-expressions; it is a monolithic
// combination of the score and tunable parameters, and is open to
// reformulation.
// The weighting function is graphed here: https://goo.gl/1blsXW
function getScore(ir) {
return ir.railScore;
}
function getWeight(ir) {
// If this IR is not in the range of interest, then remove it from the
// weightedMean calculation by setting its weight to zero.
if (!this.rangeOfInterest_.intersectsExplicitRangeExclusive(
ir.start, ir.end))
return 0;
var score = getScore(ir);
var scale = ir.railScoreScale;
if (scale === undefined)
scale = 3;
var power = ir.railScorePower;
if (power === undefined)
power = 0.3;
var base = ir.railScoreBase;
if (base === undefined)
base = Math.exp(1);
return Math.pow(base, -scale * Math.pow(score, power));
}
return tr.b.Statistics.weightedMean(
this.interactionRecords, getWeight, getScore, this);
},
asDict: function() {
return {
overallScore: this.overallScore
};
}
};
RAILScore.fromModel = function(model, opt_rangeOfInterest) {
var rirs = model.interactionRecords.filter(function(ir) {
return ir instanceof tr.e.rail.RAILInteractionRecord;
});
if (rirs.length === 0)
return undefined;
return new RAILScore(rirs, opt_rangeOfInterest);
};
return {
RAILScore: RAILScore
};
});
</script>