Skip to content

tiers

Home

Bases: HomeTierBase

Home Tier.

This, or a subclass of this should generally be the first entry in your hierarchy, essentially represents the top level folder in your hierarchy.

Source code in cassini/defaults/tiers.py
19
20
21
22
23
24
25
26
27
class Home(HomeTierBase):
    """
    Home `Tier`.

    This, or a subclass of this should generally be the first entry in your hierarchy, essentially represents the top
    level folder in your hierarchy.
    """

    pretty_type = "Home"

WorkPackage

Bases: NotebookTierBase

WorkPackage Tier.

Intended to contain all the work towards a particular goal. i.e. prove that we can do this.

Next level down are Experiments.

Source code in cassini/defaults/tiers.py
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class WorkPackage(NotebookTierBase):
    """
    WorkPackage Tier.

    Intended to contain all the work towards a particular goal. i.e. prove that we can do this.

    Next level down are `Experiment`s.
    """

    pretty_type = "WorkPackage"
    name_part_template = "WP{}"
    short_type = "wp"

    @property
    def exps(self) -> Sequence[TierABC]:
        """
        Gets a list of all this `WorkPackage`s experiments.
        """
        return list(self)

exps property

exps

Gets a list of all this WorkPackages experiments.

Experiment

Bases: NotebookTierBase

Experiment Tier.

Just below WorkPackage, experiments are intended to be collections of samples and datasets that work towards the goal of the parent WorkPackage.

Each Experiment has a number of samples.

Source code in cassini/defaults/tiers.py
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
class Experiment(NotebookTierBase):
    """
    Experiment `Tier`.

    Just below `WorkPackage`, experiments are intended to be collections of samples and datasets that work towards the
    goal of the parent `WorkPackage`.

    Each `Experiment` has a number of samples.
    """

    pretty_type = "Experiment"
    name_part_template = ".{}"
    short_type = "exp"

    @property
    def techniques(self) -> Sequence[str]:
        """
        Convenience property for looking up all the techniques that have been performed on samples in this experiment.

        Notes
        -----
        This just checks for the existence of DataSet folders, and not if they have anything in them!
        """
        techs = []
        for entry in os.scandir(self.folder):
            if entry.is_dir() and not ignore_dir(entry.name):
                techs.append(entry.name)
        return techs

    def setup_technique(self, name: str) -> None:
        """
        Convenience method for adding a new technique to this experiment.

        Essentially just creates a new folder for it in the appropriate location.

        This folder can then be filled with `DataSet`s
        """
        print("Making Data Folder")
        folder = self.folder / name

        if folder.exists():
            raise FileExistsError(f"{folder} exists already")

        with FileMaker() as maker:
            maker.mkdir(folder)

        print("Done")

    @property
    def smpls(self) -> Sequence[TierABC]:
        """
        Get a list of this `Experiment`s samples.
        """
        return list(self)

techniques property

techniques

Convenience property for looking up all the techniques that have been performed on samples in this experiment.

Notes

This just checks for the existence of DataSet folders, and not if they have anything in them!

smpls property

smpls

Get a list of this Experiments samples.

setup_technique

setup_technique(name)

Convenience method for adding a new technique to this experiment.

Essentially just creates a new folder for it in the appropriate location.

This folder can then be filled with DataSets

Source code in cassini/defaults/tiers.py
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
def setup_technique(self, name: str) -> None:
    """
    Convenience method for adding a new technique to this experiment.

    Essentially just creates a new folder for it in the appropriate location.

    This folder can then be filled with `DataSet`s
    """
    print("Making Data Folder")
    folder = self.folder / name

    if folder.exists():
        raise FileExistsError(f"{folder} exists already")

    with FileMaker() as maker:
        maker.mkdir(folder)

    print("Done")

Sample

Bases: NotebookTierBase

Sample Tier.

A Sample is intended to represent some object that you collect data on.

As such, each sample has its own DataSets.

Notes

A Sample id can't start with a number and can't contain '-' (dashes), as these confuse the name parser.

Source code in cassini/defaults/tiers.py
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
class Sample(NotebookTierBase):
    """
    Sample `Tier`.

    A `Sample` is intended to represent some object that you collect data on.

    As such, each sample has its own `DataSet`s.

    Notes
    -----
    A `Sample` id can't start with a number and can't contain `'-'` (dashes), as these confuse the name parser.
    """

    pretty_type = "Sample"
    name_part_template = "{}"
    id_regex = r"([^0-9^-][^-]*)"

    @cached_prop
    def folder(self) -> Path:
        assert self.parent
        return self.parent.folder

    @property
    def datasets(self) -> Sequence[TierABC]:
        """
        Convenient way of getting a list of `DataSet`s this sample has.
        """
        assert self.parent
        assert self.child_cls
        assert isinstance(self.parent, Experiment)

        techs = []
        for technique in self.parent.techniques:
            dataset = self.child_cls(*self.identifiers, technique, project=self.project)
            if dataset.exists():
                techs.append(dataset)
        return techs

    def __iter__(self) -> Iterator[TierABC]:
        return iter(self.datasets)

datasets property

datasets

Convenient way of getting a list of DataSets this sample has.

DataSet

Bases: FolderTierBase

DataSet Tier.

The final tier, intended to represent a folder containing a collection of files relating to a particular Sample.

Source code in cassini/defaults/tiers.py
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
class DataSet(FolderTierBase):
    """
    `DataSet` Tier.

    The final tier, intended to represent a folder containing a collection of files relating to a particular `Sample`.
    """

    pretty_type = "DataSet"
    short_type = "dset"
    name_part_template = "-{}"

    id_regex = r"(.+)"

    @cached_prop
    def folder(self) -> Path:
        assert self.parent

        return self.parent / self.id / self.parent.id

    def exists(self) -> bool:
        return self.folder.exists()

    def __truediv__(self, other: Any) -> Path:
        return cast(Path, self.folder / other)

    def __iter__(self) -> Iterator["os.DirEntry[Any]"]:
        """
        Call `os.scandir` on `self.folder`.
        """
        yield from os.scandir(self.folder)

    def __fspath__(self) -> str:
        return self.folder.__fspath__()

__iter__

__iter__()

Call os.scandir on self.folder.

Source code in cassini/defaults/tiers.py
174
175
176
177
178
def __iter__(self) -> Iterator["os.DirEntry[Any]"]:
    """
    Call `os.scandir` on `self.folder`.
    """
    yield from os.scandir(self.folder)