001/* 002 * Copyright (c) 2015 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2015-10-21 21:56:26 +0000 (Wed, 21 Oct 2015) $' 007 * '$Revision: 34052 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029package org.kepler.gis.actor.windninja; 030 031import java.io.BufferedReader; 032import java.io.File; 033import java.io.FileNotFoundException; 034import java.io.FileReader; 035import java.io.FileWriter; 036import java.io.IOException; 037import java.util.ArrayList; 038import java.util.Arrays; 039import java.util.Comparator; 040 041import ptolemy.actor.lib.Transformer; 042import ptolemy.actor.parameters.PortParameter; 043import ptolemy.data.ArrayToken; 044import ptolemy.data.StringToken; 045import ptolemy.data.type.ArrayType; 046import ptolemy.data.type.BaseType; 047import ptolemy.kernel.CompositeEntity; 048import ptolemy.kernel.util.IllegalActionException; 049import ptolemy.kernel.util.NameDuplicationException; 050import ptolemy.kernel.util.SingletonAttribute; 051import ptolemy.kernel.util.Workspace; 052 053/** Combine WindNinja ATM files into a single ATM file. 054 * 055 * @author Daniel Crawl 056 * @version $Id: ATMCombineFiles.java 34052 2015-10-21 21:56:26Z crawl $ 057 */ 058public class ATMCombineFiles extends Transformer { 059 060 public ATMCombineFiles(CompositeEntity container, String name) 061 throws IllegalActionException, NameDuplicationException { 062 super(container, name); 063 064 input.setTypeEquals(new ArrayType(BaseType.STRING)); 065 output.setTypeEquals(BaseType.STRING); 066 067 filename = new PortParameter(this, "filename"); 068 filename.setTypeEquals(BaseType.STRING); 069 new SingletonAttribute(filename.getPort(), "_showName"); 070 } 071 072 @Override 073 public Object clone(Workspace workspace) throws CloneNotSupportedException { 074 ATMCombineFiles newObject = (ATMCombineFiles) super.clone(workspace); 075 newObject._lines = new ArrayList<String>(); 076 newObject._paths = new ArrayList<String>(); 077 return newObject; 078 } 079 080 @Override 081 public void fire() throws IllegalActionException { 082 super.fire(); 083 084 _lines.clear(); 085 _paths.clear(); 086 087 filename.update(); 088 String outFileStr = ((StringToken)filename.getToken()).stringValue(); 089 File outFile = new File(outFileStr); 090 091 ArrayToken arrayToken = (ArrayToken)input.get(0); 092 for(int i = 0; i < arrayToken.length(); i++) { 093 String fileStr = ((StringToken)arrayToken.getElement(i)).stringValue(); 094 File file = new File(fileStr); 095 096 if(!file.exists()) { 097 throw new IllegalActionException(this, "ATM file does not exist: " + file); 098 } 099 100 _readATMFile(file); 101 } 102 103 // sort the lines 104 String[] lines = _lines.toArray(new String[_lines.size()]); 105 Arrays.sort(lines, new Comparator<String>() { 106 @Override 107 public int compare(String string1, String string2) { 108 return string1.substring(0, 10).compareTo(string2.substring(0, 10)); 109 } 110 }); 111 112 try(FileWriter writer = new FileWriter(outFile);) { 113 writer.write(_firstLine); 114 writer.write("\n"); 115 writer.write(_secondLine); 116 writer.write("\n"); 117 118 for(int i = 0; i < lines.length; i++) { 119 final String line = _lines.get(i); 120 final String path = _paths.get(i); 121 122 String[] parts = line.split(" "); 123 124 // month 125 writer.write(parts[0]); 126 writer.write(" "); 127 128 // day 129 writer.write(parts[1]); 130 writer.write(" "); 131 132 // hour and minute 133 writer.write(parts[2]); 134 writer.write(" "); 135 136 if(_firstLine.equals(_WINDS_AND_CLOUDS)) { 137 138 // speed 139 writer.write(path + File.separator + parts[3]); 140 writer.write(" "); 141 142 // direction 143 writer.write(path + File.separator + parts[4]); 144 writer.write(" "); 145 146 // cloud cover 147 writer.write(path + File.separator + parts[5]); 148 writer.write(" "); 149 } 150 151 writer.write("\n"); 152 } 153 } catch (IOException e) { 154 throw new IllegalActionException(this, e, "Error writing to " + outFile); 155 } 156 157 output.broadcast(new StringToken(outFileStr)); 158 } 159 160 @Override 161 public void preinitialize() throws IllegalActionException { 162 super.preinitialize(); 163 _firstLine = null; 164 _secondLine = null; 165 } 166 167 //////////////////////////////////////////////////////////////////////// 168 //// public fields //// 169 170 /** The name of the output file. */ 171 public PortParameter filename; 172 173 //////////////////////////////////////////////////////////////////////// 174 //// private methods //// 175 176 /** Read an ATM file. */ 177 private void _readATMFile(File file) throws IllegalActionException { 178 179 try(FileReader fileReader = new FileReader(file); 180 BufferedReader reader = new BufferedReader(fileReader)) { 181 182 String line = reader.readLine(); 183 184 // first line is WINDS_AND_CLOUDS 185 if(line == null) { 186 throw new IllegalActionException(this, "No lines in " + file); 187 } 188 if(_firstLine == null) { 189 _firstLine = line; 190 191 if(!line.equals(_WINDS_AND_CLOUDS)) { 192 throw new IllegalActionException(this, "Unsupported ATM type: " + line); 193 } 194 195 } else if(!_firstLine.equals(line)) { 196 throw new IllegalActionException(this, 197 "First lines do not match: " + _firstLine + " != " + 198 line + " in " + file); 199 } 200 201 // second line is ENGLISH (or METRIC) 202 line = reader.readLine(); 203 204 if(line == null) { 205 throw new IllegalActionException(this, "No second line in " + file); 206 } 207 if(_secondLine == null) { 208 _secondLine = line; 209 210 if(!line.equals(_ENGLISH) && !line.equals(_METRIC)) { 211 throw new IllegalActionException(this, "Unknow type of units: " + line); 212 } 213 214 } else if(!_secondLine.equals(line)) { 215 throw new IllegalActionException(this, 216 "Second lines do not match: " + _secondLine + " != " + 217 line + " in " + file); 218 } 219 220 while((line = reader.readLine()) != null) { 221 _lines.add(line); 222 _paths.add(file.getParent()); 223 } 224 } catch (FileNotFoundException e) { 225 throw new IllegalActionException(this, e, "File not found: " + file); 226 } catch (IOException e) { 227 throw new IllegalActionException(this, e, "Error reading " + file); 228 } 229 } 230 231 //////////////////////////////////////////////////////////////////////// 232 //// private fields //// 233 234 /** The first line read from the ATM file. */ 235 private String _firstLine; 236 237 /** The second line read from the ATM file. */ 238 private String _secondLine; 239 240 /** The lines in each ATM file. */ 241 private ArrayList<String> _lines = new ArrayList<String>(); 242 243 /** The directories containing each ATM file. */ 244 private ArrayList<String> _paths = new ArrayList<String>(); 245 246 /** The type of ATM file specifying winds and clouds. */ 247 private final static String _WINDS_AND_CLOUDS = "WINDS_AND_CLOUDS"; 248 249 /** English units. */ 250 private final static String _ENGLISH = "ENGLISH"; 251 252 /** Metric units. */ 253 private final static String _METRIC = "METRIC"; 254 255}