Skip to content

Commit

Permalink
deepcopy with sharing
Browse files Browse the repository at this point in the history
  • Loading branch information
ralwing committed Nov 25, 2024
1 parent 968d12f commit ce04d9f
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 20 deletions.
38 changes: 38 additions & 0 deletions perception_eval/perception_eval/common/deepcopy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from copy import deepcopy


# https://stackoverflow.com/a/24621200/4732868
def deepcopy_with_sharing(obj, shared_attribute_names, memo=None):
"""
Deepcopy an object, except for a given list of attributes, which should
be shared between the original object and its copy.
obj is some object
shared_attribute_names: A list of strings identifying the attributes that
should be shared between the original and its copy.
memo is the dictionary passed into __deepcopy__. Ignore this argument if
not calling from within __deepcopy__.
"""
assert isinstance(shared_attribute_names, (list, tuple))
shared_attributes = {k: getattr(obj, k) for k in shared_attribute_names}

if hasattr(obj, "__deepcopy__"):
# Do hack to prevent infinite recursion in call to deepcopy
deepcopy_method = obj.__deepcopy__
obj.__deepcopy__ = None

for attr in shared_attribute_names:
del obj.__dict__[attr]

clone = deepcopy(obj)

for attr, val in shared_attributes.items():
setattr(obj, attr, val)
setattr(clone, attr, val)

if hasattr(obj, "__deepcopy__"):
# Undo hack
obj.__deepcopy__ = deepcopy_method
del clone.__deepcopy__

return clone
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from perception_eval.common import DynamicObject
from perception_eval.common import DynamicObject2D
from perception_eval.common import ObjectType
from perception_eval.common.deepcopy import deepcopy_with_sharing
from perception_eval.common.evaluation_task import EvaluationTask
from perception_eval.common.label import LabelType
from perception_eval.common.label import TrafficLightLabel
Expand Down Expand Up @@ -106,6 +107,9 @@ def __init__(
self.iou_3d = None
self.plane_distance = None

def __deepcopy__(self, memo):
return deepcopy_with_sharing(self, shared_attribute_names = ['estimated_object', 'ground_truth_object'], memo=memo)

def get_status(
self,
matching_mode: MatchingMode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.

from __future__ import annotations
from copy import copy
from copy import copy, deepcopy
from typing import Dict
from typing import List
from typing import Optional
Expand Down Expand Up @@ -89,23 +89,6 @@ def __init__(
transforms=frame_ground_truth.transforms,
)

def copy_with_shallow_results(self) -> PerceptionFrameResult:
"""
Create a shallow copy of the current PerceptionFrameResult instance.
This method creates a new instance of PerceptionFrameResult by performing a shallow copy
of the current instance. The `metrics_score` and `pass_fail_result` attributes are also
shallow copied to the new instance.
Returns:
PerceptionFrameResult: A new instance of PerceptionFrameResult with shallow copied attributes.
"""

new_instance = copy(self)
new_instance.metrics_score = copy(self.metrics_score)
new_instance.pass_fail_result = copy(self.pass_fail_result)
return new_instance

def evaluate_frame(
self,
previous_result: Optional[PerceptionFrameResult] = None,
Expand Down
3 changes: 1 addition & 2 deletions perception_eval/perception_eval/tool/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,7 @@ def filter_frame_by_distance(
Returns:
PerceptionFrameResult: Filtered frame results.
"""
ret_frame = frame.copy_with_shallow_results()

ret_frame = deepcopy(frame)
if min_distance is not None:
min_distance_list = [min_distance] * len(ret_frame.target_labels)
else:
Expand Down

0 comments on commit ce04d9f

Please sign in to comment.