@@ -11,6 +11,12 @@ class UMFileException(Exception):
11
11
pass
12
12
13
13
14
+ # Lookup header pointers
15
+ LBLREC = 14 # Length of data record (including any extra data)
16
+ LBPACK = 20 # Packing method indicator
17
+ LBEGIN = 28 # Disk address/Start Record
18
+
19
+
14
20
class File :
15
21
"""A class for a UM file that gives a view of the file including
16
22
sets of PP records combined into variables."""
@@ -34,7 +40,7 @@ def __init__(
34
40
'little_endian' or 'big_endian'
35
41
36
42
word_size: `int`, optional
37
- 4 or 8
43
+ The size in bytes of one word. Either ``4`` or ``8``.
38
44
39
45
fmt: `str`, optional
40
46
'FF' or 'PP'
@@ -281,12 +287,14 @@ def __init__(
281
287
self .file = file
282
288
283
289
@classmethod
284
- def from_file_and_offsets (cls , file , hdr_offset , data_offset , disk_length ):
290
+ def from_file_and_offsets (
291
+ cls , file , hdr_offset , data_offset = None , disk_length = None
292
+ ):
285
293
"""Instantiate a `Rec` object from the `File` object and the
286
294
header and data offsets.
287
295
288
- The headers are read in , and also the record object is ready for
289
- calling `get_data`.
296
+ The lookup header is read from disk immediately , and the
297
+ returned record object is ready for calling `get_data`.
290
298
291
299
:Parameters:
292
300
@@ -295,26 +303,56 @@ def from_file_and_offsets(cls, file, hdr_offset, data_offset, disk_length):
295
303
into variables.
296
304
297
305
hdr_offset: `int`
298
- The start word in the file of the header.
306
+ The file start address of the header, in bytes .
299
307
300
- data_offset: `int`
301
- The start word in the file of the data.
308
+ data_offset: `int`, optional
309
+ The file start address of the data, in bytes. If
310
+ `None`, the default, then the data offset will be
311
+ calculated from the integer header.
302
312
303
313
disk_length: `int`
304
- The length in words of the data in the file.
314
+ The length in bytes of the data in the file. If
315
+ `None`, the default, then the disk length will be
316
+ calculated from the integer header.
305
317
306
318
:Returns:
307
319
308
320
`Rec`
309
321
310
322
"""
311
323
c = file ._c_interface
324
+ word_size = file .word_size
312
325
int_hdr , real_hdr = c .read_header (
313
- file .fd , hdr_offset , file .byte_ordering , file . word_size
326
+ file .fd , hdr_offset , file .byte_ordering , word_size
314
327
)
315
328
329
+ if data_offset is None :
330
+ # Calculate the data offset from the integer header
331
+ if file .fmt == "PP" :
332
+ # We only support 64-word headers, so the data starts
333
+ # 66 words after the header_offset, i.e. after 64
334
+ # words of the header, plus 2 block control words.
335
+ data_offset = hdr_offset + 66 * word_size
336
+ else :
337
+ # Fields file
338
+ data_offset = int_hdr [LBEGIN ] * word_size
339
+
340
+ if disk_length is None :
341
+ # Calculate the disk length from the integer header
342
+ disk_length = int_hdr [LBLREC ]
343
+ if int_hdr [LBPACK ] % 10 == 2 :
344
+ # Cray 32-bit packing
345
+ disk_length = disk_length * 4
346
+ else :
347
+ disk_length = disk_length * word_size
348
+
316
349
return cls (
317
- int_hdr , real_hdr , hdr_offset , data_offset , disk_length , file = file
350
+ int_hdr ,
351
+ real_hdr ,
352
+ hdr_offset ,
353
+ data_offset ,
354
+ disk_length ,
355
+ file = file ,
318
356
)
319
357
320
358
def read_extra_data (self ):
@@ -325,8 +363,8 @@ def read_extra_data(self):
325
363
`numpy.ndarray`
326
364
327
365
"""
328
- c = self .file ._c_interface
329
366
file = self .file
367
+ c = file ._c_interface
330
368
331
369
(
332
370
extra_data_offset ,
@@ -389,17 +427,18 @@ def get_data(self):
389
427
`numpy.ndarray`
390
428
391
429
"""
392
- c = self .file ._c_interface
393
430
file = self .file
394
- data_type , nwords = c .get_type_and_num_words (self .int_hdr )
431
+ c = file ._c_interface
432
+ int_hdr = self .int_hdr
433
+ data_type , nwords = c .get_type_and_num_words (int_hdr )
395
434
396
435
return c .read_record_data (
397
436
file .fd ,
398
437
self .data_offset ,
399
438
self .disk_length ,
400
439
file .byte_ordering ,
401
440
file .word_size ,
402
- self . int_hdr ,
441
+ int_hdr ,
403
442
self .real_hdr ,
404
443
data_type ,
405
444
nwords ,
0 commit comments