orto 1.8.3__py3-none-any.whl → 1.10.0__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.3'
1
+ __version__ = '1.10.0'
orto/cli.py CHANGED
@@ -11,6 +11,7 @@ import numpy as np
11
11
  import re
12
12
  from mmap import mmap, ACCESS_READ
13
13
  from shutil import move as shutilmove
14
+ from subto.job import SlurmJob
14
15
 
15
16
  from . import job
16
17
  from . import utils as ut
@@ -216,9 +217,16 @@ def extract_gmatrix_func(uargs, save=True):
216
217
  'L': oe.GMatrixLExtractor,
217
218
  'S': oe.GMatrixSExtractor,
218
219
  'eff': oe.GMatrixEffectiveExtractor,
220
+ 'dft': oe.GMatrixDFTExtractor
219
221
  }
220
222
 
221
- all_data = choices[uargs.type]().extract(uargs.output_file)
223
+ if oe.EPRNMRDetector(uargs.output_file):
224
+ uargs.type = 'dft'
225
+
226
+ try:
227
+ all_data = choices[uargs.type]().extract(uargs.output_file)
228
+ except (DataFormattingError, ValueError) as e:
229
+ ut.red_exit(str(e))
222
230
 
223
231
  if not save:
224
232
  for it, data in enumerate(all_data):
@@ -329,6 +337,86 @@ def extract_gmatrix_func(uargs, save=True):
329
337
  return
330
338
 
331
339
 
340
+ def gen_spden_func(uargs):
341
+ '''
342
+ Wrapper for CLI gen spin density call
343
+
344
+ Parameters
345
+ ----------
346
+ uargs : argparser object
347
+ User arguments
348
+
349
+ Returns
350
+ -------
351
+ None
352
+ '''
353
+
354
+ # Check orca module
355
+ if len(uargs.orca_load):
356
+ orca_load_val = copy.copy(uargs.orca_load)
357
+ elif os.getenv('orto_orca_load'):
358
+ try:
359
+ if len(os.getenv('orto_orca_load')):
360
+ orca_load_val = os.getenv('orto_orca_load')
361
+ except ValueError:
362
+ ut.red_exit(
363
+ (
364
+ 'Error in orto_orca_load environment variable'
365
+ )
366
+ )
367
+ else:
368
+ ut.red_exit(
369
+ (
370
+ 'Missing orto_orca_load environment variable or '
371
+ '--orca_load argument'
372
+ )
373
+ )
374
+
375
+ # Create string of command numbers for orca plot to follow
376
+ command_nums = '1\\n3\\ny\\n4'
377
+ command_nums += f'\\n{uargs.n_pts:d}'
378
+ command_nums += '\\n5\\n7\\n11\\n12\\n'
379
+
380
+ # Generate job file for orca_plot
381
+ spin_job = SlurmJob(
382
+ pathlib.Path(f'{uargs.gbw_file.stem}_spin_density_job.sh')
383
+ )
384
+
385
+ # Create content of job
386
+ spin_job.content_block = ''
387
+
388
+ spin_job.content_block += '# Load orca module\n'
389
+ spin_job.content_block += f'module load {orca_load_val}\n'
390
+ spin_job.content_block += '# Run orca_plot to generate spin density cube file\n' # noqa
391
+ spin_job.content_block += f'time mpirun -np {uargs.n_procs:d} $(which orca_plot_mpi) {uargs.gbw_file.name} -i aa <<< $\'{command_nums}\'\n\n' # noqa
392
+
393
+ # Set job name
394
+ spin_job.job_name = f'{uargs.gbw_file.stem}_spin_density'
395
+
396
+ spin_job.ntasks_per_node = str(uargs.n_procs)
397
+ spin_job.mem_per_cpu = str(uargs.memory)
398
+
399
+ spin_job.error = f'{uargs.gbw_file.stem}_spin_density.%j.e'
400
+ spin_job.output = f'{uargs.gbw_file.stem}_spin_density.%j.o'
401
+
402
+ # Write job script
403
+ # with submitter configuration options specified
404
+ spin_job.write_script(True)
405
+
406
+ # Submit to queue
407
+ if not uargs.no_sub:
408
+ subprocess.call(
409
+ 'cd {}; {} "{}"; cd ../'.format(
410
+ uargs.gbw_file.parents[0],
411
+ spin_job.SUBMIT_COMMAND,
412
+ spin_job.file_path
413
+ ),
414
+ shell=True
415
+ )
416
+
417
+ return
418
+
419
+
332
420
  def gen_trunc_molden_func(uargs):
333
421
  '''
334
422
  Wrapper for CLI gen truncmolden call
@@ -1649,6 +1737,7 @@ def read_args(arg_list=None):
1649
1737
 
1650
1738
  extract_coords = extract_parser.add_parser(
1651
1739
  'coords',
1740
+ aliases=['coord'],
1652
1741
  description='Extracts coordinates from Orca output file',
1653
1742
  formatter_class=argparse.RawTextHelpFormatter,
1654
1743
  usage=ut.cstring('orto extract coords <output_file> [options]', 'cyan')
@@ -1818,6 +1907,71 @@ def read_args(arg_list=None):
1818
1907
  )
1819
1908
  )
1820
1909
 
1910
+ gen_spden = gen_parser.add_parser(
1911
+ 'spdens',
1912
+ aliases=['spin_density', 'spden'],
1913
+ description='Generate spin density cube file from gbw file', # noqa
1914
+ usage=ut.cstring(
1915
+ 'orto gen spdens <gbw_file> <n_procs> [options]',
1916
+ 'cyan'
1917
+ ),
1918
+ formatter_class=argparse.RawTextHelpFormatter
1919
+ )
1920
+ gen_spden._positionals.title = 'Mandatory Arguments'
1921
+ gen_spden.set_defaults(func=gen_spden_func)
1922
+
1923
+ gen_spden.add_argument(
1924
+ 'gbw_file',
1925
+ type=pathlib.Path,
1926
+ help='Orca gbw file name'
1927
+ )
1928
+
1929
+ gen_spden.add_argument(
1930
+ 'n_procs',
1931
+ type=int,
1932
+ help='Number of processors/cores used in calculation',
1933
+ default=1
1934
+ )
1935
+
1936
+ gen_spden.add_argument(
1937
+ '--n_pts',
1938
+ '-n',
1939
+ type=int,
1940
+ default=100,
1941
+ help=(
1942
+ 'Number of points in each dimension of cube file\n'
1943
+ 'Default: %(default)s'
1944
+ )
1945
+ )
1946
+
1947
+ gen_spden.add_argument(
1948
+ '--memory',
1949
+ '-mem',
1950
+ type=int,
1951
+ default=500,
1952
+ help=(
1953
+ 'Per-core Memory to use in MB\n'
1954
+ 'Default: %(default)s'
1955
+ )
1956
+ )
1957
+
1958
+ gen_spden.add_argument(
1959
+ '-om',
1960
+ '--orca_load',
1961
+ type=str,
1962
+ default='',
1963
+ help='Orca environment module (overrides ORTO_ORCA_LOAD envvar)'
1964
+ )
1965
+
1966
+ gen_spden.add_argument(
1967
+ '--no_sub',
1968
+ '-ns',
1969
+ action='store_true',
1970
+ help=(
1971
+ 'Disables submission of job to queue'
1972
+ )
1973
+ )
1974
+
1821
1975
  gen_job = gen_parser.add_parser(
1822
1976
  'job',
1823
1977
  description=(
@@ -2364,6 +2518,7 @@ def read_args(arg_list=None):
2364
2518
 
2365
2519
  plot_ailft = plot_parser.add_parser(
2366
2520
  'ailft_orbs',
2521
+ aliases=['ailft_orb'],
2367
2522
  description='Plots AI-LFT orbital energies from output file',
2368
2523
  usage=ut.cstring(
2369
2524
  'orto plot ailft_orbs <output_file> [options]',
orto/extractor.py CHANGED
@@ -14,6 +14,19 @@ from .exceptions import DataFormattingError
14
14
  from . import constants as const
15
15
 
16
16
 
17
+ def EPRNMRDetector(file_name: str | pathlib.Path) -> bool:
18
+ '''
19
+ Detects if Orca output file is from EPR/NMR calculation
20
+ '''
21
+ with open(file_name, 'rb') as f:
22
+ file_content = f.read()
23
+
24
+ if re.search(rb'%EPRNMR', file_content):
25
+ return True
26
+ else:
27
+ return False
28
+
29
+
17
30
  class OrcaVersionExtractor(extto.LineExtractor):
18
31
  '''
