/** * NOAA-specific filtering. */ module.exports = { /** * Different years have added new columns. * 46054h1998 --> 16 cols, Missing mm (col 5). Missing TIDE (col 18) * 46054h2004 --> 17 cols. Added TIDE. Missing mm (col 5) * 46054h2006 --> 18 cols, Added mm. */ parseLine: function(str) { var arr = str.trim().split(/\s+/); // REMOVE THIS LINE? Ben 290116 arr.filter(function(val) { return (val.length > 0); }) // Add TIDE value if not there if (arr.length === 16) { arr.push('99.00'); } // Add mm value if not there if (arr.length === 17) { arr.splice(4, 0, '00'); } return arr; }, /** * Receives a stream from a file read event. */ parseTxt: function(str) { console.log('Parsing NOAA space-delimited columnar data into JSON.'); var arr = []; var cols = null; var lines = str.split('\n'); var len = lines.length; if (len > 8) { for (var i = 0; i < len; i++) { cols = module.exports.parseLine(lines[i]); cols.length > 0 ? arr.push(cols) : null; } } return arr; }, /** * After all files have been parsed, Promises.all passes them all as an array. * This function does filtering on them and finalizes a JSON string. */ convert: function(arr) { console.log('Converting aggregated month files to JSON.'); // Sort. var sorted = arr.sort(function(a, b) { var dateA = parseInt([a[0], a[1], a[2], a[3], ('00' + a[4]).substr(-2)].join('')) || 0; var dateB = parseInt([b[0], b[1], b[2], b[3], ('00' + b[4]).substr(-2)].join('')) || 0; return dateA - dateB; }); // Flag violations: headings, units, empty. // Prepare average to trim incidental head/tail data points from different years. var sum = 0; var count = 0; sorted.forEach(function(row) { if (row[0] === '#YY' || row[0] === 'YYYY' || row[0] === 'YY' || row[0] === '#yr' || row.length === 1) { row[0] = null; } else { row[0] = ('19' + row[0]).substr(-4); sum += parseInt(row[0]); count++; } }); // Filter rows that have been flagged or that are the wrong year. var year = Math.round(sum / count); var result = sorted.filter(function(row, i) { if (row[0] === null || row[0] != year) { return false; } return true; }); // Convert to JSON that can later be read easily. var str = null; if (result.length > 0) { str = JSON.stringify(result) str = str.replace(/\],\[/g, '],\n['); } return str; }, /** * Used to aggregate month files after they have been split into a lines array. * Each line has been split into individual elements. * The array passed to this function is therefore an array of two dimensional arrays. * * This function adds non-empty lines to a common result set. */ aggregate: function(arr) { console.log('Aggregating month files for the year.'); var tmp = []; arr.forEach(function(rows) { if (rows.length === 0) { return; } tmp = tmp.concat(rows); }); return tmp; } };