orto 1.8.1__py3-none-any.whl → 1.8.3__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.
orto/__version__.py CHANGED
@@ -1 +1 @@
1
- __version__ = '1.8.1'
1
+ __version__ = '1.8.3'
orto/cli.py CHANGED
@@ -527,6 +527,14 @@ def gen_job_func(uargs):
527
527
  else:
528
528
  nbo_module = None
529
529
 
530
+ # Check structure in input file or xyz file
531
+ # unless skip_structure flag is set
532
+ if not uargs.skip_structure:
533
+ try:
534
+ inp.check_structure(oj.input_file)
535
+ except (DataNotFoundError, DataFormattingError) as e:
536
+ ut.red_exit(str(e))
537
+
530
538
  # Set SLURM error and output file names
531
539
  config['error'] = 'slurm.%j.e'
532
540
  config['output'] = 'slurm.%j.o'
@@ -1880,6 +1888,15 @@ def read_args(arg_list=None):
1880
1888
  )
1881
1889
  )
1882
1890
 
1891
+ gen_job.add_argument(
1892
+ '--skip_structure',
1893
+ '-ss',
1894
+ action='store_true',
1895
+ help=(
1896
+ 'Disables checking of structure in input file or xyz file'
1897
+ )
1898
+ )
1899
+
1883
1900
  gen_job.add_argument(
1884
1901
  '-om',
1885
1902
  '--orca_load',
orto/extractor.py CHANGED
@@ -2204,6 +2204,85 @@ class XYZInputExtractor(extto.LineExtractor):
2204
2204
  return _ext.data
2205
2205
 
2206
2206
 
2207
+ class StructureInputExtractor(extto.BetweenExtractor):
2208
+ '''
2209
+ Extracts structure from xyz file
2210
+ '''
2211
+
2212
+ # Regex Start Pattern
2213
+ START_PATTERN = rb'(?<=\*xyz )'
2214
+
2215
+ # Regex End Pattern
2216
+ END_PATTERN = rb'(?=\*)'
2217
+
2218
+ @property
2219
+ def data(self) -> tuple[list[str], NDArray]:
2220
+ '''
2221
+ list of atom labels and ndarray of coordinates (N, 3)
2222
+ '''
2223
+ return self._data
2224
+
2225
+ @staticmethod
2226
+ def _process_block(block: str) -> tuple[list[str], NDArray]:
2227
+ '''
2228
+ Converts single block into data entries described in self.data
2229
+
2230
+ Parameters
2231
+ ----------
2232
+ block: str
2233
+ String block extracted from file
2234
+
2235
+ Returns
2236
+ -------
2237
+ tuple[list[str], NDArray]
2238
+ '''
2239
+
2240
+ # Get labels and coordinates
2241
+ all_info = re.findall(
2242
+ r'([A-Za-z]+\s*-?\d\.\d*\s+-?\d\.\d*\s+-?\d\.\d*)',
2243
+ block
2244
+ )
2245
+
2246
+ labels = re.findall(
2247
+ r'([A-Za-z]+)',
2248
+ block
2249
+ )
2250
+
2251
+ coords = np.asarray([
2252
+ [float(v) for v in val.split()[1:]]
2253
+ for val in all_info
2254
+ ])
2255
+
2256
+ if len(labels) != coords.shape[0]:
2257
+ raise DataFormattingError(
2258
+ 'Number of atom labels does not match number of coordinates'
2259
+ )
2260
+
2261
+ data = (labels, coords)
2262
+
2263
+ return data
2264
+
2265
+ @classmethod
2266
+ def extract(cls, file_name: str | pathlib.Path) -> tuple[list[str], NDArray]: # noqa
2267
+ '''
2268
+ Convenience method which instantiates class, extracts blocks, and
2269
+ returns processed datasets
2270
+
2271
+ Parameters
2272
+ ----------
2273
+ file_name: str | pathlib.Path
2274
+ File to parse
2275
+
2276
+ Returns
2277
+ -------
2278
+ tuple[list[str], NDArray]
2279
+ Each entry contains processed data, as defined in cls.data
2280
+ '''
2281
+ _ext = cls()
2282
+ _ext(file_name, process=True)
2283
+ return _ext.data
2284
+
2285
+
2207
2286
  class IntInputExtractor(XYZInputExtractor):
2208
2287
  '''
2209
2288
  Extracts *int line of an input file
orto/input.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from pathlib import Path
2
2
  import re
3
3
  import numpy as np
4
+ import numpy.linalg as la
4
5
  import copy
5
6
  import xyz_py as xyzp
6
7
 
@@ -304,6 +305,77 @@ def check_xyz(file_name: str | Path, skip_check) -> None:
304
305
  return
305
306
 
306
307
 
308
+ def check_structure(file_name: str | Path, threshold: float = 0.1) -> None:
309
+ '''
310
+ Checks that no atoms of the structure are overlapping.\n
311
+
312
+ Parameters
313
+ ----------
314
+ file_name: str | Path
315
+ Orca input file as either name or Path object
316
+ threshold: float
317
+ Minimum allowed distance between atoms in Angstroms
318
+
319
+ Returns
320
+ -------
321
+ None
322
+
323
+ Raises
324
+ ------
325
+ DataFormattingError
326
+ If any atoms are overlapping
327
+ '''
328
+
329
+ # Get xyz file name and check it exists and is formatted correctly
330
+ try:
331
+ xyz_file = oe.XYZFileInputExtractor.extract(file_name)
332
+ except DataNotFoundError:
333
+ xyz_file = []
334
+
335
+ try:
336
+ xyzline = oe.XYZInputExtractor.extract(file_name)
337
+ except DataNotFoundError:
338
+ xyzline = []
339
+
340
+ if not len(xyz_file) and not len(xyzline):
341
+ ut.red_exit(
342
+ 'Error: missing or incorrect *xyzfile or *xyz line in input'
343
+ )
344
+
345
+ if len(xyz_file):
346
+ # Load structure from xyz file
347
+ xyz_file = Path(xyz_file[0])
348
+ labels, coords = xyzp.load_xyz(xyz_file)
349
+ else:
350
+ # Extract structure from input file
351
+ labels, coords = oe.StructureInputExtractor.extract(file_name)[0]
352
+
353
+ # Compute pairwise differences using broadcasting
354
+ # Broadcast to shape (N, N, 3)
355
+ # from (N, 1, 3) and (1, N, 3)
356
+ diffs = coords[:, np.newaxis, :] - coords[np.newaxis, :, :]
357
+
358
+ # Compute Euclidean distances
359
+ distances = la.norm(diffs, axis=-1) # shape (N, N)
360
+
361
+ # Add large value to diagonal to avoid zero self-distances
362
+ distances += np.diag([100]*len(labels))
363
+ # Find index of zero distances
364
+ zero_dist = np.where(
365
+ distances < threshold
366
+ )
367
+ # and report
368
+ if len(zero_dist[0]):
369
+ raise DataFormattingError(
370
+ 'Error: Overlapping atoms detected in structure'
371
+ ' at atom numbers:\n' + ', '.join(
372
+ str(i+1) for i in zero_dist[0]
373
+ )
374
+ )
375
+
376
+ return
377
+
378
+
307
379
  def check_moinp_moread(file_name: str | Path) -> None:
308
380
  '''
309
381
  Checks if MORead and/or MOInp are present in the input file.\n
orto/plotter.py CHANGED
@@ -154,7 +154,10 @@ def plot_absorption_spectrum(abs_data: data.AbsorptionData,
154
154
  linefmt=stickcolour
155
155
  )
156
156
  oax.yaxis.set_minor_locator(AutoMinorLocator())
157
- oax.set_ylabel(r'$f_\mathregular{osc}$')
157
+ if normalise:
158
+ oax.set_ylabel(r'Normalised $f_\mathregular{osc}$')
159
+ else:
160
+ oax.set_ylabel(r'$f_\mathregular{osc}$')
158
161
  oax.set_ylim([0., oax.get_ylim()[1]])
159
162
  elif osc_style == 'combined':
160
163
  ax.stem(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orto
3
- Version: 1.8.1
3
+ Version: 1.8.3
4
4
  Summary: A package to make life easier when performing Orca calculations.
5
5
  Home-page: https://orto.kragskow.group
6
6
  Author: Jon Kragskow
@@ -0,0 +1,17 @@
1
+ orto/__init__.py,sha256=IedlltYr3qYZxChNUdz62qogXA9Pos_MUvXdGXqAa0E,41
2
+ orto/__version__.py,sha256=U3WnIim1rPfsaJ6EKERUuRl6DH-DG8tqNKxxzBZArOA,22
3
+ orto/cli.py,sha256=DIEcU9jMP5BPtItaDmb6vS00GJa8amoBxUwUsu6nhrQ,82209
4
+ orto/constants.py,sha256=anxaiTykO8Q_CXliR7zuOAdnXZrQ2-C4ndaviyl7kGc,419
5
+ orto/data.py,sha256=960LHFeG7l626X_WA-8YxvG2toNAsgNvLo86OoYAmBY,14910
6
+ orto/exceptions.py,sha256=D7oNeAEGeJNt5thzt6PaCn5FY6JcbJOWUE1N1LVhhuE,159
7
+ orto/extractor.py,sha256=S27297-gasqLaLbMOqW9sj1X0U0mr3OjikxHcz9Es3o,77867
8
+ orto/input.py,sha256=uUQV6A-8D0GZpRoY1rKK_aUPmk9kVVTnMzTHuisP5t4,11888
9
+ orto/job.py,sha256=SM0nlc_bqhhPvfuuykhMvaUnkwC3Gp-6RvYw_a0TyGc,5855
10
+ orto/plotter.py,sha256=_t9bow6sUMoRAvD6gVFGJTc-_ifW7RmeR0JAPWK_lm4,17799
11
+ orto/utils.py,sha256=GcMZ9uebOSnkPQT_U5O0X49LUtTu8YpXZxEsNKgXNTY,9838
12
+ orto-1.8.3.dist-info/licenses/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
13
+ orto-1.8.3.dist-info/METADATA,sha256=fokjznTSffyKFIn8KxX5G3iItEjjDqMNvbsacMNAukY,1184
14
+ orto-1.8.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
+ orto-1.8.3.dist-info/entry_points.txt,sha256=HXenCglMp_03JkN34pK2phkjXK9CFcXTGHKv5QaVY8I,39
16
+ orto-1.8.3.dist-info/top_level.txt,sha256=hQ-z28gTN_FZ2B5Kiwxr_9cUTcCoib9W5HjbkceDXw4,5
17
+ orto-1.8.3.dist-info/RECORD,,
@@ -1,17 +0,0 @@
1
- orto/__init__.py,sha256=IedlltYr3qYZxChNUdz62qogXA9Pos_MUvXdGXqAa0E,41
2
- orto/__version__.py,sha256=7MCtJDgGo9X0p4xZ0jS5djhQPWK-HOaXAyASTwUa4Fc,22
3
- orto/cli.py,sha256=L2i5FHwXSH8AdE2hZHA0VcqJv1oxxGZ3MUgPSE9Dn_E,81704
4
- orto/constants.py,sha256=anxaiTykO8Q_CXliR7zuOAdnXZrQ2-C4ndaviyl7kGc,419
5
- orto/data.py,sha256=960LHFeG7l626X_WA-8YxvG2toNAsgNvLo86OoYAmBY,14910
6
- orto/exceptions.py,sha256=D7oNeAEGeJNt5thzt6PaCn5FY6JcbJOWUE1N1LVhhuE,159
7
- orto/extractor.py,sha256=d2_pGQeIjK_JbsMINTawUgcO2vcPq0b9uQj9VKuI720,75953
8
- orto/input.py,sha256=N8JbySSVEC_qmXZ7ppJsZ7Z1qel6PfalGYRtnX1hJ6U,9900
9
- orto/job.py,sha256=SM0nlc_bqhhPvfuuykhMvaUnkwC3Gp-6RvYw_a0TyGc,5855
10
- orto/plotter.py,sha256=IATM7vBauT3StFXqk_4DKzCSiTnUunrCeNYRBKM3eUE,17695
11
- orto/utils.py,sha256=GcMZ9uebOSnkPQT_U5O0X49LUtTu8YpXZxEsNKgXNTY,9838
12
- orto-1.8.1.dist-info/licenses/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
13
- orto-1.8.1.dist-info/METADATA,sha256=iFQdVfoNx5SpWOOcw4gC69tj7zewzVcQq4Wugv781xE,1184
14
- orto-1.8.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
- orto-1.8.1.dist-info/entry_points.txt,sha256=HXenCglMp_03JkN34pK2phkjXK9CFcXTGHKv5QaVY8I,39
16
- orto-1.8.1.dist-info/top_level.txt,sha256=hQ-z28gTN_FZ2B5Kiwxr_9cUTcCoib9W5HjbkceDXw4,5
17
- orto-1.8.1.dist-info/RECORD,,
File without changes