orto 1.11.1__tar.gz → 1.11.3__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.11.1
3
+ Version: 1.11.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 @@
1
+ __version__ = '1.11.3'
@@ -929,6 +929,8 @@ def plot_xes_func(uargs):
929
929
  x_values = np.asarray(data['energy (cm^-1)'])
930
930
  elif uargs.x_unit == 'wavelength':
931
931
  x_values = 1E7 / np.asarray(data['energy (cm^-1)'])
932
+ elif uargs.x_unit == 'wavelength_rev':
933
+ x_values = 1E7 / np.asarray(data['energy (cm^-1)'])
932
934
  elif uargs.x_unit == 'energy':
933
935
  x_values = np.asarray(data['energy (ev)'])
934
936
 
@@ -1096,42 +1098,12 @@ def plot_abs_func(uargs, save_data_only=False):
1096
1098
  -------
1097
1099
  None
1098
1100
  '''
1099
- import matplotlib.pyplot as plt
1100
- import matplotlib as mpl
1101
- import matplotlib.colors as mcolors
1102
1101
  from . import plotter
1103
1102
  from . import extractor as oe
1104
1103
  from . import data as d
1105
1104
 
1106
- # Change matplotlib font size to be larger
1107
- mpl.rcParams.update({'font.size': 12})
1108
- # Set user specified font name
1109
- ut.check_font_envvar()
1110
-
1111
- # Change matplotlib font size to be larger
1112
- mpl.rcParams.update({'font.size': 12})
1113
-
1114
- if len(uargs.output_file) == 1:
1115
- colours = ['black']
1116
- else:
1117
- colours = list(mcolors.TABLEAU_COLORS.values())
1118
-
1119
- fig, ax = plt.subplots(1, 1, figsize=(6, 4))
1120
- oax = ax.twinx()
1121
-
1122
- # Find unique name from multiple file names
1123
- if len(uargs.output_file) > 1:
1124
- if uargs.unique_names:
1125
- base_names = [of.stem for of in uargs.output_file]
1126
- unique_names = ut.find_unique_substring(base_names)
1127
- else:
1128
- unique_names = [of.stem for of in uargs.output_file]
1129
- legend = True
1130
- else:
1131
- legend = False
1132
- unique_names = ['']
1133
1105
 
1134
- # Handle x_shift argument
1106
+ # Process x_shift argument
1135
1107
  if uargs.x_shift is None:
1136
1108
  uargs.x_shift = [0.0 for _ in uargs.output_file]
1137
1109
  elif len(uargs.x_shift) != len(uargs.output_file):
@@ -1139,6 +1111,10 @@ def plot_abs_func(uargs, save_data_only=False):
1139
1111
  'Number of x_shift values must match number of output files'
1140
1112
  )
1141
1113
 
1114
+ # Create dictionary to hold absorption data for plotting later
1115
+ spectra_dict = {}
1116
+
1117
+ # Extract data from each output file
1142
1118
  for it, output_file in enumerate(uargs.output_file):
1143
1119
 
1144
1120
  version = oe.OrcaVersionExtractor.extract(output_file)
@@ -1150,6 +1126,9 @@ def plot_abs_func(uargs, save_data_only=False):
1150
1126
  )
1151
1127
  version = [6, 0, 0]
1152
1128
 
1129
+ # Extract absorption data from file
1130
+ # using appropriate extractor for version
1131
+ # and intensity type
1153
1132
  if version[0] < 6:
1154
1133
  if uargs.intensities == 'electric':
1155
1134
  all_datasets = oe.OldAbsorptionElectricDipoleExtractor.extract(
@@ -1175,6 +1154,9 @@ def plot_abs_func(uargs, save_data_only=False):
1175
1154
 
1176
1155
  ut.cprint('Using intensities: {}'.format(uargs.intensities), 'cyan')
1177
1156
 
1157
+ # Create absorption data object
1158
+ # one per dataset extracted
1159
+ # (doubtful multiple datasets will be present, but just in case)
1178
1160
  all_abs_data = [
1179
1161
  d.AbsorptionData.from_extractor_dataset(
1180
1162
  dataset,
@@ -1184,10 +1166,12 @@ def plot_abs_func(uargs, save_data_only=False):
1184
1166
  for dataset in all_datasets
1185
1167
  ]
1186
1168
 
1169
+ # Check absorption data was found
1187
1170
  if len(all_abs_data) == 0:
1188
1171
  ut.red_exit(
1189
1172
  f'No ABSORPTION data found in file {output_file}', 'red'
1190
1173
  )
1174
+ # report if multiple absorption sections found
1191
1175
  elif len(all_abs_data) > 1:
1192
1176
  ut.cprint(
1193
1177
  f'Found {len(all_abs_data)} ABSORPTION sections in '
@@ -1195,23 +1179,35 @@ def plot_abs_func(uargs, save_data_only=False):
1195
1179
  f'Plotting final section ONLY',
1196
1180
  'cyan'
1197
1181
  )
1198
-
1182
+ # and only use final one
1183
+ # (again, doubtful multiple sections will be present, but just in case)
1199
1184
  abs_data = all_abs_data[-1]
1200
1185
 
1186
+ # Determine x values for setting x limits of computed spectrum
1201
1187
  if uargs.x_unit == 'wavenumber':
1202
1188
  x_vals = abs_data.wavenumbers
1203
1189
  min_factor = 0.8
1204
1190
  max_factor = 1.1
1191
+ x_reversed = False
1205
1192
  elif uargs.x_unit == 'wavelength':
1206
1193
  x_vals = abs_data.wavelengths
1207
1194
  max_factor = 1.1
1208
1195
  min_factor = 0.8
1196
+ x_reversed = False
1197
+ elif uargs.x_unit == 'wavelength_rev':
1198
+ x_vals = abs_data.wavelengths
1199
+ max_factor = 1.1
1200
+ min_factor = 0.8
1201
+ x_reversed = True
1202
+ uargs.x_unit = 'wavelength'
1209
1203
  elif uargs.x_unit == 'energy':
1210
1204
  x_vals = abs_data.energies
1211
1205
  min_factor = 0.9995
1212
1206
  max_factor = 1.0005
1207
+ x_reversed = False
1213
1208
 
1214
- # Set x_min and x_max
1209
+ # Set x_min
1210
+ # based on user arguments
1215
1211
  if isinstance(uargs.x_lim[0], str):
1216
1212
  if uargs.x_lim[0] == 'auto':
1217
1213
  x_min = min(x_vals) * min_factor
@@ -1222,6 +1218,8 @@ def plot_abs_func(uargs, save_data_only=False):
1222
1218
  else:
1223
1219
  x_min = uargs.x_lim[0]
1224
1220
 
1221
+ # Set x_max
1222
+ # based on user arguments
1225
1223
  if isinstance(uargs.x_lim[1], str):
1226
1224
  if uargs.x_lim[1] == 'auto':
1227
1225
  x_max = max(x_vals) * max_factor
@@ -1236,7 +1234,7 @@ def plot_abs_func(uargs, save_data_only=False):
1236
1234
  if uargs.trim_transitions is not None:
1237
1235
  abs_data.trim_to_n(uargs.trim_transitions)
1238
1236
 
1239
- # Generate spectrum
1237
+ # Generate spectrum data
1240
1238
  abs_data.generate_spectrum(
1241
1239
  fwhm=uargs.linewidth,
1242
1240
  lineshape=uargs.lineshape,
@@ -1244,11 +1242,12 @@ def plot_abs_func(uargs, save_data_only=False):
1244
1242
  num_points=10000,
1245
1243
  x_min=x_min,
1246
1244
  x_max=x_max,
1247
- comment=unique_names[it]
1245
+ comment=output_file,
1246
+ x_reversed=x_reversed
1248
1247
  )
1249
1248
 
1249
+ # Save spectrum data to file
1250
1250
  if save_data_only:
1251
- # Save spectrum data to file
1252
1251
  abs_data.save_spectrum_data(
1253
1252
  f'absorption_spectrum_{output_file.stem}.csv',
1254
1253
  comments='Data from {}\nfwhm={}, lineshape={}\nintensities={}'.format( # noqa
@@ -1274,33 +1273,98 @@ def plot_abs_func(uargs, save_data_only=False):
1274
1273
  'cyan'
1275
1274
  )
1276
1275
  else:
1277
- # Plot absorption spectrum
1278
- plotter.plot_absorption_spectrum(
1279
- abs_data,
1280
- linecolor=colours[it],
1281
- stickcolour=colours[it],
1282
- osc_style=uargs.osc_style,
1283
- normalise=uargs.normalise,
1284
- window_title='',
1285
- fig=fig,
1286
- ax=ax,
1287
- oax=oax,
1288
- show=False,
1289
- save=False,
1290
- x_lim=[x_min, x_max],
1291
- y_lim=uargs.y_lim,
1292
- x_shift=uargs.x_shift[it],
1293
- legend=legend
1294
- )
1276
+ # Add to dictionary of spectra for plotting later
1277
+ spectra_dict[output_file] = abs_data
1278
+
1279
+ # Exit if only saving data
1280
+ if save_data_only:
1281
+ return
1282
+
1283
+ ## Plot all spectra
1284
+ import matplotlib.pyplot as plt
1285
+ import matplotlib.colors as mcolors
1286
+
1287
+ # Set font name and size
1288
+ plt.rcParams['font.family'] = 'Arial'
1289
+ plt.rcParams['font.size'] = 10
1290
+ plt.rcParams['legend.fontsize'] = 9
1291
+ plt.rcParams['legend.loc'] = 'center right'
1295
1292
 
1296
- if not save_data_only:
1297
- if _SAVE_CONV[uargs.plot]:
1298
- savename = f'absorption_spectrum_{output_file.stem}.png'
1299
- plt.savefig(savename, dpi=500)
1300
- ut.cprint(f'Saved image to {savename}', 'cyan')
1293
+ # Create list of colours for plotting
1294
+ if len(uargs.output_file) == 1:
1295
+ colours = ['black']
1296
+ else:
1297
+ colours = list(mcolors.TABLEAU_COLORS.values())
1298
+
1299
+ # Width of figure in inches
1300
+ # Make wider if multiple spectra to plot
1301
+ # to include legend
1302
+ if len(spectra_dict) > 1:
1303
+ width = 6.
1304
+ else:
1305
+ width = 4
1306
+ # width in cm
1307
+ width_cm = 2.54 * width
1308
+
1309
+ # Create figure and axis with
1310
+ # height based on golden ratio
1311
+ golden = (1 + np.sqrt(5))/2
1312
+ fig, ax = plt.subplots(
1313
+ 1,
1314
+ 1,
1315
+ num='Absorption Spectrum',
1316
+ figsize=(width, 4. / golden)
1317
+ )
1318
+ # Secondary axis for oscillator strength sticks
1319
+ oax = ax.twinx()
1320
+
1321
+ # Plot absorption spectrum for each file
1322
+ for it, (output_file, abs_data) in enumerate(spectra_dict.items()): # noqa
1323
+
1324
+ plotter.plot_absorption_spectrum(
1325
+ abs_data,
1326
+ linecolor=colours[it],
1327
+ stickcolour=colours[it],
1328
+ osc_style=uargs.osc_style,
1329
+ normalise=uargs.normalise,
1330
+ window_title='',
1331
+ fig=fig,
1332
+ ax=ax,
1333
+ oax=oax,
1334
+ show=False,
1335
+ save=False,
1336
+ x_lim=[x_min, x_max],
1337
+ y_lim=uargs.y_lim,
1338
+ x_shift=uargs.x_shift[it],
1339
+ legend=False
1340
+ )
1341
+
1342
+ if uargs.x_lim != ['auto', 'auto']:
1343
+ ax.set_xlim(float(uargs.x_lim[0]), float(uargs.x_lim[1]))
1344
+
1345
+ fig.tight_layout()
1346
+
1347
+ if len(spectra_dict) > 1:
1348
+ fig.subplots_adjust(right=3.3/6.)
1349
+ if uargs.legend is None:
1350
+ legend_labels = [
1351
+ f'{output_file.stem}' for output_file in spectra_dict.keys()
1352
+ ]
1353
+ fig.legend(legend_labels, loc=7)
1354
+ else:
1355
+ fig.legend(uargs.legend, loc=7)
1356
+
1357
+ if _SAVE_CONV[uargs.plot]:
1358
+ savename = f'absorption_spectrum_{output_file.stem}.png'
1359
+ plt.savefig(savename, dpi=500)
1360
+ ut.cprint(f'Saved image to {savename}', 'cyan')
1361
+ ut.cprint(
1362
+ f'Use width={width:.1f} in. or {width_cm:.1f} cm',
1363
+ 'cyan'
1364
+ )
1301
1365
 
1302
- if _SHOW_CONV[uargs.plot]:
1303
- plt.show()
1366
+ if _SHOW_CONV[uargs.plot]:
1367
+ plt.show()
1304
1368
 
1305
1369
  return
1306
1370
 
@@ -2540,9 +2604,9 @@ def read_args(arg_list=None):
2540
2604
  plot_abs.add_argument(
2541
2605
  '--x_unit',
2542
2606
  type=str,
2543
- choices=['energy', 'wavelength', 'wavenumber'],
2607
+ choices=['energy', 'wavelength', 'wavelength_rev', 'wavenumber'],
2544
2608
  default='energy',
2545
- help='x units to use for spectrum'
2609
+ help='x units to use for spectrum (rev = reversed axis direction)'
2546
2610
  )
2547
2611
 
2548
2612
  plot_abs.add_argument(
@@ -2592,12 +2656,13 @@ def read_args(arg_list=None):
2592
2656
  )
2593
2657
 
2594
2658
  plot_abs.add_argument(
2595
- '--unique_names',
2596
- action='store_true',
2597
- default=False,
2659
+ '--legend',
2660
+ type=str,
2661
+ nargs='+',
2662
+ default=None,
2598
2663
  help=(
2599
- 'Attempt to shorten file names in plot legend\n'
2600
- 'Default: %(default)s'
2664
+ 'Legend labels for each spectrum plotted\n'
2665
+ 'If not provided, file names are used\n'
2601
2666
  )
2602
2667
  )
2603
2668
 
@@ -33,6 +33,9 @@ class AbsorptionSpectrum():
33
33
  Full width at half maximum used in spectrum generation
34
34
  comment: str, default=''
35
35
  Comment or metadata for the spectrum
36
+ x_reversed: bool, default False
37
+ Whether the x axis is reversed (e.g. for wavelength spectra)\n
38
+ By default, False - increasing x values from left to right
36
39
 
37
40
  Attributes
38
41
  ----------
@@ -61,7 +64,7 @@ class AbsorptionSpectrum():
61
64
  def __init__(self, x_grid: NDArray, x_unit: str, x_label: str,
62
65
  x_label_mathmode: str, y_unit: str, y_label: str,
63
66
  y_label_mathmode: str, y_values: NDArray, fwhm: float,
64
- comment: str = '') -> None:
67
+ comment: str = '', x_reversed: bool = False) -> None:
65
68
  self.x_grid = x_grid
66
69
  self.x_unit = x_unit
67
70
  self.x_label = x_label
@@ -72,30 +75,9 @@ class AbsorptionSpectrum():
72
75
  self.fwhm = fwhm
73
76
  self.y_values = y_values
74
77
  self.comment = comment
78
+ self.x_reversed = x_reversed
75
79
  return
76
80
 
77
- @classmethod
78
- def from_data(cls, x_grid: NDArray, y_values: NDArray,
79
- fwhm: float) -> 'AbsorptionSpectrum':
80
- '''
81
- Creates AbsorptionSpectrum object from data
82
-
83
- Parameters
84
- ----------
85
- x_grid: NDArray
86
- Grid of x values (energies, wavelengths, or wavenumbers)
87
- y_values: NDArray
88
- Absorption spectrum values at each point in x_grid
89
- fwhm: float
90
- Full width at half maximum used in spectrum generation
91
-
92
- Returns
93
- -------
94
- AbsorptionSpectrum
95
- Created AbsorptionSpectrum object
96
- '''
97
- return cls(x_grid, y_values, fwhm)
98
-
99
81
 
100
82
  class AbsorptionData():
101
83
  '''
@@ -282,7 +264,8 @@ class AbsorptionData():
282
264
  def generate_spectrum(self, fwhm: float, lineshape: str, x_min: float,
283
265
  x_max: float, num_points: int,
284
266
  x_type: str = 'energy',
285
- comment: str = '') -> AbsorptionSpectrum:
267
+ comment: str = '',
268
+ x_reversed: bool = False) -> AbsorptionSpectrum:
286
269
  '''
287
270
  Generates absorption spectrum using Gaussian broadening
288
271
 
@@ -306,6 +289,9 @@ class AbsorptionData():
306
289
  'wavenumber' (cm^-1)
307
290
  comment: str
308
291
  Comment to add to spectrum metadata
292
+ x_reversed: bool
293
+ Whether to reverse the x axis (e.g. for wavelength spectra)\n
294
+ By default, False - increasing x values from left to right
309
295
 
310
296
  Returns
311
297
  -------
@@ -387,7 +373,8 @@ class AbsorptionData():
387
373
  y_label_mathmode=y_label_mathmode,
388
374
  y_values=y_vals,
389
375
  fwhm=fwhm,
390
- comment=comment
376
+ comment=comment,
377
+ x_reversed=x_reversed
391
378
  )
392
379
 
393
380
  self.spectrum = spectrum
@@ -79,7 +79,18 @@ def plot_absorption_spectrum(abs_data: data.AbsorptionData,
79
79
  raise ValueError('AbsorptionData object does not contain spectrum')
80
80
 
81
81
  if fig is None or ax is None:
82
- fig, ax = plt.subplots(1, 1, num=window_title)
82
+ width = 4
83
+ width_cm = 10.4
84
+ golden = (1 + np.sqrt(5))/2
85
+ fig, ax = plt.subplots(
86
+ 1,
87
+ 1,
88
+ num=window_title,
89
+ figsize=(width, width / golden)
90
+ )
91
+ else:
92
+ width = fig.get_size_inches()[0]
93
+ width_cm = width * 2.54
83
94
 
84
95
  if oax is None and osc_style == 'separate':
85
96
  oax = ax.twinx()
@@ -118,7 +129,6 @@ def plot_absorption_spectrum(abs_data: data.AbsorptionData,
118
129
  ax.set_ylabel(abs_data.spectrum.y_label_mathmode)
119
130
 
120
131
  if abs_data.spectrum.x_label.split()[0].lower() == 'wavelength':
121
- ax.invert_xaxis()
122
132
  stick_x_values = [
123
133
  wavelength + x_shift
124
134
  for wavelength in abs_data.wavelengths
@@ -134,6 +144,9 @@ def plot_absorption_spectrum(abs_data: data.AbsorptionData,
134
144
  for wavenumber in abs_data.wavenumbers
135
145
  ]
136
146
 
147
+ if abs_data.spectrum.x_reversed:
148
+ ax.invert_xaxis()
149
+
137
150
  x_values = abs_data.spectrum.x_grid + x_shift
138
151
 
139
152
  # Main spectrum
@@ -141,18 +154,20 @@ def plot_absorption_spectrum(abs_data: data.AbsorptionData,
141
154
  x_values,
142
155
  _y_values,
143
156
  color=linecolor,
157
+ lw=1.1,
144
158
  label=abs_data.spectrum.comment
145
159
  )
146
160
 
147
161
  if osc_style == 'separate':
148
162
  # Oscillator strength twin axis
149
- oax.stem(
163
+ _, stemlines, _ = oax.stem(
150
164
  stick_x_values,
151
165
  _osc,
152
166
  basefmt=' ',
153
167
  markerfmt=' ',
154
168
  linefmt=stickcolour
155
169
  )
170
+ plt.setp(stemlines, 'linewidth', 1.1)
156
171
  oax.yaxis.set_minor_locator(AutoMinorLocator())
157
172
  if normalise:
158
173
  oax.set_ylabel(r'Normalised $f_\mathregular{osc}$')
@@ -216,6 +231,10 @@ def plot_absorption_spectrum(abs_data: data.AbsorptionData,
216
231
  f'\nSpectrum saved to\n {save_name}',
217
232
  'cyan'
218
233
  )
234
+ ut.cprint(
235
+ f'Use width={width:.1f} in. or {width_cm:.1f} cm',
236
+ 'cyan'
237
+ )
219
238
 
220
239
  if show:
221
240
  plt.show()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orto
3
- Version: 1.11.1
3
+ Version: 1.11.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
@@ -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.11.1'
11
+ __version__ = '1.11.3'
12
12
 
13
13
  setuptools.setup(
14
14
  name='orto',
@@ -1 +0,0 @@
1
- __version__ = '1.11.1'
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
File without changes
File without changes