From aaa6011d6bf3a06f5aaeb373f20ec2e1f84257a7 Mon Sep 17 00:00:00 2001 From: Guillaume Bouvignies Date: Thu, 13 Jun 2024 21:59:17 +0200 Subject: [PATCH] Fitting errors in Chemex v2024.05.2 with MC and BS syntaxes (Error #2) (#245) Fixes #244 --- chemex/parameters/spin_system/atom.py | 36 ++++++++++++++++++++++++ chemex/parameters/spin_system/group.py | 39 +++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/chemex/parameters/spin_system/atom.py b/chemex/parameters/spin_system/atom.py index 9649577c..e47da978 100644 --- a/chemex/parameters/spin_system/atom.py +++ b/chemex/parameters/spin_system/atom.py @@ -3,7 +3,9 @@ from __future__ import annotations from collections.abc import Hashable +from copy import deepcopy from dataclasses import dataclass, field +from typing import Self from .constants import CORRECT_ATOM_NAME from .nucleus import Nucleus, str2nucleus @@ -69,3 +71,37 @@ def __str__(self) -> str: str: The name of the atom. """ return self.name + + def __deepcopy__(self, memo: dict[int, Self]) -> Self: + """Creates a deep copy of the Atom instance. + + Args: + memo (dict[int, Self]): A dictionary of memoized objects. + + Returns: + Self: A deep copy of the Atom instance. + """ + if id(self) in memo: + return memo[id(self)] + + # Create a new instance of Atom without calling __init__ + cls = self.__class__ + new_atom = cls.__new__(cls) + + # Copy all attributes to the new instance + new_atom.name = deepcopy(self.name, memo) + new_atom.nucleus = deepcopy(self.nucleus, memo) + + # Copy search_keys excluding self + new_search_keys = deepcopy( + {key for key in self.search_keys if key is not self}, memo + ) + new_atom.search_keys = new_search_keys + + # Add the new_atom to its own search_keys set + new_atom.search_keys.add(new_atom) + + # Memoize the new instance + memo[id(self)] = new_atom + + return new_atom diff --git a/chemex/parameters/spin_system/group.py b/chemex/parameters/spin_system/group.py index e61a49fc..8c6630fc 100644 --- a/chemex/parameters/spin_system/group.py +++ b/chemex/parameters/spin_system/group.py @@ -1,8 +1,10 @@ from __future__ import annotations from collections.abc import Hashable +from copy import deepcopy from functools import cache, total_ordering from re import search +from typing import Self from .constants import AAA_TO_A @@ -113,7 +115,7 @@ def __hash__(self) -> int: Returns: int: The hash value of the group. """ - return hash(self.name) + return hash((self.symbol, self.number, self.suffix)) def __bool__(self) -> bool: """Boolean representation of the Group object. @@ -130,3 +132,38 @@ def __str__(self) -> str: str: The full name of the group. """ return self.name + + def __deepcopy__(self, memo: dict[int, Self]) -> Self: + """Deep copy of the Group object. + + Args: + memo (dict[int, object]): A dictionary for tracking copied objects. + + Returns: + Group: A deep copy of the group. + """ + if id(self) in memo: + return memo[id(self)] + + # Create a new instance of Group without calling __init__ + cls = self.__class__ + new_group = cls.__new__(cls) + + # Deep copy all attributes to the new instance + new_group.symbol = deepcopy(self.symbol, memo) + new_group.number = deepcopy(self.number, memo) + new_group.suffix = deepcopy(self.suffix, memo) + + # Copy search_keys excluding self + new_search_keys = deepcopy( + {key for key in self.search_keys if key is not self}, memo + ) + new_group.search_keys = new_search_keys + + # Add the new_group to its own search_keys set + new_group.search_keys.add(new_group) + + # Memoize the new instance + memo[id(self)] = new_group + + return new_group