Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

qpp-measures-data

Package Overview
Dependencies
Maintainers
1
Versions
271
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

qpp-measures-data - npm Package Compare versions

Comparing version 1.0.0-alpha.15 to 1.0.0-alpha.16

scripts/measures/test2.json

12

index.js
// Libraries
var fs = require('fs');
var path = require('path');
var YAML = require('yamljs');
const fs = require('fs');
const path = require('path');
const YAML = require('yamljs');
var yearRegEx = /^[0-9]{4}/;
var benchmarkJsonFileRegEx = /^[0-9]{4}\.json$/;
const yearRegEx = /^[0-9]{4}/;
const benchmarkJsonFileRegEx = /^[0-9]{4}\.json$/;

@@ -16,3 +16,3 @@ /**

exports.getBenchmarksData = function() {
var benchmarksByYear = {};
const benchmarksByYear = {};

@@ -19,0 +19,0 @@ fs.readdirSync(path.join(__dirname, 'benchmarks')).forEach(function(file) {

{
"name": "qpp-measures-data",
"version": "1.0.0-alpha.15",
"version": "1.0.0-alpha.16",
"description": "Quality Payment Program Measures Data Repository",

@@ -27,5 +28,4 @@ "repository": {

"eslint": "^4.2.0",
"eslint-config-nava": "^1.0.0",
"eslint-config-nava": "^2.0.0",
"eslint-plugin-react": "^7.1.0",
"eslint-plugin-standard": "^3.0.1",
"lodash": "^4.16.4",

@@ -32,0 +32,0 @@ "mocha": "^3.2.0",

// Utility functions for formatting the csv records
// Libraries
var keyBy = require('lodash/keyBy');
const keyBy = require('lodash/keyBy');
// Data
var measures = require('../../measures/measures-data.json');
const measures = require('../../measures/measures-data.json');
// Constants

@@ -12,3 +12,3 @@ /**

*/
var SUBMISSION_METHOD_MAP = {
const SUBMISSION_METHOD_MAP = {
'claims': 'claims',

@@ -25,3 +25,3 @@ 'registry': 'registry',

*/
var MEASURE_ID_TO_MEASURE_MAP = keyBy(measures, function(measure) {
const MEASURE_ID_TO_MEASURE_MAP = keyBy(measures, function(measure) {
/**

@@ -40,7 +40,7 @@ * NOTE: Quality measurements' measureIds are usually string integers.

*/
var formatSubmissionMethod = function(submissionMethod) {
const formatSubmissionMethod = function(submissionMethod) {
return SUBMISSION_METHOD_MAP[submissionMethod.replace(/\s/g, '').toLowerCase()];
};
var isInverseBenchmarkRecord = require('../../util/benchmarks/is-inverse-benchmark-record');
var floatRegex = /([0-9]*[.]?[0-9]+)/g;
const isInverseBenchmarkRecord = require('../../util/benchmarks/is-inverse-benchmark-record');
const floatRegex = /([0-9]*[.]?[0-9]+)/g;
/**

@@ -69,6 +69,6 @@ * Generator function to create a

*/
var formatDecileGenerator = function(record) {
var isInverseMeasure = isInverseBenchmarkRecord(record);
var top = isInverseMeasure ? 0 : 100;
var bottom = isInverseMeasure ? 100 : 0;
const formatDecileGenerator = function(record) {
const isInverseMeasure = isInverseBenchmarkRecord(record);
const top = isInverseMeasure ? 0 : 100;
const bottom = isInverseMeasure ? 100 : 0;

@@ -83,7 +83,7 @@ /**

return function(decileString, index, array) {
var range = decileString ? decileString.match(floatRegex) : null;
var nextIndex = index + 1;
var prevIndex = index - 1;
var definedPredecessor;
var definedSuccessor;
const range = decileString ? decileString.match(floatRegex) : null;
let nextIndex = index + 1;
let prevIndex = index - 1;
let definedPredecessor;
let definedSuccessor;

@@ -168,3 +168,3 @@ // If decile is explicitly defined:

*/
var formatBenchmarkRecord = function(record, options) {
const formatBenchmarkRecord = function(record, options) {
/**

@@ -175,3 +175,3 @@ * NOTE: Some of the benchmarks don't correspond to

*/
var measure = MEASURE_ID_TO_MEASURE_MAP[record.qualityId];
const measure = MEASURE_ID_TO_MEASURE_MAP[record.qualityId];

@@ -178,0 +178,0 @@ if (!measure) return;

// Libraries
var parse = require('csv-parse');
const parse = require('csv-parse');
// Constants
var BENCHMARK_CSV_COLUMNS = [
const BENCHMARK_CSV_COLUMNS = [
'measureName',

@@ -21,5 +21,5 @@ 'qualityId',

// Utils
var formatBenchmarkRecord = require('./format-benchmark-record');
const formatBenchmarkRecord = require('./format-benchmark-record');
// Data
var benchmarksData = '';
let benchmarksData = '';

@@ -32,6 +32,6 @@ /**

*/
var benchmarks = [];
const benchmarks = [];
// Commandline Arguments
var benchmarkYear = process.argv[2];
var performanceYear = process.argv[3];
const benchmarkYear = process.argv[2];
const performanceYear = process.argv[3];

@@ -42,3 +42,3 @@ if (benchmarkYear && performanceYear) {

process.stdin.on('readable', function() {
var chunk = process.stdin.read();
const chunk = process.stdin.read();
if (chunk !== null) {

@@ -55,3 +55,3 @@ benchmarksData += chunk;

records.forEach(function(record) {
var benchmark = formatBenchmarkRecord(record, {benchmarkYear: benchmarkYear, performanceYear: performanceYear});
const benchmark = formatBenchmarkRecord(record, {benchmarkYear: benchmarkYear, performanceYear: performanceYear});

@@ -58,0 +58,0 @@ if (benchmark) benchmarks.push(benchmark);

@@ -20,14 +20,14 @@ /**

*/
var fs = require('fs');
var _ = require('lodash');
var parse = require('csv-parse/lib/sync');
const fs = require('fs');
const _ = require('lodash');
const parse = require('csv-parse/lib/sync');
var MAX_SPECIALITY_SET_SIZE = 6;
var SUPPORTED_PERFORMANCE_YEARS = [2017];
const MAX_SPECIALITY_SET_SIZE = 6;
const SUPPORTED_PERFORMANCE_YEARS = [2017];
var measuresJson = '';
var claimsClusterFilePath = process.argv[2];
var registryClusterFilePath = process.argv[3];
let measuresJson = '';
const claimsClusterFilePath = process.argv[2];
const registryClusterFilePath = process.argv[3];
var specialClusterRelations = {
const specialClusterRelations = {
registry: [

@@ -92,7 +92,7 @@ {measureId: '047', optionals: []},

function populateClinicalClusters(clusterMap, measures, submissionMethod, filePath) {
let contents = fs.readFileSync(filePath, 'utf8');
let rows = parse(contents, {columns: true});
const contents = fs.readFileSync(filePath, 'utf8');
const rows = parse(contents, {columns: true});
// group the measures by cluster
let byClusterName = _.chain(rows)
const byClusterName = _.chain(rows)
.map(r => ({clusterName: _.camelCase(r['Title']), measureId: _.padStart(r['Quality ID'], 3, '0')}))

@@ -106,4 +106,4 @@ .groupBy('clusterName')

clinicalCluster.measureIds.forEach(measureId => {
let measure = measures.find(m => m.measureId === measureId);
let cluster = clusterMap.get(measureId) || {
const measure = measures.find(m => m.measureId === measureId);
const cluster = clusterMap.get(measureId) || {
measureId: measureId,

@@ -123,3 +123,3 @@ submissionMethod: submissionMethod,

// group the measures of submissionMethod by specialty set
let bySpecialty = _.chain(measures)
const bySpecialty = _.chain(measures)
.filter(m => m.category === 'quality')

@@ -136,4 +136,4 @@ .filter(m => m.submissionMethods && m.submissionMethods.indexOf(submissionMethod) > -1)

specialty.measureIds.forEach(measureId => {
let measure = measures.find(m => m.measureId === measureId);
let cluster = clusterMap.get(measureId) || {
const measure = measures.find(m => m.measureId === measureId);
const cluster = clusterMap.get(measureId) || {
measureId: measureId,

@@ -153,3 +153,3 @@ submissionMethod: submissionMethod,

function generateEMAClusters(allMeasures) {
let measures = allMeasures.filter(m =>
const measures = allMeasures.filter(m =>
(SUPPORTED_PERFORMANCE_YEARS.indexOf(m.firstPerformanceYear) > -1) &&

@@ -159,4 +159,4 @@ (m.lastPerformanceYear == null || SUPPORTED_PERFORMANCE_YEARS.indexOf(m.lastPerformanceYear) > -1)

let claimsClusterMap = new Map();
let registryClusterMap = new Map();
const claimsClusterMap = new Map();
const registryClusterMap = new Map();

@@ -173,3 +173,3 @@ // set the claims and registry specialty set

let emaClusters = [];
const emaClusters = [];

@@ -185,5 +185,5 @@ claimsClusterMap

if (ema.clinicalClusters) {
let clinicalClusters = [];
const clinicalClusters = [];
ema.clinicalClusters.forEach(cc => {
let cluster = Object.assign({}, cc, {measureIds: cc.measureIds.concat([ema.measureId])});
const cluster = Object.assign({}, cc, {measureIds: cc.measureIds.concat([ema.measureId])});
clinicalClusters.push(cluster);

@@ -202,3 +202,3 @@ cluster.measureIds = _.uniq(cluster.measureIds);

process.stdin.on('readable', () => {
var chunk = process.stdin.read();
const chunk = process.stdin.read();
if (chunk !== null) {

@@ -205,0 +205,0 @@ measuresJson += chunk;

@@ -9,7 +9,7 @@ /**

var xml2js = require('xml2js');
const xml2js = require('xml2js');
var schemaType = 'measures';
const schemaType = 'measures';
var json = '';
let json = '';
/**

@@ -32,4 +32,4 @@ * XML does not allow for multiple elements without a root element. So by

function convertToXml(json) {
var builder = new xml2js.Builder({rootName: schemaType});
var xml = builder.buildObject(JSON.parse(json, 'utf8'));
const builder = new xml2js.Builder({rootName: schemaType});
const xml = builder.buildObject(JSON.parse(json, 'utf8'));
process.stdout.write(

@@ -47,3 +47,3 @@ xml

process.stdin.on('readable', function() {
var chunk = this.read();
const chunk = this.read();
if (chunk !== null) {

@@ -50,0 +50,0 @@ json += chunk;

@@ -16,3 +16,3 @@ #!/usr/bin/env node

const additionalMeasuresFilepath = '../../util/measures/additional-measures.json';
var additionalMeasures = require(additionalMeasuresFilepath);
let additionalMeasures = require(additionalMeasuresFilepath);

@@ -53,3 +53,3 @@ // Some measures have an NqfId (NQF: National Quality Forum) of '0005'

// Initialize a string to store the CSV data.
var cahpsMeasuresData = '';
let cahpsMeasuresData = '';

@@ -59,3 +59,3 @@ process.stdin.setEncoding('utf8');

process.stdin.on('readable', function() {
var chunk = process.stdin.read();
const chunk = process.stdin.read();
if (chunk !== null) {

@@ -67,4 +67,4 @@ cahpsMeasuresData += chunk;

function generateCahpsMeasure(record, idx) {
var measureTitle = record['Measure Name'];
var measureIdx = cahpsTitleToMeasureIdIndexMap[measureTitle];
const measureTitle = record['Measure Name'];
const measureIdx = cahpsTitleToMeasureIdIndexMap[measureTitle];

@@ -108,3 +108,3 @@ if (measureIdx === undefined) {

additionalMeasures = additionalMeasures.filter(function(measure) {
var re = /CAHPS_\d+/i;
const re = /CAHPS_\d+/i;
return measure.measureId.match(re) === null;

@@ -114,3 +114,3 @@ });

records.forEach(function(record, idx) {
var measure = generateCahpsMeasure(record, idx);
const measure = generateCahpsMeasure(record, idx);
if (measure) additionalMeasures.push(measure);

@@ -117,0 +117,0 @@ });

@@ -47,3 +47,3 @@ /**

process.stdin.on('readable', () => {
var chunk = process.stdin.read();
const chunk = process.stdin.read();
if (chunk !== null) {

@@ -122,7 +122,7 @@ qpp += chunk;

}
var result = [];
const result = [];
for (var i = 0; i < measureList.length; i++) {
var measure = measureList[i];
var obj = {};
for (let i = 0; i < measureList.length; i++) {
const measure = measureList[i];
const obj = {};
obj.category = category;

@@ -129,0 +129,0 @@ obj.firstPerformanceYear = new Date().getFullYear();

@@ -24,3 +24,3 @@ #!/usr/bin/env node

process.stdin.on('readable', () => {
var chunk = process.stdin.read();
const chunk = process.stdin.read();
if (chunk !== null) {

@@ -27,0 +27,0 @@ measuresData += chunk;

@@ -7,10 +7,10 @@ // running this will generate a file in util/measures/quality-performace-rates.json

var _ = require('lodash');
var fs = require('fs');
var program = require('commander');
var pdfToText = require('pdf-to-text');
var p = require('path');
const _ = require('lodash');
const fs = require('fs');
const program = require('commander');
const pdfToText = require('pdf-to-text');
const p = require('path');
var folderPath = null;
var performanceRateJson = [];
let folderPath = null;
const performanceRateJson = [];

@@ -33,3 +33,3 @@ function setPath(path) {

function cleanUpString(input) {
var removeWords = ['OR', 'AND', 'Eligible clinicians should continue to report the measure as specified, with no additional steps needed to account for multiple performance rates.'];
const removeWords = ['OR', 'AND', 'Eligible clinicians should continue to report the measure as specified, with no additional steps needed to account for multiple performance rates.'];

@@ -49,5 +49,5 @@ removeWords.forEach(function(word) {

var rateDescriptions = [];
const rateDescriptions = [];
var found = data.match(/This measure will be calculated with (\d) performance rates:/);
let found = data.match(/This measure will be calculated with (\d) performance rates:/);

@@ -59,6 +59,7 @@ if (!found) {

let foundRate;
if (!found) {
// only a single performace rate
let rateRegex = /DESCRIPTION:((.|\s)*?)INSTRUCTIONS:/;
var foundRate = data.match(rateRegex);
const rateRegex = /DESCRIPTION:((.|\s)*?)INSTRUCTIONS:/;
foundRate = data.match(rateRegex);

@@ -68,6 +69,6 @@ rateDescriptions.push(cleanUpString(foundRate[1]));

// multi performance rate
var numOfRates = found[1];
const numOfRates = found[1];
var reportingStart = /REPORTING CRITERIA FOR THIS MEASURE:/;
var reportingFound = data.match(reportingStart);
const reportingStart = /REPORTING CRITERIA FOR THIS MEASURE:/;
let reportingFound = data.match(reportingStart);
if (reportingFound == null) {

@@ -77,8 +78,8 @@ reportingFound = found;

var remainingFile = data.substring(reportingFound.index + reportingFound[0].length);
const remainingFile = data.substring(reportingFound.index + reportingFound[0].length);
// find the 1, see if a ) or a . comes after each performance rate number
var firstPos = remainingFile.indexOf('1');
var delineationChar = remainingFile[firstPos + 1];
const firstPos = remainingFile.indexOf('1');
const delineationChar = remainingFile[firstPos + 1];
for (var i = 1; i <= numOfRates; i++) {
for (let i = 1; i <= numOfRates; i++) {
// look for the description between 1) and 2)

@@ -89,3 +90,3 @@ let rateRegex = new RegExp(i + '\\' + delineationChar + '((.|\\s)*?)(' + (i + 1) + '\\' + delineationChar + '|Version 1\\.0)');

// if this is the last rate, look for the description between x) and the ending phrases
var endingPhrases = '(REPORTING CRITERIA|Measure Reporting:|Version 1\\.0|DENOMINATOR \\(REPORTING|The eligible clinician should submit data)';
const endingPhrases = '(REPORTING CRITERIA|Measure Reporting:|Version 1\\.0|DENOMINATOR \\(REPORTING|The eligible clinician should submit data)';
rateRegex = new RegExp(i + '\\' + delineationChar + '((.|\\s)*?)' + endingPhrases);

@@ -105,4 +106,4 @@ }

// group the files by the qualityId. This way we don't have to look through the claims and registry files
var groupedFiles = fs.readdirSync(folderPath).reduce(function(arr, current) {
var qualityId = current.split('_')[2];
const groupedFiles = fs.readdirSync(folderPath).reduce(function(arr, current) {
const qualityId = current.split('_')[2];
arr[qualityId] ? arr[qualityId].push(current) : arr[qualityId] = [current];

@@ -112,3 +113,3 @@ return arr;

var qualityIds = Object.keys(groupedFiles);
const qualityIds = Object.keys(groupedFiles);
qualityIds.forEach(function(qualityId, i) {

@@ -121,3 +122,3 @@ getRates(p.join(folderPath, groupedFiles[qualityId][0]), function(rateDescriptions) {

// sort all performance rates
var sortedRates = _.sortBy(performanceRateJson, ['qualityId']);
const sortedRates = _.sortBy(performanceRateJson, ['qualityId']);
// write file to tmp

@@ -124,0 +125,0 @@ fs.writeFile(p.join(__dirname, '../../util/measures/quality-performance-rates.json'), JSON.stringify(sortedRates, null, 2));

@@ -14,3 +14,3 @@ // this script merges the util/measures/quality-performance-rates.json,

process.stdin.on('readable', () => {
var chunk = process.stdin.read();
const chunk = process.stdin.read();
if (chunk !== null) {

@@ -27,12 +27,12 @@ qpp += chunk;

// read in tmp/quality-performance-rates.json
var performanceRatesJson = JSON.parse(fs.readFileSync(path.join(__dirname, '../../util/measures/quality-performance-rates.json'), 'utf8'));
const performanceRatesJson = JSON.parse(fs.readFileSync(path.join(__dirname, '../../util/measures/quality-performance-rates.json'), 'utf8'));
// read in measures/quality-measures-additional-info.json
var performanceRateAdditionalJson = JSON.parse(fs.readFileSync(path.join(__dirname, '../../util/measures/quality-measures-strata-details.json'), 'utf8'));
const performanceRateAdditionalJson = JSON.parse(fs.readFileSync(path.join(__dirname, '../../util/measures/quality-measures-strata-details.json'), 'utf8'));
var measuresNotFound = [];
const measuresNotFound = [];
// iterate through all qppJson measures and find matching items from other json blobs
qppJson.forEach(function(qppItem, index) {
if (qppItem.category === 'quality') {
var performanceRateDescription = _.find(performanceRatesJson, {'qualityId': qppItem.measureId});
var performanceRateInfo = _.find(performanceRateAdditionalJson, {'qualityId': qppItem.measureId});
const performanceRateDescription = _.find(performanceRatesJson, {'qualityId': qppItem.measureId});
const performanceRateInfo = _.find(performanceRateAdditionalJson, {'qualityId': qppItem.measureId});

@@ -43,3 +43,3 @@ if (!performanceRateDescription || !performanceRateInfo) {

var strataDetails = [];
const strataDetails = [];
performanceRateDescription.descriptions.forEach(function(description, index) {

@@ -140,3 +140,3 @@ strataDetails.push({description: description, name: performanceRateInfo.performanceRates[index]});

// find the relation and populate reporting category and substitutions
var aciRelation = aciRelations[measure.measureId];
const aciRelation = aciRelations[measure.measureId];
if (aciRelation) {

@@ -143,0 +143,0 @@ measure.reportingCategory = aciRelation.reportingCategory;

@@ -35,3 +35,3 @@ const fs = require('fs');

// find the relation and populate reporting category and substitutions
var aciRelation = aciRelations[measure.measureId];
const aciRelation = aciRelations[measure.measureId];
if (aciRelation) {

@@ -53,3 +53,3 @@ measure.reportingCategory = aciRelation.reportingCategory;

Object.keys(cpcPlusGroups).forEach((groupId) => {
var match = cpcPlusGroups[groupId].find((id) => id === measure.eMeasureId);
const match = cpcPlusGroups[groupId].find((id) => id === measure.eMeasureId);
if (match !== undefined) {

@@ -67,4 +67,4 @@ measure.cpcPlusGroup = groupId;

function enrichAddMeasuresSpecification(measures) {
var csv = parse(fs.readFileSync(path.join(__dirname, '../../util/measures/measurePDF-Specification.csv'), 'utf8'));
var mappedLinks = csv.reduce(function(acc, [submissionMethod, measureId, link]) {
const csv = parse(fs.readFileSync(path.join(__dirname, '../../util/measures/measurePDF-Specification.csv'), 'utf8'));
const mappedLinks = csv.reduce(function(acc, [submissionMethod, measureId, link]) {
acc[measureId] = acc[measureId] || {};

@@ -74,3 +74,3 @@ acc[measureId][submissionMethod] = link;

}, {});
var measureData = measures.map(function(measure) {
const measureData = measures.map(function(measure) {
measure.measureSpecification = mappedLinks[measure.measureId];

@@ -87,3 +87,3 @@ return measure;

function enrichInverseMeasures(measures) {
let inverseMeasures = JSON.parse(fs.readFileSync(path.join(__dirname, '../../util/measures/inverse-measures.json')));
const inverseMeasures = JSON.parse(fs.readFileSync(path.join(__dirname, '../../util/measures/inverse-measures.json')));
measures.forEach(measure => {

@@ -90,0 +90,0 @@ if (inverseMeasures.hasOwnProperty(measure.measureId)) {

@@ -40,3 +40,3 @@ // running this will print out whether each measure is an inverse measure

let found = data.match(/inverse measure/i); // ignore case
const found = data.match(/inverse measure/i); // ignore case

@@ -54,3 +54,3 @@ if (found) {

const groupedFiles = fs.readdirSync(folderPath).reduce(function(arr, current) {
let qualityId = current.split('_')[2];
const qualityId = current.split('_')[2];
arr[qualityId] ? arr[qualityId].push(current) : arr[qualityId] = [current];

@@ -57,0 +57,0 @@ return arr;

@@ -30,7 +30,2 @@ const parse = require('csv-parse/lib/sync');

nqfId: null,
strata: [
{
name: 'overall'
}
],
measureSets: [],

@@ -90,2 +85,55 @@ isRegistryMeasure: true

const addMultiPerformanceRateDetails = function(newMeasure, record, qcdrStrataNamesDataPath) {
// Parse the names for qcdr measures with multiple strata/performance rates
// { measureId: [name of 1st performance rate, name of 2nd performance rate, etc.] }
//
// In the strata names file, note that the order of the array values matter.
// Also, unlike the descriptions for each of the strata/performance rates,
// the names do not come from a source outside of this codebase. They were
// created by manually selecting distinct keywords from the associated
// performance rate description and are used when submitting to the API.
const strataNames = fs.readFileSync(path.join(__dirname, qcdrStrataNamesDataPath), 'utf8');
const qcdrStrataNames = JSON.parse(strataNames);
newMeasure['metricType'] = 'multiPerformanceRate';
const overallPerformanceRate = _.lowerCase(_.trim(record[12]));
const nthPerformanceRate = _.parseInt(overallPerformanceRate);
if (_.isInteger(nthPerformanceRate)) {
newMeasure['overallAlgorithm'] = 'overallStratumOnly';
} else if (overallPerformanceRate === 'sum numerators') {
newMeasure['overallAlgorithm'] = 'sumNumerators';
} else if (overallPerformanceRate === 'weighted average') {
newMeasure['overallAlgorithm'] = 'weightedAverage';
}
// Add the names and descriptions of strata
let strataName;
const measureId = _.trim(record[2]);
const measureDescription = _.trim(record[4]);
// Measure description column contains performance rate description
// Split '*summary* Rate 1: text Rate 2: text' into [text, text]
const strata = _.split(measureDescription, /\s*[Rr]ate [0-9]+:\s*/);
// Drop anything before 'Rate 1' (usually a description of the measure)
strata.shift();
newMeasure['strata'] = [];
_.each(strata, function(stratum, index) {
strataName = qcdrStrataNames[measureId][index];
// i + 1 because Rates in the csv are numbered starting from 1
if (_.lowerCase(strataName) === 'overall' &&
index + 1 !== nthPerformanceRate) {
throw TypeError('"Overall" strata for ' + measureId + ' in QCDR ' +
'CSV doesn\'t match the name in the strata details file');
}
newMeasure['strata'].push({
'name': strataName,
'description': strata[index]
});
});
return newMeasure;
};
/**

@@ -97,5 +145,7 @@ * [convertCsvToMeasures description]

*
* We trim all data sourced from CSVs because people sometimes unintentionally include spaces or linebreaks
* Notes:
* 1. The terms [performance rate] 'strata' and 'performance rates' are used interchangeably
* 2. We trim all data sourced from CSVs because people sometimes unintentionally include spaces or linebreaks
*/
const convertCsvToMeasures = function(records, config) {
const convertCsvToMeasures = function(records, config, qcdrStrataNamesDataPath) {
const sourcedFields = config.sourced_fields;

@@ -105,3 +155,3 @@ const constantFields = config.constant_fields;

const newMeasures = records.map(function(record) {
var newMeasure = {};
const newMeasure = {};
Object.entries(sourcedFields).forEach(function([measureKey, columnObject]) {

@@ -127,11 +177,15 @@ if (typeof columnObject === 'number') {

// (continuous and ratio, cols 18 and 19) are N, metricType should be
// 'singlePerformanceRate'. Otherwise it should be 'nonProportion'
//
// Note: if the 'proportion' column is Y *and* there are multiple
// strata, then the metricType should be 'multiPerformanceRate'
// TODO(kalvin): implement multiPerformanceRate;
if (record[17] === 'Y' &&
record[18] === 'N' &&
record[19] === 'N') {
newMeasure['metricType'] = 'singlePerformanceRate';
// 'singlePerformanceRate', or 'multiPerformanceRate' if there are multiple
// strata/performance rates. Otherwise it should be 'nonProportion'
const proportion = _.trim(record[17]);
const continuous = _.trim(record[18]);
const ratio = _.trim(record[19]);
if (proportion === 'Y' && continuous === 'N' && ratio === 'N') {
// returns an integer if passed string '3', NaN if passed 'N/A'
const numPerformanceRates = _.parseInt(_.trim(record[11]));
if (_.isInteger(numPerformanceRates) && numPerformanceRates > 1) {
addMultiPerformanceRateDetails(newMeasure, record, qcdrStrataNamesDataPath);
} else {
newMeasure['metricType'] = 'singlePerformanceRate';
}
} else {

@@ -209,3 +263,3 @@ newMeasure['metricType'] = 'nonProportion';

function importMeasures(measuresDataPath, qcdrMeasuresDataPath, outputPath) {
function importMeasures(measuresDataPath, qcdrMeasuresDataPath, qcdrStrataNamesDataPath, outputPath) {
const qpp = fs.readFileSync(path.join(__dirname, measuresDataPath), 'utf8');

@@ -215,9 +269,10 @@ const allMeasures = JSON.parse(qpp);

const csv = fs.readFileSync(path.join(__dirname, qcdrMeasuresDataPath), 'utf8');
const records = parse(csv, 'utf8');
const qcdrCsv = parse(csv, 'utf8');
// remove header
records.shift();
qcdrCsv.shift();
// If there's more than one QCDR measure with the same measure, we can
// arbitrarily pick one and ignore the others (they should all be
// identical except for the QCDR Organization Name which we don't care about)
const qcdrMeasures = _.uniqBy(convertCsvToMeasures(records, config), 'measureId');
const qcdrMeasures = _.uniqBy(convertCsvToMeasures(qcdrCsv, config, qcdrStrataNamesDataPath), 'measureId');

@@ -230,5 +285,6 @@ const mergedMeasures = mergeMeasures(allMeasures, qcdrMeasures, outputPath);

const qcdrMeasuresDataPath = process.argv[3];
const outputPath = process.argv[4];
const qcdrStrataNamesDataPath = process.argv[4];
const outputPath = process.argv[5];
const newMeasures = importMeasures(measuresDataPath, qcdrMeasuresDataPath, outputPath);
const newMeasures = importMeasures(measuresDataPath, qcdrMeasuresDataPath, qcdrStrataNamesDataPath, outputPath);
fs.writeFileSync(path.join(__dirname, outputPath), newMeasures);

@@ -13,13 +13,13 @@ /**

var Ajv = require('ajv');
var path = require('path');
var YAML = require('yamljs');
const Ajv = require('ajv');
const path = require('path');
const YAML = require('yamljs');
var ajv = Ajv();
const ajv = Ajv();
var schemaType = process.argv[2];
const schemaType = process.argv[2];
var json = '';
let json = '';
function validate(json) {
var valid = ajv.validate(
const valid = ajv.validate(
YAML.load(path.join(__dirname, '../' + schemaType,

@@ -39,3 +39,3 @@ schemaType + '-schema.yaml')),

process.stdin.on('readable', function() {
var chunk = this.read();
const chunk = this.read();
if (chunk !== null) {

@@ -42,0 +42,0 @@ json += chunk;

@@ -6,3 +6,3 @@ /**

*/
var isInverseBenchmarkRecord = function(record) {
const isInverseBenchmarkRecord = function(record) {
if (parseFloat(record.decile10) === 100) return false;

@@ -13,3 +13,3 @@ if (parseFloat(record.decile10) === 0) return true;

var deciles = [
const deciles = [
record.decile1,

@@ -27,7 +27,7 @@ record.decile2,

for (var i = 0; i < deciles.length; i++) {
var decile = deciles[i];
for (let i = 0; i < deciles.length; i++) {
const decile = deciles[i];
if (decile) {
var range = decile.match(/(\d{0,3}\.?\d{2,})/g);
const range = decile.match(/(\d{0,3}\.?\d{2,})/g);

@@ -34,0 +34,0 @@ if (range) {

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc