Skip to content

cssfproject

cssfproject

CSSFinder uses its own project format allowing for file based customization of parameters used by gilbert algorithm.

CSSFProject

Bases: CommonBaseModel

CSSFProject file specification.

Source code in cssfinder/cssfproject.py
class CSSFProject(CommonBaseModel):
    """CSSFProject file specification."""

    meta: Meta
    """Project meta information like name and author."""

    tasks: Dict[str, Task]
    """List of tasks within project which can be executed."""

    _project_path: Path
    """Path to cssfproject.json file."""

    def __init__(
        self,
        meta: Meta,
        tasks: list[Task] | dict[str, Task],
        project_path: str | Path,
        *_: Any,
        **_k: Any,
    ) -> None:
        """Initialize instance.

        extra args and kwargs are ignored.

        """
        super().__init__(meta=meta, tasks=tasks)

        if not isinstance(project_path, Path):
            project_path = Path(project_path)

        self._project_path = project_path.expanduser().resolve()

        if not self._project_path.exists():
            raise FileNotFoundError(self._project_path)

        self.bind()

    @validator("tasks", pre=True, always=True)
    @classmethod
    def _validate_tasks(
        cls,
        value: Iterable[dict[str, Any] | Task] | dict[str, dict[str, Any] | Task | Any],
    ) -> dict[str, dict[str, Any] | Task]:
        if isinstance(value, dict):
            for k, v in value.items():
                if not isinstance(v, (dict, Task)):
                    error_message = f"Incorrect format of Tasks field {k!r}."
                    raise IncorrectFormatOfTaskFieldError(error_message)

            return {str(k): dict(v) for k, v in value.items()}

        for i, v in enumerate(value):
            if not isinstance(v, (dict, Task)):
                error_message = f"Incorrect format of Tasks field {i!r}."
                raise IncorrectFormatOfTaskFieldError(error_message)

        return {str(i): t for i, t in enumerate(value)}

    def bind(self) -> None:
        """Bind fields to this CSSFProject object."""
        self.meta.bind(self)

        for task_name, task in self.tasks.items():
            task.bind(self, task_name)

    @property
    def project_file(self) -> Path:
        """Path to `cssfproject.json` file."""
        return project_file_path(self._project_path)

    @property
    def project_directory(self) -> Path:
        """Path to directory containing `cssfproject.json` file."""
        return self.project_file.parent

    @property
    def project_output_directory(self) -> Path:
        """Path to output directory for this project."""
        directory = self.project_directory / "output"
        directory.mkdir(0o777, parents=True, exist_ok=True)
        return directory

    @classmethod
    def load_project(cls, file_or_directory: str | Path) -> Self:
        """Load CSSFinder project in at least 1.0.0 version.

        Parameters
        ----------
        file_or_directory : str | Path
            Either project file (cssfproject.json) or directory containing project file.

        Returns
        -------
        CSSFProject
            Project information container.

        Raises
        ------
        InvalidCSSFProjectContent
            Raised when project file content is not a dictionary.
        MalformedProjectFileError
            When content of project file is not valid json.

        """
        # Unify path type to Path
        file_or_directory = Path(file_or_directory).expanduser().resolve()

        # When points to directory, dir must contain cssfproject.json file
        project_path = project_file_path(file_or_directory)

        if project_path.suffix == ".json":
            return cls._load_json_project(project_path)

        if project_path.suffix == ".py":
            return cls._load_py_cssfproject(project_path)

        msg = f"Unknown project format {project_path.suffix} of project {project_path}"
        raise FileNotFoundError(msg)

    @staticmethod
    def is_project_path(file_or_directory: Path) -> bool:
        """Check if path points to CSSFinder project file or project directory."""
        try:
            project_file_path(file_or_directory)
        except FileNotFoundError:
            return False
        else:
            return True

    @classmethod
    def _load_json_project(cls, project_path: Path) -> Self:
        logging.debug("Resolved project path to %r", project_path.as_posix())
        try:
            content = project_path.read_text(encoding="utf-8")
        except FileNotFoundError as exc:
            error_message = f"Make sure you path is correct: {project_path}"
            raise ProjectFileNotFoundError(error_message) from exc

        try:
            decoded_content = jsonref.loads(content)
        except json.decoder.JSONDecodeError as exc:
            raise MalformedProjectFileError(exc.msg, exc.doc, exc.pos) from exc

        if not isinstance(decoded_content, dict):
            logging.critical("Content of cssfproject.json file is not a dictionary.")
            raise InvalidCSSFProjectContentError(decoded_content)

        return cls(**decoded_content, project_path=project_path)

    @classmethod
    def _load_py_cssfproject(cls, project_path: Path) -> Self:
        spec = importlib.util.spec_from_file_location(
            project_path.name[:-3],
            project_path.as_posix(),
        )
        if spec is None or spec.loader is None:
            msg = f"Failed to load project file {project_path}"
            raise ImportError(msg)

        project_module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(project_module)

        project_object = getattr(project_module, "__project__", None)

        if project_object is None:
            msg = (
                "Missing '__project__' field containing CSSFProject object.\n"
                f"From {project_path}."
            )
            raise ImportError(msg)

        if not isinstance(project_object, cls):
            msg = (
                f"Expected CSSFProject object in '__project__' field in {project_path}."
            )
            raise TypeError(
                msg,
            )

        if not isinstance(project_object, cls):
            msg = (
                "Incorrect object in '__project__' field, should contain "
                f"CSSFProject object.\nFrom {project_path}."
            )

        return project_object

    def select_tasks(self, patterns: list[str] | None = None) -> list[Task]:
        """Select all tasks matching list of patterns."""
        if patterns is None:
            return list(self.tasks.values())

        keys = set()

        for pattern in patterns:
            keys.update(fnmatch.filter(self.tasks.keys(), pattern))

        return [self.tasks[k] for k in keys]

    def to_python_project_template(self) -> str:
        """Convert contents of this project into Python project file."""
        return (
            get_cssfinder_jinja2_environment()
            .get_template(
                "python_base_project.pyjinja2",
            )
            .render(project=self)
        )

