yu-mcal 0.1.4__py3-none-any.whl → 0.1.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
mcal/mcal.py CHANGED
@@ -140,7 +140,7 @@ def main():
140
140
  cif_path_without_ext = f'{directory}/{filename}'
141
141
 
142
142
  print('----------------------------------------')
143
- print(' mcal 0.1.4 (2026/01/20) by Matsui Lab. ')
143
+ print(' mcal 0.1.6 (2026/01/29) by Matsui Lab. ')
144
144
  print('----------------------------------------')
145
145
 
146
146
  if args.read_pickle:
@@ -471,8 +471,8 @@ def cal_eigenvalue_decomposition(mobility_tensor: NDArray[np.float64]) -> Tuple[
471
471
  Tuple[NDArray[np.float64], NDArray[np.float64]]
472
472
  Eigenvalue(mobility value) and eigenvector(mobility vector)
473
473
  """
474
- value, vector = np.linalg.eig(mobility_tensor)
475
- return value, vector
474
+ value, vector = np.linalg.eigh(mobility_tensor)
475
+ return value[::-1], vector[:, ::-1]
476
476
 
477
477
 
478
478
  def cal_min_distance(
mcal/utils/cif_reader.py CHANGED
@@ -1,10 +1,11 @@
1
- """CifReader beta (2025/10/30)"""
1
+ """CifReader beta (2026/01/29)"""
2
2
  import os
3
3
  import re
4
+ import warnings
5
+ from collections import deque
4
6
  from itertools import product
5
7
  from pathlib import Path
6
8
  from typing import Dict, List, Literal, Tuple
7
- import warnings
8
9
 
9
10
  import numpy as np
10
11
  import pandas as pd
@@ -67,13 +68,26 @@ class CifReader:
67
68
  self._make_adjacency_mat()
68
69
  self._split_mols()
69
70
  self._put_unit_cell()
71
+ self._unwrap_molecules()
72
+ self._put_unit_cell()
73
+ # Remove duplicates again as they may occur when moving atoms into the unit cell
70
74
  self.sym_symbols, self.sym_coords = self.remove_duplicates(self.sym_symbols, self.sym_coords)
71
75
  self._make_adjacency_mat()
72
76
  self._split_mols()
73
77
  self._calc_z_value()
74
78
 
75
79
  if self._ref_z_value != 0 and self.z_value != self._ref_z_value:
76
- raise ZValueIsNotMatchError('Z value is not match.')
80
+ raise ZValueIsNotMatchError(
81
+ f'Z value is not match. Z value in cif file is {self._ref_z_value}, but calculated Z value is {self.z_value}.'
82
+ )
83
+
84
+ def _apply_minimum_image(self):
85
+ """Apply minimum image convention."""
86
+ frac_diff = self.sym_coords[:, np.newaxis, :] - self.sym_coords[np.newaxis, :, :]
87
+ frac_diff = frac_diff - np.round(frac_diff)
88
+ cart_diff = np.dot(frac_diff, self.lattice)
89
+ distance = np.linalg.norm(cart_diff, axis=-1)
90
+ return distance
77
91
 
78
92
  def _calc_lattice(self):
79
93
  """Calculate lattice."""
@@ -128,7 +142,7 @@ class CifReader:
128
142
  num_atoms = len(self.sym_symbols)
129
143
  self.adjacency_mat = np.zeros((num_atoms, num_atoms), dtype=bool)
130
144
 
131
- self.cart_coords = np.dot(self.sym_coords, self.lattice)
145
+ distance = self._apply_minimum_image()
132
146
 
133
147
  try:
134
148
  covalent_distance = np.array([self.COVALENT_RADII[symbol] for symbol in self.sym_symbols]) \
@@ -136,7 +150,6 @@ class CifReader:
136
150
  except KeyError:
137
151
  raise ElementPropertiesIsNotDefinedError('Element properties is not defined.')
138
152
 
139
- distance = np.linalg.norm(self.cart_coords[:, np.newaxis, :] - self.cart_coords[np.newaxis, :, :], axis=-1)
140
153
  self.adjacency_mat[(distance <= covalent_distance * 1.3) & (distance != 0)] = 1
141
154
 
142
155
  def _operate_sym(self) -> None:
@@ -293,10 +306,11 @@ class CifReader:
293
306
  if '?' not in tmp_atom_data[atom_data_index['_atom_site_label']]:
294
307
  if atom_data_index['_atom_site_type_symbol'] is None:
295
308
  symbol_label = tmp_atom_data[atom_data_index['_atom_site_label']]
296
- symbol = symbol_label
297
- for s in ['A', 'B', 'C']:
298
- symbol = symbol.replace(s, '')
299
- symbol = re.sub(r'\d+', '', symbol)
309
+ symbol = re.match(r'[A-Z][a-z]?', symbol_label)
310
+ if symbol:
311
+ symbol = symbol.group(0)
312
+ else:
313
+ raise ValueError(f'Symbol label {symbol_label} is not valid.')
300
314
  else:
301
315
  symbol_label = tmp_atom_data[atom_data_index['_atom_site_label']]
302
316
  symbol = tmp_atom_data[atom_data_index['_atom_site_type_symbol']]
@@ -310,11 +324,10 @@ class CifReader:
310
324
  # get symmetry operation information
311
325
  elif is_read_sym:
312
326
  if "'" in line:
313
- line = list(map(lambda x: x.strip().replace(' ', ''), line.split("'")))
314
- self.symmetry_pos.append(line[symmetry_data_index].lower())
327
+ line = list(map(lambda x: x.strip().replace(' ', '').replace("'", ""), line.split()))
315
328
  else:
316
329
  line = list(map(lambda x: x.strip().replace(' ', ''), line.split()))
317
- self.symmetry_pos.append(line[symmetry_data_index].lower())
330
+ self.symmetry_pos.append(line[symmetry_data_index].lower())
318
331
 
319
332
  self.symbols = np.array(self.symbols)
320
333
  self.coordinates = np.array(self.coordinates)
@@ -359,6 +372,35 @@ class CifReader:
359
372
  sub_matrix = self.adjacency_mat[np.ix_(index_group, index_group)]
360
373
  self.sub_matrices.append(sub_matrix)
361
374
 
375
+ def _unwrap_molecules(self):
376
+ """Unwrap molecules using the adjacency matrix based on the minimum image convention."""
377
+ for atom_group in self.bonded_atoms:
378
+ if len(atom_group) <= 1:
379
+ continue
380
+
381
+ criterion_idx = atom_group[0]
382
+
383
+ # Depth-first search
384
+ visited = {criterion_idx}
385
+ stack = deque([criterion_idx])
386
+
387
+ while stack:
388
+ current_idx = stack.popleft()
389
+ current_coord = self.sym_coords[current_idx]
390
+
391
+ for neighbor_idx in atom_group:
392
+ if neighbor_idx in visited:
393
+ continue
394
+
395
+ if self.adjacency_mat[current_idx, neighbor_idx]:
396
+ # Minimum image convention
397
+ frac_diff = self.sym_coords[neighbor_idx] - current_coord
398
+ frac_diff = frac_diff - np.round(frac_diff)
399
+ self.sym_coords[neighbor_idx] = current_coord + frac_diff
400
+
401
+ visited.add(neighbor_idx)
402
+ stack.append(neighbor_idx)
403
+
362
404
  def calc_cen_of_weight(self, coordinates: NDArray[np.float64]) -> NDArray[np.float64]:
363
405
  """Calculate center of weight.
364
406
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yu-mcal
3
- Version: 0.1.4
3
+ Version: 0.1.6
4
4
  Summary: Program for the calculation of mobility tensor for organic semiconductor crystals
5
5
  Author: Koki Ozawa
6
6
  Author-email: Hiroyuki Matsui <h-matsui@yz.yamagata-u.ac.jp>
@@ -1,15 +1,15 @@
1
1
  mcal/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
2
- mcal/mcal.py,sha256=dUw4CrbtrSDrez47MwwnpX-OFv3OcnArVOuaHlLixrk,29264
2
+ mcal/mcal.py,sha256=LRKAcLKG8Uv0yI16zZW0GmOEiRkbUHuVWVYOrHZR014,29280
3
3
  mcal/calculations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  mcal/calculations/hopping_mobility_model.py,sha256=eD9doesa1yVDQxzBYW0N41OyjikZb77S69I_mIMbL2g,13180
5
5
  mcal/calculations/rcal.py,sha256=CH3iV18KTM8xU7M7zKR3e1m67GbJLH8zi0j50TsUXLE,13500
6
6
  mcal/constants/element_properties.csv,sha256=_Yanl713VZQaAqPYoLNn-hXDdg01ZfkYsCLQ1SQSX8w,4073
7
7
  mcal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- mcal/utils/cif_reader.py,sha256=nhvk7y8ix4yKhyKjDaw2Luotw6YFMGbGCaeBVP6Qd5E,22901
8
+ mcal/utils/cif_reader.py,sha256=QAV6xXMd3nfKLpJqBncA6fbGJ5kgYKDeKIx-sK_4P_M,24532
9
9
  mcal/utils/gaus_log_reader.py,sha256=nNIgBae9hRUgpmNF7eIC5LOENSo6NQmuckMM4A3HAa8,3159
10
10
  mcal/utils/gjf_maker.py,sha256=Kkh_gNcifFfhTikZar6SzoNJ7AyEBiCBXJTQkHxHX-0,8193
11
- yu_mcal-0.1.4.dist-info/METADATA,sha256=y_vQTgF-UcwXOuyV3BpWh9WfCAvtn5Z3bv1KmmL91k4,7890
12
- yu_mcal-0.1.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
13
- yu_mcal-0.1.4.dist-info/entry_points.txt,sha256=_0xZR3t9qvFSd9L6Iot03NixVLxXioEY19L6w3Fs1Ew,40
14
- yu_mcal-0.1.4.dist-info/licenses/LICENSE,sha256=JP8vm7gYE73jLgnMFTOLNo_RnH88RrB4Goyh7H_muto,1072
15
- yu_mcal-0.1.4.dist-info/RECORD,,
11
+ yu_mcal-0.1.6.dist-info/METADATA,sha256=6qhMLEDBBrwAKLXWz7hlohj-2JI26xxrX2kuf0AF8gE,7890
12
+ yu_mcal-0.1.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
13
+ yu_mcal-0.1.6.dist-info/entry_points.txt,sha256=_0xZR3t9qvFSd9L6Iot03NixVLxXioEY19L6w3Fs1Ew,40
14
+ yu_mcal-0.1.6.dist-info/licenses/LICENSE,sha256=JP8vm7gYE73jLgnMFTOLNo_RnH88RrB4Goyh7H_muto,1072
15
+ yu_mcal-0.1.6.dist-info/RECORD,,