Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
K
Knoten
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
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
aflab
astrogeology
Knoten
Commits
43902583
Commit
43902583
authored
5 years ago
by
Jesse Mapel
Browse files
Options
Downloads
Patches
Plain Diff
Rought bundle adjust utilities
parent
56228bfb
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
knoten/bundle.py
+201
-0
201 additions, 0 deletions
knoten/bundle.py
with
201 additions
and
0 deletions
knoten/bundle.py
0 → 100644
+
201
−
0
View file @
43902583
import
numpy
as
np
import
pandas
as
pd
import
pvl
import
os
import
csmapi
def
closest_approach
(
points
,
direction
):
"""
Compute the point of closest approach between lines.
Parameters
----------
points : ndarray
An n x 3 array of points on each line
direction : ndarray
An n x 3 array of vectors that defines the direction of each line
Returns
-------
: array
The (x, y, z) point that is closest to all of the lines
"""
num_lines
=
points
.
shape
[
0
]
design_mat
=
np
.
zeros
((
num_lines
*
3
,
3
))
rhs
=
np
.
zeros
(
num_lines
*
3
)
for
i
in
range
(
num_lines
):
point
=
points
[
i
]
line
=
direction
[
i
]
/
np
.
linalg
.
norm
(
direction
[
i
])
design_mat
[
3
*
i
:
3
*
i
+
3
]
=
np
.
identity
(
3
)
-
np
.
outer
(
line
,
line
)
rhs
[
3
*
i
:
3
*
i
+
3
]
=
np
.
dot
(
point
,
line
)
*
line
+
point
closest_point
,
_
=
np
.
linalg
.
lstsq
(
design_mat
,
rhs
)
return
closest_point
def
compute_apriori_ground_points
(
network
,
sensors
):
"""
Compute a priori ground points for all of the free points in a control network.
Parameters
----------
network : DataFrame
The control network as a dataframe generated by plio
sensors : dict
A dictionary that maps ISIS serial numbers to CSM sensors
Returns
-------
: DataFrame
The control network dataframe with updated ground points
"""
for
point_id
,
group
in
df
.
groupby
(
'
id
'
):
# Free points are type 2 for V2 and V5 control networks
if
group
.
iloc
[
0
][
"
pointType
"
]
!=
2
:
continue
positions
=
[]
look_vecs
=
[]
for
measure_id
,
row
in
group
.
iterrows
():
measure
=
csmapi
.
ImageCoord
(
row
[
"
line
"
],
row
[
"
sample
"
])
locus
=
sensors
[
row
[
"
serialnumber
"
]].
imageToRemoteImagingLocus
(
measure
)
positions
.
append
([
locus
.
point
.
x
,
locus
.
point
.
y
,
locus
.
point
.
z
])
look_vecs
.
append
([
locus
.
direction
.
x
,
locus
.
direction
.
y
,
locus
.
direction
.
z
])
ground_pt
=
closest_approach
(
np
.
array
(
positions
),
np
.
array
(
look_vecs
))
network
.
loc
[
network
.
id
==
point_id
,
[
"
adjustedX
"
,
"
adjustedY
"
,
"
adjustedZ
"
]]
=
ground_pt
return
network
class
CsmParameter
:
"""
Container class that describes a parameter for a CSM sensor model
"""
def
__init__
(
self
,
sensor
,
index
):
self
.
index
=
index
self
.
name
=
sensor
.
getParameterName
(
index
)
self
.
type
=
sensor
.
getParameterType
(
index
)
self
.
units
=
sensor
.
getParameterUnits
(
index
)
self
.
value
=
sensor
.
setParameterValue
(
index
)
def
get_sensor_parameters
(
sensor
,
set
=
"
adjustable
"
):
"""
Get a set of the CSM parameters for a CSM sensor
Parameters
----------
sensor : CSM sensor
The CSM sensor model
set : str
The CSM parameter set to get. Either valid, adjustable, or non_adjustable
Returns
-------
: List
A list of CsmParameters
"""
if
(
set
.
upper
()
==
"
VALID
"
):
param_set
=
csmapi
.
VALID
elif
(
set
.
upper
()
==
"
ADJUSTABLE
"
):
param_set
=
csmapi
.
ADJUSTABLE
elif
(
set
.
upper
()
==
"
NON_ADJUSTABLE
"
):
param_set
=
csmapi
.
NON_ADJUSTABLE
else
:
raise
ValueError
(
f
"
Invalid parameter set
\"
{}
\"
.
"
)
return
[
CsmParameter
(
sensor
,
index
)
for
index
in
sensor
.
getParameterSetIndices
(
param_set
)]
def
compute_sensor_partials
(
sensor
,
parameters
,
ground_pt
):
"""
Compute the partial derivatives of the line and sample with respect to a set
of parameters.
Parameters
----------
sensor : CSM sensor
The CSM sensor model
parameters : list
The list of CsmParameter to compute the partials W.R.T.
ground_pt : array
The (x, y, z) ground point to compute the partial derivatives at
Returns
-------
: ndarray
The 2 x n array of partial derivatives. The first array is the line
partials and the second array is the sample partials. The partial
derivatives are in the same order as the parameter list passed in.
"""
partials
=
np
.
zeros
((
2
,
len
(
parameters
)))
csm_ground
=
csmapi
.
EcefCoord
(
ground_pt
[
0
],
ground_pt
[
1
],
ground_pt
[
2
])
for
i
in
range
(
len
(
parameters
)):
partials
[:,
i
]
=
sensor
.
computeSensorPartials
(
parameters
[
i
].
index
,
csm_ground
)
return
partials
def
compute_ground_partials
(
sensor
,
ground_pt
):
"""
Compute the partial derivatives of the line and sample with respect to a
ground point.
Parameters
----------
sensor : CSM sensor
The CSM sensor model
ground_pt : array
The (x, y, z) ground point to compute the partial derivatives W.R.T.
Returns
-------
: ndarray
The 2 x 3 array of partial derivatives. The first array is the line
partials and the second array is the sample partials. The partial
derivatives are in (x, y, z) order.
"""
csm_ground
=
csmapi
.
EcefCoord
(
ground_pt
[
0
],
ground_pt
[
1
],
ground_pt
[
2
])
partials
=
np
.
array
(
sensor
.
computeGroundPartials
(
csm_ground
))
return
np
.
reshape
(
partials
,
(
2
,
3
))
def
compute_jacobian
(
network
,
sensors
,
parameters
):
"""
Compute the Jacobian matrix.
Parameters
----------
network : DataFrame
The control network as a dataframe generated by plio. The ground
point columns will be in the same order as the control points are
in this.
sensors : dict
Dictionary that maps ISIS serial numbers to CSM sensor models
parameters : dict
Dictionary that maps serial numbers to lists of parameters to
solve for. The image parameter columns of the Jacobian will be
in the same order as this.
Returns
-------
: ndarray
The Jacobian matrix
"""
num_columns
=
0
coefficient_columns
=
{}
for
serial
,
params
in
parameters
.
items
():
coefficient_columns
[
serial
]
=
num_columns
num_columns
+=
len
(
params
)
for
point_id
in
network
[
"
id
"
].
unique
():
# Skip fixed points
if
network
.
loc
[
network
.
id
==
point_id
,
0
][
"
pointType
"
]
==
4
:
continue
coefficient_columns
[
serial
]
=
num_columns
num_columns
+=
len
(
params
)
num_rows
=
len
(
network
)
*
2
jacobian
=
np
.
zeros
((
num_rows
,
num_columns
))
for
i
in
range
(
len
(
network
)):
row
=
network
.
iloc
[
i
]
serial
=
row
[
"
serialnumber
"
]
ground_pt
=
row
[[
"
adjustedX
"
,
"
adjustedY
"
,
"
adjustedZ
"
]]
sensor
=
sensor
[
serial
]
params
=
parameters
[
serial
]
image_column
=
coefficient_columns
[
serial
]
point_column
=
coefficient_columns
[
row
[
"
id
"
]]
jacobian
[
2
*
i
:
2
*
i
+
2
,
image_column
:
image_column
+
len
(
params
)]
=
compute_sensor_partials
(
sensor
,
params
,
ground_pt
)
jacobian
[
2
*
i
:
2
*
i
+
2
,
point_column
:
point_column
+
3
]
=
compute_ground_partials
(
sensor
,
ground_pt
)
return
jacobian
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