Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linting the MATS apps #1117

Merged
merged 37 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
4d29c61
Final linting of cb-metar
mollybsmith-noaa Oct 16, 2023
74b6f81
Update cb-metar tests
mollybsmith-noaa Oct 16, 2023
4401e23
More concise cb-metar main.js syntax
mollybsmith-noaa Oct 16, 2023
bd4ef60
ceil-vis main and data_series linting
mollybsmith-noaa Oct 16, 2023
2340271
ceil-vis data_validtime linting
mollybsmith-noaa Oct 17, 2023
eb5e8a5
ceil-vis data_dieoff and data_dailymodelcycle linting
mollybsmith-noaa Oct 17, 2023
c01e2b7
ceil-vis data_threshold linting
mollybsmith-noaa Oct 17, 2023
0e55a6a
ceil-vis data_histogram linting
mollybsmith-noaa Oct 17, 2023
2ad7d45
ceil-vis data_map linting
mollybsmith-noaa Oct 17, 2023
16eed43
ceil-vis data_perfDiagram linting
mollybsmith-noaa Oct 17, 2023
063d8ff
ceil-vis contour diagram linting
mollybsmith-noaa Oct 17, 2023
a80c0f3
fully linted ceil-vis15
mollybsmith-noaa Oct 18, 2023
5bdfef9
Updated release notes
mollybsmith-noaa Oct 18, 2023
ab329f4
fully linted radar
mollybsmith-noaa Oct 18, 2023
e7b7d9b
fully linted precipAccum
mollybsmith-noaa Oct 18, 2023
40e2a89
Updated chromedriver
mollybsmith-noaa Oct 20, 2023
64d77de
Added linter ignore lines to radar
mollybsmith-noaa Oct 20, 2023
0d8935f
Added linter ignore lines to precipAccum
mollybsmith-noaa Oct 20, 2023
e08c6c9
Added linter ignore lines to cb-metar
mollybsmith-noaa Oct 20, 2023
f2228bb
Added linter ignore lines to ceil-vis
mollybsmith-noaa Oct 24, 2023
9657203
Added linter ignore lines to ceil-vis15
mollybsmith-noaa Oct 24, 2023
e960267
fully linted precipGauge
mollybsmith-noaa Oct 24, 2023
88b9fcd
fully linted precipitation1hr
mollybsmith-noaa Oct 24, 2023
5893c0a
fully linted ptype
mollybsmith-noaa Oct 25, 2023
b1189d5
fully linted surfrad
mollybsmith-noaa Nov 7, 2023
096833c
fully linted landuse
mollybsmith-noaa Nov 8, 2023
25dc81a
fully linted anomalycor
mollybsmith-noaa Nov 8, 2023
8f83c58
fully linted surface
mollybsmith-noaa Nov 9, 2023
41f2d87
fully linted scorecard
mollybsmith-noaa Nov 10, 2023
4e52500
fully linted scorecard
mollybsmith-noaa Nov 10, 2023
420c665
Fixed METexpress conflict
mollybsmith-noaa Nov 10, 2023
92536a0
MATS submodule conflict resolution
mollybsmith-noaa Nov 10, 2023
2797675
At some point an extra space messed up the linter, curse it
mollybsmith-noaa Nov 10, 2023
e0b223a
Another one!
mollybsmith-noaa Nov 10, 2023
f3250cb
Merge branch 'development' into feature_lint_mats_apps
mollybsmith-noaa Nov 16, 2023
61245d3
Removed comment about custom linter rules from MATS apps
mollybsmith-noaa Nov 16, 2023
3ede681
Added global variable comment to cb-metar files
mollybsmith-noaa Nov 16, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion METexpress
18 changes: 1 addition & 17 deletions apps/anomalycor/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,6 @@
"space-before-function-paren": "off",
// for Meteor API's that rely on `this` context, e.g. Template.onCreated and publications
"func-names": "off",
"prefer-arrow-callback": "off",

