/*
* Módulo utils, conjunto de funciones y herrameintas que son utilizadas de forma genérica por vario módulos
*
* @module module_utils
*
*/
var utils_module = (function (verbose) {
var _VERBOSE = verbose;
var buckets = 20;
var deciles = 10;
var _TYPE_BIO = 0;
/**
* Método que procesa la información para los histogramas de epsion y score por especie.
*
* @function processDataForFreqSpecie
* @public
*
* @param {json} data - Colección de datos resultantes del análisis configurado.
*/
function processDataForFreqSpecie(data) {
var min_eps = d3.min(data.map(function (d) {
return parseFloat(d.epsilon);
}));
// debug("min_eps: " + min_eps)
var max_eps = d3.max(data.map(function (d) {
return parseFloat(d.epsilon);
}));
// debug("max_eps: " + max_eps)
var min_scr = d3.min(data.map(function (d) {
return parseFloat(d.score);
}));
// debug("min_scr: " + min_scr)
var max_scr = d3.max(data.map(function (d) {
return parseFloat(d.score);
}));
// debug("max_scr: " + max_scr)
var beans = d3.range(1, buckets + 1, 1);
// var epsRange = d3.scaleQuantile().domain([min_eps, max_eps]).range(beans);
// var scrRange = d3.scaleQuantile().domain([min_scr, max_scr]).range(beans);
var epsRange = d3.scale.quantile().domain([min_eps, max_eps]).range(beans);
var scrRange = d3.scale.quantile().domain([min_scr, max_scr]).range(beans);
// debug("epsRange: " + epsRange.invertExtent(1))
var cross_species = crossfilter(data)
cross_species.groupAll();
var eps_dimension = cross_species.dimension(function (d) {
return parseFloat(d.epsilon);
});
var scr_dimension = cross_species.dimension(function (d) {
return parseFloat(d.score);
});
var groupByEpsilon = eps_dimension.group(function (d) {
// debug("epsRange: " + epsRange(d))
return epsRange(d)
});
var groupByScore = scr_dimension.group(function (d) {
return scrRange(d)
});
var data_eps = groupByEpsilon.top(Infinity);
data_eps.sort(_compare);
// debug(data_eps);
var data_scr = groupByScore.top(Infinity);
data_scr.sort(_compare);
// debug(data_scr);
var data_freq = [];
data_freq = generateFrequencyBeans(data_eps, epsRange, "_epsilon", data_freq, buckets);
data_freq = generateFrequencyBeans(data_scr, scrRange, "_score", data_freq, buckets);
// debug(data_freq);
return data_freq;
}
/**
* Método que procesa la información para el histograma de score por celda.
*
* @function processDataForFreqCell
* @public
*
* @param {json} data - Colección de datos resultantes del análisis configurado.
*/
function processDataForFreqCell(data) {
var min_scr = d3.min(data.map(function (d) {
return parseFloat(d.tscore);
}));
// debug("min_score: " + min_scr)
var max_scr = d3.max(data.map(function (d) {
return parseFloat(d.tscore);
}));
// debug("min_score: " + max_scr)
var beans = d3.range(1, buckets + 1, 1);
// var scrRange = d3.scaleQuantile().domain([min_scr, max_scr]).range(beans);
var scrRange = d3.scale.quantile().domain([min_scr, max_scr]).range(beans);
var cross_score = crossfilter(data)
cross_score.groupAll();
var scr_dimension = cross_score.dimension(function (d) {
return parseFloat(d.tscore);
});
var groupByScoreCell = scr_dimension.group(function (d) {
return scrRange(d)
});
var score_cell_data = groupByScoreCell.top(Infinity);
score_cell_data.sort(_compare);
// console.log(score_cell_data)
var data_freq = [];
data_freq = generateFrequencyBeans(score_cell_data, scrRange, "", data_freq, buckets);
// debug(data_freq)
return data_freq;
}
/**
* Método que procesa la información para el histograma de score por celda.
*
* @function generateFrequencyBeans
* @public
*
* @param {json} data_bucket - Mapa de datos agrupados por un valor específico.
* @param {function} funcRange - Función de quantiles con dominio y rango definidos.
* @param {sting} paramType - Prefijo para diferenciar resultados.
* @param {json} data_freq - Referencia al arreglo de resultados.
* @param {array} buckets - Colección con las cubetas donde son divididos los resultados.
*/
function generateFrequencyBeans(data_bucket, funcRange, paramType, data_freq, buckets) {
var index = 0;
var index_bucket = 0;
while (index_bucket < buckets) {
const entry = data_bucket[index];
var bucket = entry["key"];
var freq = entry["value"];
var range = funcRange.invertExtent((index_bucket + 1));
// debug("freq" + paramType+ ": " + freq);
// debug("bucket" + paramType+ ": " + bucket);
// debug("index+1" + paramType+ ": " + (index_bucket+1));
if ((index_bucket + 1) === bucket) {
if (data_freq[index_bucket] === undefined) {
var item = {};
item["bucket"] = bucket;
item["freq" + paramType] = freq;
item["min" + paramType] = parseFloat((range[0]).toFixed(3));
item["max" + paramType] = parseFloat((range[1]).toFixed(3));
data_freq.push(item);
} else {
data_freq[index_bucket]["freq" + paramType] = freq;
data_freq[index_bucket]["min" + paramType] = parseFloat(range[0].toFixed(3));
data_freq[index_bucket]["max" + paramType] = parseFloat(range[1].toFixed(3));
}
index++;
} else {
if (data_freq[index_bucket] === undefined) {
var item = {};
item["bucket"] = index_bucket + 1;
item["freq" + paramType] = 0;
item["min" + paramType] = parseFloat((range[0]).toFixed(3));
item["max" + paramType] = parseFloat((range[1]).toFixed(3));
data_freq.push(item);
} else {
data_freq[index_bucket]["freq" + paramType] = 0;
data_freq[index_bucket]["min" + paramType] = parseFloat(range[0].toFixed(3));
data_freq[index_bucket]["max" + paramType] = parseFloat(range[1].toFixed(3));
}
}
index_bucket++;
}
return data_freq;
}
/**
* Suma el score por cada celda, retorna el score total por cada celda existente en el arreglo
*
* @function reduceScoreCell
* @public
*
*/
function reduceScoreCell(data, val_apriori = 0, numr = 1) {
var cross_cells = crossfilter(data)
cross_cells.groupAll();
var cells_dimension = cross_cells.dimension(function (d) {
return d.gridid;
});
var groupByCell = cells_dimension.group().reduceSum(function (d) {
return d.tscore;
});
var map_cell = groupByCell.top(Infinity);
var cell_score_array = [];
for (var i = 0; i < map_cell.length; i++) {
const entry = map_cell[i];
var tscore = parseFloat(entry["value"]) - (val_apriori*(numr-1))
var gridid = entry["key"]
cell_score_array.push({gridid: gridid, tscore: parseFloat(tscore.toFixed(3))})
}
// console.log(cell_score_array);
return cell_score_array;
}
/**
* Obtiene las celdas de cada especie de la respuesta obtenida. Asigna a cada celda el valor de la especie y finalmente se raliza la sumatoria del score por celda
*
* @function processDataForScoreCell
* @public
*
*/
function processDataForScoreCell(data, apriori, mapa_prob, all_cells = []) {
_VERBOSE ? console.log("processDataForScoreCell") : _VERBOSE;
var cells_array = data.map(function (d) {
return {cells: d.cells, score: parseFloat(d.score)}
});
var cells = [];
cells_array.forEach(function (item, index) {
item.cells.forEach(function (cell_item, index) {
cells.push({cell: cell_item, score: item.score})
})
})
// debug(cells)
var cross_cells = crossfilter(cells)
cross_cells.groupAll();
var cells_dimension = cross_cells.dimension(function (d) {
return d.cell;
});
var groupByCell = cells_dimension.group().reduceSum(function (d) {
return parseFloat(d.score);
});
var map_cell = groupByCell.top(Infinity);
var cell_score_array = [];
for (var i = 0; i < map_cell.length; i++) {
const entry = map_cell[i];
cell_score_array.push({gridid: entry["key"], tscore: parseFloat(entry["value"].toFixed(3))})
}
var data_freq = [];
// debug(cell_score_array)
return cell_score_array
}
function processDataForScoreDecil(data_cell) {
_VERBOSE ? console.log("processDataForScoreDecil") : _VERBOSE;
var decile = 10;
var delta = Math.floor(data_cell.length / decile)
// debug(data_cell.length)
// debug(delta)
data_cell.reverse()
data_cell.forEach(function (item, index) {
var dec = Math.floor(index / delta) + 1
item["decile"] = dec > decile ? decile : dec
// item["avg"] = 0
})
// data_cell.reverse()
console.log(data_cell)
var map_groupd = d3.map([]);
data_cell.forEach(function (row_item, index) {
if (!map_groupd.has(row_item.decile)) {
var item = {};
item.decile = row_item.decile
item.tscore = row_item.tscore
item.max = row_item.tscore
item.min = row_item.tscore
item.cont = 1
map_groupd.set(item.decile, item)
}
else {
var item = map_groupd.get(row_item.decile);
item.tscore = item.tscore + row_item.tscore
item.max = item.max < row_item.tscore ? row_item.tscore : item.max
item.min = item.min > row_item.tscore ? row_item.tscore : item.min
item.cont += 1
map_groupd.set(item.decile, item)
}
})
// console.log(map_groupd)
// var cross_score = crossfilter(data_cell)
// cross_score.groupAll()
// var scr_dimension = cross_score.dimension(function (d) {
// return d.decile
// });
// var groupByScoreCell = scr_dimension.group().reduce(
// function (item, add) {
// item.val = item.val + 1
// item.sum = item.sum + add.tscore
// item.min = item.min < add.tscore ? item.min : add.tscore
// item.max = item.max > add.tscore ? item.max : add.tscore
// return item
// },
// function (item, remove) {
// item.val = item.val - 1
// item.sum = item.sum - remove.tscore
// item.min = item.min < add.tscore ? item.min : add.tscore
// item.max = item.max > add.tscore ? item.max : add.tscore
// return item
// },
// function () {
// return {
// val: 0,
// sum: 0,
// min: Number.MAX_VALUE,
// max: Number.MIN_VALUE
// }
// }
// )
// var score_cell_decil = groupByScoreCell.top(Infinity);
// score_cell_decil.sort(_compare_desc)
// // debug(score_cell_decil)
var score_cell_decil = map_groupd.values()
var cell_decil_array = []
console.log(score_cell_decil)
for (var i = 0; i < score_cell_decil.length; i++) {
cell_decil_array.push({
decil: score_cell_decil[i].decile,
avg: parseFloat(score_cell_decil[i].tscore / score_cell_decil[i].cont).toFixed(3),
l_sup: score_cell_decil[i].max,
l_inf: score_cell_decil[i].min,
vp: 0,
fn: 0,
nulos: 0,
recall: 0
})
}
console.log(cell_decil_array)
cell_decil_array.reverse();
return cell_decil_array;
}
function hashCode(str) {
return str.split('').reduce((prevHash, currVal) =>
(((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0);
}
function processTitleGroup(groupid, tfilters) {
_VERBOSE ? console.log("processTitleGroup") : _VERBOSE;
_VERBOSE ? console.log(groupid) : _VERBOSE;
_VERBOSE ? console.log(tfilters) : _VERBOSE;
var title_valor = ''
// debug("groupid: " + groupid)
// debug(tfilters)
if (groupid !== undefined) {
// group_item = 0 ->> root
if (parseInt(tfilters[0].type) === _TYPE_BIO) {
title_valor = JSON.stringify(
{'title': 'Grupo Bio ' + groupid,
'type': tfilters[0].type,
'group_item': tfilters[0].group_item,
'is_parent': true})
} else { //if (tfilters[0].type != 0) {
title_valor = JSON.stringify(
{'title': 'Grupo Raster ' + groupid,
'type': tfilters[0].type,
'group_item': tfilters[0].group_item,
'is_parent': true})
}
// else {
// title_valor = JSON.stringify(
// {'title':'Grupo Topo ' + groupid,
// 'type': tfilters[0].type ,
// 'group_item': tfilters[0].group_item,
// 'is_parent':true })
// }
} else if (tfilters[0].value) {
if (parseInt(tfilters[0].type) === _TYPE_BIO) {
title_valor = JSON.stringify(
{'title': tfilters[0].value,
'type': tfilters[0].type,
'group_item': tfilters[0].group_item,
'is_parent': false})
} else {
title_valor = JSON.stringify(
{'title': tfilters[0].label,
'type': tfilters[0].type,
'group_item': tfilters[0].group_item,
'is_parent': false})
}
}
return JSON.parse(title_valor)
}
/**
* Asigna el decil a cada una de las celdas, filtra las celdas que pertenecen al decil selecionado y obtiene el número de presencias de cada especie por decil
*
* @function processDataForScoreDecilTable
* @public
*
*/
function processDataForScoreDecilTable(data_cell, decil_selected) {
_VERBOSE ? console.log("processDataForScoreDecilTable") : _VERBOSE;
var decile = deciles
var delta = Math.floor(data_cell.length / decile)
data_cell.reverse()
data_cell.forEach(function (item, index) {
var dec = Math.floor(index / delta) + 1
item["decile"] = dec > decile ? decile : dec
})
data_cell.reverse()
// console.log(data_cell)
console.log(data_cell.length)
// console.log(data_cell[0].decile)
// console.log(decil_selected)
// console.log(data_cell[0].decile === decil_selected)
// console.log(data_cell[0].decile == decil_selected)
// console.log(8 == decil_selected)
var decil_array = data_cell.filter(function(item){
return item.decile == decil_selected
});
// console.log(decil_array)
console.log(decil_array.length)
var map_spid = d3.map([]);
// data_cell.forEach(function (row_item, index) {
decil_array.forEach(function (row_item, index) {
// if (row_item.decile != decil_selected)
// return;
row_item.species.forEach(function (specie, index) {
// if (!map_spid.has(specie.spid)) {
if (!map_spid.has(specie.name)) {
var item = {};
item.decile = row_item.decile
// item.spid = specie.spid
item.gridid = row_item.gridid
item.score = specie.score
item.epsilon = specie.epsilon
item.nj = specie.nj
item.njd = 1
item.name = specie.name
// map_spid.set(specie.spid, item)
map_spid.set(specie.name, item)
} else {
// var item = map_spid.get(specie.spid);
var item = map_spid.get(specie.name);
item.njd = item.njd + 1
map_spid.set(specie.name, item)
// map_spid.set(specie.spid, item)
}
})
})
return {
tbl_freq_decil: map_spid.values(),
length_decil: decil_array.length,
decil_array: decil_array
}
}
/**
* Obtiene el score por celda. Obtiene la sumatoria de todas las especies que tiene presencia en cada celda.
*
* @function processDataForScoreCellTable
* @public
*
*/
function processDataForScoreCellTable(data) {
_VERBOSE ? console.log("processDataForScoreCellTable") : _VERBOSE;
var total_length
var cells = d3.map([]);
data.forEach(function (item, index) {
total_length = item.n
item.cells.forEach(function (cell_item, index) {
var name = item.reinovalido === "" ? (item.layer + " " + item.tag) : (item.generovalido +" "+item.especieepiteto+" "+item.nombreinfra)
var item_map = {
cell: cell_item,
score: parseFloat(item.score),
epsilon: parseFloat(item.epsilon),
nj: parseFloat(item.nj),
name: name
}
cells.set("" + cell_item + name, item_map)
})
})
console.log("cells_values: " + cells.values().length)
var cross_cells = crossfilter(cells.values())
cross_cells.groupAll();
var cells_dimension = cross_cells.dimension(function (d) {
return d.cell;
});
var groupByScoreCell = cells_dimension.group().reduce(
function (item, add) {
item.tscore = item.tscore + add.score
// item.spids.push(add.spid)
item.epsilons.push(add.epsilon)
item.scores.push(add.score)
item.njs.push(add.nj)
item.names.push(add.name)
return item
},
function (item, remove) {
item.tscore = item.tscore - remove.score
var index = item.names.indexOf(remove.name);
if (index > -1) {
item.epsilons.splice(index, 1);
item.scores.splice(index, 1);
item.njs.splice(index, 1);
item.names.splice(index, 1);
}
return item
},
function () {
return {
tscore: 0,
spids: [],
epsilons: [],
scores: [],
njs: [],
names: []
}
}
)
// var groupByCell = cells_dimension.group().reduceSum(function(d) { return parseFloat(parseFloat(d.score).toFixed(3)); });
var map_cell = groupByScoreCell.top(Infinity);
console.log(map_cell)
console.log("map_cell: " + map_cell.length)
// Obtiene un array con gridid, score total (key) y un array con las espcecies en la celda, cada especie con sus valores de epsilon, score y nj
var cell_score_array = [];
for (var i = 0; i < map_cell.length; i++) {
const entry = map_cell[i];
// var len = entry["value"].spids.length;
var len = entry["value"].names.length;
// console.log("len: " + len)
var item = {};
item.gridid = entry["key"];
item.key = parseFloat((entry["value"].tscore).toFixed(3));
var species = [];
for (var j = 0; j < len; j++) {
var specie = {};
// specie.spid = entry["value"].spids[j];
specie.epsilon = entry["value"].epsilons[j];
specie.score = entry["value"].scores[j];
specie.nj = entry["value"].njs[j];
specie.name = entry["value"].names[j];
species.push(specie)
}
item.species = species;
cell_score_array.push(item)
}
cell_score_array.sort(_compare_desc);
// retorna y el total de celdas de la malla
return {array: cell_score_array, total_length: total_length}
}
function reduceDecilGroups(validatation_data_result){
var cross_cells = crossfilter(validatation_data_result)
cross_cells.groupAll();
var decil_dimension = cross_cells.dimension(function(d) { return d.decil; });
var groupByDecil = decil_dimension.group().reduce(
function(item,add){
++item.count
item.vp += add.vp
item.fn = item.fn + add.fn
item.nulo = item.nulo + add.nulo
item.recall = item.recall + add.recall
return item
},
function(item,remove){
--item.count
item.vp -= remove.vp
item.fn = item.fn - remove.fn
item.nulo = item.nulo - remove.nulo
item.recall = item.recall - remove.recall
return item
},
function(){
return {
count: 0,
vp: 0,
fn: 0,
nulo: 0,
recall: 0
}
}
)
var reduce_data = groupByDecil.top(Infinity);
reduce_data.sort(_compare_desc)
var data_result = []
for(var i=0; i<reduce_data.length; i++){
const entry = reduce_data[i];
data_result.push({
decil: entry["key"],
vp: parseFloat((entry["value"].vp / entry["value"].count).toFixed(2)),
fn: parseFloat((entry["value"].fn / entry["value"].count).toFixed(2)),
nulo: parseFloat((entry["value"].nulo / entry["value"].count).toFixed(2)),
recall: parseFloat((entry["value"].recall / entry["value"].count).toFixed(2))
})
}
// debug(data_result)
return data_result
}
function _compare(a, b) {
if (a.key < b.key)
return -1;
if (a.key > b.key)
return 1;
return 0;
}
function _compare_desc(a, b) {
_VERBOSE ? console.log("_compare_desc") : _VERBOSE;
if (a.key > b.key)
return -1;
if (a.key < b.key)
return 1;
return 0;
}
function getLinkToken(data_link, type, url_api, url_front) {
console.log("utils getLinkToken");
// console.log(data_link)
$.ajax({
url: url_api + "/niche/especie/getToken",
type: 'post',
data: data_link,
dataType: "json",
success: function (resp) {
var cadena_ini = url_front + '#link/?';
var tokenlink = resp.data[0].token;
console.log("token: " + tokenlink);
$("#modalRegenera").modal();
$("#lb_enlace").val(cadena_ini + "token=" + tokenlink);
},
error: function (jqXHR, textStatus, errorThrown) {
_VERBOSE ? console.log("error: " + textStatus) : _VERBOSE;
}
});
}
function genLinkURL() {
_VERBOSE ? console.log("utils genLinkURL") : _VERBOSE;
if (_json_config == undefined) {
return;
}
// console.log(_json_config.token);
var token = _json_config.token;
getValuesFromToken(token);
}
/**
* Regresa la fecha actual con formato YYYY-MM-DD
*
* @function _getDateNow
* @private
*/
function _getDateNow() {
_VERBOSE ? console.log("_getDateNow") : _VERBOSE;
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth() + 1; //January is 0!
var yyyy = today.getFullYear();
if (dd < 10) {
dd = "0" + dd;
}
if (mm < 10) {
mm = "0" + mm;
}
today = yyyy + "-" + mm + "-" + dd;
return today;
}
/**
* Parsea una URL a un JSON.
*
* @function parseURL
* @private
*
* @param {string} url - URL en formato cadena para ser parseado.
*
*/
function parseURL(url) {
// console.log(url);
var regex = /[?&]([^=#]+)=([^&#]*)/g, url = url, params = {}, match;
while (match = regex.exec(url)) {
params[match[1]] = match[2];
}
return params;
}
// No utilizado
function getQuerystring2(path, key, default_) {
_VERBOSE ? console.log("getQuerystring2") : _VERBOSE;
if (default_ == null) {
default_ = "";
}
var search = unescape(path);
if (search == "") {
return default_;
}
search = search.substr(1);
var params = search.split("&");
for (var i = 0; i < params.length; i++) {
var pairs = params[i].split("=");
if (pairs[0] == key) {
return pairs[1];
}
}
return default_;
}
/**
* Función que inicializa las variables necesarias para la creación de histogramas.
*
* @function startUtilsModule
* @public
*
*/
function startUtilsModule() {
_VERBOSE ? console.log("startUtilsModule") : _VERBOSE;
}
// Añadir los miembros públicos
return{
startUtilsModule: startUtilsModule,
processDataForScoreCell: processDataForScoreCell,
processDataForScoreDecil: processDataForScoreDecil,
processTitleGroup: processTitleGroup,
processDataForScoreDecilTable: processDataForScoreDecilTable,
processDataForScoreCellTable: processDataForScoreCellTable,
processDataForFreqSpecie: processDataForFreqSpecie,
processDataForFreqCell: processDataForFreqCell,
reduceScoreCell: reduceScoreCell,
reduceDecilGroups: reduceDecilGroups,
hashCode: hashCode,
getLinkToken: getLinkToken,
parseURL: parseURL
// genLinkURL: genLinkURL
// getValuesFromToken: getValuesFromToken
}
});