106 The readheader function returns a special class (Structure) which behaves
107 like a dictionary. It contains all the metadata from the simulation which
108 is contained in the "header" or "header_nest" binary files from the model
112 It is recommended to use the :class:`Header` class: H = pf.Header(path)
114 This version is using the BinaryFile class rather than FortFlex.
118 > H = read_header(pathname) #Don't include header filename
122 H = dictionary like object with all the run metadata.
125 .. tabularcolumns:: |l|L|
127 ============= ========================================
128 keyword Description [default]
129 ============= ========================================
130 pathname FLEXPART run output directory
131 readp read release points 0=no, [1]=y
132 nested nested output [False] or True
133 headerfile provide custom name for header file
134 datefile provide a custom name for the date file
135 verbose print information while loading header
136 ============= ========================================
139 **This function is in development**
141 Please report any bugs found.
145 probably a lot of things, among which ...
147 [] choose skip/getbin or direct seek/read
148 [] define output keys in docstring
152 The user is no longer required to indicate which version of FLEXPART
153 the header is from. Checks are made, and the header is read accordingly.
154 Please report any problems...
163 OPS.headerfile =
None
167 for k
in kwargs.keys():
168 if k
not in OPS.keys():
169 print(
"WARNING: {0} not a valid input option.".format(k))
172 if 'nest' in kwargs.keys():
173 raise IOError(
"nest is no longer a valid keyword, see docs. \n Now use nested=True or nested=False")
176 if 'nested' in kwargs.keys():
177 if kwargs[
'nested']
is 1:
178 print(
"WARNING, use of nested=1, deprecated converting to nested=True")
179 kwargs[
'nested'] =
True
181 if 'nested' in kwargs.keys():
182 if kwargs[
'nested']
is 0:
183 print(
"WARNING, use of nested=0, deprecated converting to nested=False")
184 kwargs[
'nested'] =
False
189 print "Reading Header with:\n"
192 print "%s ==> %s" % (o, OPS[o])
195 skip =
lambda n = 8 : bf.seek(n, 1)
196 getbin =
lambda dtype, n = 1 : bf.read(dtype, (n,))
203 filename = os.path.join(pathname, OPS.headerfile);
205 elif OPS.nested
is True:
206 filename = os.path.join(pathname,
'header_nest')
209 filename = os.path.join(pathname,
'header')
213 if not os.path.exists(filename):
214 raise IOError(
"No such file: {0}".format(filename))
219 raise IOError(
"Error opening: {0} with BinaryFile class".format(filename))
223 datefile = os.path.join(pathname, OPS.datefile)
225 datefile = os.path.join(pathname,
'dates')
227 if not os.path.exists(datefile):
228 raise IOError(
"No DATEFILE: {0}".format(datefile))
231 fd = file(datefile,
'r').readlines()
233 raise IOError(
"Could not read datefile: {0}".format(datefile))
236 fd = sorted(list(set(fd)))
237 h[
'available_dates'] = [d.strip(
'\n')
for d
in fd]
250 h[
'ireleasestart'] = []
251 h[
'ireleaseend'] = []
255 I = {0:
'_0', 1:
'ibdate', 2:
'ibtime', 3:
'flexpart', \
256 4:
'_1', 5:
'loutstep', 6:
'loutaver', 7:
'loutsample', \
257 8:
'_2', 9:
'outlon0', 10:
'outlat0', 11:
'numxgrid', \
258 12:
'numygrid', 13:
'dxout', 14:
'dyout', 15:
'_3', 16:
'numzgrid', \
261 Dfmt = [
'i',
'i',
'i',
'13S',
'2i',
'i',
'i',
'i',
'2i',
'f',
'f',
'i',
'i',
'f',
'f',
'2i',
'i']
263 a = [bf.read(fmt)
for fmt
in Dfmt]
264 for j
in range(len(a)):
267 h[
'outheight'] = np.array([bf.read(
'f')
for i
in range(h[
'numzgrid'])])
268 junk.append(bf.read(
'2i'))
269 h[
'jjjjmmdd'] = bf.read(
'i')
270 h[
'hhmmss'] = bf.read(
'i')
271 junk.append(bf.read(
'2i'))
272 h[
'nspec'] = bf.read(
'i') / 3
273 h[
'numpointspec'] = bf.read(
'i')
274 junk.append(bf.read(
'2i'))
278 for i
in range(h[
'nspec']):
281 h[
'wetdep'].append(
''.join([bf.read(
'c')
for i
in range(10)]).strip())
282 junk.append(bf.read(
'2i'))
283 junk.append(bf.read(
'i'))
284 h[
'drydep'].append(
''.join([bf.read(
'c')
for i
in range(10)]).strip())
285 junk.append(bf.read(
'2i'))
286 h[
'nz_list'].append(getbin(
'i'))
287 h[
'species'].append(
''.join([getbin(
'c')
for i
in range(10)]).strip())
291 junk.append(bf.read(
'i'))
292 h[
'wetdep'].append(
''.join([bf.read(
'c')
for i
in range(10)]).strip())
293 junk.append(bf.read(
'2i'))
294 junk.append(bf.read(
'i'))
295 h[
'drydep'].append(
''.join([bf.read(
'c')
for i
in range(10)]).strip())
296 junk.append(bf.read(
'2i'))
297 h[
'nz_list'].append(bf.read(
'i'))
298 h[
'species'].append(
''.join([bf.read(
'c')
for i
in range(10)]).strip())
299 junk.append(bf.read(
'2i'))
304 h[
'numpoint'] = bf.read(
'i')
310 before_readp = bf.tell()
313 I = {2:
'kindz', 3:
'xp1', 4:
'yp1', 5:
'xp2', \
314 6:
'yp2', 7:
'zpoint1', 8:
'zpoint2', 9:
'npart', 10:
'mpart'}
316 for k, v
in I.iteritems():
317 h[v] = np.zeros(h[
'numpoint'])
319 h[
'xmass'] = np.zeros((h[
'numpoint'], h[
'nspec']))
326 junk.append(bf.read(
'i'))
327 for i
in range(h[
'numpoint']):
328 junk.append(bf.read(
'i'))
330 h[
'ireleasestart'].append(bf.read(
'i'))
331 h[
'ireleaseend'].append(bf.read(
'i'))
332 h[
'kindz'][i] = bf.read(
'h')
333 junk.append(bf.read(
'2i'))
335 h[
'xp1'][i] = bf.read(
'f')
336 h[
'yp1'][i] = bf.read(
'f')
337 h[
'xp2'][i] = bf.read(
'f')
338 h[
'yp2'][i] = bf.read(
'f')
339 h[
'zpoint1'][i] = bf.read(
'f')
340 h[
'zpoint2'][i] = bf.read(
'f')
342 junk.append(bf.read(
'2i'))
343 h[
'npart'][i] = bf.read(
'i')
344 h[
'mpart'][i] = bf.read(
'i')
346 junk.append(bf.read(
'i'))
352 while re.search(
"\w", bf.read(
'c')):
354 sp = sp + bf.read(
'c')
358 h[
'compoint'].append(sp)
361 junk.append(bf.read(
'i'))
363 for v
in range(h[
'nspec']):
364 Dfmt = [
'i',
'f',
'2i',
'f',
'2i',
'f',
'i']
365 a = [bf.read(fmt)
for fmt
in Dfmt]
366 h[
'xmass'][i, v] = a[1]
368 if OPS.readp
is False:
370 We get the first set of release points here in order
371 to get some information, but skip reading the rest
373 bf.seek(before_readp)
375 bf.seek(157 * h[
'numpoint'], 1);
377 bf.seek(119 * h[
'numpoint'] + (h[
'nspec'] * 36) * h[
'numpoint'] + 4, 1)
383 h[
'method'] = bf.read(
'i')
386 junk.append(bf.read(
'i'))
387 junk.append(bf.read(
'i'))
389 h[
'lsubgrid'] = bf.read(
'i')
390 h[
'lconvection'] = bf.read(
'i')
391 h[
'ind_source'] = bf.read(
'i')
392 h[
'ind_receptor'] = bf.read(
'i')
397 junk.append(bf.read(
'2i'))
399 h[
'nageclass'] = bf.read(
'i')
401 Lage_fmt = [
'i'] * h.nageclass
402 h[
'lage'] = [bf.read(fmt)
for fmt
in Lage_fmt]
408 h[
'oro'] = np.zeros((nx, ny), np.float)
409 junk.append(bf.read(
'2i'))
412 h[
'oro'][ix] = bf.read(
'f', ny)
426 h[
'pathname'] = pathname
427 h[
'decayconstant'] = 0
438 Heightnn = np.zeros((nx, ny, nz), np.float)
441 Heightnn[ix, :, 0] = oro[ix, :]
443 Heightnn[ix, :, 0] = np.zeros(ny)
447 Heightnn[ix, :, iz] = [h[
'outheight'][iz] + oro[ix, y]
for y
in range(ny)]
449 Heightnn[ix, :, iz] = h[
'outheight'][iz]
452 h[
'Heightnn'] = Heightnn
458 start_day = datetime.datetime.strptime(str(h[
'ibdate']),
'%Y%m%d')
459 H, M, S , = [int(str(h[
'ibtime']).zfill(6)[i:i + 2])
for i
in range(0, 6, 2)]
460 start_time = datetime.timedelta(hours=H, minutes=M, seconds=S)
461 h[
'simulationstart'] = start_day + start_time
464 releasestart, releaseend = [], []
465 for i
in range(h.numpointspec):
466 releasestart.append(h.simulationstart + \
467 datetime.timedelta(seconds=int(h.ireleasestart[i])))
468 releaseend.append(h.simulationstart + \
469 datetime.timedelta(seconds=int(h.ireleaseend[i])))
470 h.releasestart = releasestart
471 h.releaseend = releaseend[:h.numpointspec]
472 h.releasetimes = [b - ((b - a) / 2)
for a, b
in zip(h.releasestart, h.releaseend)]
475 available_dates_dt = []
476 for i
in h.available_dates:
477 available_dates_dt.append(datetime.datetime(
478 int(i[:4]), int(i[4:6]), int(i[6:8]), int(i[8:10]), int(i[10:12]), int(i[12:])))
479 h.available_dates_dt = available_dates_dt
480 h.first_date = available_dates_dt[0]
481 h.last_date = available_dates_dt[-1]
482 h.ageclasses = np.array([act - h.simulationstart
for act
in h.available_dates_dt])
483 h.numageclasses = len(h.ageclasses)
490 h.maxpoint = h.numpoint
491 h.maxageclass = h.numageclasses
500 if 'kindz' not in h.keys():
506 h.alt_unit =
'm.a.s.l.'
508 h.alt_unit =
'm.a.g.l.'
512 h.direction =
'forward'
516 h.direction =
'backward'
518 h.plot_unit =
'ns / kg'
521 if h.direction ==
'forward':
522 if h.ind_source == 1:
523 if h.ind_receptor == 1:
524 h.output_unit =
'ng m-3'
525 if h.ind_receptor == 2:
526 h.output_unit =
'pptm'
527 if h.ind_source == 2:
528 if h.ind_receptor == 1:
529 h.output_unit =
'ng m-3'
530 if h.ind_receptor == 2:
531 h.output_unit =
'pptm'
532 if h.direction ==
'backward':
533 if h.ind_source == 1:
534 if h.ind_receptor == 1:
536 if h.ind_receptor == 2:
537 h.output_unit =
's m^3 kg-1'
538 if h.ind_source == 2:
539 if h.ind_receptor == 1:
540 h.output_unit =
's kg m-3'
541 if h.ind_receptor == 2:
547 layerthickness = [h.outheight[0]]
548 for i, lh
in enumerate(h.outheight[1:]):
549 layerthickness.append(lh - h.outheight[i])
550 h.layerthickness = layerthickness
553 h.fp_version = h.flexpart