meta instance-attribute

meta: Meta

Project meta information like name and author.

tasks instance-attribute

tasks: Dict[str, Task]

List of tasks within project which can be executed.

project_file property

project_file: Path

Path to cssfproject.json file.

project_directory property

project_directory: Path

Path to directory containing cssfproject.json file.

project_output_directory property

project_output_directory: Path

Path to output directory for this project.

__init__

__init__(
    meta: Meta,
    tasks: list[Task] | dict[str, Task],
    project_path: str | Path,
    *_: Any,
    **_k: Any
) -> None

Initialize instance.

extra args and kwargs are ignored.

Source code in cssfinder/cssfproject.py
def __init__(
    self,
    meta: Meta,
    tasks: list[Task] | dict[str, Task],
    project_path: str | Path,
    *_: Any,
    **_k: Any,
) -> None:
    """Initialize instance.

    extra args and kwargs are ignored.

    """
    super().__init__(meta=meta, tasks=tasks)

    if not isinstance(project_path, Path):
        project_path = Path(project_path)

    self._project_path = project_path.expanduser().resolve()

    if not self._project_path.exists():
        raise FileNotFoundError(self._project_path)

    self.bind()

bind

bind() -> None

Bind fields to this CSSFProject object.

Source code in cssfinder/cssfproject.py
def bind(self) -> None:
    """Bind fields to this CSSFProject object."""
    self.meta.bind(self)

    for task_name, task in self.tasks.items():
        task.bind(self, task_name)

load_project classmethod

load_project(file_or_directory: str | Path) -> Self

Load CSSFinder project in at least 1.0.0 version.

Parameters:

Name Type Description Default
file_or_directory str | Path

Either project file (cssfproject.json) or directory containing project file.

required

Returns:

Type Description
CSSFProject

Project information container.

Raises:

Type Description
InvalidCSSFProjectContent

Raised when project file content is not a dictionary.

MalformedProjectFileError

When content of project file is not valid json.

Source code in cssfinder/cssfproject.py
@classmethod
def load_project(cls, file_or_directory: str | Path) -> Self:
    """Load CSSFinder project in at least 1.0.0 version.

    Parameters
    ----------
    file_or_directory : str | Path
        Either project file (cssfproject.json) or directory containing project file.

    Returns
    -------
    CSSFProject
        Project information container.

    Raises
    ------
    InvalidCSSFProjectContent
        Raised when project file content is not a dictionary.
    MalformedProjectFileError
        When content of project file is not valid json.

    """
    # Unify path type to Path
    file_or_directory = Path(file_or_directory).expanduser().resolve()

    # When points to directory, dir must contain cssfproject.json file
    project_path = project_file_path(file_or_directory)

    if project_path.suffix == ".json":
        return cls._load_json_project(project_path)

    if project_path.suffix == ".py":
        return cls._load_py_cssfproject(project_path)

    msg = f"Unknown project format {project_path.suffix} of project {project_path}"
    raise FileNotFoundError(msg)

is_project_path staticmethod

is_project_path(file_or_directory: Path) -> bool

Check if path points to CSSFinder project file or project directory.

Source code in cssfinder/cssfproject.py
@staticmethod
def is_project_path(file_or_directory: Path) -> bool:
    """Check if path points to CSSFinder project file or project directory."""
    try:
        project_file_path(file_or_directory)
    except FileNotFoundError:
        return False
    else:
        return True

select_tasks

select_tasks(
    patterns: list[str] | None = None,
) -> list[Task]

Select all tasks matching list of patterns.

Source code in cssfinder/cssfproject.py
def select_tasks(self, patterns: list[str] | None = None) -> list[Task]:
    """Select all tasks matching list of patterns."""
    if patterns is None:
        return list(self.tasks.values())

    keys = set()

    for pattern in patterns:
        keys.update(fnmatch.filter(self.tasks.keys(), pattern))

    return [self.tasks[k] for k in keys]

to_python_project_template

to_python_project_template() -> str

Convert contents of this project into Python project file.

Source code in cssfinder/cssfproject.py
def to_python_project_template(self) -> str:
    """Convert contents of this project into Python project file."""
    return (
        get_cssfinder_jinja2_environment()
        .get_template(
            "python_base_project.pyjinja2",
        )
        .render(project=self)
    )

InvalidCSSFProjectContentError

Bases: ValueError

Raised by load_from() when file content is not a dictionary.

Source code in cssfinder/cssfproject.py
class InvalidCSSFProjectContentError(ValueError):
    """Raised by load_from() when file content is not a dictionary."""

IncorrectFormatOfTaskFieldError

Bases: ValueError

Raised when "tasks" field contains incorrectly specified tasks.

Source code in cssfinder/cssfproject.py
class IncorrectFormatOfTaskFieldError(ValueError):
    """Raised when "tasks" field contains incorrectly specified tasks."""

MalformedProjectFileError

Bases: JSONDecodeError

Rased when project file content can't be correctly decoded.

Source code in cssfinder/cssfproject.py
class MalformedProjectFileError(json.decoder.JSONDecodeError):
    """Rased when project file content can't be correctly decoded."""

    def __str__(self) -> str:
        """Convert exception to readable error explanation."""
        p = " " * 4
        line_index = self.lineno

        start_index = line_index - 10
        if start_index < 0:
            start_index = 0

        lines = self.doc.split("\n")[start_index:line_index]
        lines_joined = f"{p}\n" + "\n".join(
            f"{start_index + i + 1:>4}|{p}{line}" for i, line in enumerate(lines)
        )
        ellipsis_line = f"{start_index:>4}|{p}..." if start_index != 0 else ""

        context_header = f"\n\n{ellipsis_line}{lines_joined}"
        pointer_line = f"{' ' * 4}{self.colno * ' '}~~~~^^^^^"

        msg = f"{self.msg}: line {self.lineno} column {self.colno} (char {self.pos})"
        return f"{context_header}\n{pointer_line}\n{p}{msg}.\n"

__str__

__str__() -> str

Convert exception to readable error explanation.

Source code in cssfinder/cssfproject.py
def __str__(self) -> str:
    """Convert exception to readable error explanation."""
    p = " " * 4
    line_index = self.lineno

    start_index = line_index - 10
    if start_index < 0:
        start_index = 0

    lines = self.doc.split("\n")[start_index:line_index]
    lines_joined = f"{p}\n" + "\n".join(
        f"{start_index + i + 1:>4}|{p}{line}" for i, line in enumerate(lines)
    )
    ellipsis_line = f"{start_index:>4}|{p}..." if start_index != 0 else ""

    context_header = f"\n\n{ellipsis_line}{lines_joined}"
    pointer_line = f"{' ' * 4}{self.colno * ' '}~~~~^^^^^"

    msg = f"{self.msg}: line {self.lineno} column {self.colno} (char {self.pos})"
    return f"{context_header}\n{pointer_line}\n{p}{msg}.\n"

ProjectFileNotFoundError

Bases: FileNotFoundError

Raised when project file can't be found in expected place.

Source code in cssfinder/cssfproject.py
class ProjectFileNotFoundError(FileNotFoundError):
    """Raised when project file can't be found in expected place."""

NotBoundToProjectError

Bases: Exception

Raised when unbound object is used in context requiring it to be bound to CSSFProject instance.

Source code in cssfinder/cssfproject.py
class NotBoundToProjectError(Exception):
    """Raised when unbound object is used in context requiring it to be bound to
    CSSFProject instance.
    """

    def __init__(self, ob: Any, context_msg: str) -> None:
        super().__init__(
            f"Attempted to use unbound object {ob} in context requiring it to be "
            f"bound. ({context_msg})",
        )

Meta

Bases: CommonBaseModel, _ProjectFieldMixin

Project meta information.

Source code in cssfinder/cssfproject.py
class Meta(CommonBaseModel, _ProjectFieldMixin):
    """Project meta information."""

    author: str
    """Author full name."""

    email: EmailStr
    """Author email address."""

    name: str
    """Name of the project."""

    description: str
    """Description of the project."""

    version: SemVerStr
    """Version of the project."""

    _project: Optional[CSSFProject] = None
    """Reference to project object."""

author instance-attribute

author: str

Author full name.

email instance-attribute

email: EmailStr

Author email address.

name instance-attribute

name: str

Name of the project.

description instance-attribute

description: str

Description of the project.

version instance-attribute

version: SemVerStr

Version of the project.

SemVerStr

Bases: ConstrainedStr

Semantic versioning string regex, see https://semver.org/.

Source code in cssfinder/cssfproject.py
class SemVerStr(ConstrainedStr):
    """Semantic versioning string regex, see https://semver.org/."""

    regex = (
        r"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-]"
        r"[0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+("
        r"[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"
    )

NotBoundToTaskError

Bases: NotBoundToProjectError

Raised when unbound object is used in context requiring it to be bound to Task instance.

Source code in cssfinder/cssfproject.py
class NotBoundToTaskError(NotBoundToProjectError):
    """Raised when unbound object is used in context requiring it to be bound to Task
    instance.
    """

Task

Bases: CommonBaseModel, _TaskMixin

Container representing CSSFinder task with some algorithm.

Source code in cssfinder/cssfproject.py
class Task(CommonBaseModel, _TaskMixin):
    """Container representing CSSFinder task with some algorithm."""

    gilbert: Optional[GilbertCfg] = Field(default=None)
    """Configuration of gilbert algorithm."""

    _project: Optional[CSSFProject] = None
    """Reference to project object."""

    _task_name: Optional[str] = None
    """Name of task assigned to it in project."""

    def bind(self, project: CSSFProject, task_name: Optional[str] = None) -> None:
        """Bind task to specific CSSFProject instance."""
        super().bind(project, task_name)
        if self.gilbert is not None:
            self.gilbert.bind(project, task_name, self)

gilbert class-attribute instance-attribute

gilbert: Optional[GilbertCfg] = Field(default=None)

Configuration of gilbert algorithm.

bind

bind(
    project: CSSFProject, task_name: Optional[str] = None
) -> None

Bind task to specific CSSFProject instance.

Source code in cssfinder/cssfproject.py
def bind(self, project: CSSFProject, task_name: Optional[str] = None) -> None:
    """Bind task to specific CSSFProject instance."""
    super().bind(project, task_name)
    if self.gilbert is not None:
        self.gilbert.bind(project, task_name, self)

GilbertCfg

Bases: CommonBaseModel, _TaskFieldMixin

Gilbert algorithm configuration container class.

Source code in cssfinder/cssfproject.py
class GilbertCfg(CommonBaseModel, _TaskFieldMixin):
    """Gilbert algorithm configuration container class."""

    mode: AlgoMode
    """Algorithm mode to use."""

    backend: Optional[BackendCfg] = Field(default=None)
    """Configuration of backend which will be used for execution.

    When backend configuration is not specified, numpy with double precision is used.

    """

    state: Union[State, str]
    """Path to file containing initial state matrix."""

    runtime: RuntimeCfg
    """Configuration of runtime limits and parameters influencing algorithm run time."""

    resources: Optional[Resources] = Field(default=None)
    """Additional resources which may be used by algorithm."""

    _project: Optional[CSSFProject] = None
    """Reference to project object."""

    _task_name: Optional[str] = None
    """Name of task assigned to it in project."""

    _task: Optional[Task] = None
    """Reference to task object containing this object."""

    @validator("state", always=True)
    @classmethod
    def _validate_state(cls, value: str | State) -> State:
        if not isinstance(value, State):
            return State(file=value)

        return value

    def get_backend(self) -> BackendCfg:
        """Return resources object."""
        if self.backend is None:
            self.backend = BackendCfg(name="numpy", precision=Precision.DOUBLE)
        return self.backend

    def get_resources(self) -> Resources:
        """Return resources object."""
        if self.resources is None:
            self.resources = Resources()
        return self.resources

    def bind(
        self,
        project: CSSFProject,
        task_name: Optional[str] = None,
        task: Optional[Task] = None,
    ) -> None:
        """Evaluate dynamic path expressions."""
        super().bind(project, task_name, task)
        if not isinstance(self.state, State):
            msg = "State field must be of State type."
            raise TypeError(msg)

        self.state.bind(project, task_name, task)
        self.get_resources().bind(project, task_name, task)

    def get_state(self) -> State:
        """Return initial state information."""
        if not isinstance(self.state, State):
            msg = "State field must be of State type."
            raise TypeError(msg)
        return self.state

mode instance-attribute

mode: AlgoMode

Algorithm mode to use.

backend class-attribute instance-attribute

backend: Optional[BackendCfg] = Field(default=None)

Configuration of backend which will be used for execution.

When backend configuration is not specified, numpy with double precision is used.

state instance-attribute

state: Union[State, str]

Path to file containing initial state matrix.

runtime instance-attribute

runtime: RuntimeCfg

Configuration of runtime limits and parameters influencing algorithm run time.

resources class-attribute instance-attribute

resources: Optional[Resources] = Field(default=None)

Additional resources which may be used by algorithm.

get_backend

get_backend() -> BackendCfg

Return resources object.

Source code in cssfinder/cssfproject.py
def get_backend(self) -> BackendCfg:
    """Return resources object."""
    if self.backend is None:
        self.backend = BackendCfg(name="numpy", precision=Precision.DOUBLE)
    return self.backend

get_resources

get_resources() -> Resources

Return resources object.

Source code in cssfinder/cssfproject.py
def get_resources(self) -> Resources:
    """Return resources object."""
    if self.resources is None:
        self.resources = Resources()
    return self.resources

bind

bind(
    project: CSSFProject,
    task_name: Optional[str] = None,
    task: Optional[Task] = None,
) -> None

Evaluate dynamic path expressions.

Source code in cssfinder/cssfproject.py
def bind(
    self,
    project: CSSFProject,
    task_name: Optional[str] = None,
    task: Optional[Task] = None,
) -> None:
    """Evaluate dynamic path expressions."""
    super().bind(project, task_name, task)
    if not isinstance(self.state, State):
        msg = "State field must be of State type."
        raise TypeError(msg)

    self.state.bind(project, task_name, task)
    self.get_resources().bind(project, task_name, task)

get_state