// Vx Team modifications - Warn on rules that would require refactoring to implement.
// We want to be able to turn these back into "error"'s at some point. However, for
// our first pass, we'll only consider the checks that ESLint can auto-fix as errors.
// https://eslint.org/docs/latest/use/configure/rules#rule-severities
"no-undef": "warn",
"no-plusplus": "warn",
"vars-on-top": "warn",
"no-var": "warn",
"block-scoped-var": "warn",
"no-loop-func": "warn",
"no-unused-vars": "warn",
"prefer-destructuring": "warn",
"no-param-reassign": "warn",
"camelcase": "warn",
"no-redeclare": "warn"
"prefer-arrow-callback": "off"
}
}
1 change: 1 addition & 0 deletions apps/anomalycor/client/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Copyright (c) 2021 Colorado State University and Regents of the University of Colorado. All rights reserved.
*/

// eslint-disable-next-line no-unused-vars
import { matsTypes, matsCollections, methods } from "meteor/randyp:mats-common";
import "@fortawesome/fontawesome-free";
import "@fortawesome/fontawesome-free/css/all.css";
Expand Down
242 changes: 136 additions & 106 deletions apps/anomalycor/server/dataFunctions/data_contour.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from "meteor/randyp:mats-common";
import { moment } from "meteor/momentjs:moment";

