qrotor 4.2.2__py3-none-any.whl → 4.4.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.

Potentially problematic release.


This version of qrotor might be problematic. Click here for more details.

qrotor/_version.py CHANGED
@@ -11,5 +11,5 @@ https://semver.org/
11
11
  ---
12
12
  """
13
13
 
14
- __version__ = "v4.2.2"
14
+ __version__ = "v4.4.0"
15
15
 
qrotor/plot.py CHANGED
@@ -98,7 +98,10 @@ def energies(
98
98
  data,
99
99
  title:str=None,
100
100
  ) -> None:
101
- """Plot the eigenvalues of `data` (System or a list of System objects)."""
101
+ """Plot the eigenvalues of `data` (System or a list of System objects).
102
+
103
+ You can use up to 1 tag per system to differentiate between molecular groups.
104
+ """
102
105
  if isinstance(data, System):
103
106
  var = [data]
104
107
  else: # Should be a list
@@ -137,14 +140,14 @@ def energies(
137
140
  # Plot eigenvalues
138
141
  if any(system.eigenvalues):
139
142
  text_offset = 3 * len(unique_groups)
140
- if system.group not in unique_groups:
141
- unique_groups.append(system.group)
143
+ if system.tags not in unique_groups:
144
+ unique_groups.append(system.tags)
142
145
  for j, energy in enumerate(system.eigenvalues):
143
146
  plt.axhline(y=energy, color=E_color, linestyle=E_linestyle)
144
147
  # Textbox positions are a bit weird when plotting more than 2 systems, but whatever...
145
148
  plt.text(j%3*1.0 + text_offset, energy, f'$E_{{{j}}}$ = {round(energy,4):.04f}', va='top', bbox=dict(edgecolor=edgecolor, boxstyle='round,pad=0.2', facecolor='white', alpha=0.8))
146
149
  if len(systems.get_groups(var)) > 1:
147
- plt.plot([], [], color=E_color, label=f'{system.group} Energies') # Add to legend
150
+ plt.plot([], [], color=E_color, label=f'{system.tags} Energies') # Add to legend
148
151
 
149
152
  if len(systems.get_groups(var)) > 1:
150
153
  plt.subplots_adjust(right=0.85)
qrotor/potential.py CHANGED
@@ -49,7 +49,7 @@ from copy import deepcopy
49
49
  from scipy.interpolate import CubicSpline
50
50
  import aton.alias as alias
51
51
  import aton.file as file
52
- import aton.api.qe as qe
52
+ import aton.api.pwx as pwx
53
53
  from ._version import __version__
54
54
 
55
55
 
@@ -125,6 +125,7 @@ def save(
125
125
  def load(
126
126
  filepath:str='potential.csv',
127
127
  comment:str=None,
128
+ tags:str='',
128
129
  system:System=None,
129
130
  angle:str='deg',
130
131
  energy:str='meV',
@@ -184,6 +185,8 @@ def load(
184
185
  system.comment = loaded_comment
185
186
  else:
186
187
  system.comment = os.path.basename(os.path.dirname(file_path))
188
+ if tags:
189
+ system.tags = tags
187
190
  print(f"Loaded {filepath}")
188
191
  return system
189
192
 
@@ -196,8 +199,8 @@ def from_qe(
196
199
  energy:str='meV',
197
200
  comment:str=None,
198
201
  ) -> System:
199
- """Compiles a rotational potential CSV file from Quantum ESPRESSO outputs,
200
- created with `qrotor.rotate.structure_qe()`.
202
+ """Compiles a rotational potential CSV file from Quantum ESPRESSO pw.x outputs,
203
+ created with `qrotor.rotate.input_qe()`.
201
204
  Returns a `System` object with the new potential values.
202
205
 
203
206
  The angle in degrees is extracted from the output filenames,
@@ -227,7 +230,7 @@ def from_qe(
227
230
  # Set header
228
231
  potential_data = f'## {comment}\n' if comment else f'## {folder_name}\n'
229
232
  potential_data += '# Rotational potential dataset\n'
230
- potential_data += f'# Calculated with QE using QRotor {__version__}\n'
233
+ potential_data += f'# Calculated with QE pw.x using QRotor {__version__}\n'
231
234
  potential_data += '# https://pablogila.github.io/qrotor\n'
232
235
  potential_data += '#\n'
233
236
  if energy.lower() in alias.units['eV']:
@@ -249,7 +252,7 @@ def from_qe(
249
252
  file_path = file.get(filepath=file_path, include='.out', return_anyway=True)
250
253
  if not file_path: # Not an output file, skip it
251
254
  continue
252
- content = qe.read_out(file_path)
255
+ content = pwx.read_out(file_path)
253
256
  if not content['Success']: # Ignore unsuccessful calculations
254
257
  print(f'x {filename}')
255
258
  counter_errors += 1
qrotor/rotate.py CHANGED
@@ -9,7 +9,7 @@ Works with Quantum ESPRESSO input files.
9
9
 
10
10
  | | |
11
11
  | --- | --- |
12
- | `structure_qe()` | Rotate specific atoms from a Quantum ESPRESSO input file |
12
+ | `input_qe()` | Rotate specific atoms from a Quantum ESPRESSO input file |
13
13
  | `rotate_coords()` | Rotate a specific list of coordinates |
14
14
 
15
15
  ---
@@ -26,7 +26,7 @@ import aton.txt.extract as extract
26
26
  import aton.txt.edit as edit
27
27
 
28
28
 
29
- def structure_qe(
29
+ def input_qe(
30
30
  filepath:str,
31
31
  positions:list,
32
32
  angle:float,
@@ -66,13 +66,13 @@ def structure_qe(
66
66
  lines = []
67
67
  full_positions = []
68
68
  for position in positions:
69
- line = api.qe.get_atom(filepath, position, precision)
69
+ line = api.pwx.get_atom(filepath, position, precision)
70
70
  lines.append(line)
71
71
  pos = extract.coords(line)
72
72
  if len(pos) > 3: # Keep only the first three coordinates
73
73
  pos = pos[:3]
74
74
  # Convert to cartesian
75
- pos_cartesian = api.qe.to_cartesian(filepath, pos)
75
+ pos_cartesian = api.pwx.to_cartesian(filepath, pos)
76
76
  full_positions.append(pos_cartesian)
77
77
  print(f'Found atom: "{line}"')
78
78
  # Set the angles to rotate
@@ -92,7 +92,7 @@ def structure_qe(
92
92
  rotated_positions_cartesian = rotate_coords(full_positions, angle, use_centroid, show_axis)
93
93
  rotated_positions = []
94
94
  for coord in rotated_positions_cartesian:
95
- pos = api.qe.from_cartesian(filepath, coord)
95
+ pos = api.pwx.from_cartesian(filepath, coord)
96
96
  rotated_positions.append(pos)
97
97
  _save_qe(filepath, output, lines, rotated_positions)
98
98
  outputs.append(output)
@@ -184,7 +184,7 @@ def _save_qe(
184
184
  additional_positions = positions[-2:]
185
185
  for pos in additional_positions:
186
186
  pos.insert(0, 'He')
187
- api.qe.add_atom(output, pos)
187
+ api.pwx.add_atom(output, pos)
188
188
  elif len(lines) != len(positions):
189
189
  raise ValueError(f"What?! len(lines)={len(lines)} and len(positions)={len(positions)}")
190
190
  # Add angle to calculation prefix
@@ -192,11 +192,11 @@ def _save_qe(
192
192
  splits = output_name.split('_')
193
193
  angle_str = splits[-1].replace('.in', '')
194
194
  prefix = ''
195
- content = api.qe.read_in(output)
195
+ content = api.pwx.read_in(output)
196
196
  if 'prefix' in content.keys():
197
197
  prefix = content['prefix']
198
198
  prefix = prefix.strip("'")
199
199
  prefix = "'" + prefix + angle_str + "'"
200
- api.qe.set_value(output, 'prefix', prefix)
200
+ api.pwx.set_value(output, 'prefix', prefix)
201
201
  return output
202
202
 
qrotor/system.py CHANGED
@@ -24,16 +24,14 @@ class System:
24
24
  def __init__(
25
25
  self,
26
26
  comment: str = None,
27
+ B: float = B_CH3,
28
+ gridsize: int = 200000,
27
29
  searched_E: int = 21,
28
30
  correct_potential_offset: bool = True,
29
31
  save_eigenvectors: bool = True,
30
- group: str = '',
31
- B: float = B_CH3,
32
- gridsize: int = 200000,
33
- grid = [],
34
32
  potential_name: str = '',
35
33
  potential_constants: list = None,
36
- potential_values = [],
34
+ tags: str = '',
37
35
  ):
38
36
  """A new quantum system can be instantiated as `system = qrotor.System()`.
39
37
  This new system will contain the default values listed above.
@@ -49,17 +47,12 @@ class System:
49
47
  """Correct the potential offset as `V - min(V)` or not."""
50
48
  self.save_eigenvectors: bool = save_eigenvectors
51
49
  """Save or not the eigenvectors. Final file size will be bigger."""
52
- self.group: str = group
53
- """Chemical group, methyl or amine: `'CH3'`, `'CD3'`, `'NH3'`, `'ND3'`.
50
+ self.tags: str = tags
51
+ """Custom tags separated by spaces, such as the molecular group, etc.
54
52
 
55
- Can be used to set the value of `B` automatically at startup.
56
- It can also be configured afterwards with `System.set_group()`.
57
- This group can be used as metadata to analyse different datasets.
53
+ Can be used to filter between datasets.
58
54
  """
59
- self.set_group(group) # Normalise the group name, and set the value of B
60
55
  ## Potential
61
- if not B:
62
- B = self.B
63
56
  self.B: float = B
64
57
  """Kinetic rotational energy, as in $B=\\frac{\\hbar^2}{2I}$.
65
58
 
@@ -67,7 +60,7 @@ class System:
67
60
  """
68
61
  self.gridsize: int = gridsize
69
62
  """Number of points in the grid."""
70
- self.grid = grid
63
+ self.grid = []
71
64
  """The grid with the points to be used in the calculation.
72
65
 
73
66
  Can be set automatically over $2 \\pi$ with `System.set_grid()`.
@@ -80,7 +73,7 @@ class System:
80
73
  """
81
74
  self.potential_constants: list = potential_constants
82
75
  """List of constants to be used in the calculation of the potential energy, in the `qrotor.potential` module."""
83
- self.potential_values = potential_values
76
+ self.potential_values = []
84
77
  """Numpy [ndarray](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html) with the potential values for each point in the grid.
85
78
 
86
79
  Can be calculated with a function available in the `qrotor.potential` module,
@@ -205,40 +198,6 @@ class System:
205
198
  else:
206
199
  raise ValueError('gridsize must be provided if there is no System.gridsize')
207
200
  return self
208
-
209
- def set_group(self, group:str=None, B:float=None):
210
- """Normalise `System.group` name, and set `System.B` based on it."""
211
- for name in alias.chemical['CH3']:
212
- if group.lower() == name:
213
- self.group = 'CH3'
214
- if not B:
215
- B = B_CH3
216
- self.B = B
217
- return self
218
- for name in alias.chemical['CD3']:
219
- if group.lower() == name:
220
- self.group = 'CD3'
221
- if not B:
222
- B = B_CD3
223
- self.B = B
224
- return self
225
- for name in alias.chemical['NH3']:
226
- if group.lower() == name:
227
- self.group = 'NH3'
228
- if not B:
229
- B = B_NH3
230
- self.B = B
231
- return self
232
- for name in alias.chemical['ND3']:
233
- if group.lower() == name:
234
- self.group = 'ND3'
235
- if not B:
236
- B = B_ND3
237
- self.B = B
238
- return self
239
- self.group = group # No match was found
240
- self.B = None
241
- return self
242
201
 
243
202
  def reduce_size(self):
244
203
  """Discard data that takes too much space,
@@ -256,7 +215,7 @@ class System:
256
215
  'searched_E': self.searched_E,
257
216
  'correct_potential_offset': self.correct_potential_offset,
258
217
  'save_eigenvectors': self.save_eigenvectors,
259
- 'group': self.group,
218
+ 'tags': self.tags,
260
219
  'B': self.B,
261
220
  'gridsize': self.gridsize,
262
221
  'potential_name': self.potential_name,
qrotor/systems.py CHANGED
@@ -12,14 +12,16 @@ These are commonly used as a list of `System` objects.
12
12
  | `as_list()` | Ensures that a list only contains System objects |
13
13
  | `save_energies()` | Save the energy eigenvalues for all systems to a CSV |
14
14
  | `save_splittings()` | Save the tunnel splitting energies for all systems to a CSV |
15
+ | `save_summary()` | Save a summary of some relevant parameters for all systems to a CSV |
15
16
  | `get_energies()` | Get the eigenvalues from all systems |
16
17
  | `get_gridsizes()` | Get all gridsizes |
17
18
  | `get_runtimes()` | Get all runtimes |
18
- | `get_groups()` | Get the chemical groups in use |
19
19
  | `get_ideal_E()` | Calculate the ideal energy for a specified level |
20
20
  | `sort_by_gridsize()` | Sort systems by gridsize |
21
21
  | `reduce_size()` | Discard data that takes too much space |
22
22
  | `summary()` | Print a summary of a System or list of Systems |
23
+ | `list_tags()` | Get a list with all system tags |
24
+ | `filter_tags()` | Filter the systems with or without specific tags |
23
25
 
24
26
  ---
25
27
  """
@@ -51,9 +53,9 @@ def as_list(systems) -> None:
51
53
  def save_energies(
52
54
  systems:list,
53
55
  comment:str='',
54
- filepath:str='eigenvalues.csv',
56
+ filepath:str='qrotor_eigenvalues.csv',
55
57
  ) -> pd.DataFrame:
56
- """Save the energy eigenvalues for all `systems` to a eigenvalues.csv file.
58
+ """Save the energy eigenvalues for all `systems` to a qrotor_eigenvalues.csv file.
57
59
 
58
60
  Returns a Pandas Dataset with `System.comment` columns and `System.eigenvalues` values.
59
61
 
@@ -62,7 +64,7 @@ def save_energies(
62
64
  A `comment` can be included at the top of the file.
63
65
  Note that `System.comment` must not include commas (`,`).
64
66
  """
65
- as_list(systems)
67
+ systems = as_list(systems)
66
68
  version = systems[0].version
67
69
  E = {}
68
70
  # Find max length of eigenvalues
@@ -81,7 +83,7 @@ def save_energies(
81
83
  # Else save to file
82
84
  df.to_csv(filepath, sep=',', index=False)
83
85
  # Include a comment at the top of the file
84
- file_comment = f'# {comment}\n' if comment else f''
86
+ file_comment = f'## {comment}\n' if comment else f''
85
87
  file_comment += f'# Energy eigenvalues\n'
86
88
  file_comment += f'# Calculated with QRotor {version}\n'
87
89
  file_comment += f'# https://pablogila.github.io/qrotor\n#'
@@ -93,9 +95,9 @@ def save_energies(
93
95
  def save_splittings(
94
96
  systems:list,
95
97
  comment:str='',
96
- filepath:str='splittings.csv',
98
+ filepath:str='qrotor_splittings.csv',
97
99
  ) -> pd.DataFrame:
98
- """Save the tunnel splitting energies for all `systems` to a splittings.csv file.
100
+ """Save the tunnel splitting energies for all `systems` to a qrotor_splittings.csv file.
99
101
 
100
102
  Returns a Pandas Dataset with `System.comment` columns and `System.splittings` values.
101
103
 
@@ -105,7 +107,7 @@ def save_splittings(
105
107
  Note that `System.comment` must not include commas (`,`).
106
108
  Different splitting lengths across systems are allowed - missing values will be NaN.
107
109
  """
108
- as_list(systems)
110
+ systems = as_list(systems)
109
111
  version = systems[0].version
110
112
  tunnelling_E = {}
111
113
  # Find max length of splittings
@@ -119,7 +121,7 @@ def save_splittings(
119
121
  # Else save to file
120
122
  df.to_csv(filepath, sep=',', index=False)
121
123
  # Include a comment at the top of the file
122
- file_comment = f'# {comment}\n' if comment else f''
124
+ file_comment = f'## {comment}\n' if comment else f''
123
125
  file_comment += f'# Tunnel splitting energies\n'
124
126
  file_comment += f'# Calculated with QRotor {version}\n'
125
127
  file_comment += f'# https://pablogila.github.io/qrotor\n#'
@@ -128,12 +130,80 @@ def save_splittings(
128
130
  return df
129
131
 
130
132
 
133
+ def save_summary(
134
+ systems:list,
135
+ comment:str='',
136
+ filepath:str='qrotor_summary.csv',
137
+ ) -> pd.DataFrame:
138
+ """Save a summary for all `systems` to a qrotor_summary.csv file.
139
+
140
+ Produces one row per System with the columns:
141
+ `comment`, `ZPE`, `E_activation`, `potential_max`, `1st_splitting`,
142
+ `1st_excitation`, `B`, `degeneracy`, `gridsize`.
143
+
144
+ Set `filepath` to null to just return the DataFrame.
145
+ """
146
+ systems = as_list(systems)
147
+ version = systems[0].version
148
+ rows = []
149
+ for s in systems:
150
+ eigenvalues = getattr(s, 'eigenvalues', None)
151
+ if eigenvalues is not None and len(eigenvalues) > 0:
152
+ first_val = eigenvalues[0]
153
+ zpe = float('nan') if first_val is None else first_val
154
+ else:
155
+ zpe = float('nan')
156
+ splittings = getattr(s, 'splittings', None)
157
+ if splittings is not None and len(splittings) > 0:
158
+ first_splitting = float('nan') if splittings[0] is None else splittings[0]
159
+ else:
160
+ first_splitting = float('nan')
161
+ excitations = getattr(s, 'excitations', None)
162
+ if excitations is not None and len(excitations) > 0:
163
+ first_excitation = float('nan') if excitations[0] is None else excitations[0]
164
+ else:
165
+ first_excitation = float('nan')
166
+ system_comment = getattr(s, 'comment', None)
167
+ E_activation = getattr(s, 'E_activation', None)
168
+ B = getattr(s, 'B', None)
169
+ tags = getattr(s, 'tags', None)
170
+ deg = getattr(s, 'deg', None)
171
+ gridsize = getattr(s, 'gridsize', None)
172
+ potential_max = getattr(s, 'potential_max', None)
173
+ # Each row contains the following:
174
+ rows.append({
175
+ 'comment': system_comment,
176
+ 'ZPE': zpe,
177
+ 'E_activation': E_activation,
178
+ 'potential_max': potential_max,
179
+ '1st_splitting': first_splitting,
180
+ '1st_excitation': first_excitation,
181
+ 'B': B,
182
+ 'degeneracy': deg,
183
+ 'gridsize': gridsize,
184
+ 'tags': tags,
185
+ })
186
+ # Save to file or just return df
187
+ df = pd.DataFrame(rows)
188
+ if not filepath:
189
+ return df
190
+ df.to_csv(filepath, sep=',', index=False)
191
+ # Include a comment at the top of the file
192
+ file_comment = f'## {comment}\n' if comment else ''
193
+ file_comment += '# Summary of systems\n'
194
+ file_comment += f'# Calculated with QRotor {version}\n'
195
+ file_comment += '# https://pablogila.github.io/qrotor\n#'
196
+ txt.edit.insert_at(filepath, file_comment, 0)
197
+ print(f'Summary saved to {filepath}')
198
+ return df
199
+
200
+
131
201
  def get_energies(systems:list) -> list:
132
202
  """Get a list with all lists of eigenvalues from all systems.
133
203
 
134
204
  If no eigenvalues are present for a particular system, appends None.
135
205
  """
136
- as_list(systems)
206
+ systems = as_list(systems)
137
207
  energies = []
138
208
  for i in systems:
139
209
  if all(i.eigenvalues):
@@ -148,7 +218,7 @@ def get_gridsizes(systems:list) -> list:
148
218
 
149
219
  If no gridsize value is present for a particular system, appends None.
150
220
  """
151
- as_list(systems)
221
+ systems = as_list(systems)
152
222
  gridsizes = []
153
223
  for i in systems:
154
224
  if i.gridsize:
@@ -165,7 +235,7 @@ def get_runtimes(systems:list) -> list:
165
235
 
166
236
  If no runtime value is present for a particular system, appends None.
167
237
  """
168
- as_list(systems)
238
+ systems = as_list(systems)
169
239
  runtimes = []
170
240
  for i in systems:
171
241
  if i.runtime:
@@ -175,16 +245,6 @@ def get_runtimes(systems:list) -> list:
175
245
  return runtimes
176
246
 
177
247
 
178
- def get_groups(systems:list) -> list:
179
- """Returns a list with all `System.group` values."""
180
- as_list(systems)
181
- groups = []
182
- for i in systems:
183
- if i.group not in groups:
184
- groups.append(i.group)
185
- return groups
186
-
187
-
188
248
  def get_ideal_E(E_level:int) -> int:
189
249
  """Calculates the ideal energy for a specified `E_level`.
190
250
 
@@ -201,7 +261,7 @@ def get_ideal_E(E_level:int) -> int:
201
261
 
202
262
  def sort_by_gridsize(systems:list) -> list:
203
263
  """Sorts a list of System objects by `System.gridsize`."""
204
- as_list(systems)
264
+ systems = as_list(systems)
205
265
  systems = sorted(systems, key=lambda sys: sys.gridsize)
206
266
  return systems
207
267
 
@@ -212,13 +272,16 @@ def reduce_size(systems:list) -> list:
212
272
  Removes eigenvectors, potential values and grids,
213
273
  for all System values inside the `systems` list.
214
274
  """
215
- as_list(systems)
275
+ systems = as_list(systems)
216
276
  for dataset in systems:
217
277
  dataset = dataset.reduce_size()
218
278
  return systems
219
279
 
220
280
 
221
- def summary(systems, verbose:bool=False) -> None:
281
+ def summary(
282
+ systems,
283
+ verbose:bool=False
284
+ ) -> None:
222
285
  """Print a summary of a System or list of Systems.
223
286
 
224
287
  Print extra info with `verbose=True`
@@ -243,3 +306,42 @@ def summary(systems, verbose:bool=False) -> None:
243
306
  print('--------------------')
244
307
  return None
245
308
 
309
+
310
+ def list_tags(systems:list) -> list:
311
+ """Returns a list with all system tags."""
312
+ systems = as_list(systems)
313
+ tags = []
314
+ for i in systems:
315
+ # i.tags is guaranteed to exist and be a string (may be empty)
316
+ system_tags = i.tags.split()
317
+ for tag in system_tags:
318
+ if tag not in tags:
319
+ tags.append(tag)
320
+ return tags
321
+
322
+
323
+ def filter_tags(
324
+ systems:list,
325
+ include:str='',
326
+ exclude:str='',
327
+ ) -> list:
328
+ """Returns a filtered list of systems with or without specific tags.
329
+
330
+ Tags are separated by blank spaces.
331
+ Include tags from `include`, exclude tags from `exclude`.
332
+ """
333
+ systems = as_list(systems)
334
+ included_tags = include.split()
335
+ excluded_tags = exclude.split()
336
+ filtered_systems = []
337
+ for i in systems:
338
+ tags_found = list_tags(i)
339
+ if excluded_tags and any(tag in excluded_tags for tag in tags_found):
340
+ continue
341
+ if included_tags:
342
+ if any(tag in included_tags for tag in tags_found):
343
+ filtered_systems.append(i)
344
+ else:
345
+ filtered_systems.append(i)
346
+ return filtered_systems
347
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qrotor
3
- Version: 4.2.2
3
+ Version: 4.4.0
4
4
  Summary: QRotor
5
5
  Author: Pablo Gila-Herranz
6
6
  Author-email: pgila001@ikasle.ehu.eus
@@ -0,0 +1,14 @@
1
+ qrotor/__init__.py,sha256=rG2dH4QjsVUOMBhFnv5gXs3QnrUg7fywd5pIDmMBXcQ,246
2
+ qrotor/_version.py,sha256=ROJNaCCcVwCHHX73Jf2tvmDGOerQZHlj_2VO-tE-DCw,198
3
+ qrotor/constants.py,sha256=YRri136Zg5dqqDS-180sxOB5ytBJW74msUbHYbrfiMc,6655
4
+ qrotor/plot.py,sha256=iJWHohW8hvKGRUjoqLYyQXweqrahF0XOIyyhDJ05_bI,14171
5
+ qrotor/potential.py,sha256=MsmUoac3wRhlIprY8ipThy0HNYaO8iRnfF51VsUJ5HU,18561
6
+ qrotor/rotate.py,sha256=FppTiAwE3c7JtPyOGBF4YHxq9JzE-YilN_lpaOgPm9Q,8109
7
+ qrotor/solve.py,sha256=YkOR1SJlpk41PCNEhslv6X3wV1TWMNztT78qX3Pngf0,10722
8
+ qrotor/system.py,sha256=NQ7fcSo2R1QY1D0k9ymjJT9i9BSvuAOE7zqt5NJxFCQ,9946
9
+ qrotor/systems.py,sha256=h2e5cP0GKaXbnbbna5dyCbRYHWloSrQXVs_wrV69Mto,12006
10
+ qrotor-4.4.0.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
11
+ qrotor-4.4.0.dist-info/METADATA,sha256=ZJwODdQbVnxqiLEPZ3Iid_guIiWcw500ou-67Sn7oh8,9649
12
+ qrotor-4.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
+ qrotor-4.4.0.dist-info/top_level.txt,sha256=SFRMgcJiR1GiEtZ4aLo-x5TdfSCo7Igxezp2qyI0u5A,7
14
+ qrotor-4.4.0.dist-info/RECORD,,
@@ -1,20 +0,0 @@
1
- qrotor/__init__.py,sha256=rG2dH4QjsVUOMBhFnv5gXs3QnrUg7fywd5pIDmMBXcQ,246
2
- qrotor/_version.py,sha256=xJziIF1hUqXZ6UNnYfvk3UOaM4YT6tHCKcJ7dYAuyRQ,198
3
- qrotor/constants.py,sha256=YRri136Zg5dqqDS-180sxOB5ytBJW74msUbHYbrfiMc,6655
4
- qrotor/plot.py,sha256=loyd-1sXvfD8_PyHCThE3VQpRC0qs1iONGY4LXjJyZ4,14086
5
- qrotor/potential.py,sha256=2HjSDVJWSvwplyH5pq0MMPoQsLIBJbbTwkr350u949I,18491
6
- qrotor/rotate.py,sha256=Wje9Q9SFhDvizz58MzNGBwsmgV-3wN9z2SnUNTIXzeg,8107
7
- qrotor/solve.py,sha256=YkOR1SJlpk41PCNEhslv6X3wV1TWMNztT78qX3Pngf0,10722
8
- qrotor/system.py,sha256=ahYurNUmVOV7B6aZSe7rhcruagj5rW9UClqG-H1vVvY,11454
9
- qrotor/systems.py,sha256=Hcx0QvMWpaPMfC6HWpkZPPWDyHk9rxWKdAxWNnD2NMg,8184
10
- qrotor-4.2.2.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
11
- tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- tests/test_constants.py,sha256=YHKkPyZlzjchxxzON_VSNsQdKnpkknsFVoIA6TcUk70,399
13
- tests/test_potential.py,sha256=_Vq9t9Xm59kNbyYwXlRnvKcxwL7vntD2j14W2aUtF6I,1302
14
- tests/test_rotate.py,sha256=2On2d1E82hdisFC5DXpaqqYNnteX7ZP3PAnGa_oGm2M,1896
15
- tests/test_solve.py,sha256=tEjLUZC7oe6LCQD5b2xf2aaK9lu-zI4lzuPXOGR2GAs,861
16
- tests/test_system.py,sha256=36d-8AdoJdzq0O9_O3s8wwBPGa-M7A86YiHqhhAsCZ8,742
17
- qrotor-4.2.2.dist-info/METADATA,sha256=q11ZEF8wbyCfEJ36y_1KkO4Sxge0KnSMOSN78Ha4uKU,9649
18
- qrotor-4.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
19
- qrotor-4.2.2.dist-info/top_level.txt,sha256=mLnYs07-amqX4TqbDV2_XvgdpHfgrYmzmYb7dwoh6EQ,13
20
- qrotor-4.2.2.dist-info/RECORD,,
tests/__init__.py DELETED
File without changes
tests/test_constants.py DELETED
@@ -1,13 +0,0 @@
1
- import qrotor as qr
2
-
3
-
4
- def test_constants():
5
- assert round(qr.B_CH3, 5) == 0.64518
6
- assert round(qr.B_CD3, 5) == 0.32289
7
- assert round(qr.B_NH3, 5) == 0.73569
8
- assert round(qr.B_ND3, 5) == 0.36819
9
- assert round(qr.Ry_to_eV, 5) == 13.60569
10
- assert round(qr.Ry_to_meV, 5) == 13605.69312
11
- assert round(qr.eV_to_Ry, 5) == 0.07350
12
- assert round(qr.meV_to_Ry, 10) == .0000734986
13
-
tests/test_potential.py DELETED
@@ -1,37 +0,0 @@
1
- import qrotor as qr
2
- import aton
3
-
4
-
5
- folder = 'tests/samples/'
6
- structure = folder + 'CH3NH3.in'
7
- structure_120 = folder + 'CH3NH3_120.in'
8
- structure_60 = folder + 'CH3NH3_60.in'
9
-
10
-
11
- def test_save_and_load():
12
- system = qr.System()
13
- system.gridsize = 36
14
- system.potential_name = 'sin'
15
- system.B = 1
16
- system.solve_potential()
17
- potential_file = folder + '_temp_potential.csv'
18
- # Remove the file if it exists
19
- try:
20
- aton.file.remove(potential_file)
21
- except:
22
- pass
23
- qr.potential.save(system, comment='hi', filepath=potential_file)
24
- system_new = qr.potential.load(potential_file)
25
- assert system_new.gridsize == system.gridsize
26
- assert round(system_new.potential_values[0], 5) == round(system.potential_values[0], 5)
27
- assert round(system_new.potential_values[5], 5) == round(system.potential_values[5], 5)
28
- assert round(system_new.potential_values[13], 5) == round(system.potential_values[13], 5)
29
- assert system_new.comment == 'hi'
30
- aton.file.remove(potential_file)
31
- # If we don't provide a comment, it should be the name of the folder
32
- system.comment = None
33
- qr.potential.save(system, filepath=potential_file)
34
- system_new = qr.potential.load(potential_file)
35
- assert system_new.comment == 'samples'
36
- aton.file.remove(potential_file)
37
-
tests/test_rotate.py DELETED
@@ -1,53 +0,0 @@
1
- import qrotor as qr
2
- import aton.api as api
3
- import aton.txt.extract as extract
4
- import aton.file as file
5
-
6
-
7
- folder = 'tests/samples/'
8
- structure = folder + 'CH3NH3.in'
9
- structure_120 = folder + 'CH3NH3_120.in'
10
- structure_60 = folder + 'CH3NH3_60.in'
11
-
12
-
13
- def test_rotate():
14
- CH3 = [
15
- '0.100 0.183 0.316',
16
- '0.151 0.532 0.842',
17
- '0.118 0.816 0.277',
18
- ]
19
- # 120 degrees (it should remain the same)
20
- qr.rotate.structure_qe(filepath=structure, positions=CH3, angle=120, precision=2)
21
- for coord in CH3:
22
- rotated_coord = api.qe.get_atom(filepath=structure_120, position=coord, precision=2)
23
- rotated_coord = extract.coords(rotated_coord)
24
- coord = extract.coords(coord)
25
- rotated_coord_rounded = []
26
- coord_rounded = []
27
- for i in rotated_coord:
28
- rotated_coord_rounded.append(round(i, 2))
29
- for i in coord:
30
- coord_rounded.append(round(i, 2))
31
- assert coord_rounded == rotated_coord_rounded
32
- file.remove(structure_120)
33
-
34
- # 60 degrees (it should change quite a lot)
35
- ideal = [
36
- '0.146468644022416 0.837865866372631 0.641449758215011',
37
- '0.095062781582172 0.488975944606740 0.115053787468686',
38
- '0.128156574395412 0.205890189020629 0.680672454316303',
39
- ]
40
- qr.rotate.structure_qe(filepath=structure, positions=CH3, angle=60, precision=2)
41
- for coord in ideal:
42
- rotated_coord = api.qe.get_atom(filepath=structure_60, position=coord, precision=3)
43
- rotated_coord = extract.coords(rotated_coord)
44
- coord = extract.coords(coord)
45
- rotated_coord_rounded = []
46
- coord_rounded = []
47
- for i in rotated_coord:
48
- rotated_coord_rounded.append(round(i, 2))
49
- for i in coord:
50
- coord_rounded.append(round(i, 2))
51
- assert coord_rounded == rotated_coord_rounded
52
- file.remove(structure_60)
53
-
tests/test_solve.py DELETED
@@ -1,28 +0,0 @@
1
- import qrotor as qr
2
-
3
-
4
- def test_solve_zero():
5
- system = qr.System()
6
- system.gridsize = 50000
7
- system.potential_name = 'zero'
8
- system.B = 1
9
- system.solve()
10
- assert round(system.eigenvalues[0], 2) == 0.0
11
- assert round(system.eigenvalues[1], 2) == 1.0
12
- assert round(system.eigenvalues[2], 2) == 1.0
13
- assert round(system.eigenvalues[3], 2) == 4.0
14
- assert round(system.eigenvalues[4], 2) == 4.0
15
- assert round(system.eigenvalues[5], 2) == 9.0
16
- assert round(system.eigenvalues[6], 2) == 9.0
17
- assert round(system.eigenvalues[7], 2) == 16.0
18
- assert round(system.eigenvalues[8], 2) == 16.0
19
-
20
-
21
- def test_solve_potential():
22
- system = qr.System()
23
- system.gridsize = 500
24
- system.potential_name = 'sin'
25
- system.potential_constants = [0, 1, 3, 0]
26
- system.solve_potential()
27
- assert round(system.potential_max, 2) == 1.0
28
-
tests/test_system.py DELETED
@@ -1,24 +0,0 @@
1
- import qrotor as qr
2
- import numpy as np
3
-
4
-
5
- def test_phase():
6
- sys = qr.System()
7
- sys.B = 1.0
8
- sys.potential_name = 'cos'
9
- sys.gridsize = 10000
10
- sys.solve()
11
- # plus pi/2, which will be -3pi/2
12
- sys.change_phase(0.5)
13
- assert round(sys.grid[0], 2) == round(-np.pi * 3/2, 2)
14
- # The first potential value should be 0,
15
- # but remember that the potential offset is corrected
16
- # so it should be half potential_max, so 1.0/2
17
- assert round(sys.potential_values[0], 2) == 0.5
18
- # minus pi, which will become -pi/2
19
- sys.change_phase(-1)
20
- assert round(sys.grid[0], 2) == round(-np.pi/2, 2)
21
- assert round(sys.potential_values[0], 2) == 0.5
22
- # Were eigenvalues calculated?
23
- assert len(sys.eigenvalues) > 0
24
-
File without changes