1
|
|
|
# -*- coding: utf-8 -*- |
2
|
|
|
# vim:fileencoding=utf-8 |
3
|
|
|
# |
4
|
|
|
# Copyright (c) 2014-2017 Stefan Bender |
5
|
|
|
# |
6
|
|
|
# This file is part of sciapy. |
7
|
|
|
# sciapy is free software: you can redistribute it or modify it |
8
|
|
|
# under the terms of the GNU General Public License as published by |
9
|
|
|
# the Free Software Foundation, version 2. |
10
|
|
|
# See accompanying LICENSE file or http://www.gnu.org/licenses/gpl-2.0.html. |
11
|
1 |
|
"""SCIAMACHY level 1c limb spectra binary interface |
12
|
|
|
""" |
13
|
|
|
|
14
|
1 |
|
from __future__ import absolute_import, division, print_function |
15
|
|
|
|
16
|
1 |
|
import numpy as np |
17
|
|
|
|
18
|
1 |
|
from ._types import _float_type, _int_type, _limb_data_dtype |
19
|
|
|
|
20
|
1 |
|
def _write_padded_string(fp, s, padding): |
21
|
1 |
|
s = s.encode('ascii', "ignore") |
22
|
1 |
|
count = padding - len(s) |
23
|
1 |
|
fp.write(s) |
24
|
|
|
# pad |
25
|
1 |
|
fp.write(b'\x00' * count) |
26
|
|
|
|
27
|
1 |
|
def _read_single_float(fp): |
28
|
|
|
ret = np.frombuffer(fp.read(4), dtype=_float_type)[0] |
29
|
|
|
return ret |
30
|
|
|
|
31
|
1 |
|
def _write_int_to_binary(fp, a): |
32
|
1 |
|
fp.write(np.asarray(a, dtype=_int_type).tostring()) |
33
|
|
|
|
34
|
1 |
|
def _write_float_to_binary(fp, a): |
35
|
1 |
|
fp.write(np.asarray(a, dtype=_float_type).tostring()) |
36
|
|
|
|
37
|
|
|
|
38
|
1 |
|
def read_from_mpl_binary(self, filename): |
39
|
|
|
"""SCIAMACHY level 1c limb scan binary import |
40
|
|
|
|
41
|
|
|
Parameters |
42
|
|
|
---------- |
43
|
|
|
filename : str |
44
|
|
|
The binary filename to read the data from. |
45
|
|
|
|
46
|
|
|
Returns |
47
|
|
|
------- |
48
|
|
|
nothing |
49
|
|
|
""" |
50
|
1 |
|
if hasattr(filename, 'seek'): |
51
|
|
|
f = filename |
52
|
|
|
else: |
53
|
1 |
|
f = open(filename, 'rb') |
54
|
1 |
|
hlen = 100 |
55
|
|
|
# the first bytes of the first 100 header bytes are |
56
|
|
|
# the number of header lines that follow |
57
|
1 |
|
nline = "" |
58
|
1 |
|
j = 0 |
59
|
1 |
|
flag = 0 |
60
|
1 |
|
while j < hlen: |
61
|
1 |
|
char = bytes(f.read(1)) |
62
|
1 |
|
if char == b'\n': |
63
|
|
|
# we have a usual text file, abort binary reading. |
64
|
|
|
raise ValueError |
65
|
1 |
|
j += 1 |
66
|
1 |
|
if char and char != b'\x00' and flag == 0: |
67
|
1 |
|
nline += char.decode() |
68
|
|
|
else: |
69
|
1 |
|
flag = 1 |
70
|
|
|
|
71
|
1 |
|
self.textheader_length = int(''.join(nline)) |
72
|
|
|
|
73
|
1 |
|
h_list = [] |
74
|
1 |
|
for _ in range(self.textheader_length): |
75
|
1 |
|
line = "" |
76
|
1 |
|
j = 0 |
77
|
1 |
|
flag = 0 |
78
|
1 |
|
while j < hlen: |
79
|
1 |
|
char = bytes(f.read(1)) |
80
|
1 |
|
j += 1 |
81
|
1 |
|
if char and char != b'\x00' and flag == 0: |
82
|
1 |
|
line += char.decode() |
83
|
|
|
else: |
84
|
1 |
|
flag = 1 |
85
|
1 |
|
h_list.append(line.rstrip()) |
86
|
|
|
|
87
|
1 |
|
self.textheader = '\n'.join(h_list) |
88
|
1 |
|
self.parse_textheader() |
89
|
|
|
|
90
|
|
|
# global data |
91
|
1 |
|
self.nalt = np.frombuffer(f.read(4), dtype=_int_type)[0] |
92
|
1 |
|
self.npix = np.frombuffer(f.read(4), dtype=_int_type)[0] |
93
|
1 |
|
self.orbit_state = np.frombuffer(f.read(4 * 5), dtype=_int_type) |
94
|
1 |
|
(self.orbit, self.state_in_orbit, self.state_id, |
95
|
|
|
self.profiles_per_state, self.profile_in_state) = self.orbit_state |
96
|
1 |
|
self.date = np.frombuffer(f.read(4 * 6), dtype=_int_type) |
97
|
1 |
|
self.cent_lat_lon = np.frombuffer(f.read(4 * 10), dtype=_float_type) |
98
|
1 |
|
if self.textheader_length > 29: |
99
|
1 |
|
self.orbit_phase = np.frombuffer(f.read(4), dtype=_float_type)[0] |
100
|
|
|
|
101
|
1 |
|
self.wls = np.frombuffer(f.read(4 * self.npix), dtype=_float_type) |
102
|
|
|
|
103
|
1 |
|
if self._limb_data_dtype is None: |
104
|
1 |
|
self._limb_data_dtype = _limb_data_dtype[:] |
105
|
1 |
|
if self.textheader_length < 28: |
106
|
|
|
self._limb_data_dtype.remove(("sub_sat_lat", _float_type)) |
107
|
|
|
self._limb_data_dtype.remove(("sub_sat_lon", _float_type)) |
108
|
|
|
|
109
|
1 |
|
self._limb_data_dtype.append(("rad", _float_type, (self.npix))) |
110
|
1 |
|
self._limb_data_dtype.append(("err", _float_type, (self.npix))) |
111
|
|
|
|
112
|
1 |
|
self.limb_data = np.fromfile(f, dtype=np.dtype(self._limb_data_dtype), |
113
|
|
|
count=self.nalt).view(type=np.recarray) |
114
|
|
|
|
115
|
1 |
|
def write_to_mpl_binary(self, filename): |
116
|
|
|
"""SCIAMACHY level 1c limb scan binary export |
117
|
|
|
|
118
|
|
|
Parameters |
119
|
|
|
---------- |
120
|
|
|
filename : str |
121
|
|
|
The binary filename to write the data to. |
122
|
|
|
|
123
|
|
|
Returns |
124
|
|
|
------- |
125
|
|
|
nothing |
126
|
|
|
""" |
127
|
1 |
|
if hasattr(filename, 'seek'): |
128
|
|
|
f = filename |
129
|
|
|
else: |
130
|
1 |
|
f = open(filename, 'wb') |
131
|
|
|
|
132
|
|
|
# write out the padded header first |
133
|
1 |
|
bufsize = 100 |
134
|
1 |
|
_write_padded_string(f, str(self.textheader_length), bufsize) |
135
|
1 |
|
h_list = self.textheader.split('\n') |
136
|
1 |
|
for h_line in h_list: |
137
|
1 |
|
_write_padded_string(f, h_line, bufsize) |
138
|
|
|
|
139
|
1 |
|
_write_int_to_binary(f, self.nalt) |
140
|
1 |
|
_write_int_to_binary(f, self.npix) |
141
|
|
|
|
142
|
1 |
|
_write_int_to_binary(f, self.orbit_state) |
143
|
1 |
|
_write_int_to_binary(f, self.date) |
144
|
1 |
|
_write_float_to_binary(f, self.cent_lat_lon) |
145
|
1 |
|
if self.textheader_length > 29: |
146
|
1 |
|
_write_float_to_binary(f, self.orbit_phase) |
147
|
|
|
|
148
|
1 |
|
_write_float_to_binary(f, self.wls) |
149
|
|
|
|
150
|
|
|
# write the data as is, the dtype should take care of |
151
|
|
|
# all the formatting. |
152
|
1 |
|
self.limb_data.tofile(f) |
153
|
|
|
|
154
|
|
|
f.close() |
155
|
|
|
|