1 | #!/usr/bin/env python |
---|
2 | |
---|
3 | """ |
---|
4 | The MaxAsc() function. |
---|
5 | Takes 1 or more ASC files and generates an output ASC file with |
---|
6 | an element-wise maximum. |
---|
7 | """ |
---|
8 | |
---|
9 | import sys |
---|
10 | import re |
---|
11 | |
---|
12 | # if user does 'from ... import *' only give her/him MaxAsc |
---|
13 | __all__ = ['MaxAsc'] |
---|
14 | |
---|
15 | HEADER_SIZE = 6 |
---|
16 | |
---|
17 | # pattern string used to split multimax data |
---|
18 | SpacesPatternString = ' +' |
---|
19 | |
---|
20 | # generate 're' pattern for 'any number of spaces' |
---|
21 | SpacesPattern = re.compile(SpacesPatternString) |
---|
22 | |
---|
23 | |
---|
24 | ## |
---|
25 | # @brief Convert multiple ASC files into one with max value at each element. |
---|
26 | # @param out_file Name of the output file. |
---|
27 | # @param in_files List of input filenames. |
---|
28 | def MaxAsc(out_file, in_files): |
---|
29 | """ |
---|
30 | MaxAsc('output_filename', ['list', 'of', 'filenames']) |
---|
31 | |
---|
32 | The output file is an ASC file with each element being the maximum of |
---|
33 | the corresponding element in all the input ASC files. The output file |
---|
34 | has the same shape as the input file(s). |
---|
35 | """ |
---|
36 | |
---|
37 | # get all file data into memory |
---|
38 | file_data = [] |
---|
39 | for f in in_files: |
---|
40 | fd = open(f, 'r') |
---|
41 | data = fd.readlines() |
---|
42 | file_data.append(data) |
---|
43 | fd.close() |
---|
44 | |
---|
45 | # check we have same number of lines in each file |
---|
46 | num_lines = len(file_data[0]) |
---|
47 | for (i, d) in enumerate(file_data): |
---|
48 | if len(d) != num_lines: |
---|
49 | raise RuntimeError, \ |
---|
50 | ("File %s has the wrong number of lines " |
---|
51 | "(%d, expected %d)." % (in_files[i], len(d), num_lines)) |
---|
52 | |
---|
53 | # open the output file |
---|
54 | out_fd = open(out_file, 'w') |
---|
55 | |
---|
56 | # read header lines, check same, write out |
---|
57 | for i in range(HEADER_SIZE): |
---|
58 | line = file_data[0][i] |
---|
59 | for (j, f) in enumerate(file_data): |
---|
60 | d = f[i] |
---|
61 | if d != line: |
---|
62 | out_fd.close() |
---|
63 | raise RuntimeError, \ |
---|
64 | "File %s has the wrong header at line %d." % \ |
---|
65 | (in_files[j], i) |
---|
66 | out_fd.write(line) |
---|
67 | |
---|
68 | # read data lines |
---|
69 | for line_num in range(HEADER_SIZE, num_lines): |
---|
70 | lines = [] |
---|
71 | col_file = '' |
---|
72 | columns = None |
---|
73 | for (i, f) in enumerate(file_data): |
---|
74 | data = f[line_num] |
---|
75 | if len(data) > 1: |
---|
76 | data = data.strip() |
---|
77 | data = SpacesPattern.split(data) |
---|
78 | if columns: |
---|
79 | if columns != len(data): |
---|
80 | out_fd.close() |
---|
81 | raise RuntimeError, \ |
---|
82 | ("File %s doesn't have same number of columns " |
---|
83 | "(%d) as file %s (%d), line %d!?" % |
---|
84 | (fd.name, len(data), col_file, columns, line_num)) |
---|
85 | else: |
---|
86 | col_file = in_files[i] |
---|
87 | columns = len(data) |
---|
88 | fdata = [float(value) for value in data] |
---|
89 | lines.append(fdata) |
---|
90 | outline = '' |
---|
91 | for i in range(columns): |
---|
92 | maximum = lines[0][i] |
---|
93 | for d in lines: |
---|
94 | if maximum < d[i]: |
---|
95 | maximum = d[i] |
---|
96 | outline += ' %10.4e ' % maximum |
---|
97 | out_fd.write('%s\n' % outline) |
---|
98 | |
---|
99 | # close the output file |
---|
100 | out_fd.close() |
---|