// eslint-disable-next-line no-undef
dataContour = function (plotParams, plotFunction) {
// initialize variables common to all curves
const appParams = {
Expand All @@ -22,60 +23,75 @@ dataContour = function (plotParams, plotFunction) {
hideGaps: plotParams.noGapsCheck,
hasLevels: true,
};

const totalProcessingStart = moment();
const dataRequests = {}; // used to store data queries
let dataFoundForCurve = true;
const totalProcessingStart = moment();

const curves = JSON.parse(JSON.stringify(plotParams.curves));
if (curves.length > 1) {
throw new Error("INFO: There must only be one added curve.");
}

const axisMap = Object.create(null);

let statement = "";
let error = "";
const dataset = [];

const dateRange = matsDataUtils.getDateRange(plotParams.dates);
const fromSecs = dateRange.fromSeconds;
const toSecs = dateRange.toSeconds;

const xAxisParam = plotParams["x-axis-parameter"];
const yAxisParam = plotParams["y-axis-parameter"];
const xValClause = matsCollections.PlotParams.findOne({ name: "x-axis-parameter" })
.optionsMap[xAxisParam];
const yValClause = matsCollections.PlotParams.findOne({ name: "y-axis-parameter" })
.optionsMap[yAxisParam];
let error = "";
const curves = JSON.parse(JSON.stringify(plotParams.curves));
if (curves.length > 1) {
throw new Error("INFO: There must only be one added curve.");
}
const dataset = [];
const axisMap = Object.create(null);

// initialize variables specific to the curve
// initialize variables specific to this curve
const curve = curves[0];
const { label } = curve;
const { diffFrom } = curve;
const model = matsCollections["data-source"].findOne({ name: "data-source" })
.optionsMap[curve["data-source"]][0];
const regionStr = curve.region;
const region = Object.keys(
matsCollections.region.findOne({ name: "region" }).valuesMap
).find(
(key) =>
matsCollections.region.findOne({ name: "region" }).valuesMap[key] === regionStr
);
const queryTableClause = `from ${model}_anomcorr_${region} as m0`;

const { variable } = curve;
const variableClause = `and m0.variable = '${variable}'`;

let validTimeClause = "";
let forecastLengthClause = "";
let dateString = "";
let dateClause = "";
let levelClause = "";
if (xAxisParam !== "Valid UTC hour" && yAxisParam !== "Valid UTC hour") {
const validTimeStr =
curve["valid-time"] === matsTypes.InputTypes.unused
? "both"
: curve["valid-time"];
validTimeClause = matsCollections["valid-time"].findOne(
[validTimeClause] = matsCollections["valid-time"].findOne(
{ name: "valid-time" },
{ optionsMap: 1 }
).optionsMap[validTimeStr][0];
).optionsMap[validTimeStr];
}

let forecastLengthClause = "";
if (xAxisParam !== "Fcst lead time" && yAxisParam !== "Fcst lead time") {
const forecastLength = curve["forecast-length"];
if (forecastLength === undefined) {
throw new Error(
`INFO: ${label}'s forecast lead time is undefined. Please assign it a value.`
);
}
forecastLengthClause = `and m0.fcst_len = ${forecastLength}`;
}

const statisticClause =
"avg(m0.wacorr/100) as stat, " +
"stddev(m0.wacorr/100) as stdev, " +
"group_concat(unix_timestamp(m0.valid_date) + 3600 * m0.valid_hour, ';', m0.level, ';', m0.wacorr / 100 " +
"order by unix_timestamp(m0.valid_date) + 3600 * m0.valid_hour, m0.level) as sub_data, " +
"count(m0.wacorr) as N0";

let dateString = "";
let dateClause = "";
if (
(xAxisParam === "Init Date" || yAxisParam === "Init Date") &&
xAxisParam !== "Valid Date" &&
Expand All @@ -86,104 +102,118 @@ dataContour = function (plotParams, plotFunction) {
dateString = "unix_timestamp(m0.valid_date)+3600*m0.valid_hour";
}
dateClause = `and ${dateString} >= ${fromSecs} and ${dateString} <= ${toSecs}`;

let levelClause = "";
if (xAxisParam !== "Pressure level" && yAxisParam !== "Pressure level") {
const levels = curve.level === undefined ? [] : curve.level;
if (levels.length > 0 && levels !== matsTypes.InputTypes.unused) {
if (levels.length !== 0 && levels !== matsTypes.InputTypes.unused) {
levelClause = `and m0.level IN(${levels})`;
}
}
const statisticClause =
"avg(m0.wacorr/100) as stat, " +
"stddev(m0.wacorr/100) as stdev, " +
"group_concat(unix_timestamp(m0.valid_date) + 3600 * m0.valid_hour, ';', m0.level, ';', m0.wacorr / 100 " +
"order by unix_timestamp(m0.valid_date) + 3600 * m0.valid_hour, m0.level) as sub_data, " +
"count(m0.wacorr) as N0";
const statType = "ACC";
curve.statistic = "Correlation";

const regionStr = curve.region;
const region = Object.keys(
matsCollections.region.findOne({ name: "region" }).valuesMap
).find(
(key) =>
matsCollections.region.findOne({ name: "region" }).valuesMap[key] === regionStr
);

const queryTableClause = `from ${model}_anomcorr_${region} as m0`;

// For contours, this functions as the colorbar label.
curve.unitKey = curve.statistic;
const statType = "ACC";
const axisKey = "Correlation";
curve.statistic = axisKey;
curve.unitKey = axisKey;

let d;
// this is a database driven curve, not a difference curve
// prepare the query from the above parameters
let statement =
"{{xValClause}} " +
"{{yValClause}} " +
"count(distinct {{dateString}}) as N_times, " +
"min({{dateString}}) as min_secs, " +
"max({{dateString}}) as max_secs, " +
"{{statisticClause}} " +
"{{queryTableClause}} " +
"where 1=1 " +
"{{dateClause}} " +
"{{variableClause}} " +
"{{validTimeClause}} " +
"{{forecastLengthClause}} " +
"{{levelClause}} " +
"group by xVal,yVal " +
"order by xVal,yVal" +
";";

statement = statement.replace("{{xValClause}}", xValClause);
statement = statement.replace("{{yValClause}}", yValClause);
statement = statement.replace("{{statisticClause}}", statisticClause);
statement = statement.replace("{{queryTableClause}}", queryTableClause);
statement = statement.replace("{{variableClause}}", variableClause);
statement = statement.replace("{{validTimeClause}}", validTimeClause);
statement = statement.replace("{{forecastLengthClause}}", forecastLengthClause);
statement = statement.replace("{{levelClause}}", levelClause);
statement = statement.replace("{{dateClause}}", dateClause);
statement = statement.split("{{dateString}}").join(dateString);
dataRequests[label] = statement;

let queryResult;
const startMoment = moment();
let finishMoment;
try {
// send the query statement to the query function
queryResult = matsDataQueryUtils.queryDBContour(
sumPool,
statement,
appParams,
"Anomaly Correlation"
);
finishMoment = moment();
dataRequests[`data retrieval (query) time - ${label}`] = {
begin: startMoment.format(),
finish: finishMoment.format(),
duration: `${moment
.duration(finishMoment.diff(startMoment))
.asSeconds()} seconds`,
recordCount: queryResult.data.xTextOutput.length,
};
// get the data back from the query
d = queryResult.data;
} catch (e) {
// this is an error produced by a bug in the query function, not an error returned by the mysql database
e.message = `Error in queryDB: ${e.message} for statement: ${statement}`;
throw new Error(e.message);
}
if (queryResult.error !== undefined && queryResult.error !== "") {
if (queryResult.error === matsTypes.Messages.NO_DATA_FOUND) {
// this is NOT an error just a no data condition
dataFoundForCurve = false;
} else {
// this is an error returned by the mysql database
error += `Error from verification query: <br>${queryResult.error}<br> query: <br>${statement}<br>`;
throw new Error(error);
if (!diffFrom) {
let queryResult;
const startMoment = moment();
let finishMoment;
try {
statement =
"{{xValClause}} " +
"{{yValClause}} " +
"count(distinct {{dateString}}) as N_times, " +
"min({{dateString}}) as min_secs, " +
"max({{dateString}}) as max_secs, " +
"{{statisticClause}} " +
"{{queryTableClause}} " +
"where 1=1 " +
"{{dateClause}} " +
"{{variableClause}} " +
"{{validTimeClause}} " +
"{{forecastLengthClause}} " +
"{{levelClause}} " +
"group by xVal,yVal " +
"order by xVal,yVal" +
";";

statement = statement.replace("{{xValClause}}", xValClause);
statement = statement.replace("{{yValClause}}", yValClause);
statement = statement.replace("{{statisticClause}}", statisticClause);
statement = statement.replace("{{queryTableClause}}", queryTableClause);
statement = statement.replace("{{variableClause}}", variableClause);
statement = statement.replace("{{validTimeClause}}", validTimeClause);
statement = statement.replace("{{forecastLengthClause}}", forecastLengthClause);
statement = statement.replace("{{levelClause}}", levelClause);
statement = statement.replace("{{dateClause}}", dateClause);
statement = statement.split("{{dateString}}").join(dateString);
dataRequests[label] = statement;

// send the query statement to the query function
queryResult = matsDataQueryUtils.queryDBContour(
sumPool, // eslint-disable-line no-undef
statement,
appParams,
"Anomaly Correlation"
);

finishMoment = moment();
dataRequests[label] = statement;
dataRequests[`data retrieval (query) time - ${label}`] = {
begin: startMoment.format(),
finish: finishMoment.format(),
duration: `${moment
.duration(finishMoment.diff(startMoment))
.asSeconds()} seconds`,
recordCount: queryResult.data.xTextOutput.length,
};
// get the data back from the query
d = queryResult.data;
} catch (e) {
// this is an error produced by a bug in the query function, not an error returned by the mysql database
e.message = `Error in queryDB: ${e.message} for statement: ${statement}`;
throw new Error(e.message);
}
}

if (!dataFoundForCurve) {
// we found no data for any curves so don't bother proceeding
throw new Error("INFO: No valid data for any curves.");
}
if (queryResult.error !== undefined && queryResult.error !== "") {
if (queryResult.error === matsTypes.Messages.NO_DATA_FOUND) {
// this is NOT an error just a no data condition
dataFoundForCurve = false;
} else {
// this is an error returned by the mysql database
error += `Error from verification query: <br>${queryResult.error}<br> query: <br>${statement}<br>`;
throw new Error(error);
}
}

const postQueryStartMoment = moment();
if (!dataFoundForCurve) {
// we found no data for any curves so don't bother proceeding
throw new Error("INFO: No valid data for any curves.");
}
} else {
// this is a difference curve -- not supported for contours
throw new Error(
"INFO: Difference curves are not supported for contours, as there is only one curve."
);
}

// set curve annotation to be the curve mean -- may be recalculated later
// also pass previously calculated axis stats to curve options
const postQueryStartMoment = moment();
const { mean } = d.glob_stats;
const annotation =
mean === undefined
Expand Down
Loading
Loading