/** * TimeSeries reader for NtuQuarter Datalogger files. * <p/> * These contain Channel_Level, Velocity, Temperature, Conductivity, pH, Turbidity, NTU DO, Battery, Flow * <p/> * <p/> * The locationID is encoded in the filename e.g: MC02_Quarter.dat contains data for * locationId MC02 * <p/> * <pre> * Colums are: * Date/time * number * Level, m (by SW or SL) (parameter name: level) * Channel_Level, m (by US level sensor) (parameter name: channel_level) * Velocity, m/s (parameter name: velocity) * Temperature, oC (parameter name: temperature) * Conductivity, mS/cm (parameter name: conductivity) * pH (parameter name: ph) * Turbidity, ( parameter name: turbidity) * NTU DO, mg/L (parameter name: ntu_do) * Battery, V (parameter name: battery) * Flow, m3/s (parameter name: flow) * <p/> * Example: * "2007-05-08 00:10:00",7892,0.809,0,-0.187,28.76,0.36,7.56,141.9,2.03,12.86272,-3.933358 * "2007-05-08 00:15:00",7893,0.849,0,-0.167,29.04,0.413,7.59,144.8,2.61,12.87867,-3.686358 * "2007-05-08 00:20:00",7894,0.89,0,-0.137,29.37,0.475,7.65,146,2.48,12.87363,-3.17018 * "2007-05-08 00:25:00",7895,0.929,0,-0.109,29.68,0.629,7.67,146.3,3.26,12.85852,-2.632786 * "2007-05-08 00:30:00",7896,0.966,0,-0.13,30.11,0.907,7.76,147.3,3.96,12.8686,-3.26508 * "2007-05-08 00:35:00",7897,1.003,0,-0.094,30.4,1.161,7.78,147.5,4.44,12.85601,-2.451332 * </pre> * The second column (data number) is not used in the import * <p/> */ public class NtuQuarterTimeSeriesParser implements TextParser<TimeSeriesContentHandler> { private static final Logger log = Logger.getLogger(NtuQuarterTimeSeriesParser.class); private static final String[] PARAMETER_NAMES = new String[]{ "level", "channel_level", "velocity", "temperature", "conductivity", "ph", "turbidity", "ntu_do", "battery", "flow"}; private String virtualFileName = null; private DefaultTimeSeriesHeader timeSeriesHeader = new DefaultTimeSeriesHeader(); @Override public void parse(LineReader reader, String virtualFileName, TimeSeriesContentHandler contentHandler) throws Exception { this.virtualFileName = virtualFileName; reader.setCommentLinePrefix('#'); parseLocationIdFromFileName(); for (int i = 0; i < PARAMETER_NAMES.length; i++) { timeSeriesHeader.setParameterId(PARAMETER_NAMES[i]); contentHandler.createTimeSeriesHeaderAlias(i, timeSeriesHeader); } for (String[] items = new String[PARAMETER_NAMES.length + 2]; reader.readLine(',', items) != -1l;) { contentHandler.setTime(contentHandler.getDefaultTimeZone(), "yyyy-MM-dd HH:mm:ss", items[0]); for (int i = 0; i < PARAMETER_NAMES.length; i++) { contentHandler.setTimeSeriesHeader(i); contentHandler.setValue('.', items[i + 2]); contentHandler.applyCurrentFields(); } } } private void parseLocationIdFromFileName() throws Exception { /* parsefile name This is locationid and type concanated e.g. MC02_Rain.dat we only need the locationID */ String fileName = FileUtils.getNameWithoutExt(virtualFileName); /* Check if filename contains the file name seperator */ // spit on underscore - first items are the externalLocatioId, second Parameter (Rain) String[] fileNameParts = TextUtils.split(fileName, '_'); if (fileNameParts.length < 2) throw new Exception("File with name <" + this.virtualFileName + "> cannot be parsed to find location Id"); timeSeriesHeader.setLocationId(fileNameParts[0]); if (!fileNameParts[1].equals("Quarter")) { log.warn("File <" + fileName + "> contains unexpected ending <" + fileNameParts[1] + "> Expected Quarter"); } if (log.isDebugEnabled()) log.debug("File <" + fileName + "> contains data for external locationdId <" + fileNameParts[0] + "> and reader type <Quarter>"); } }