get_state() -> State

Return initial state information.

Source code in cssfinder/cssfproject.py
def get_state(self) -> State:
    """Return initial state information."""
    if not isinstance(self.state, State):
        msg = "State field must be of State type."
        raise TypeError(msg)
    return self.state

AlgoMode

Bases: CaseInsensitiveEnum

Mode of algorithm.

Source code in cssfinder/cssfproject.py
class AlgoMode(CaseInsensitiveEnum):
    """Mode of algorithm."""

    # pylint: disable=invalid-name

    FSnQd = "FSnQd"
    """Full separability of n-quDit state."""

    SBiPa = "SBiPa"
    """Separability of a bipartite state."""

    G3PaE3qD = "G3PaE3qD"
    """Genuine 3-partite entanglement of a 3-quDit state."""

    G4PaE3qD = "G4PaE3qD"
    """Genuine 4-partite entanglement of a 3-quDit state."""

FSnQd class-attribute instance-attribute

FSnQd = 'FSnQd'

Full separability of n-quDit state.

SBiPa class-attribute instance-attribute

SBiPa = 'SBiPa'

Separability of a bipartite state.

G3PaE3qD class-attribute instance-attribute

G3PaE3qD = 'G3PaE3qD'

Genuine 3-partite entanglement of a 3-quDit state.

G4PaE3qD class-attribute instance-attribute

G4PaE3qD = 'G4PaE3qD'

Genuine 4-partite entanglement of a 3-quDit state.

BackendCfg

Bases: CommonBaseModel

Container class grouping configuration of backend used by Gilbert algorithm.

Source code in cssfinder/cssfproject.py
class BackendCfg(CommonBaseModel):
    """Container class grouping configuration of backend used by Gilbert algorithm."""

    name: str
    """Name of backend to use."""

    precision: Precision
    """Specify precision of calculations."""

name instance-attribute

name: str

Name of backend to use.

precision instance-attribute

precision: Precision

Specify precision of calculations.

Precision

Bases: CaseInsensitiveEnum

Precision of calculations performed.

Source code in cssfinder/cssfproject.py
class Precision(CaseInsensitiveEnum):
    """Precision of calculations performed."""

    # pylint: disable=invalid-name

    DOUBLE = "double"
    """64 bit floating point real part with 64 bit floating point complex value."""

    SINGLE = "single"
    """32 bit floating point real part with 32 bit floating point complex value."""

DOUBLE class-attribute instance-attribute

DOUBLE = 'double'

64 bit floating point real part with 64 bit floating point complex value.

SINGLE class-attribute instance-attribute

SINGLE = 'single'

32 bit floating point real part with 32 bit floating point complex value.

State

Bases: CommonBaseModel, _TaskFieldMixin

State configuration.

Source code in cssfinder/cssfproject.py
class State(CommonBaseModel, _TaskFieldMixin):
    """State configuration."""

    file: str
    """Path to file containing state matrix."""

    depth: Optional[int] = Field(default=None)
    """Depth of system, ie.

    number of dimensions in qu(D)it. (d)

    """

    quantity: Optional[int] = Field(default=None)
    """Quantity of systems.

    ie. number of qu(D)its in state. (n)

    """

    _project: Optional[CSSFProject] = None
    """Reference to project object."""

    _task_name: Optional[str] = None
    """Name of task assigned to it in project."""

    _task: Optional[Task] = None
    """Reference to task object containing this object."""

    def bind(
        self,
        project: CSSFProject,
        task_name: Optional[str] = None,
        task: Optional[Task] = None,
    ) -> None:
        """Evaluate dynamic path expressions.

        Path expands user (~) and is resolved only when correctly bound to project.

        """
        super().bind(project, task_name, task)

        if task_name is None or task is None:
            return

    def is_predefined_dimensions(self) -> bool:
        """Return True when both dimensions are available."""
        return self.depth is not None and self.quantity is not None

    def get_depth(self) -> int:
        """Return system depth or raise NoDimensionsError if not specified in config."""
        if self.depth is None:
            msg = "Depth is not specified."
            raise NoDimensionsError(msg)
        return self.depth

    def get_quantity(self) -> int:
        """Return system quantity or raise NoDimensionsError if not specified in
        config.
        """
        if self.quantity is None:
            msg = "quantity is not specified."
            raise NoDimensionsError(msg)
        return self.quantity

    @property
    def expanded_file(self) -> str:
        """Return expanded path to file."""
        if self._project is None:
            raise NotBoundToProjectError(self, "Access to 'expanded_file' property.")
        return (
            Path(
                self.file.format(
                    project=self.project,
                    task_name=self.task_name,
                    task=self.task,
                ),
            )
            .expanduser()
            .resolve()
            .as_posix()
        )