19
32
  Extracts Orca version from output file
@@ -2421,6 +2434,100 @@ class SimpleInputExtractor(extto.LineExtractor):
2421
2434
  return _ext.data
2422
2435
 
2423
2436
 
2437
+ class GMatrixDFTExtractor(extto.BetweenExtractor):
2438
+ '''
2439
+ Extracts DFT ELECTRONIC G-MATRIX block from output file
2440
+ '''
2441
+
2442
+ # Regex Start Pattern
2443
+ START_PATTERN = rb'(?<=ELECTRONIC G-MATRIX\s[\S\s]{19}\s)'
2444
+
2445
+ # Regex End Pattern
2446
+ END_PATTERN = rb'(?=EPR g-tensor done in)'
2447
+
2448
+ @property
2449
+ def data(self) -> dict[str, NDArray]:
2450
+ '''
2451
+ G Matrix data:\n
2452
+ A dictionary with keys:\n
2453
+ matrix\n
2454
+ values\n
2455
+ vectors
2456
+ All values are ndarray of floats
2457
+ '''
2458
+ return self._data
2459
+
2460
+ @staticmethod
2461
+ def _process_block(block: str) -> dict[str, NDArray]:
2462
+ '''
2463
+ Converts single block into data entries described in self.data
2464
+
2465
+ Parameters
2466
+ ----------
2467
+ block: str
2468
+ String block extracted from file
2469
+
2470
+ Returns
2471
+ -------
2472
+ dict[str, NDArray]
2473
+ '''
2474
+
2475
+ # Trim block to lines after Orientation:
2476
+
2477
+ block = block.split('The g-matrix:')[-1]
2478
+
2479
+ # Get Matrix
2480
+ _matrix = re.findall(
2481
+ r'(\s-?\d\.\d{7}\s+-?\d\.\d{7}\s+-?\d\.\d{7})',
2482
+ block
2483
+ )[:3]
2484
+
2485
+ # Convert to matrix of floats
2486
+ matrix = np.asarray([
2487
+ [float(v) for v in val.split()]
2488
+ for val in _matrix
2489
+ ])
2490
+
2491
+ if matrix.shape != (3, 3):
2492
+ raise DataFormattingError(
2493
+ 'G-matrix is not the correct shape (3x3)'
2494
+ )
2495
+
2496
+ # Diagonalise g.g^T
2497
+ vals, vecs = la.eigh(matrix @ matrix.T)
2498
+
2499
+ # get g values as sqrt of eigenvalues of g.g^T
2500
+ vals = np.sqrt(vals)
2501
+
2502
+ data = {
2503
+ 'matrix': matrix,
2504
+ 'values': vals,
2505
+ 'vectors': vecs
2506
+ }
2507
+
2508
+ return data
2509
+
2510
+ @classmethod
2511
+ def extract(cls, file_name: str | pathlib.Path) -> list[dict[str, NDArray]]: # noqa
2512
+ '''
2513
+ Convenience method which instantiates class, extracts blocks, and
2514
+ returns processed datasets
2515
+
2516
+ Parameters
2517
+ ----------
2518
+ file_name: str | pathlib.Path
2519
+ File to parse
2520
+
2521
+ Returns
2522
+ -------
2523
+ list[dict[str, NDArray]]
2524
+ Each entry contains processed data, as defined in cls.data
2525
+ '''
2526
+ _ext = cls()
2527
+ _ext(file_name, process=True)
2528
+ return _ext.data
2529
+
2530
+
2424
2531
  class GMatrixExtractor(extto.BetweenExtractor):
