This repository has been archived by the owner on Mar 30, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
binutils.py
205 lines (161 loc) · 5.34 KB
/
binutils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
"""
Binary Utilities Class.
Selection of utility functions for binary operations
and other handy functions.
@author [email protected]
@copyright 2018 Intel Ltd (see LICENSE file).
"""
from __future__ import print_function
import time
import argparse
import numpy as np
from os.path import splitext
def normalize(val, minval, maxval):
"""Scale a value between 0 and 1."""
if val >= maxval:
return 1
elif val <= minval:
return 0
normed = float(val - minval) / float(maxval - minval)
return normed
def normalize_np(vals, minval, maxval):
"""Scale values within a numpy array between 0 and 1."""
normed = np.float64(vals - minval) / np.float64(maxval - minval)
normed[normed < 0] = 0
normed[normed > 1] = 1
return normed
def set_bit(bit64, index):
"""Set bit index on 64 bit unsigned integer to one."""
bit64 |= np.uint64(1) << np.uint64(index)
return bit64
def unset_bit(bit64, index):
"""Set bit index on 64 bit unsigned integer to zero."""
bit64 &= ~(np.uint64(1) << np.uint64(index))
return bit64
def flip_bit(bit64, index):
"""Set bit index on 64 bit unsigned integer to opposite of what it was."""
bit64 ^= np.uint64(1) << np.uint64(index)
return bit64
def read_bit(bit64, index):
"""Pull the value at bit index."""
bit = (int(bit64) >> index) & 1
return bit
def count_bits(vol):
"""Count all bits set to 1."""
count = 0
vol = np.uint64(vol)
for i in range(64):
bit = read_bit(vol, i)
if bit == 1:
count += 1
return count
def count_neighbours(target, mask):
"""Use a mask to calculate the bit occupancy of the surrounding pixels."""
result = target & mask
neighbours = count_bits(result)
masksize = count_bits(mask)
return neighbours, masksize
def print_binary(np64):
"""Print as string with all the zeros."""
print("{0:064b}".format(np64))
def get_indexes(vol):
"""Return all the indices in a given vol."""
indices = []
vol = np.uint64(vol)
for i in range(64):
bit = read_bit(vol, i)
if bit == 1:
indices.append(i)
return indices
def get_byte_array(intval):
"""Generate byte array from numpy integer."""
byte_array = [int(i) for i in intval.tobytes()]
return byte_array
def xyz_from_sparse_index(indexes):
"""Generate coordinates from sparse index."""
x, y, z, = 0, 0, 0
for level, index in enumerate(indexes):
mult = pow(4, ((len(indexes) - 1) - level))
x += (index % 4) * mult
y += (index % 16 // 4) * mult
z += (index // 16) * mult
return (x, y, z)
def sparse_indexes(coord, depth):
"""Generate sparse indexes from coordinate."""
indexes = [0] * depth
x = coord[0]
y = coord[1]
z = coord[2]
for i in range(depth):
divx, modx = divmod(x, 4)
divy, mody = divmod(y, 4)
divz, modz = divmod(z, 4)
index = modx + (mody * 4) + (modz * 16)
level = (depth - i) - 1
indexes[level] = index
x = divx
y = divy
z = divz
return indexes
def timer(starttime=None):
"""Generate timing information in h,m,s format."""
if starttime is None:
return time.time()
else:
endtime = time.time()
seconds = endtime - starttime
m, s = divmod(seconds, 60)
h, m = divmod(m, 60)
print("Time Taken: %d:%02d:%02d" % (h, m, s))
return endtime
def parser_args(wildcards):
"""Default parser arguments, all in one handy place."""
parser = argparse.ArgumentParser()
parser.add_argument(
"input",
help="the name of the file / files / directory you want to open.\
You can used wildcards(" + wildcards + ") or the directory\
for multiple files. Make sure you put it in quotation marks\
otherwise linux will expand it e.g.: xyz2vola \"*.laz\"",
type=str)
parser.add_argument(
"depth", help="how many levels the vola tree will use", type=int)
parser.add_argument(
"--crs",
help="the coordinate system of the input, e.g.,\
29902 (irish grid epsg code)",
type=int, default=2000)
parser.add_argument(
"-n",
"--nbits",
help="use 1+nbits per voxel. The parser works out what info to embed",
action='store_true')
parser.add_argument(
"-d",
"--dense",
help="output a dense point cloud",
action='store_true')
return parser
def add_reverse(parser):
""" adds reverse argument for reversing z and y columns """
parser.add_argument(
"-z", "--reverse_zy",
help="reverse the z and y axes in data",
action="store_true")
return parser
def sub(filepath, new_ext):
""" replacement for re.sub that only modifies the extension """
bare_file = splitext(filepath)[0]
if '.' in new_ext:
return bare_file + new_ext
else:
return bare_file + '.' + new_ext
def print_ratio(filename, outfilename):
""" print small size comparison result for user """
from os.path import getsize, join
from os import getcwd
path = getcwd()
sizeold = getsize(join(path, filename))
sizenew = getsize(join(path, outfilename))
percentage = round(100 * sizenew/sizeold, 2)
print("\nThe .vol file is " + str(percentage) + "% of the original")