1 | #!/usr/bin/env python |
---|
2 | |
---|
3 | """ |
---|
4 | Module to convert a .csv file to an .sts file. |
---|
5 | |
---|
6 | You can use the function from your own scripts, or call this script on the |
---|
7 | command line. |
---|
8 | |
---|
9 | Use this module to convert an arbitrary csv file to an sts file. |
---|
10 | The csv file must have a header containing the column names. This will |
---|
11 | be converted to a NetCDF .sts file containing the same data, with the |
---|
12 | addition of optional latitude and longitude values. |
---|
13 | |
---|
14 | For example, the following .csv file: |
---|
15 | |
---|
16 | time stage |
---|
17 | 0 4 |
---|
18 | 1 150.66667 |
---|
19 | 2 150.83334 |
---|
20 | 3 151. |
---|
21 | 4 151.16667 |
---|
22 | 5 -34. |
---|
23 | 6 -34.16667 |
---|
24 | 7 -34.33333 |
---|
25 | 8 -34.5 |
---|
26 | 9 -1. |
---|
27 | 10 -5. |
---|
28 | 11 -9. |
---|
29 | 12 -13. |
---|
30 | |
---|
31 | Using this command: |
---|
32 | python csv2sts --lat 14 --lon 56 infile.csv foo.sts |
---|
33 | Will be converted to the following .sts file: |
---|
34 | |
---|
35 | netcdf foo { |
---|
36 | dimensions: |
---|
37 | number_of_timesteps = 13 ; |
---|
38 | variables: |
---|
39 | double stage(number_of_timesteps) ; |
---|
40 | double time(number_of_timesteps) ; |
---|
41 | |
---|
42 | // global attributes: |
---|
43 | :latitude = 14. ; |
---|
44 | :longitude = 56. ; |
---|
45 | data: |
---|
46 | |
---|
47 | stage = 4, 150.66667, 150.83334, 151, 151.16667, -34, -34.16667, |
---|
48 | -34.33333, -34.5, -1, -5, -9, -13 ; |
---|
49 | |
---|
50 | time = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ; |
---|
51 | } |
---|
52 | |
---|
53 | As of June 2010 this module has a pylint quality rating of 9.30/10. |
---|
54 | """ |
---|
55 | |
---|
56 | import sys |
---|
57 | import getopt |
---|
58 | from anuga.utilities import log |
---|
59 | from anuga.file.netcdf import NetCDFFile |
---|
60 | from anuga.file.csv_file import load_csv_as_dict |
---|
61 | from anuga.config import netcdf_mode_w, netcdf_float |
---|
62 | |
---|
63 | |
---|
64 | def csv2sts(infile, outfile, latitude = None, longitude = None, |
---|
65 | verbose = False): |
---|
66 | """ |
---|
67 | Take a csv file and convert it to an sts file. |
---|
68 | |
---|
69 | May be used for timeseries, or any other data. |
---|
70 | """ |
---|
71 | |
---|
72 | timeseries_data, col_names = load_csv_as_dict(infile, delimiter=' ') |
---|
73 | |
---|
74 | if not col_names: |
---|
75 | raise IOError('csv2sts: file %s is empty or unreadable.' % infile) |
---|
76 | |
---|
77 | if verbose: |
---|
78 | log.critical('csv2sts input data:') |
---|
79 | for col in col_names: |
---|
80 | log.critical('column ' + col + ':') |
---|
81 | log.critical(timeseries_data[col]) |
---|
82 | |
---|
83 | data_len = len(timeseries_data.values()[0]) |
---|
84 | if verbose: |
---|
85 | log.critical(' data length = %d.' % data_len) |
---|
86 | |
---|
87 | fid = NetCDFFile(outfile, netcdf_mode_w) |
---|
88 | |
---|
89 | fid.createDimension('number_of_timesteps', data_len) |
---|
90 | |
---|
91 | if latitude: |
---|
92 | fid.latitude = latitude |
---|
93 | |
---|
94 | if longitude: |
---|
95 | fid.longitude = longitude |
---|
96 | |
---|
97 | for col in col_names: |
---|
98 | fid.createVariable(col, netcdf_float, ('number_of_timesteps',)) |
---|
99 | |
---|
100 | fid.variables[col][:] = timeseries_data[col] |
---|
101 | |
---|
102 | fid.close() |
---|
103 | |
---|
104 | |
---|
105 | |
---|
106 | ###### |
---|
107 | # Script is being run from command line. |
---|
108 | # |
---|
109 | |
---|
110 | def usage(): |
---|
111 | """ Display usage of this module from the comand line. """ |
---|
112 | print 'csv2sts - convert a csv file to an sts file.' |
---|
113 | print 'Usage: csv2sts [-hv] [--help] [--verbose]', |
---|
114 | print '[-x --lat --latitude <degrees>]', |
---|
115 | print '[-y --lon --longitude <degrees>] <in.csv> <out.sts>' |
---|
116 | print 'eg:' |
---|
117 | print 'python csv2sts.py -v --lat 10 --lon 20 infile.csv sts_out.sts' |
---|
118 | print |
---|
119 | |
---|
120 | def main(argv): |
---|
121 | """ Script is being run from the command line. """ |
---|
122 | lat = None |
---|
123 | lon = None |
---|
124 | verbose = False |
---|
125 | |
---|
126 | try: |
---|
127 | long_parms = ["help", "verbose", \ |
---|
128 | "lat=", "lon=", "latitude=", "longitude="] |
---|
129 | opts, args = getopt.getopt(argv, "hvx:y:", long_parms) |
---|
130 | except getopt.GetoptError: |
---|
131 | usage() |
---|
132 | sys.exit(2) |
---|
133 | for opt, arg in opts: |
---|
134 | if opt in ("-h", "--help"): |
---|
135 | usage() |
---|
136 | sys.exit() |
---|
137 | elif opt in ("-x", "--lat", "--latitude"): |
---|
138 | lat = float(arg) |
---|
139 | elif opt in ("-y", "--lon", "--longitude"): |
---|
140 | lon = float(arg) |
---|
141 | if opt in ("-v", "--verbose"): |
---|
142 | verbose = True |
---|
143 | |
---|
144 | if len(args) != 2: |
---|
145 | usage() |
---|
146 | sys.exit(2) |
---|
147 | |
---|
148 | infile = args[0] |
---|
149 | outfile = args[1] |
---|
150 | |
---|
151 | if verbose: |
---|
152 | msg = 'csv2sts: converting %s to %s' % (infile, outfile) |
---|
153 | if lat and lon: |
---|
154 | msg += ' with lat = %d, lon = %d...' % (lat, lon) |
---|
155 | print msg |
---|
156 | csv2sts(infile, outfile, lat, lon) |
---|
157 | |
---|
158 | if verbose: |
---|
159 | print 'done!' |
---|
160 | |
---|
161 | |
---|
162 | |
---|
163 | |
---|
164 | if __name__ == "__main__": |
---|
165 | main(sys.argv[1:]) |
---|