2425
2532
  '''
2426
2533
  Extracts ELECTRONIC G-MATRIX block from output file
@@ -2471,6 +2578,11 @@ class GMatrixExtractor(extto.BetweenExtractor):
2471
2578
  for val in _matrix
2472
2579
  ])
2473
2580
 
2581
+ if matrix.shape != (3, 3):
2582
+ raise DataFormattingError(
2583
+ 'G-matrix is not the correct shape (3x3)'
2584
+ )
2585
+
2474
2586
  # Diagonalise g.g^T
2475
2587
  vals, vecs = la.eigh(matrix @ matrix.T)
2476
2588
 
orto/job.py CHANGED
@@ -29,7 +29,7 @@ class OrcaJob():
29
29
  Orca output file name. Default is same as input with extension \n
30
30
  replaced by .out
31
31
  job_file: pathlib.Path
32
- Submission script name. Default is same as input with extension \n
32
+ Submission script file path. Default is same as input with extension \n
33
33
  replaced by scheduler job file extension e.g. '.slm'
34
34
  job_name: str
35
35
  Job name. Default is same as input without extension
@@ -99,6 +99,9 @@ class OrcaJob():
99
99
 
100
100
  @property
101
101
  def job_file(self) -> pathlib.Path:
102
+ '''
103
+ The submission script file path
104
+ '''
102
105
  return self._job_file
103
106
 
104
107
  @job_file.setter
@@ -164,7 +167,7 @@ class OrcaJob():
164
167
  verbose: bool, default True
165
168
  If True, jobscript location is written to screen
166
169
  **kwargs
167
- The keyword arguments are passed to `subto.job.Job` constructor
170
+ Keyword arguments passed to `subto.job.Job` constructor
168
171
  '''
169
172
 
170
173
  if len(self.load):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orto
3
- Version: 1.8.3
3
+ Version: 1.10.0
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=ZXE8njb1SRoMJuadNA6KRGRdfAFsM49XLsgr_fSOXts,23
3
+ orto/cli.py,sha256=XBeO5dTWaZP_mnNA5IR2eZBcnhHEtwW6IuFtLgUPMkA,86309
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=oqRdDWLaVPIwB4aZ5nrITWexx60hKn0zghACmymwVfM,80618
8
+ orto/input.py,sha256=uUQV6A-8D0GZpRoY1rKK_aUPmk9kVVTnMzTHuisP5t4,11888
9
+ orto/job.py,sha256=tDiz9omFwinoYJamgz66MZez0Ee9HMhuCIAeHMhXRF8,5916
10
+ orto/plotter.py,sha256=_t9bow6sUMoRAvD6gVFGJTc-_ifW7RmeR0JAPWK_lm4,17799
11
+ orto/utils.py,sha256=GcMZ9uebOSnkPQT_U5O0X49LUtTu8YpXZxEsNKgXNTY,9838
12
+ orto-1.10.0.dist-info/licenses/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
13
+ orto-1.10.0.dist-info/METADATA,sha256=2qdWW5pyurXxTVD-6GXUSvuxZhLJ2BTbkGUtDdPJVoQ,1185
14
+ orto-1.10.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
+ orto-1.10.0.dist-info/entry_points.txt,sha256=HXenCglMp_03JkN34pK2phkjXK9CFcXTGHKv5QaVY8I,39
16
+ orto-1.10.0.dist-info/top_level.txt,sha256=hQ-z28gTN_FZ2B5Kiwxr_9cUTcCoib9W5HjbkceDXw4,5
17
+ orto-1.10.0.dist-info/RECORD,,
@@ -1,17 +0,0 @@
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,,
File without changes