file instance-attribute

file: str

Path to file containing state matrix.

depth class-attribute instance-attribute

depth: Optional[int] = Field(default=None)

Depth of system, ie.

number of dimensions in qu(D)it. (d)

quantity class-attribute instance-attribute

quantity: Optional[int] = Field(default=None)

Quantity of systems.

ie. number of qu(D)its in state. (n)

expanded_file property

expanded_file: str

Return expanded path to file.

bind

bind(
    project: CSSFProject,
    task_name: Optional[str] = None,
    task: Optional[Task] = None,
) -> None

Evaluate dynamic path expressions.

Path expands user (~) and is resolved only when correctly bound to project.

Source code in cssfinder/cssfproject.py
def bind(
    self,
    project: CSSFProject,
    task_name: Optional[str] = None,
    task: Optional[Task] = None,
) -> None:
    """Evaluate dynamic path expressions.

    Path expands user (~) and is resolved only when correctly bound to project.

    """
    super().bind(project, task_name, task)

    if task_name is None or task is None:
        return

is_predefined_dimensions

is_predefined_dimensions() -> bool

Return True when both dimensions are available.

Source code in cssfinder/cssfproject.py
def is_predefined_dimensions(self) -> bool:
    """Return True when both dimensions are available."""
    return self.depth is not None and self.quantity is not None

get_depth

get_depth() -> int

Return system depth or raise NoDimensionsError if not specified in config.

Source code in cssfinder/cssfproject.py
def get_depth(self) -> int:
    """Return system depth or raise NoDimensionsError if not specified in config."""
    if self.depth is None:
        msg = "Depth is not specified."
        raise NoDimensionsError(msg)
    return self.depth

get_quantity

get_quantity() -> int

Return system quantity or raise NoDimensionsError if not specified in config.

Source code in cssfinder/cssfproject.py
def get_quantity(self) -> int:
    """Return system quantity or raise NoDimensionsError if not specified in
    config.
    """
    if self.quantity is None:
        msg = "quantity is not specified."
        raise NoDimensionsError(msg)
    return self.quantity

NoDimensionsError

Bases: ValueError

Raised when system dimensions were requested but are not specified in config.

Source code in cssfinder/cssfproject.py
class NoDimensionsError(ValueError):
    """Raised when system dimensions were requested but are not specified in config."""

RuntimeCfg

Bases: CommonBaseModel

Configuration of runtime limits and parameters influencing algorithm run time.

Source code in cssfinder/cssfproject.py
class RuntimeCfg(CommonBaseModel):
    """Configuration of runtime limits and parameters influencing algorithm run time."""

    visibility: float = Field(ge=0.0, le=1.0)
    """Visibility against white noise.

    Between 0 and 1.

    """

    max_epochs: int = Field(ge=1, le=1_000_000_000)
    """Maximal number of algorithm epochs to perform.

    If other interruption condition is met before the number of epochs, algorithm wont
    execute the rest of epochs.

    """

    iters_per_epoch: int = Field(ge=1, le=1_000_000_000)
    """Number of iterations per epochs.

    Between iterations no checks are performed, which may speed up calculations. However
    intermediate state of systems are not saved anywhere.

    """

    max_corrections: int
    """Maximal number of corrections to collect.

    Use -1 to disable this limit.

    """

visibility class-attribute instance-attribute

visibility: float = Field(ge=0.0, le=1.0)

Visibility against white noise.

Between 0 and 1.

max_epochs class-attribute instance-attribute

max_epochs: int = Field(ge=1, le=1000000000)

Maximal number of algorithm epochs to perform.

If other interruption condition is met before the number of epochs, algorithm wont execute the rest of epochs.

iters_per_epoch class-attribute instance-attribute

iters_per_epoch: int = Field(ge=1, le=1000000000)

Number of iterations per epochs.

Between iterations no checks are performed, which may speed up calculations. However intermediate state of systems are not saved anywhere.

max_corrections instance-attribute

max_corrections: int

Maximal number of corrections to collect.

Use -1 to disable this limit.

Resources

Bases: CommonBaseModel, _TaskFieldMixin

Project resources.

Source code in cssfinder/cssfproject.py
class Resources(CommonBaseModel, _TaskFieldMixin):
    """Project resources."""

    symmetries: Optional[List[List[str]]] = Field(default=None)
    """List of paths to files containing symmetry matrices."""

    projection: Optional[str] = Field(default=None)
    """Path to file containing projection matrix."""

    _project: Optional[CSSFProject] = None
    """Reference to project object."""

    _task_name: Optional[str] = None
    """Name of task assigned to it in project."""

    _task: Optional[Task] = None
    """Reference to task object containing this object."""

    def bind(
        self,
        project: CSSFProject,
        task_name: Optional[str] = None,
        task: Optional[Task] = None,
    ) -> None:
        """Evaluate dynamic path expressions.

        Paths expands user (~) and are resolved only when correctly bound to project.

        """
        super().bind(project, task_name, task)

        if task_name is None or task is None:
            return

        if self.symmetries is not None:
            self.symmetries = [
                [
                    Path(
                        sym.format(
                            project=project,
                            task_name=task_name,
                            task=task,
                        ),
                    )
                    .expanduser()
                    .resolve()
                    .as_posix()
                    for sym in row
                ]
                for row in self.symmetries
            ]

        if self.projection is not None:
            self.projection = (
                Path(
                    self.projection.format(
                        project=project,
                        task_name=task_name,
                        task=task,
                    ),
                )
                .expanduser()
                .resolve()
                .as_posix()
            )

symmetries class-attribute instance-attribute

symmetries: Optional[List[List[str]]] = Field(default=None)

List of paths to files containing symmetry matrices.

projection class-attribute instance-attribute

projection: Optional[str] = Field(default=None)

Path to file containing projection matrix.

bind

bind(
    project: CSSFProject,
    task_name: Optional[str] = None,
    task: Optional[Task] = None,
) -> None

Evaluate dynamic path expressions.

Paths expands user (~) and are resolved only when correctly bound to project.

Source code in cssfinder/cssfproject.py
def bind(
    self,
    project: CSSFProject,
    task_name: Optional[str] = None,
    task: Optional[Task] = None,
) -> None:
    """Evaluate dynamic path expressions.

    Paths expands user (~) and are resolved only when correctly bound to project.

    """
    super().bind(project, task_name, task)

    if task_name is None or task is None:
        return

    if self.symmetries is not None:
        self.symmetries = [
            [
                Path(
                    sym.format(
                        project=project,
                        task_name=task_name,
                        task=task,
                    ),
                )
                .expanduser()
                .resolve()
                .as_posix()
                for sym in row
            ]
            for row in self.symmetries
        ]

    if self.projection is not None:
        self.projection = (
            Path(
                self.projection.format(
                    project=project,
                    task_name=task_name,
                    task=task,
                ),
            )
            .expanduser()
            .resolve()
            .as_posix()
        )

project_file_path

project_file_path(directory_or_file: Path) -> Path

Return path to project file (JSON/PY).

Source code in cssfinder/cssfproject.py
def project_file_path(directory_or_file: Path) -> Path:
    """Return path to project file (JSON/PY)."""
    if directory_or_file.is_file():
        return directory_or_file

    json_file = directory_or_file / "cssfproject.json"

    if directory_or_file.is_dir() and json_file.exists():
        return json_file

    py_file = directory_or_file / "cssfproject.py"

    if directory_or_file.is_dir() and py_file.exists():
        return py_file

    raise FileNotFoundError(directory_or_file)