Skip to content

Commit dfb5899

Browse files
improve: optionally disregard malformed data
1 parent a827699 commit dfb5899

File tree

3 files changed

+33
-27
lines changed

3 files changed

+33
-27
lines changed

kmm/header/header.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ class Header(kmm.FunctionalBase):
1313

1414
@staticmethod
1515
@validate_arguments
16-
def from_path(path: Path):
16+
def from_path(path: Path, raise_on_malformed_data: bool = True):
1717
"""
1818
Loads header data from .hdr file.
1919
"""
2020
try:
2121
tree = ElementTree.parse(path)
2222
except ElementTree.ParseError:
23+
if raise_on_malformed_data:
24+
raise ValueError("Unable to parse header file, invalid XML.")
2325
tree = attempt_to_patch_xml(path)
2426

2527
position, sync = kmm.header.position_sync(tree)

kmm/positions/positions.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
from kmm.header.header import Header
21
from pathlib import Path
2+
33
import pandas as pd
44
from pydantic import validate_arguments
55

66
import kmm
7+
from kmm.header.header import Header
78

89

910
class Positions(kmm.FunctionalBase):
10-
1111
dataframe: pd.DataFrame
1212

1313
class Config:
@@ -34,21 +34,29 @@ def read_sync_adjust(
3434
kmm_path: Path,
3535
header_path: Path,
3636
adjustment: kmm.PositionAdjustment = kmm.PositionAdjustment.WIRE_CAMERA,
37+
raise_on_malformed_data: bool = True,
3738
):
3839
"""
3940
Loads positions from .kmm or .kmm2 file + .hdr file, then performs
4041
frame index sync, position adjustment and geodetic coordinate transformation.
4142
"""
42-
header = kmm.Header.from_path(header_path)
43+
header = kmm.Header.from_path(header_path, raise_on_malformed_data)
4344
return (
4445
Positions.from_path(kmm_path)
45-
.sync_frame_index(header, adjustment)
46+
.sync_frame_index(header, adjustment, raise_on_malformed_data)
4647
.geodetic()
4748
)
4849

4950
@validate_arguments
50-
def sync_frame_index(self, header: Header, adjustment: kmm.PositionAdjustment):
51-
return kmm.positions.sync_frame_index(self, header, adjustment)
51+
def sync_frame_index(
52+
self,
53+
header: Header,
54+
adjustment: kmm.PositionAdjustment,
55+
raise_on_malformed_data: bool = True,
56+
):
57+
return kmm.positions.sync_frame_index(
58+
self, header, adjustment, raise_on_malformed_data
59+
)
5260

5361
def geodetic(self):
5462
return kmm.positions.geodetic(self)

kmm/positions/sync_frame_index.py

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,30 @@
22
from pydantic import validate_arguments
33

44
from kmm import CarDirection, PositionAdjustment
5-
from kmm.positions.positions import Positions
65
from kmm.header.header import Header
6+
from kmm.positions.positions import Positions
77

88

99
@validate_arguments(config=dict(arbitrary_types_allowed=True))
10-
def sync_frame_index(positions: Positions, header: Header, adjustment: PositionAdjustment):
11-
12-
validate_meter_increments(positions)
10+
def sync_frame_index(
11+
positions: Positions,
12+
header: Header,
13+
adjustment: PositionAdjustment,
14+
raise_on_malformed_data: bool = True,
15+
):
16+
if raise_on_malformed_data:
17+
validate_meter_increments(positions)
1318
frame_index = (
14-
(
15-
positions.dataframe["centimeter"].values
16-
+ header.position
17-
- header.sync
18-
) / 10
19+
(positions.dataframe["centimeter"].values + header.position - header.sync) / 10
1920
).astype(int)
2021

2122
if header.car_direction == CarDirection.A:
22-
dataframe = (
23-
positions.dataframe
24-
.iloc[:-adjustment]
25-
.assign(frame_index=frame_index[adjustment:])
23+
dataframe = positions.dataframe.iloc[:-adjustment].assign(
24+
frame_index=frame_index[adjustment:]
2625
)
2726
elif header.car_direction == CarDirection.B:
28-
dataframe = (
29-
positions.dataframe
30-
.iloc[adjustment:]
31-
.assign(frame_index=frame_index[:-adjustment])
27+
dataframe = positions.dataframe.iloc[adjustment:].assign(
28+
frame_index=frame_index[:-adjustment]
3229
)
3330
else:
3431
raise ValueError(f"Unsupported car direction {header.car_direction}")
@@ -39,9 +36,8 @@ def sync_frame_index(positions: Positions, header: Header, adjustment: PositionA
3936

4037

4138
def validate_meter_increments(positions):
42-
for (track_section, kilometer), group in (
43-
positions.dataframe
44-
.groupby(["track_section", "kilometer"])
39+
for (track_section, kilometer), group in positions.dataframe.groupby(
40+
["track_section", "kilometer"]
4541
):
4642
diffs = np.sign(group["meter"].values[1:] - group["meter"].values[:-1])
4743
if len(diffs) >= 10 and (diffs > 0).mean() < 0.9 and (diffs < 0).mean() < 0.9:

0 commit comments

Comments
 (0)