read_from_mpl_binary()   F
last analyzed

Complexity

Conditions 15

Size

Total Lines 76
Code Lines 50

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 44
CRAP Score 15.13

Importance

Changes 0
Metric Value
cc 15
eloc 50
nop 2
dl 0
loc 76
ccs 44
cts 48
cp 0.9167
crap 15.13
rs 2.9998
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like sciapy.level1c.scia_limb_mpl.read_from_mpl_binary() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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