orto 1.3.0__tar.gz → 1.5.0__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orto
3
- Version: 1.3.0
3
+ Version: 1.5.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 @@
1
+ __version__ = '1.5.0'
@@ -554,6 +554,127 @@ def gen_job_func(uargs):
554
554
  return
555
555
 
556
556
 
557
+ def plot_xes_func(uargs):
558
+ '''
559
+ Wrapper for CLI plot xes call
560
+
561
+ Parameters
562
+ ----------
563
+ uargs : argparser object
564
+ User arguments
565
+
566
+ Returns
567
+ -------
568
+ None
569
+ '''
570
+ import matplotlib.pyplot as plt
571
+ import matplotlib as mpl
572
+ from . import plotter
573
+ from . import extractor as oe
574
+
575
+ # Set user specified font name
576
+ if os.getenv('orto_fontname'):
577
+ try:
578
+ plt.rcParams['font.family'] = os.getenv('orto_fontname')
579
+ except ValueError:
580
+ ut.cprint('Error in orto_fontname environment variable', 'red')
581
+ sys.exit(1)
582
+
583
+ # Change matplotlib font size to be larger
584
+ mpl.rcParams.update({'font.size': 12})
585
+
586
+ version = oe.OrcaVersionExtractor.extract(uargs.output_file)
587
+
588
+ if not len(version):
589
+ ut.cprint(
590
+ 'Warning: Cannot find version number in Orca output file',
591
+ 'black_yellowbg'
592
+ )
593
+ version = [6, 0, 0]
594
+
595
+ if version[0] >= 6:
596
+ if uargs.intensities == 'electric':
597
+ all_data = oe.XESElectricDipoleExtractor.extract(
598
+ uargs.output_file
599
+ )
600
+ elif uargs.intensities == 'velocity':
601
+ all_data = oe.XESVelocityDipoleExtractor.extract(
602
+ uargs.output_file
603
+ )
604
+ elif uargs.intensities == 'semi-classical':
605
+ all_data = oe.XESSemiClassicalDipoleExtractor.extract(
606
+ uargs.output_file
607
+ )
608
+ elif uargs.intensities == 'so_electric':
609
+ all_data = oe.SOXESElectricDipoleExtractor.extract(
610
+ uargs.output_file
611
+ )
612
+ elif uargs.intensities == 'so_velocity':
613
+ all_data = oe.SOXESVelocityDipoleExtractor.extract(
614
+ uargs.output_file
615
+ )
616
+ elif uargs.intensities == 'so_semi-classical':
617
+ all_data = oe.SOXESSemiClassicalDipoleExtractor.extract(
618
+ uargs.output_file
619
+ )
620
+ elif version[0] < 6:
621
+ ut.cprint('Unsupported version of Orca for XES extraction', 'red')
622
+
623
+ ut.cprint('Using intensities: {}'.format(uargs.intensities), 'cyan')
624
+
625
+ # Plot each section
626
+ for it, data in enumerate(all_data):
627
+
628
+ if len(all_data) > 1:
629
+ save_name = f'emission_spectrum_section_{it:d}.png'
630
+ else:
631
+ save_name = 'emission_spectrum.png'
632
+
633
+ if uargs.x_unit == 'wavenumber':
634
+ x_values = np.asarray(data['energy (cm^-1)'])
635
+ elif uargs.x_unit == 'wavelength':
636
+ x_values = 1E7 / np.asarray(data['energy (cm^-1)'])
637
+ elif uargs.x_unit == 'energy':
638
+ x_values = np.asarray(data['energy (ev)'])
639
+
640
+ data['fosc'] = np.asarray(data['fosc'])
641
+
642
+ # Remove transitions with zero oscillator strength from
643
+ # beginning and end of spectrum
644
+ if not uargs.no_trim:
645
+ # Find first non-zero oscillator strength
646
+ first_nonzero = np.where(data['fosc'] > 1E-6)[0][0]
647
+ # Find last non-zero oscillator strength
648
+ last_nonzero = np.where(data['fosc'] > 1E-6)[0][-1]
649
+
650
+ # Trim data
651
+ x_values = x_values[first_nonzero:last_nonzero + 1]
652
+ data['fosc'] = data['fosc'][first_nonzero:last_nonzero + 1]
653
+
654
+ # Plot emission spectrum
655
+ fig, ax = plotter.plot_abs(
656
+ x_values,
657
+ uargs.x_unit,
658
+ data['fosc'],
659
+ show=_SHOW_CONV[uargs.plot],
660
+ save=_SAVE_CONV[uargs.plot],
661
+ save_name=save_name,
662
+ x_lim=uargs.x_lim,
663
+ y_lim=uargs.y_lim,
664
+ x_shift=uargs.shift,
665
+ linewidth=uargs.linewidth,
666
+ lineshape=uargs.lineshape,
667
+ window_title=f'Emission Spectrum from {uargs.output_file}',
668
+ osc_style=uargs.osc_style,
669
+ normalise=uargs.normalise,
670
+ plot_type='emission'
671
+ )
672
+
673
+ if uargs.x_unit == 'wavenumber':
674
+ ax[0].set_xlim([0, 50000])
675
+ plt.show()
676
+
677
+
557
678
  def plot_abs_func(uargs):
558
679
  '''
559
680
  Wrapper for CLI plot abs call
@@ -593,28 +714,30 @@ def plot_abs_func(uargs):
593
714
  version = [6, 0, 0]
594
715
 
595
716
  if version[0] < 6:
596
- if uargs.intensity_type == 'electric':
717
+ if uargs.intensities == 'electric':
597
718
  all_data = oe.OldAbsorptionElectricDipoleExtractor.extract(
598
719
  uargs.output_file
599
720
  )
600
- elif uargs.intensity_type == 'velocity':
721
+ elif uargs.intensities == 'velocity':
601
722
  all_data = oe.OldAbsorptionVelocityDipoleExtractor.extract(
602
723
  uargs.output_file
603
724
  )
604
725
  elif version[0] >= 6:
605
- if uargs.intensity_type == 'electric':
726
+ if uargs.intensities == 'electric':
606
727
  all_data = oe.AbsorptionElectricDipoleExtractor.extract(
607
728
  uargs.output_file
608
729
  )
609
- elif uargs.intensity_type == 'velocity':
730
+ elif uargs.intensities == 'velocity':
610
731
  all_data = oe.AbsorptionVelocityDipoleExtractor.extract(
611
732
  uargs.output_file
612
733
  )
613
- elif uargs.intensity_type == 'semi-classical':
734
+ elif uargs.intensities == 'semi-classical':
614
735
  all_data = oe.AbsorptionSemiClassicalDipoleExtractor.extract(
615
736
  uargs.output_file
616
737
  )
617
738
 
739
+ ut.cprint('Using intensities: {}'.format(uargs.intensities), 'cyan')
740
+
618
741
  # Plot each section
619
742
  for it, data in enumerate(all_data):
620
743
 
@@ -624,11 +747,25 @@ def plot_abs_func(uargs):
624
747
  save_name = 'absorption_spectrum.png'
625
748
 
626
749
  if uargs.x_unit == 'wavenumber':
627
- x_values = data['energy (cm^-1)']
750
+ x_values = np.asarray(data['energy (cm^-1)'])
628
751
  elif uargs.x_unit == 'wavelength':
629
- x_values = 1E7 / data['energy (cm^-1)']
752
+ x_values = 1E7 / np.asarray(data['energy (cm^-1)'])
630
753
  elif uargs.x_unit == 'energy':
631
- x_values = data['energy (ev)']
754
+ x_values = np.asarray(data['energy (ev)'])
755
+
756
+ data['fosc'] = np.asarray(data['fosc'])
757
+
758
+ # Remove transitions with zero oscillator strength from
759
+ # beginning and end of spectrum
760
+ if not uargs.no_trim:
761
+ # Find first non-zero oscillator strength
762
+ first_nonzero = np.where(data['fosc'] > 1E-6)[0][0]
763
+ # Find last non-zero oscillator strength
764
+ last_nonzero = np.where(data['fosc'] > 1E-6)[0][-1]
765
+
766
+ # Trim data
767
+ x_values = x_values[first_nonzero:last_nonzero + 1]
768
+ data['fosc'] = data['fosc'][first_nonzero:last_nonzero + 1]
632
769
 
633
770
  # Plot absorption spectrum
634
771
  fig, ax = plotter.plot_abs(
@@ -644,8 +781,8 @@ def plot_abs_func(uargs):
644
781
  linewidth=uargs.linewidth,
645
782
  lineshape=uargs.lineshape,
646
783
  window_title=f'Absorption Spectrum from {uargs.output_file}',
647
- show_osc=not uargs.no_osc,
648
- normalise=uargs.normalise_absorption
784
+ osc_style=uargs.osc_style,
785
+ normalise=uargs.normalise
649
786
  )
650
787
 
651
788
  if uargs.x_unit == 'wavenumber':
@@ -1606,7 +1743,7 @@ def read_args(arg_list=None):
1606
1743
  )
1607
1744
 
1608
1745
  plot_abs.add_argument(
1609
- '--intensity_type',
1746
+ '--intensities',
1610
1747
  '-i',
1611
1748
  type=str,
1612
1749
  choices=['velocity', 'electric', 'semi-classical'],
@@ -1626,10 +1763,15 @@ def read_args(arg_list=None):
1626
1763
  )
1627
1764
 
1628
1765
  plot_abs.add_argument(
1629
- '--no_osc',
1630
- action='store_true',
1766
+ '--osc_style',
1767
+ type=str,
1768
+ default='combined',
1631
1769
  help=(
1632
- 'Disables oscillator strength stem plots'
1770
+ 'Style of oscillators to plot\n'
1771
+ ' - \'separate\' plots oscillator strengths as stems on separate axis\n' # noqa
1772
+ ' - \'combined\' plots oscillator strengths on intensity axis\n'
1773
+ ' - \'off\' does not plot oscillator strengths\n'
1774
+ 'Default: %(default)s'
1633
1775
  )
1634
1776
  )
1635
1777
 
@@ -1677,6 +1819,16 @@ def read_args(arg_list=None):
1677
1819
  )
1678
1820
  )
1679
1821
 
1822
+ plot_abs.add_argument(
1823
+ '--no_trim',
1824
+ action='store_true',
1825
+ default=False,
1826
+ help=(
1827
+ 'Do not trim spectrum to non-zero oscillator strength\n'
1828
+ 'Default: %(default)s'
1829
+ )
1830
+ )
1831
+
1680
1832
  plot_abs.add_argument(
1681
1833
  '--x_lim',
1682
1834
  nargs=2,
@@ -1692,12 +1844,147 @@ def read_args(arg_list=None):
1692
1844
  )
1693
1845
 
1694
1846
  plot_abs.add_argument(
1695
- '--normalise_absorption',
1696
- '-na',
1847
+ '--normalise',
1848
+ '-n',
1849
+ action='store_true',
1850
+ default=False,
1851
+ help=(
1852
+ 'Normalises spectrum to maximum value\n'
1853
+ 'Default: %(default)s'
1854
+ )
1855
+ )
1856
+
1857
+ plot_xes = plot_parser.add_parser(
1858
+ 'xes',
1859
+ description='Plots XES from CI calculation output',
1860
+ usage=ut.cstring('orto plot xes <output_file>', 'cyan'),
1861
+ formatter_class=argparse.RawTextHelpFormatter
1862
+ )
1863
+ plot_xes._positionals.title = 'Mandatory Arguments'
1864
+
1865
+ plot_xes.set_defaults(func=plot_xes_func)
1866
+
1867
+ plot_xes.add_argument(
1868
+ 'output_file',
1869
+ type=pathlib.Path,
1870
+ help='Orca output file name'
1871
+ )
1872
+
1873
+ plot_xes.add_argument(
1874
+ '--intensities',
1875
+ '-i',
1876
+ type=str,
1877
+ choices=[
1878
+ 'velocity',
1879
+ 'electric',
1880
+ 'semi-classical',
1881
+ 'so_velocity',
1882
+ 'so_electric',
1883
+ 'so_semi-classical',
1884
+ ],
1885
+ default='electric',
1886
+ help='Type of intensity to plot (orca_mapspc uses electric)'
1887
+ )
1888
+
1889
+ plot_xes.add_argument(
1890
+ '--linewidth',
1891
+ '-lw',
1892
+ type=float,
1893
+ default=2000,
1894
+ help=(
1895
+ 'Width of signal (FWHM for Gaussian, Width for Lorentzian),'
1896
+ ' in Wavenumbers'
1897
+ )
1898
+ )
1899
+
1900
+ plot_xes.add_argument(
1901
+ '--osc_style',
1902
+ type=str,
1903
+ default='combined',
1904
+ help=(
1905
+ 'Style of oscillators to plot\n'
1906
+ ' - \'separate\' plots oscillator strengths as stems on separate axis\n' # noqa
1907
+ ' - \'combined\' plots oscillator strengths on intensity axis\n'
1908
+ ' - \'off\' does not plot oscillator strengths\n'
1909
+ 'Default: %(default)s'
1910
+ )
1911
+ )
1912
+
1913
+ plot_xes.add_argument(
1914
+ '--plot',
1915
+ '-p',
1916
+ choices=['on', 'show', 'save', 'off'],
1917
+ metavar='<str>',
1918
+ type=str,
1919
+ default='on',
1920
+ help=(
1921
+ 'Controls plot appearance/save \n'
1922
+ ' - \'on\' shows and saves the plots\n'
1923
+ ' - \'show\' shows the plots\n'
1924
+ ' - \'save\' saves the plots\n'
1925
+ ' - \'off\' neither shows nor saves\n'
1926
+ 'Default: %(default)s'
1927
+ )
1928
+ )
1929
+
1930
+ plot_xes.add_argument(
1931
+ '--lineshape',
1932
+ '-ls',
1933
+ type=str,
1934
+ choices=['gaussian', 'lorentzian'],
1935
+ default='lorentzian',
1936
+ help='Lineshape to use for each signal'
1937
+ )
1938
+
1939
+ plot_xes.add_argument(
1940
+ '--x_unit',
1941
+ type=str,
1942
+ choices=['wavenumber', 'energy', 'wavelength'],
1943
+ default='wavenumber',
1944
+ help='x units to use for spectrum'
1945
+ )
1946
+
1947
+ plot_xes.add_argument(
1948
+ '--shift',
1949
+ type=float,
1950
+ default=0.,
1951
+ help=(
1952
+ 'Shift spectrum by this amount in x units\n'
1953
+ 'Default: %(default)s'
1954
+ )
1955
+ )
1956
+
1957
+ plot_xes.add_argument(
1958
+ '--no_trim',
1959
+ action='store_true',
1960
+ default=False,
1961
+ help=(
1962
+ 'Do not trim spectrum to non-zero oscillator strength\n'
1963
+ 'Default: %(default)s'
1964
+ )
1965
+ )
1966
+
1967
+ plot_xes.add_argument(
1968
+ '--x_lim',
1969
+ nargs=2,
1970
+ default=['auto', 'auto'],
1971
+ help='x limits of spectrum'
1972
+ )
1973
+
1974
+ plot_xes.add_argument(
1975
+ '--y_lim',
1976
+ nargs=2,
1977
+ default=[0., 'auto'],
1978
+ help='Epsilon limits of spectrum in cm^-1 mol^-1 L'
1979
+ )
1980
+
1981
+ plot_xes.add_argument(
1982
+ '--normalise',
1983
+ '-n',
1697
1984
  action='store_true',
1698
1985
  default=False,
1699
1986
  help=(
1700
- 'Normalises absorption spectrum to maximum value\n'
1987
+ 'Normalises spectrum to maximum value\n'
1701
1988
  'Default: %(default)s'
1702
1989
  )
1703
1990
  )
@@ -1575,6 +1575,72 @@ class OldAbsorptionVelocityDipoleExtractor(OldAbsorptionElectricDipoleExtractor)
1575
1575
  END_PATTERN = rb'(?=-{77})'
1576
1576
 
1577
1577
 
1578
+ class XESElectricDipoleExtractor(AbsorptionElectricDipoleExtractor):
1579
+ '''
1580
+ Extracts X-RAY EMISSION SPECTRUM VIA TRANSITION ELECTRIC DIPOLE MOMENTS table\n # noqa
1581
+ from ORCA output file for versions newer than 6.
1582
+ '''
1583
+
1584
+ # Regex Start Pattern
1585
+ START_PATTERN = rb'(?<= X-RAY EMISSION SPECTRUM VIA TRANSITION VELOCITY DIPOLE MOMENTS\s[\S\s]{408}\s)' # noqa
1586
+
1587
+ # Regex End Pattern
1588
+ END_PATTERN = rb'(?=-{77})'
1589
+
1590
+
1591
+ class XESVelocityDipoleExtractor(AbsorptionElectricDipoleExtractor):
1592
+ '''
1593
+ Extracts X-RAY EMISSION SPECTRUM VIA TRANSITION VELOCITY DIPOLE MOMENTS table\n # noqa
1594
+ from ORCA output file for versions newer than 6.
1595
+ '''
1596
+
1597
+ # Regex Start Pattern
1598
+ START_PATTERN = rb'(?<= X-RAY EMISSION SPECTRUM VIA TRANSITION VELOCITY DIPOLE MOMENTS\s[\S\s]{415}\s)' # noqa
1599
+
1600
+
1601
+ class SOXESElectricDipoleExtractor(AbsorptionElectricDipoleExtractor):
1602
+ '''
1603
+ Extracts SPIN-ORBIT X-RAY EMISSION SPECTRUM VIA TRANSITION ELECTRIC DIPOLE MOMENTS table\n # noqa
1604
+ from ORCA output file for versions newer than 6.
1605
+ '''
1606
+
1607
+ # Regex Start Pattern
1608
+ START_PATTERN = rb'(?<=SPIN-ORBIT X-RAY EMISSION SPECTRUM VIA TRANSITION ELECTRIC DIPOLE MOMENTS\s[\S\s]{415}\s)' # noqa
1609
+
1610
+ # Regex End Pattern
1611
+ END_PATTERN = rb'(?=-{77})'
1612
+
1613
+
1614
+ class SOXESVelocityDipoleExtractor(AbsorptionElectricDipoleExtractor):
1615
+ '''
1616
+ Extracts SPIN-ORBIT X-RAY EMISSION SPECTRUM VIA TRANSITION VELOCITY DIPOLE MOMENTS table\n # noqa
1617
+ from ORCA output file for versions newer than 6.
1618
+ '''
1619
+
1620
+ # Regex Start Pattern
1621
+ START_PATTERN = rb'(?<=SPIN-ORBIT X-RAY EMISSION SPECTRUM VIA TRANSITION VELOCITY DIPOLE MOMENTS\s[\S\s]{408}\s)' # noqa
1622
+
1623
+
1624
+ class XESSemiClassicalDipoleExtractor(AbsorptionSemiClassicalDipoleExtractor):
1625
+ '''
1626
+ Extracts X-RAY EMISSION SPECTRUM VIA FULL SEMI-CLASSICAL FORMULATION table\n # noqa
1627
+ from ORCA output file for versions newer than 6.
1628
+ '''
1629
+
1630
+ # Regex Start Pattern
1631
+ START_PATTERN = rb'(?<= X-RAY EMISSION SPECTRUM VIA FULL SEMI-CLASSICAL FORMULATION\s[\S\s]{408}\s)' # noqa
1632
+
1633
+
1634
+ class SOXESSemiClassicalDipoleExtractor(AbsorptionSemiClassicalDipoleExtractor): # noqa
1635
+ '''
1636
+ Extracts SPIN-ORBIT X-RAY EMISSION SPECTRUM VIA TRANSITION VELOCITY DIPOLE MOMENTS table\n # noqa
1637
+ from ORCA output file for versions newer than 6.
1638
+ '''
1639
+
1640
+ # Regex Start Pattern
1641
+ START_PATTERN = rb'(?<= SPIN-ORBIT X-RAY EMISSION SPECTRUM VIA FULL SEMI-CLASSICAL FORMULATION\s[\S\s]{408}\s)' # noqa
1642
+
1643
+
1578
1644
  class HessNameInputExtractor(extto.LineExtractor):
1579
1645
  '''
1580
1646
  Extracts Hessian file name from %mtr block of input file
@@ -4,6 +4,7 @@ from matplotlib.ticker import AutoMinorLocator
4
4
  import numpy as np
5
5
  from numpy.typing import ArrayLike, NDArray
6
6
  import itertools
7
+ import pathlib
7
8
 
8
9
  from . import utils as ut
9
10
 
@@ -81,9 +82,11 @@ def plot_abs(x_values: ArrayLike, x_type: str, foscs: ArrayLike,
81
82
  abs_type: str = 'napierian',
82
83
  y_lim: list[float] = [0., 'auto'],
83
84
  x_shift: float = 0., normalise: bool = False,
84
- show_osc: bool = True, save: bool = False,
85
+ osc_style: str = 'separate', save: bool = False,
85
86
  save_name: str = 'absorption_spectrum.png', show: bool = False,
86
- window_title: str = 'Absorption Spectrum') -> tuple[plt.Figure, list[plt.Axes]]: # noqa
87
+ verbose: bool = True,
88
+ window_title: str = 'Absorption Spectrum',
89
+ plot_type: str = 'absorption') -> tuple[plt.Figure, list[plt.Axes]]: # noqa
87
90
  '''
88
91
  Plots absorption spectrum with intensity specified by oscillator strength.\n # noqa
89
92
  Spectrum is computed as a sum of Gaussian or Lorentzian lineshapes.\n
@@ -112,16 +115,23 @@ def plot_abs(x_values: ArrayLike, x_type: str, foscs: ArrayLike,
112
115
  Absorbance (and epsilon) type to use. Orca_mapspc uses napierian
113
116
  normalise: bool, default False
114
117
  If True, normalise the absorption spectrum to the maximum value.
115
- show_osc: bool, default True
116
- If True, show oscillator strength stemplots
118
+ osc_style: str, default 'separate'
119
+ Style of oscillator strength plots:
120
+ - 'separate': plots oscillator strengths as stems on separate axis
121
+ - 'combined': plots oscillator strengths on intensity axis
122
+ - 'off': does not plot oscillator strengths
117
123
  save: bool, default False
118
124
  If True, plot is saved to save_name
119
- save_name: str
125
+ save_name: str | pathlib.Path, default 'absorption_spectrum.png'
120
126
  If save is True, plot is saved to this location/filename
121
127
  show: bool, default False
122
128
  If True, plot is shown on screen
129
+ verbose: bool, default True
130
+ If True, plot file location is written to terminal
123
131
  window_title: str, default 'UV-Visible Absorption Spectrum'
124
132
  Title of figure window, not of plot
133
+ plot_type: str, default 'absorption'
134
+ Type of plot to create, either 'absorption' or 'emission'.
125
135
 
126
136
  Returns
127
137
  -------
@@ -132,6 +142,8 @@ def plot_abs(x_values: ArrayLike, x_type: str, foscs: ArrayLike,
132
142
  Matplotlib Axis object for twinx oscillator strength axis
133
143
  '''
134
144
 
145
+ save_name = pathlib.Path(save_name)
146
+
135
147
  x_values = np.asarray(x_values) + x_shift
136
148
  foscs = np.asarray(foscs)
137
149
  if len(x_values) != len(foscs):
@@ -195,24 +207,51 @@ def plot_abs(x_values: ArrayLike, x_type: str, foscs: ArrayLike,
195
207
  if normalise:
196
208
  # Normalise the spectrum to the maximum value
197
209
  spectrum /= np.max(spectrum)
198
- ax.set_ylabel('Normalised Absorbance (arbitrary units)') # noqa
210
+ ax.set_ylabel(
211
+ 'Normalised {} (arbitrary units)'.format(
212
+ plot_type.capitalize()
213
+ )
214
+ ) # noqa
199
215
  else:
200
216
  ax.set_ylabel(r'$\epsilon$ (cm$^\mathregular{-1}$ mol$^\mathregular{-1}$ L)') # noqa
201
217
 
202
- np.savetxt('spectrum.txt', np.vstack([x_grid, spectrum]).T, fmt='%.5f')
218
+ _txt_save_name = save_name.with_suffix('.txt')
219
+ np.savetxt(
220
+ _txt_save_name,
221
+ np.vstack([x_grid, spectrum]).T,
222
+ fmt='%.5f',
223
+ header=f'{plot_type.capitalize()} spectrum data\nx (wavenumber, wavelength or energy), y (absorbance)' # noqa
224
+ )
225
+ if verbose:
226
+ ut.cprint(
227
+ f'\n{plot_type.capitalize()} spectrum data saved to\n {_txt_save_name}', # noqa
228
+ 'cyan'
229
+ )
203
230
 
204
231
  # Main spectrum
205
232
  ax.plot(x_grid, spectrum, color='k')
206
233
 
207
- if show_osc:
234
+ if osc_style == 'separate':
208
235
  fax = ax.twinx()
209
236
  # Oscillator strength twin axis
210
- plt.stem(x_values, foscs, basefmt=' ')
237
+ fax.stem(x_values, foscs, basefmt=' ', markerfmt=' ')
211
238
  fax.yaxis.set_minor_locator(AutoMinorLocator())
212
239
  fax.set_ylabel(r'$f_\mathregular{osc}$')
213
240
  fax.set_ylim([0., fax.get_ylim()[1]])
241
+ elif osc_style == 'combined':
242
+ fax = None
243
+ plt.subplots_adjust(right=0.2)
244
+ ax.stem(
245
+ x_values,
246
+ foscs/np.max(foscs) * np.max(spectrum),
247
+ basefmt=' ',
248
+ markerfmt=' '
249
+ )
250
+ ax.spines['right'].set_visible(False)
251
+ ax.spines['top'].set_visible(False)
214
252
  else:
215
253
  fax = None
254
+ # No oscillator strength plot
216
255
  plt.subplots_adjust(right=0.2)
217
256
  ax.spines['right'].set_visible(False)
218
257
  ax.spines['top'].set_visible(False)
@@ -245,6 +284,11 @@ def plot_abs(x_values: ArrayLike, x_type: str, foscs: ArrayLike,
245
284
 
246
285
  if save:
247
286
  plt.savefig(save_name, dpi=500)
287
+ if verbose:
288
+ ut.cprint(
289
+ f'\n{plot_type.capitalize()} spectrum saved to\n {save_name}',
290
+ 'cyan'
291
+ )
248
292
 
249
293
  if show:
250
294
  plt.show()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orto
3
- Version: 1.3.0
3
+ Version: 1.5.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
@@ -8,7 +8,7 @@ Please see the `orto` documentation for more details.
8
8
 
9
9
  # DO NOT EDIT THIS NUMBER!
10
10
  # IT IS AUTOMATICALLY CHANGED BY python-semantic-release
11
- __version__ = '1.3.0'
11
+ __version__ = '1.5.0'
12
12
 
13
13
  setuptools.setup(
14
14
  name='orto',
@@ -1 +0,0 @@
1
- __version__ = '1.3.0'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes