1 |
Format for raw output files from MITgcmUV |
2 |
========================================= |
3 |
|
4 |
Introduction |
5 |
------------ |
6 |
When running in parallel mode with multiple processes the MITgcmUV |
7 |
model operates as N separate programs, each responsible for its "local" |
8 |
region of the "total" model domain. Synchronisation and sharing of data between |
9 |
these processes is done explicitly by calls to data exchange and |
10 |
barrier routines. Consequently there is no single program that has |
11 |
a view of the whole model domain as the code is running. Any simple |
12 |
I/O can only operate on the local region of the model domain - I/O |
13 |
operations to and from datasets that represent the total domain need |
14 |
to address the multiple process behavior explicitly. |
15 |
Under MITgcmUV there are a set of I/O support routines that mask the |
16 |
details of this process and enable end-users to read and write datasets |
17 |
in a straight-forward manner. The routines use the following design |
18 |
strategy: |
19 |
o Input datasets are for the total domain |
20 |
o Output datasets are for the local domain |
21 |
o A separate program "joinds" is provided which joins a set of |
22 |
local domain datasets together to form total model domain dataset. |
23 |
|
24 |
MITgcmUV IO support routines |
25 |
---------------------------- |
26 |
- READ_FLD_XY_RS |
27 |
- READ_FLD_XY_RL |
28 |
- READ_FLD_XYZ_RS |
29 |
- READ_FLD_XYZ_RL |
30 |
|
31 |
- WRITE_FLD_XY_RS |
32 |
- WRITE_FLD_XY_RL |
33 |
- WRITE_FLD_XYZ_RS |
34 |
- WRITE_FLD_XYZ_RL |
35 |
|
36 |
Dataset format |
37 |
-------------- |
38 |
Datasets are written using the standard Fortran 77 sequential binary |
39 |
file format. The Fortran IO statements in he model code do not specify any |
40 |
particular format, however, compile and run-time flags are used on some platforms. |
41 |
On DEC platforms by default the IO form is set to big-endian with a compile time |
42 |
flag. On CRAY platforms a runtime flag is normally used to select IEEE |
43 |
representation. The Fortran 77 sequential binary file format is |
44 |
4 byte header |
45 |
data |
46 |
4 byte terminator |
47 |
The header and terminator are unsigned integers which give the length |
48 |
of the data section in bytes. This is format is standard over all UNIX |
49 |
platforms. In Fortran this style of file is generated by code of the |
50 |
form |
51 |
|
52 |
REAL A(dim1, dim2, ..... ) |
53 |
OPEN(unitnumber,filename,FORM='FORMATTED') |
54 |
WRITE(unitnumber) A |
55 |
END |
56 |
|
57 |
The data is sequenced in the standard Fortran convention of the left-most |
58 |
index varying fastest. This convention holds for any dimension of datsets |
59 |
one-dimensional, two-dimensional, three-dimensional and four-dimensional or |
60 |
more datasets are all written this way. |
61 |
|
62 |
Multiprocess support |
63 |
-------------------- |
64 |
The format described above is used for multi-process simulations. In this |
65 |
case the data written to separate files with each process writing data that |
66 |
is local to it. To support this approach a file naming convention is used and a second |
67 |
file of "meta" information accompanines the data. The naming convention |
68 |
is used to avoid duplicate names and to make it easy to identify sets of |
69 |
files that together represent the total domain data. The meta file contains |
70 |
information about the extent of the sub-domain within each file. |
71 |
The naming convention used is |
72 |
PREF.SUFF.pPNUMBER.tTNUMBER.data |
73 |
PREF.SUFF.pPNUMBER.tTNUMBER.meta |
74 |
|
75 |
where |
76 |
PREF - Is a field identifying the data within the file. For |
77 |
temperature PREF is T, for zonal velocity PREF is U etc... |
78 |
SUFF - Is a field identifying the "instance" of the data within the |
79 |
file. The instance is typically the time level. In general |
80 |
the instance will be a model timestep number. |
81 |
PNUMBER - Is a process number used to identitfy which process of |
82 |
a multi-process run generated this data. The number ranges |
83 |
from 0 to (number of processors)-1. |
84 |
TNUMBER - Is a thread number used to identify which thread of a |
85 |
multi-threaded run generated this data. The number ranges |
86 |
from 0 to (number of threads)-1. |
87 |
|
88 |
the .data suffix identifies the file containing the actual data. |
89 |
the .meta suffix identifies the file containing textual information |
90 |
indicating the extent of the domain written to the .data file. |
91 |
|
92 |
.meta file Format |
93 |
----------------- |
94 |
This file contains a set of parameters that are specified using the |
95 |
generic parameter specification format used in GCMPACK software. This |
96 |
format consists of a sequence of assignments and comments |
97 |
Assignments have the form |
98 |
keyword =[ val-list ]; |
99 |
|
100 |
where |
101 |
keyword is a text string |
102 |
val-list is a sequence of one or more fields separated by commas |
103 |
|
104 |
Comments are preceeded by // or # characters or contained in |
105 |
/* */ pairs. |
106 |
The keywords contained in a .meta file are |
107 |
id - This is a numeric identifier. It can be used to |
108 |
verify consistency over a set of .meta files. |
109 |
nDims - This is a single integer indicating the dimensionality |
110 |
of the data in the .data file. |
111 |
dimList - This is a sequence of triplets. There is one triplet for |
112 |
each dimension and the triplets are ordered in the same |
113 |
way as the dimensions. Each triplet is made of three integers. |
114 |
The first integer gives the domain extent globally for |
115 |
the associated dimension. |
116 |
The second integer gives the low coordinate for the values |
117 |
within .data file for the associated dimension. |
118 |
The third integer gives the high coordinate for the values |
119 |
within .data file for the associated dimension. |
120 |
Thus for a .data file containing the north-west quadrant of |
121 |
a global domain of size 90 x 40 the .meta might read |
122 |
nDims = [ 2 ]; |
123 |
dimList = [ 90, 46, 90, 40, 1, 20]; |
124 |
For a global domain of size 90 x 40 x 33 the .meta file |
125 |
would read |
126 |
nDims = [ 3 ]; |
127 |
dimList = [ 90, 46, 90, 40, 1, 20, 33, 1, 33]; |
128 |
|
129 |
|
130 |
|
131 |
Example matlab program to join files |
132 |
------------------------------------ |
133 |
The following matlab script joins together a collection of files that |
134 |
were written in split form. The files to join are indicated by a user |
135 |
defined PREF.SUFF pair. e.g. T.0000002800. The script uses the UNIX |
136 |
ls command to find all files starting with T.0000002800 and then |
137 |
scans the .meta files to extract the dimensions. It then merges all |
138 |
the sections together to form a complete representation of the global |
139 |
dataset. |
140 |
>> function [AA] = rdmeta(fname,varargin) |
141 |
>> % |
142 |
>> % Read MITgcmUV Meta/Data files |
143 |
>> % |
144 |
>> % A = RDMETA(FNAME) reads data described by meta/data file format. |
145 |
>> % FNAME is a string containing the "head" of the file names. |
146 |
>> % |
147 |
>> % eg. To load the meta-data files |
148 |
>> % T.0000002880.p0000.t0000.meta, T.0000002880.p0000.t0000.data |
149 |
>> % T.0000002880.p0001.t0000.meta, T.0000002880.p0001.t0000.data |
150 |
>> % T.0000002880.p0002.t0000.meta, T.0000002880.p0002.t0000.data |
151 |
>> % T.0000002880.p0003.t0000.meta, T.0000002880.p0003.t0000.data |
152 |
>> % use |
153 |
>> % >> A=rdmeta('T.0000002880'); |
154 |
>> % |
155 |
>> % A = RDMETA(FNAME,MACHINEFORMAT) allows the machine format to be specified |
156 |
>> % which MACHINEFORMAT is on of the following strings: |
157 |
>> % |
158 |
>> % 'native' or 'n' - local machine format - the default |
159 |
>> % 'ieee-le' or 'l' - IEEE floating point with little-endian |
160 |
>> % byte ordering |
161 |
>> % 'ieee-be' or 'b' - IEEE floating point with big-endian |
162 |
>> % byte ordering |
163 |
>> % 'vaxd' or 'd' - VAX D floating point and VAX ordering |
164 |
>> % 'vaxg' or 'g' - VAX G floating point and VAX ordering |
165 |
>> % 'cray' or 'c' - Cray floating point with big-endian |
166 |
>> % byte ordering |
167 |
>> % 'ieee-le.l64' or 'a' - IEEE floating point with little-endian |
168 |
>> % byte ordering and 64 bit long data type |
169 |
>> % 'ieee-be.l64' or 's' - IEEE floating point with big-endian byte |
170 |
>> % ordering and 64 bit long data type. |
171 |
>> % |
172 |
>> |
173 |
>> % Default options |
174 |
>> ieee='n'; |
175 |
>> |
176 |
>> % Check optional arguments |
177 |
>> args=char(varargin); |
178 |
>> while (size(args,1) > 0) |
179 |
>> if deblank(args(1,:)) == 'n' | deblank(args(1,:)) == 'native' |
180 |
>> ieee='n'; |
181 |
>> elseif deblank(args(1,:)) == 'l' | deblank(args(1,:)) == 'ieee-le' |
182 |
>> ieee='l'; |
183 |
>> elseif deblank(args(1,:)) == 'b' | deblank(args(1,:)) == 'ieee-be' |
184 |
>> ieee='b'; |
185 |
>> elseif deblank(args(1,:)) == 'c' | deblank(args(1,:)) == 'cray' |
186 |
>> ieee='c'; |
187 |
>> elseif deblank(args(1,:)) == 'a' | deblank(args(1,:)) == 'ieee-le.l64' |
188 |
>> ieee='a'; |
189 |
>> elseif deblank(args(1,:)) == 's' | deblank(args(1,:)) == 'ieee-be.l64' |
190 |
>> ieee='s'; |
191 |
>> else |
192 |
>> sprintf(['Optional argument ' args(1,:) ' is unknown']) |
193 |
>> return |
194 |
>> end |
195 |
>> args=args(2:end,:); |
196 |
>> end |
197 |
>> |
198 |
>> % Match name of all meta-files |
199 |
>> eval(['ls ' fname '*.meta;']); |
200 |
>> allfiles=ans; |
201 |
>> |
202 |
>> % Beginning and end of strings |
203 |
>> Iend=findstr(allfiles,'.meta')+4; |
204 |
>> Ibeg=[1 Iend(1:end-1)+2]; |
205 |
>> |
206 |
>> % Loop through allfiles |
207 |
>> for j=1:prod(size(Ibeg)), |
208 |
>> |
209 |
>> % Read meta- and data-file |
210 |
>> [A,N] = localrdmeta(allfiles(Ibeg(j):Iend(j)),ieee); |
211 |
>> |
212 |
>> bdims=N(1,:); |
213 |
>> r0=N(2,:); |
214 |
>> rN=N(3,:); |
215 |
>> ndims=prod(size(bdims)); |
216 |
>> if (ndims == 1) |
217 |
>> AA(r0(1):rN(1))=A; |
218 |
>> elseif (ndims == 2) |
219 |
>> AA(r0(1):rN(1),r0(2):rN(2))=A; |
220 |
>> elseif (ndims == 3) |
221 |
>> AA(r0(1):rN(1),r0(2):rN(2),r0(3):rN(3))=A; |
222 |
>> elseif (ndims == 4) |
223 |
>> AA(r0(1):rN(1),r0(2):rN(2),r0(3):rN(3),r0(4):rN(4))=A; |
224 |
>> else |
225 |
>> sprintf('Dimension of data set is larger than currently coded. Sorry!') |
226 |
>> return |
227 |
>> end |
228 |
>> |
229 |
>> end |
230 |
>> |
231 |
>> %------------------------------------------------------------------------------- |
232 |
>> |
233 |
>> function [A,N] = localrdmeta(fname,ieee) |
234 |
>> |
235 |
>> mname=fname; |
236 |
>> dname=strrep(mname,'.meta','.data'); |
237 |
>> |
238 |
>> % Read and interpret Meta file |
239 |
>> fid = fopen(mname,'r'); |
240 |
>> if (fid == -1) |
241 |
>> sprintf(['Fila e' mname ' could not be opened']) |
242 |
>> return |
243 |
>> end |
244 |
>> |
245 |
>> % Scan each line of the Meta file |
246 |
>> allstr=' '; |
247 |
>> keepgoing = 1; |
248 |
>> while keepgoing > 0, |
249 |
>> line = fgetl(fid); |
250 |
>> if (line == -1) |
251 |
>> keepgoing=-1; |
252 |
>> else |
253 |
>> % Strip out "(PID.TID *.*)" by finding first ")" |
254 |
>> ind=findstr([line ')'],')'); line=line(ind(1)+1:end); |
255 |
>> % Remove comments of form // |
256 |
>> line=[line ' //']; ind=findstr(line,'//'); line=line(1:ind(1)-1); |
257 |
>> % Add to total string |
258 |
>> allstr=[allstr line]; |
259 |
>> end |
260 |
>> end |
261 |
>> |
262 |
>> % Close meta file |
263 |
>> fclose(fid); |
264 |
>> |
265 |
>> % Strip out comments of form /* ... */ |
266 |
>> ind1=findstr(allstr,'/*'); ind2=findstr(allstr,'*/'); |
267 |
>> if size(ind1) ~= size(ind2) |
268 |
>> sprintf('The /* ... */ comments are not properly paired') |
269 |
>> return |
270 |
>> end |
271 |
>> while size(ind1,2) > 0 |
272 |
>> allstr=[allstr(1:ind1(1)-1) allstr(ind2(1)+3:end)]; |
273 |
>> ind1=findstr(allstr,'/*'); ind2=findstr(allstr,'*/'); |
274 |
>> end |
275 |
>> |
276 |
>> eval(lower(allstr)); |
277 |
>> |
278 |
>> N=reshape( dimlist , 3 , prod(size(dimlist))/3 ); |
279 |
>> |
280 |
>> A=allstr; |
281 |
>> % Open data file |
282 |
>> fid=fopen(dname,'r',ieee); |
283 |
>> |
284 |
>> % Read record size in bytes |
285 |
>> recsz=fread(fid,1,'uint32'); |
286 |
>> ldims=N(3,:)-N(2,:)+1; |
287 |
>> numels=prod(ldims); |
288 |
>> |
289 |
>> rat=recsz/numels; |
290 |
>> if rat == 4 |
291 |
>> A=fread(fid,numels,'real*4'); |
292 |
>> elseif rat == 8 |
293 |
>> A=fread(fid,numels,'real*8'); |
294 |
>> else |
295 |
>> sprintf('Ratio between record size and size in meta-file inconsistent') |
296 |
>> sprintf(' Implied size in meta-file = %d', numels ) |
297 |
>> sprintf(' Record size in data-file = %d', recsz ) |
298 |
>> return |
299 |
>> end |
300 |
>> |
301 |
>> erecsz=fread(fid,1,'uint32'); |
302 |
>> if erecsz ~= recsz |
303 |
>> sprintf('WARNING: Record sizes at beginning and end of file are inconsistent') |
304 |
>> end |
305 |
>> |
306 |
>> fclose(fid); |
307 |
>> |
308 |
>> A=reshape(A,ldims); |
309 |
>> |