Skip to content

Added a Linear TS search job adapter#695

Open
alongd wants to merge 20 commits intomainfrom
linear_ts
Open

Added a Linear TS search job adapter#695
alongd wants to merge 20 commits intomainfrom
linear_ts

Conversation

@alongd
Copy link
Member

@alongd alongd commented Aug 21, 2023

Added a method for generating TS structures from atom mapped reactants and products.
The method works for unimolecular reactions, and at present is only implemented for isomerization reactions.

@codecov
Copy link

codecov bot commented Aug 22, 2023

Codecov Report

Attention: Patch coverage is 87.93103% with 35 lines in your changes are missing coverage. Please review.

Project coverage is 73.97%. Comparing base (3631196) to head (cbec920).

Current head cbec920 differs from pull request most recent head 69759f8

Please upload reports for the commit 69759f8 to get more accurate results.

Files Patch % Lines
arc/job/adapters/ts/linear.py 75.63% 18 Missing and 11 partials ⚠️
arc/mapping/engine.py 86.66% 3 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #695      +/-   ##
==========================================
+ Coverage   73.80%   73.97%   +0.17%     
==========================================
  Files          99      101       +2     
  Lines       27352    27596     +244     
  Branches     5718     5746      +28     
==========================================
+ Hits        20187    20415     +228     
- Misses       5738     5745       +7     
- Partials     1427     1436       +9     
Flag Coverage Δ
unittests 73.97% <87.93%> (+0.17%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@alongd alongd force-pushed the linear_ts branch 5 times, most recently from 8825e9f to cbec920 Compare May 15, 2024 07:02
@alongd alongd marked this pull request as ready for review May 15, 2024 09:26
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

print(self.rxn_2.ts_species.ts_guesses[0].initial_xyz)
self.assertEqual(self.rxn_2.ts_species.ts_guesses[0].initial_xyz['symbols'],
('C', 'C', 'O', 'N', 'O', 'H', 'H', 'H', 'H', 'H'))
expected_xyz = 1 # todo

Check notice

Code scanning / CodeQL

Unused local variable Note

Variable expected_xyz is not used.

Copilot Autofix

AI 3 days ago

In general, to fix an unused local variable you either (1) remove the variable assignment if it is unnecessary, ensuring you preserve any side effects on the right-hand side, or (2) rename it to an "unused" style name (for example, _ or unused_expected_xyz) if it is intentionally unused. Here, the right-hand side is the literal 1, which has no side effects, and the variable is not used. The cleanest fix without changing functionality is to delete the expected_xyz assignment but retain the # todo comment so the intent is preserved.

Concretely, in arc/job/adapters/ts/linear_test.py inside test_linear_adapter_2, remove line 1167 (expected_xyz = 1 # todo) and leave everything else unchanged. No imports, methods, or additional definitions are needed.

Suggested changeset 1
arc/job/adapters/ts/linear_test.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/arc/job/adapters/ts/linear_test.py b/arc/job/adapters/ts/linear_test.py
--- a/arc/job/adapters/ts/linear_test.py
+++ b/arc/job/adapters/ts/linear_test.py
@@ -1164,7 +1164,7 @@
         print(self.rxn_2.ts_species.ts_guesses[0].initial_xyz)
         self.assertEqual(self.rxn_2.ts_species.ts_guesses[0].initial_xyz['symbols'],
                          ('C', 'C', 'O', 'N', 'O', 'H', 'H', 'H', 'H', 'H'))
-        expected_xyz = 1  # todo
+        # todo: add assertion on expected_xyz once reference geometry is defined
 
     def test_get_r_constraints(self):
         """Test the get_r_constraints() function."""
EOF
@@ -1164,7 +1164,7 @@
print(self.rxn_2.ts_species.ts_guesses[0].initial_xyz)
self.assertEqual(self.rxn_2.ts_species.ts_guesses[0].initial_xyz['symbols'],
('C', 'C', 'O', 'N', 'O', 'H', 'H', 'H', 'H', 'H'))
expected_xyz = 1 # todo
# todo: add assertion on expected_xyz once reference geometry is defined

def test_get_r_constraints(self):
"""Test the get_r_constraints() function."""
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +2497 to +2506
# for val in zmat['map'].values():
# if isinstance(val, str) and 'X' in val:
# idx = int(val[1:])
# if idx > max_index:
# max_index = idx
# elif isinstance(val, int):
# if val > max_index:
# max_index = val
#
# # Fill list with Real atoms, None for placeholders up to max_index

Check notice

Code scanning / CodeQL

Commented-out code Note

This comment appears to contain commented-out code.

Copilot Autofix

AI 3 days ago

In general, to fix commented‑out code you either (1) fully reinstate it as active code if the functionality is required and currently missing, or (2) delete it entirely if it is obsolete or superseded. Given only this snippet and no indication that this function is needed, the least risky and cleanest fix is to remove the commented‑out implementation.

Concretely, in arc/species/zmat.py around lines 2480–2518, there is a large block of what was once a function body, fully commented out line by line. To avoid changing current behavior, we will not attempt to revive or modify this logic; instead, we will delete the commented lines. No new imports, methods, or definitions are required since we are only removing dead code. The edit is a straightforward deletion of the commented block starting at the # Args: line (and possibly including any surrounding # def ... if present in the full file) through the last commented dummy_index = int(map_idx[1:]) line shown.

Suggested changeset 1
arc/species/zmat.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/arc/species/zmat.py b/arc/species/zmat.py
--- a/arc/species/zmat.py
+++ b/arc/species/zmat.py
@@ -2477,45 +2477,45 @@
 #     Update a zmat vars by xyz.
 #     Calculates the Cartesian coordinates of any dummy atoms present in the Z-matrix
 #     but missing from the xyz input, assuming rigid dummy atom definitions from the input zmat.
-#
-#     Args:
-#         zmat (dict): The zmat to update.
-#         xyz (dict): The xyz to update the zmat with.
-#
-#     Returns:
-#         dict: The updated zmat.
-#     """
-#     zmat_out = {'symbols': zmat['symbols'],
-#                 'coords': zmat['coords'],
-#                 'vars': zmat['vars'],
-#                 'map': zmat['map'],
-#                 }
-#
-#     # Create a mutable list of coordinates that we can extend with dummy atoms
-#     # Ensure it's large enough to hold the indices referenced in zmat['map']
-#     max_index = len(xyz['coords']) - 1
-#     for val in zmat['map'].values():
-#         if isinstance(val, str) and 'X' in val:
-#             idx = int(val[1:])
-#             if idx > max_index:
-#                 max_index = idx
-#         elif isinstance(val, int):
-#             if val > max_index:
-#                 max_index = val
-#
-#     # Fill list with Real atoms, None for placeholders up to max_index
-#     coords_list = [None] * (max_index + 1)
-#     for i, coord in enumerate(xyz['coords']):
-#         coords_list[i] = coord
-#
-#     # Iterate through Z-matrix rows to calculate Dummy Atom positions
-#     for i, row in enumerate(zmat['coords']):
-#         map_idx = zmat['map'][i]
-#
-#         # Check if this is a dummy atom (mapped to string 'X...')
-#         if isinstance(map_idx, str) and 'X' in map_idx:
-#             dummy_index = int(map_idx[1:])
-#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 #             # Retrieve definition (R, A, D) from zmat vars
 #             # row format: (r_var, a_var, d_var)
 #             r_key, a_key, d_key = row
EOF
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +2508 to +2550
# for i, coord in enumerate(xyz['coords']):
# coords_list[i] = coord
#
# # Iterate through Z-matrix rows to calculate Dummy Atom positions
# for i, row in enumerate(zmat['coords']):
# map_idx = zmat['map'][i]
#
# # Check if this is a dummy atom (mapped to string 'X...')
# if isinstance(map_idx, str) and 'X' in map_idx:
# dummy_index = int(map_idx[1:])
#
# # Retrieve definition (R, A, D) from zmat vars
# # row format: (r_var, a_var, d_var)
# r_key, a_key, d_key = row
#
# # Helper to get parent index from var name (e.g., 'R_7_6' -> parent is 6)
# # zmat parameters are usually stored as 'Type_Current_Parent...'
# def _get_parent_idx(key_):
# if key_:
# # The second number in the string is usually the parent for R, A, D
# # e.g., R_7_6 -> 6. A_7_6_4 -> 6 (first parent).
# parts = key_.split('_')
# # parts[1] is the current atom zmat-index, parts[2] is the parent zmat-index
# parent_zmat_idx = int(parts[2])
# # We need the xyz-index (or map value) of that parent
# parent_map_idx = zmat['map'][parent_zmat_idx]
# if isinstance(parent_map_idx, str):
# return int(parent_map_idx[1:])
# return parent_map_idx
# return None
#
# p1_idx = _get_parent_idx(r_key)
# p2_idx = _get_parent_idx(a_key)
# p3_idx = _get_parent_idx(d_key)
#
# # Get values (Dummy definitions are assumed constant/rigid from input zmat)
# r_val = zmat['vars'][r_key]
# a_val = zmat['vars'][a_key] if a_key else 90.0
# d_val = zmat['vars'][d_key] if d_key else 0.0
#
# # Calculate Cartesian Position
# if p1_idx is not None and coords_list[p1_idx] is not None:
# p1 = coords_list[p1_idx]

Check notice

Code scanning / CodeQL

Commented-out code Note

This comment appears to contain commented-out code.

Copilot Autofix

AI 3 days ago

To fix the problem, the commented-out code should be removed rather than left in the file. This eliminates dead, untested logic and leaves only the active implementation in the module. If this logic is needed in the future, it can be recovered from version control.

Concretely, in arc/species/zmat.py, delete the entire commented block starting around line 2491 (# 'map': zmat['map'],) down to line 2584 (# zmat_out['vars'] = new_vars / # return zmat_out). No replacement functionality is required because the code is already entirely disabled and not part of the current behavior. No new imports, methods, or definitions are needed; we are only cleaning up unused commented code.

Suggested changeset 1
arc/species/zmat.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/arc/species/zmat.py b/arc/species/zmat.py
--- a/arc/species/zmat.py
+++ b/arc/species/zmat.py
@@ -2488,97 +2488,3 @@
 #     zmat_out = {'symbols': zmat['symbols'],
 #                 'coords': zmat['coords'],
 #                 'vars': zmat['vars'],
-#                 'map': zmat['map'],
-#                 }
-#
-#     # Create a mutable list of coordinates that we can extend with dummy atoms
-#     # Ensure it's large enough to hold the indices referenced in zmat['map']
-#     max_index = len(xyz['coords']) - 1
-#     for val in zmat['map'].values():
-#         if isinstance(val, str) and 'X' in val:
-#             idx = int(val[1:])
-#             if idx > max_index:
-#                 max_index = idx
-#         elif isinstance(val, int):
-#             if val > max_index:
-#                 max_index = val
-#
-#     # Fill list with Real atoms, None for placeholders up to max_index
-#     coords_list = [None] * (max_index + 1)
-#     for i, coord in enumerate(xyz['coords']):
-#         coords_list[i] = coord
-#
-#     # Iterate through Z-matrix rows to calculate Dummy Atom positions
-#     for i, row in enumerate(zmat['coords']):
-#         map_idx = zmat['map'][i]
-#
-#         # Check if this is a dummy atom (mapped to string 'X...')
-#         if isinstance(map_idx, str) and 'X' in map_idx:
-#             dummy_index = int(map_idx[1:])
-#
-#             # Retrieve definition (R, A, D) from zmat vars
-#             # row format: (r_var, a_var, d_var)
-#             r_key, a_key, d_key = row
-#
-#             # Helper to get parent index from var name (e.g., 'R_7_6' -> parent is 6)
-#             # zmat parameters are usually stored as 'Type_Current_Parent...'
-#             def _get_parent_idx(key_):
-#                 if key_:
-#                     # The second number in the string is usually the parent for R, A, D
-#                     # e.g., R_7_6 -> 6. A_7_6_4 -> 6 (first parent).
-#                     parts = key_.split('_')
-#                     # parts[1] is the current atom zmat-index, parts[2] is the parent zmat-index
-#                     parent_zmat_idx = int(parts[2])
-#                     # We need the xyz-index (or map value) of that parent
-#                     parent_map_idx = zmat['map'][parent_zmat_idx]
-#                     if isinstance(parent_map_idx, str):
-#                         return int(parent_map_idx[1:])
-#                     return parent_map_idx
-#                 return None
-#
-#             p1_idx = _get_parent_idx(r_key)
-#             p2_idx = _get_parent_idx(a_key)
-#             p3_idx = _get_parent_idx(d_key)
-#
-#             # Get values (Dummy definitions are assumed constant/rigid from input zmat)
-#             r_val = zmat['vars'][r_key]
-#             a_val = zmat['vars'][a_key] if a_key else 90.0
-#             d_val = zmat['vars'][d_key] if d_key else 0.0
-#
-#             # Calculate Cartesian Position
-#             if p1_idx is not None and coords_list[p1_idx] is not None:
-#                 p1 = coords_list[p1_idx]
-#                 p2 = coords_list[p2_idx] if p2_idx is not None else None
-#                 p3 = coords_list[p3_idx] if p3_idx is not None else None
-#
-#                 dummy_pos = get_position(r=r_val, theta=a_val, phi=d_val, p1=p1, p2=p2, p3=p3)
-#                 coords_list[dummy_index] = dummy_pos
-#
-#     # Now calculate new variables using the augmented coordinates list
-#     # Re-package coordinates into a dict structure expected by calculate_param logic if needed,
-#     # or just pass the list if calculate_param accepts it (it accepts lists/tuples).
-#     new_vars = dict()
-#     for key, val in zmat['vars'].items():
-#         # Identify if this variable *defines* a dummy atom (starts with 'RX', 'AX', 'DX')
-#         # If so, keep original value (rigid dummy assumption).
-#         # Otherwise, calculate it (real atom or real atom referencing dummy).
-#         if key.startswith('RX') or key.startswith('AX') or key.startswith('DX'):
-#             new_vars[key] = val
-#         else:
-#             # Standard calculation
-#             # We need to get atom indices.
-#             indices = get_atom_indices_from_zmat_parameter(key)[0]
-#
-#             # Map Z-mat indices to XYZ indices (handling 'X' strings)
-#             mapped_indices = []
-#             for index in indices:
-#                 m_val = zmat['map'][index]
-#                 if isinstance(m_val, str) and 'X' in m_val:
-#                     mapped_indices.append(int(m_val[1:]))
-#                 else:
-#                     mapped_indices.append(m_val)
-#
-#             new_vars[key] = calculate_param(coords=coords_list, atoms=mapped_indices)
-#
-#     zmat_out['vars'] = new_vars
-#     return zmat_out
EOF
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +2561 to +2581
# for key, val in zmat['vars'].items():
# # Identify if this variable *defines* a dummy atom (starts with 'RX', 'AX', 'DX')
# # If so, keep original value (rigid dummy assumption).
# # Otherwise, calculate it (real atom or real atom referencing dummy).
# if key.startswith('RX') or key.startswith('AX') or key.startswith('DX'):
# new_vars[key] = val
# else:
# # Standard calculation
# # We need to get atom indices.
# indices = get_atom_indices_from_zmat_parameter(key)[0]
#
# # Map Z-mat indices to XYZ indices (handling 'X' strings)
# mapped_indices = []
# for index in indices:
# m_val = zmat['map'][index]
# if isinstance(m_val, str) and 'X' in m_val:
# mapped_indices.append(int(m_val[1:]))
# else:
# mapped_indices.append(m_val)
#
# new_vars[key] = calculate_param(coords=coords_list, atoms=mapped_indices)

Check notice

Code scanning / CodeQL

Commented-out code Note

This comment appears to contain commented-out code.

Copilot Autofix

AI 3 days ago

To fix the problem, we should eliminate the commented-out code block rather than leaving it in place. This removes the distraction and ensures the file only contains executable code and meaningful comments. Since we must avoid changing existing functionality, we should not try to “revive” this logic; instead, we delete it, leaving the surrounding working code untouched.

Concretely, in arc/species/zmat.py, remove the entire commented-out block starting at line 2536 (# return parent_map_idx) down through line 2584 (# return zmat_out). No new imports, functions, or variables are needed, and no other regions of the file should be modified.

Suggested changeset 1
arc/species/zmat.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/arc/species/zmat.py b/arc/species/zmat.py
--- a/arc/species/zmat.py
+++ b/arc/species/zmat.py
@@ -2533,52 +2533,4 @@
 #                     parent_map_idx = zmat['map'][parent_zmat_idx]
 #                     if isinstance(parent_map_idx, str):
 #                         return int(parent_map_idx[1:])
-#                     return parent_map_idx
-#                 return None
-#
-#             p1_idx = _get_parent_idx(r_key)
-#             p2_idx = _get_parent_idx(a_key)
-#             p3_idx = _get_parent_idx(d_key)
-#
-#             # Get values (Dummy definitions are assumed constant/rigid from input zmat)
-#             r_val = zmat['vars'][r_key]
-#             a_val = zmat['vars'][a_key] if a_key else 90.0
-#             d_val = zmat['vars'][d_key] if d_key else 0.0
-#
-#             # Calculate Cartesian Position
-#             if p1_idx is not None and coords_list[p1_idx] is not None:
-#                 p1 = coords_list[p1_idx]
-#                 p2 = coords_list[p2_idx] if p2_idx is not None else None
-#                 p3 = coords_list[p3_idx] if p3_idx is not None else None
-#
-#                 dummy_pos = get_position(r=r_val, theta=a_val, phi=d_val, p1=p1, p2=p2, p3=p3)
-#                 coords_list[dummy_index] = dummy_pos
-#
-#     # Now calculate new variables using the augmented coordinates list
-#     # Re-package coordinates into a dict structure expected by calculate_param logic if needed,
-#     # or just pass the list if calculate_param accepts it (it accepts lists/tuples).
-#     new_vars = dict()
-#     for key, val in zmat['vars'].items():
-#         # Identify if this variable *defines* a dummy atom (starts with 'RX', 'AX', 'DX')
-#         # If so, keep original value (rigid dummy assumption).
-#         # Otherwise, calculate it (real atom or real atom referencing dummy).
-#         if key.startswith('RX') or key.startswith('AX') or key.startswith('DX'):
-#             new_vars[key] = val
-#         else:
-#             # Standard calculation
-#             # We need to get atom indices.
-#             indices = get_atom_indices_from_zmat_parameter(key)[0]
-#
-#             # Map Z-mat indices to XYZ indices (handling 'X' strings)
-#             mapped_indices = []
-#             for index in indices:
-#                 m_val = zmat['map'][index]
-#                 if isinstance(m_val, str) and 'X' in m_val:
-#                     mapped_indices.append(int(m_val[1:]))
-#                 else:
-#                     mapped_indices.append(m_val)
-#
-#             new_vars[key] = calculate_param(coords=coords_list, atoms=mapped_indices)
-#
-#     zmat_out['vars'] = new_vars
-#     return zmat_out
+
EOF
@@ -2533,52 +2533,4 @@
# parent_map_idx = zmat['map'][parent_zmat_idx]
# if isinstance(parent_map_idx, str):
# return int(parent_map_idx[1:])
# return parent_map_idx
# return None
#
# p1_idx = _get_parent_idx(r_key)
# p2_idx = _get_parent_idx(a_key)
# p3_idx = _get_parent_idx(d_key)
#
# # Get values (Dummy definitions are assumed constant/rigid from input zmat)
# r_val = zmat['vars'][r_key]
# a_val = zmat['vars'][a_key] if a_key else 90.0
# d_val = zmat['vars'][d_key] if d_key else 0.0
#
# # Calculate Cartesian Position
# if p1_idx is not None and coords_list[p1_idx] is not None:
# p1 = coords_list[p1_idx]
# p2 = coords_list[p2_idx] if p2_idx is not None else None
# p3 = coords_list[p3_idx] if p3_idx is not None else None
#
# dummy_pos = get_position(r=r_val, theta=a_val, phi=d_val, p1=p1, p2=p2, p3=p3)
# coords_list[dummy_index] = dummy_pos
#
# # Now calculate new variables using the augmented coordinates list
# # Re-package coordinates into a dict structure expected by calculate_param logic if needed,
# # or just pass the list if calculate_param accepts it (it accepts lists/tuples).
# new_vars = dict()
# for key, val in zmat['vars'].items():
# # Identify if this variable *defines* a dummy atom (starts with 'RX', 'AX', 'DX')
# # If so, keep original value (rigid dummy assumption).
# # Otherwise, calculate it (real atom or real atom referencing dummy).
# if key.startswith('RX') or key.startswith('AX') or key.startswith('DX'):
# new_vars[key] = val
# else:
# # Standard calculation
# # We need to get atom indices.
# indices = get_atom_indices_from_zmat_parameter(key)[0]
#
# # Map Z-mat indices to XYZ indices (handling 'X' strings)
# mapped_indices = []
# for index in indices:
# m_val = zmat['map'][index]
# if isinstance(m_val, str) and 'X' in m_val:
# mapped_indices.append(int(m_val[1:]))
# else:
# mapped_indices.append(m_val)
#
# new_vars[key] = calculate_param(coords=coords_list, atoms=mapped_indices)
#
# zmat_out['vars'] = new_vars
# return zmat_out

Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants