Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
I
ISIS3
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
aflab
astrogeology
ISIS3
Commits
5228b652
Unverified
Commit
5228b652
authored
Jun 10, 2021
by
acpaquette
Committed by
GitHub
Jun 10, 2021
Browse files
Options
Downloads
Patches
Plain Diff
Added themis notebook to crop themis images (#4204)
parent
820a2594
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
isis/notebooks/crop_themis.ipynb
+221
-0
221 additions, 0 deletions
isis/notebooks/crop_themis.ipynb
with
221 additions
and
0 deletions
isis/notebooks/crop_themis.ipynb
0 → 100644
+
221
−
0
View file @
5228b652
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os.path\n",
"import datetime\n",
"\n",
"import pvl\n",
"import numpy as np\n",
"\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"themis_file = '/Path/to/themis/raw_data.QUB'\n",
"image_file = themis_file"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"header = pvl.load(image_file)\n",
"header"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"with open(image_file, 'rb') as f:\n",
" # -1 offset obtained from ISIS, record offset likely one based \n",
" # so subtract one as we need it to be zero based\n",
" image_offset = int((header['^SPECTRAL_QUBE'] - 1) * header['RECORD_BYTES'])\n",
"\n",
" f.seek(image_offset)\n",
" b_image_data = f.read()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"n_bands = header['SPECTRAL_QUBE']['CORE_ITEMS'][header['SPECTRAL_QUBE']['AXIS_NAME'].index('BAND')]\n",
"# n_bands = 5\n",
"n_lines = header['SPECTRAL_QUBE']['CORE_ITEMS'][header['SPECTRAL_QUBE']['AXIS_NAME'].index('LINE')]\n",
"n_lines = 10\n",
"\n",
"if 'LINE_SUFFIX_ITEM_BYTES' in header['SPECTRAL_QUBE'].keys():\n",
" n_lines += 2\n",
" \n",
"line_length = header['RECORD_BYTES']\n",
"# Add line suffix offset to handle reading two extra lines from each band\n",
"if 'LINE_SUFFIX_ITEM_BYTES' in header['SPECTRAL_QUBE'].keys():\n",
" bytes_per_band = ((header['SPECTRAL_QUBE']['CORE_ITEMS'][header['SPECTRAL_QUBE']['AXIS_NAME'].index('LINE')]) + header['SPECTRAL_QUBE']['LINE_SUFFIX_ITEM_BYTES']) * line_length\n",
"else:\n",
" bytes_per_band = (header['SPECTRAL_QUBE']['CORE_ITEMS'][1]) * line_length\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"image_data = []\n",
"# Custom numpy data type to handle appropriate DN conversion\n",
"# Not necessary but was done for debugging purposes\n",
"dt = np.dtype(np.int16)\n",
"dt = dt.newbyteorder('>')\n",
"\n",
"for i in range(n_bands):\n",
"# image_data.append([])\n",
" for j in range(n_lines):\n",
" start = (j*line_length) + (bytes_per_band * i)\n",
" stop = ((j+1)*line_length) + (bytes_per_band * i)\n",
" image_sample = np.frombuffer(b_image_data[start:stop], dtype=dt, count=line_length//2)\n",
" image_data.append(image_sample)\n",
"image_data = np.array(image_data, dtype=dt)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure(0, figsize=(20, 20))\n",
"plt.imshow(image_data)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class RealIsisCubeLabelEncoder(pvl.encoder.ISISEncoder): \n",
" def encode_time(self, value):\n",
" if value.microsecond:\n",
" second = u'%02d.%06d' % (value.second, value.microsecond)\n",
" else:\n",
" second = u'%02d' % value.second\n",
"\n",
" time = u'%02d:%02d:%s' % (value.hour, value.minute, second)\n",
" return time"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"image_fn, image_ext = os.path.splitext(image_file)\n",
"crop = '_cropped'\n",
"themis_image_fn = image_fn + crop + image_ext\n",
"themis_image_bn = os.path.basename(themis_image_fn)\n",
"\n",
"grammar = pvl.grammar.ISISGrammar()\n",
"grammar.comments+=((\"#\", \"\\n\"), )\n",
"encoder = RealIsisCubeLabelEncoder()\n",
"\n",
"if header['SPECTRAL_QUBE']['DESCRIPTION'] == '':\n",
" header['SPECTRAL_QUBE']['DESCRIPTION'] = \" \"\n",
"\n",
"# Overwrite the number of lines in the label\n",
"if 'LINE_SUFFIX_ITEM_BYTES' in header['SPECTRAL_QUBE'].keys():\n",
" n_lines -= 2\n",
"header['SPECTRAL_QUBE']['CORE_ITEMS'][header['SPECTRAL_QUBE']['AXIS_NAME'].index('LINE')] = n_lines\n",
"\n",
"# Calculate the new offset\n",
"# Run this twice as the change to the header will change the headers length.\n",
"# Then add two to handle an extra new line character later on\n",
"header['^SPECTRAL_QUBE'] = pvl.collections.Units(len(pvl.dumps(header, encoder=encoder, grammar=grammar)), 'BYTES')\n",
"header['^SPECTRAL_QUBE'] = pvl.collections.Units(len(pvl.dumps(header, encoder=encoder, grammar=grammar)) + 2, 'BYTES')\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"label_fn, label_ext = os.path.splitext(themis_file)\n",
"out_label = label_fn + crop + label_ext\n",
"\n",
"pvl.dump(header, out_label, encoder=encoder, grammar=grammar)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"with open(themis_image_fn, 'ab+') as f:\n",
" b_reduced_image_data = image_data.tobytes()\n",
" f.seek(0, 2)\n",
" f.write(b'\\n')\n",
" f.write(b_reduced_image_data)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"new_header = pvl.load(out_label)\n",
"new_header"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
%% Cell type:code id: tags:
```
python
import
os.path
import
datetime
import
pvl
import
numpy
as
np
import
matplotlib.pyplot
as
plt
```
%% Cell type:code id: tags:
```
python
themis_file
=
'
/Path/to/themis/raw_data.QUB
'
image_file
=
themis_file
```
%% Cell type:code id: tags:
```
python
header
=
pvl
.
load
(
image_file
)
header
```
%% Cell type:code id: tags:
```
python
with
open
(
image_file
,
'
rb
'
)
as
f
:
# -1 offset obtained from ISIS, record offset likely one based
# so subtract one as we need it to be zero based
image_offset
=
int
((
header
[
'
^SPECTRAL_QUBE
'
]
-
1
)
*
header
[
'
RECORD_BYTES
'
])
f
.
seek
(
image_offset
)
b_image_data
=
f
.
read
()
```
%% Cell type:code id: tags:
```
python
n_bands
=
header
[
'
SPECTRAL_QUBE
'
][
'
CORE_ITEMS
'
][
header
[
'
SPECTRAL_QUBE
'
][
'
AXIS_NAME
'
].
index
(
'
BAND
'
)]
# n_bands = 5
n_lines
=
header
[
'
SPECTRAL_QUBE
'
][
'
CORE_ITEMS
'
][
header
[
'
SPECTRAL_QUBE
'
][
'
AXIS_NAME
'
].
index
(
'
LINE
'
)]
n_lines
=
10
if
'
LINE_SUFFIX_ITEM_BYTES
'
in
header
[
'
SPECTRAL_QUBE
'
].
keys
():
n_lines
+=
2
line_length
=
header
[
'
RECORD_BYTES
'
]
# Add line suffix offset to handle reading two extra lines from each band
if
'
LINE_SUFFIX_ITEM_BYTES
'
in
header
[
'
SPECTRAL_QUBE
'
].
keys
():
bytes_per_band
=
((
header
[
'
SPECTRAL_QUBE
'
][
'
CORE_ITEMS
'
][
header
[
'
SPECTRAL_QUBE
'
][
'
AXIS_NAME
'
].
index
(
'
LINE
'
)])
+
header
[
'
SPECTRAL_QUBE
'
][
'
LINE_SUFFIX_ITEM_BYTES
'
])
*
line_length
else
:
bytes_per_band
=
(
header
[
'
SPECTRAL_QUBE
'
][
'
CORE_ITEMS
'
][
1
])
*
line_length
```
%% Cell type:code id: tags:
```
python
image_data
=
[]
# Custom numpy data type to handle appropriate DN conversion
# Not necessary but was done for debugging purposes
dt
=
np
.
dtype
(
np
.
int16
)
dt
=
dt
.
newbyteorder
(
'
>
'
)
for
i
in
range
(
n_bands
):
# image_data.append([])
for
j
in
range
(
n_lines
):
start
=
(
j
*
line_length
)
+
(
bytes_per_band
*
i
)
stop
=
((
j
+
1
)
*
line_length
)
+
(
bytes_per_band
*
i
)
image_sample
=
np
.
frombuffer
(
b_image_data
[
start
:
stop
],
dtype
=
dt
,
count
=
line_length
//
2
)
image_data
.
append
(
image_sample
)
image_data
=
np
.
array
(
image_data
,
dtype
=
dt
)
```
%% Cell type:code id: tags:
```
python
plt
.
figure
(
0
,
figsize
=
(
20
,
20
))
plt
.
imshow
(
image_data
)
plt
.
show
()
```
%% Cell type:code id: tags:
```
python
class
RealIsisCubeLabelEncoder
(
pvl
.
encoder
.
ISISEncoder
):
def
encode_time
(
self
,
value
):
if
value
.
microsecond
:
second
=
u
'
%02d.%06d
'
%
(
value
.
second
,
value
.
microsecond
)
else
:
second
=
u
'
%02d
'
%
value
.
second
time
=
u
'
%02d:%02d:%s
'
%
(
value
.
hour
,
value
.
minute
,
second
)
return
time
```
%% Cell type:code id: tags:
```
python
image_fn
,
image_ext
=
os
.
path
.
splitext
(
image_file
)
crop
=
'
_cropped
'
themis_image_fn
=
image_fn
+
crop
+
image_ext
themis_image_bn
=
os
.
path
.
basename
(
themis_image_fn
)
grammar
=
pvl
.
grammar
.
ISISGrammar
()
grammar
.
comments
+=
((
"
#
"
,
"
\n
"
),
)
encoder
=
RealIsisCubeLabelEncoder
()
if
header
[
'
SPECTRAL_QUBE
'
][
'
DESCRIPTION
'
]
==
''
:
header
[
'
SPECTRAL_QUBE
'
][
'
DESCRIPTION
'
]
=
"
"
# Overwrite the number of lines in the label
if
'
LINE_SUFFIX_ITEM_BYTES
'
in
header
[
'
SPECTRAL_QUBE
'
].
keys
():
n_lines
-=
2
header
[
'
SPECTRAL_QUBE
'
][
'
CORE_ITEMS
'
][
header
[
'
SPECTRAL_QUBE
'
][
'
AXIS_NAME
'
].
index
(
'
LINE
'
)]
=
n_lines
# Calculate the new offset
# Run this twice as the change to the header will change the headers length.
# Then add two to handle an extra new line character later on
header
[
'
^SPECTRAL_QUBE
'
]
=
pvl
.
collections
.
Units
(
len
(
pvl
.
dumps
(
header
,
encoder
=
encoder
,
grammar
=
grammar
)),
'
BYTES
'
)
header
[
'
^SPECTRAL_QUBE
'
]
=
pvl
.
collections
.
Units
(
len
(
pvl
.
dumps
(
header
,
encoder
=
encoder
,
grammar
=
grammar
))
+
2
,
'
BYTES
'
)
```
%% Cell type:code id: tags:
```
python
label_fn
,
label_ext
=
os
.
path
.
splitext
(
themis_file
)
out_label
=
label_fn
+
crop
+
label_ext
pvl
.
dump
(
header
,
out_label
,
encoder
=
encoder
,
grammar
=
grammar
)
```
%% Cell type:code id: tags:
```
python
with
open
(
themis_image_fn
,
'
ab+
'
)
as
f
:
b_reduced_image_data
=
image_data
.
tobytes
()
f
.
seek
(
0
,
2
)
f
.
write
(
b
'
\n
'
)
f
.
write
(
b_reduced_image_data
)
```
%% Cell type:code id: tags:
```
python
new_header
=
pvl
.
load
(
out_label
)
new_header
```
%% Cell type:code id: tags:
```
python
```
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment