Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion qse/__init__.py
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
This package is adapted from Atomic Simulation Environment (ASE).
"""

__all__ = ["Qbits", "Qbit"]
__all__ = ["Qbits", "Qbit", "Signal"]
__version__ = "0.1.1"

# from qse.calc.pulser import Pulser
Expand All @@ -15,4 +15,5 @@
from qse import utils
from qse.qbit import Qbit
from qse.qbits import Qbits
from qse.signal import Signal
from qse.visualise import draw
123 changes: 14 additions & 109 deletions qse/calc/__init__.py
Original file line number Diff line number Diff line change
@@ -1,116 +1,21 @@
"""Interface to different QSE calculators."""

__all__ = ["abc", "calculator", "signal"]
from typing import Union
__all__ = [
"calculator",
"Signal",
"PropertyNotImplementedError",
"PropertyNotPresent",
"CalculatorSetupError",
"CalculationFailed",
]

import qse.calc.abc
import qse.calc.calculator

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and content below goes into qse.calc.messages ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the Error classes defined in qse/calc/calculator.py go into qse/calc/messages.py

np = qse.np


class signal(object):
"""
signal class to represent a a signal with a duration.
It has two components: values, and duration.
Instantiation of this class supports '+' in two ways.
If w1, w2 are instantiation of signal, then
- w1 + 3 gives a signal with values, w1.values + 3 and
same duration.
- w = w1 + w2 gives signal with concatenated values, i.e.,
w.values = [w1.values, w2.values], and added duration.
w.duration = w1.duration + w2.duration
Note: Currently, the object gets created for multi-dim
arrays as well. However, it should be used for 1D only,
we haven't made it useful or consistent for multi-dim usage.
"""

#
# __slots__ = ('duration', 'values')
def __init__(self, values, duration=None) -> None:
self.values = np.asarray(values)
self._duration = len(self.values) if duration is None else int(duration)

#
@property
def duration(self):
"""time duration of signal"""
return self._duration

@duration.setter
def duration(self, value):
self._duration = value

def __iter__(self):
return iter(self.values)

#
def __getitem__(self, i):
return self.values[i]

#
def __eq__(self, other) -> bool:
return (self.duration == other.duration) and (self.values == other.values).all()

#
def __add__(self, other):
if isinstance(other, signal):
res = signal(
values=np.append(self.values, other.values),
duration=self.duration + other.duration,
)
else:
if isinstance(other, Union[float, int]):
res = signal(values=self.values + other, duration=self.duration)
else:
raise TypeError(f"wrong type for operand {type(other)}")
return res

#
def __radd__(self, other):
return self.__add__(other)

#
def __iadd__(self, other):
if isinstance(other, signal):
self.values = np.append(self.values, other.values)
self.duration += other.duration
else:
if isinstance(other, Union[float, int]):
self.values += other
else:
raise TypeError(f"wrong type for operand {type(other)}")
return self

#
def __mul__(self, other):
if isinstance(other, Union[float, int]):
res = signal(values=self.values * other, duration=self.duration)
else:
raise TypeError(f"wrong type for operand {type(other)}")
return res

#
def __rmul__(self, other):
return self.__mul__(other)

#
def __imul__(self, other):
if isinstance(other, Union[float, int]):
self.values *= other
else:
raise TypeError(f"wrong type for operand {type(other)}")
return self

#
def __repr__(self) -> str:
return f"signal(duration={self.duration}, values={self.values})"

# we need to define interpolating scheme to resample points if duration is changed externally.


#
from qse.calc.messages import (
CalculationFailed,
CalculatorSetupError,
PropertyNotImplementedError,
PropertyNotPresent,
)

from .myqlm import Myqlm
from .pulser import Pulser
65 changes: 0 additions & 65 deletions qse/calc/abc.py

This file was deleted.

103 changes: 10 additions & 93 deletions qse/calc/calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,70 +3,17 @@
import pathlib
import subprocess
import warnings
from math import pi, sqrt
from typing import Any, Dict, List, Optional, Set, Union
from typing import Any, Dict, List, Optional, Set

import numpy as np
from ase.cell import Cell
from ase.outputs import Properties, all_outputs
from ase.utils import jsonable

from qse.calc.abc import GetPropertiesMixin


class CalculatorError(RuntimeError):
"""Base class of error types related to ASE calculators."""


class CalculatorSetupError(CalculatorError):
"""Calculation cannot be performed with the given parameters.

Reasons to raise this errors are:
* The calculator is not properly configured
(missing executable, environment variables, ...)
* The given qbits object is not supported
* Calculator parameters are unsupported

Typically raised before a calculation."""


class EnvironmentError(CalculatorSetupError):
"""Raised if calculator is not properly set up with ASE.
May be missing an executable or environment variables."""


class InputError(CalculatorSetupError):
"""Raised if inputs given to the calculator were incorrect.
Bad input keywords or values, or missing pseudopotentials.
This may be raised before or during calculation, depending on
when the problem is detected."""


class CalculationFailed(CalculatorError):
"""Calculation failed unexpectedly.

Reasons to raise this error are:
* Calculation did not converge
* Calculation ran out of memory
* Segmentation fault or other abnormal termination
* Arithmetic trouble (singular matrices, NaN, ...)

Typically raised during calculation."""


class ReadError(CalculatorError):
"""Unexpected irrecoverable error while reading calculation results."""


class PropertyNotImplementedError(NotImplementedError):
"""Raised if a calculator does not implement the requested property."""


class PropertyNotPresent(CalculatorError):
"""Requested property is missing.

Maybe it was never calculated, or for some reason was not extracted
with the rest of the results, without being a fatal ReadError."""
from qse.calc.messages import (
CalculationFailed,
CalculatorSetupError,
PropertyNotImplementedError,
PropertyNotPresent,
)


def compare_qbits(qbits1, qbits2, tol=1e-15, excluded_properties=None):
Expand Down Expand Up @@ -192,37 +139,6 @@ def equal(a, b, tol=None, rtol=None, atol=None):
return np.allclose(a, b, rtol=rtol, atol=atol)


# def kptdensity2monkhorstpack(atoms, kptdensity=3.5, even=True): """Convert k-point density to Monkhorst-Pack grid size.

"""
class EigenvalOccupationMixin:
#Define 'eigenvalues' and 'occupations' properties on class.
#
#eigenvalues and occupations will be arrays of shape (spin, kpts, nbands).
#
#Classes must implement the old-fashioned get_eigenvalues and
#get_occupations methods.

@property
def eigenvalues(self):
return self.build_eig_occ_array(self.get_eigenvalues)

@property
def occupations(self):
return self.build_eig_occ_array(self.get_occupation_numbers)

def build_eig_occ_array(self, getter):
nspins = self.get_number_of_spins()
nkpts = len(self.get_ibz_k_points())
nbands = self.get_number_of_bands()
arr = np.zeros((nspins, nkpts, nbands))
for s in range(nspins):
for k in range(nkpts):
arr[s, k, :] = getter(spin=s, kpt=k)
return arr
"""


class Parameters(dict):
"""Dictionary for parameters.

Expand Down Expand Up @@ -278,8 +194,9 @@ def write(self, filename):
pathlib.Path(filename).write_text(self.tostring())


class Calculator(GetPropertiesMixin):
"""Base-class for all QSE calculators, adapted from ASE calculators.
class Calculator:
"""
Base-class for all QSE calculators, adapted from ASE calculators.

A calculator must raise PropertyNotImplementedError if asked for a
property that it can't calculate. So, if calculation of the
Expand Down
Loading