Skip to content

Commit ae6854e

Browse files
committed
fixed all docstrings
1 parent 8f05c16 commit ae6854e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+381
-146
lines changed

RATapi/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""RATapi is a Python package for modelling, fitting and optimising reflectivity problems."""
12
import RATapi.examples as examples
23
from RATapi import events, models
34
from RATapi.classlist import ClassList

RATapi/classlist.py

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
"""The classlist module. Contains the ClassList class, which defines a list containing instances of a particular
2-
class.
3-
"""
1+
"""The ClassList class, which defines a list containing instances of a particular class."""
42

53
import collections
64
import contextlib
@@ -24,18 +22,18 @@ class ClassList(collections.UserList, Generic[T]):
2422
attribute given in the ClassList's "name_field" attribute (the default is "name"), the ClassList will ensure that
2523
all objects within the ClassList have unique values for that attribute. It is then possible to use this attribute
2624
of an object in the .remove(), .count(), and .index() routines in place of the full object. Due to the requirement
27-
of unique values of the name_field attribute, the multiplication operators __mul__, __rmul__, and __imul__ have
25+
of unique values of the ``name_field`` attribute, the multiplication operators __mul__, __rmul__, and __imul__ have
2826
been disabled, since they cannot allow for unique attribute values by definition.
2927
3028
We extend the UserList class to enable objects to be added and modified using just the keyword arguments, enable
31-
the object name_field attribute to be used in place of the full object, and ensure all elements are of the
32-
specified type, with unique name_field attributes defined.
29+
the object ``name_field`` attribute to be used in place of the full object, and ensure all elements are of the
30+
specified type, with unique ``name_field`` attributes defined.
3331
3432
Parameters
3533
----------
3634
init_list : Sequence [T] or T, optional
3735
An instance, or list of instance(s), of the class to be used in this ClassList.
38-
name_field : str, optional
36+
``name_field`` : str, optional
3937
The field used to define unique objects in the ClassList (default is "name").
4038
4139
"""
@@ -171,8 +169,9 @@ def __imul__(self, n: int) -> None:
171169
raise TypeError(f"unsupported operand type(s) for *=: '{self.__class__.__name__}' and '{n.__class__.__name__}'")
172170

173171
def append(self, obj: T = None, **kwargs) -> None:
174-
"""Append a new object to the ClassList using either the object itself, or keyword arguments to set attribute
175-
values.
172+
"""Append a new object to the ClassList.
173+
174+
This method can use the object itself, or can provide attribute values as keyword arguments for a new object.
176175
177176
Parameters
178177
----------
@@ -184,7 +183,7 @@ def append(self, obj: T = None, **kwargs) -> None:
184183
Raises
185184
------
186185
ValueError
187-
Raised if the input arguments contain a name_field value already defined in the ClassList.
186+
Raised if the input arguments contain a ``name_field`` value already defined in the ClassList.
188187
189188
Warnings
190189
--------
@@ -216,8 +215,9 @@ def append(self, obj: T = None, **kwargs) -> None:
216215
self.data.append(self._class_handle(**kwargs))
217216

218217
def insert(self, index: int, obj: T = None, **kwargs) -> None:
219-
"""Insert a new object into the ClassList at a given index using either the object itself, or keyword arguments
220-
to set attribute values.
218+
"""Insert a new object at a given index.
219+
220+
This method can use the object itself, or can provide attribute values as keyword arguments for a new object.
221221
222222
Parameters
223223
----------
@@ -231,7 +231,7 @@ def insert(self, index: int, obj: T = None, **kwargs) -> None:
231231
Raises
232232
------
233233
ValueError
234-
Raised if the input arguments contain a name_field value already defined in the ClassList.
234+
Raised if the input arguments contain a ``name_field`` value already defined in the ClassList.
235235
236236
Warnings
237237
--------
@@ -263,20 +263,25 @@ def insert(self, index: int, obj: T = None, **kwargs) -> None:
263263
self.data.insert(index, self._class_handle(**kwargs))
264264

265265
def remove(self, item: Union[T, str]) -> None:
266-
"""Remove an object from the ClassList using either the object itself or its name_field value."""
266+
"""Remove an object from the ClassList using either the object itself or its ``name_field`` value."""
267267
item = self._get_item_from_name_field(item)
268268
self.data.remove(item)
269269

270270
def count(self, item: Union[T, str]) -> int:
271-
"""Return the number of times an object appears in the ClassList using either the object itself or its
272-
name_field value.
271+
"""Return the number of times an object appears in the ClassList.
272+
273+
This method can use either the object itself or its ``name_field`` value.
274+
273275
"""
274276
item = self._get_item_from_name_field(item)
275277
return self.data.count(item)
276278

277279
def index(self, item: Union[T, str], offset: bool = False, *args) -> int:
278-
"""Return the index of a particular object in the ClassList using either the object itself or its
279-
name_field value. If offset is specified, add one to the index. This is used to account for one-based indexing.
280+
"""Return the index of a particular object in the ClassList.
281+
282+
This method can use either the object itself or its ``name_field`` value.
283+
If offset is specified, add one to the index. This is used to account for one-based indexing.
284+
280285
"""
281286
item = self._get_item_from_name_field(item)
282287
return self.data.index(item, *args) + int(offset)
@@ -357,12 +362,12 @@ def __exit__(self, exctype, excinst, exctb):
357362
self._class_handle.model_validate(self.data[index])
358363

359364
def get_names(self) -> list[str]:
360-
"""Return a list of the values of the name_field attribute of each class object in the list.
365+
"""Return a list of the values of the ``name_field`` attribute of each class object in the list.
361366
362367
Returns
363368
-------
364369
names : list [str]
365-
The value of the name_field attribute of each object in the ClassList.
370+
The value of the ``name_field`` attribute of each object in the ClassList.
366371
367372
"""
368373
return [getattr(model, self.name_field) for model in self.data if hasattr(model, self.name_field)]
@@ -389,8 +394,7 @@ def get_all_matches(self, value: Any) -> list[tuple]:
389394
]
390395

391396
def _validate_name_field(self, input_args: dict[str, Any]) -> None:
392-
"""Raise a ValueError if the name_field attribute is passed as an object parameter, and its value is already
393-
used within the ClassList.
397+
"""Raise a ValueError if the user tries to add an object with a ``name_field`` already in the ClassList.
394398
395399
Parameters
396400
----------
@@ -400,7 +404,7 @@ def _validate_name_field(self, input_args: dict[str, Any]) -> None:
400404
Raises
401405
------
402406
ValueError
403-
Raised if the input arguments contain a name_field value already defined in the ClassList.
407+
Raised if the input arguments contain a ``name_field`` value already defined in the ClassList.
404408
405409
"""
406410
names = [name.lower() for name in self.get_names()]
@@ -413,8 +417,7 @@ def _validate_name_field(self, input_args: dict[str, Any]) -> None:
413417
)
414418

415419
def _check_unique_name_fields(self, input_list: Sequence[T]) -> None:
416-
"""Raise a ValueError if any value of the name_field attribute is used more than once in a list of class
417-
objects.
420+
"""Raise a ValueError if any value of the ``name_field`` attribute is repeated in a list of class objects.
418421
419422
Parameters
420423
----------
@@ -470,17 +473,17 @@ def _check_unique_name_fields(self, input_list: Sequence[T]) -> None:
470473
)
471474

472475
def _check_classes(self, input_list: Sequence[T]) -> None:
473-
"""Raise a ValueError if any object in a list of objects is not of the type specified by self._class_handle.
476+
"""Raise a ValueError if any object in a list of objects is not of the type specified by ``self._class_handle``.
474477
475478
Parameters
476479
----------
477480
input_list : iterable
478-
A list of instances of the class given in self._class_handle.
481+
A list of instances of the class given in ``self._class_handle``.
479482
480483
Raises
481484
------
482485
ValueError
483-
Raised if the input list contains objects of any type other than that given in self._class_handle.
486+
If the input list contains objects of any type other than that given in ``self._class_handle``.
484487
485488
"""
486489
error_list = []
@@ -495,18 +498,18 @@ def _check_classes(self, input_list: Sequence[T]) -> None:
495498
)
496499

497500
def _get_item_from_name_field(self, value: Union[T, str]) -> Union[T, str]:
498-
"""Return the object with the given value of the name_field attribute in the ClassList.
501+
"""Return the object with the given value of the ``name_field`` attribute in the ClassList.
499502
500503
Parameters
501504
----------
502505
value : T or str
503-
Either an object in the ClassList, or the value of the name_field attribute of an object in the ClassList.
506+
Either an object in the ClassList, or the value of the ``name_field`` for an object in the ClassList.
504507
505508
Returns
506509
-------
507510
instance : T or str
508-
Either the object with the value of the name_field attribute given by value, or the input value if an
509-
object with that value of the name_field attribute cannot be found.
511+
Either the object with the value of the ``name_field`` attribute given by value, or the input value if an
512+
object with that value of the ``name_field`` attribute cannot be found.
510513
511514
"""
512515
try:
@@ -518,24 +521,27 @@ def _get_item_from_name_field(self, value: Union[T, str]) -> Union[T, str]:
518521

519522
@staticmethod
520523
def _determine_class_handle(input_list: Sequence[T]):
521-
"""When inputting a sequence of object to a ClassList, the _class_handle should be set as the type of the
522-
element which satisfies "issubclass" for all the other elements.
524+
"""Determine the class handle from a sequence of objects.
525+
526+
The ``_class_handle`` of the sequence is the type of the first element in the sequence
527+
which is a subclass of all elements in the sequence. If no such element exists, the handle
528+
is set to be the type of the first element in the list.
523529
524530
Parameters
525531
----------
526-
input_list : Sequence [object]
532+
input_list : Sequence[T]
527533
A list of instances to populate the ClassList.
528534
529535
Returns
530536
-------
531537
class_handle : type
532-
The type object of the element fulfilling the condition of satisfying "issubclass" for all of the other
533-
elements.
538+
The type object of the first element which is a subcalss of all of the other
539+
elements, or the first element if no such element exists.
534540
535541
"""
536-
for this_element in input_list:
537-
if all([issubclass(type(instance), type(this_element)) for instance in input_list]):
538-
class_handle = type(this_element)
542+
for element in input_list:
543+
if all(issubclass(type(instance), type(element)) for instance in input_list):
544+
class_handle = type(element)
539545
break
540546
else:
541547
class_handle = type(input_list[0])

RATapi/controls.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""The Controls class for providing RAT algorithm settings."""
12
import contextlib
23
import os
34
import tempfile
@@ -196,14 +197,14 @@ def __str__(self) -> str:
196197
return table.get_string()
197198

198199
def initialise_IPC(self):
199-
"""Setup the inter-process communication file."""
200+
"""Set up the inter-process communication file."""
200201
IPC_obj, self._IPCFilePath = tempfile.mkstemp()
201202
os.write(IPC_obj, b"0")
202203
os.close(IPC_obj)
203204
return None
204205

205206
def sendStopEvent(self):
206-
"""Sends the stop event via the inter-process communication file.
207+
"""Send the stop event via the inter-process communication file.
207208
208209
Warnings:
209210
--------

RATapi/events.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1+
"""Hooks for connecting to run callback events."""
12
import os
23
from typing import Callable, Union
34

45
from RATapi.rat_core import EventBridge, EventTypes, PlotEventData, ProgressEventData
56

67

78
def notify(event_type: EventTypes, data: Union[str, PlotEventData, ProgressEventData]) -> None:
8-
"""Calls registered callbacks with the data when event type has
9-
been triggered.
9+
"""Call registered callbacks with data when event type has been triggered.
1010
1111
Parameters
1212
----------
@@ -22,7 +22,7 @@ def notify(event_type: EventTypes, data: Union[str, PlotEventData, ProgressEvent
2222

2323

2424
def get_event_callback(event_type: EventTypes) -> list[Callable[[Union[str, PlotEventData, ProgressEventData]], None]]:
25-
"""Returns all callbacks registered for the given event type.
25+
"""Return all callbacks registered for the given event type.
2626
2727
Parameters
2828
----------
@@ -39,7 +39,7 @@ def get_event_callback(event_type: EventTypes) -> list[Callable[[Union[str, Plot
3939

4040

4141
def register(event_type: EventTypes, callback: Callable[[Union[str, PlotEventData, ProgressEventData]], None]) -> None:
42-
"""Registers a new callback for the event type.
42+
"""Register a new callback for the event type.
4343
4444
Parameters
4545
----------
@@ -58,12 +58,14 @@ def register(event_type: EventTypes, callback: Callable[[Union[str, PlotEventDat
5858

5959

6060
def clear(key=None, callback=None) -> None:
61-
"""Clears all event callbacks or specific callback.
61+
"""Clear all event callbacks or specific callback.
6262
6363
Parameters
6464
----------
65-
callback : Callable[[Union[str, PlotEventData, ProgressEventData]], None]
66-
The callback for when the event is triggered.
65+
key : EventTypes, optional
66+
The event type of the callback to clear if given.
67+
callback : Callable[[Union[str, PlotEventData, ProgressEventData]], None], optional
68+
A callback for an event which will be cleared if given.
6769
6870
"""
6971
if key is None and callback is None:

RATapi/examples/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""Usage examples for the Python RAT API."""
12
from RATapi.examples.absorption.absorption import absorption
23
from RATapi.examples.convert_rascal_project.convert_rascal import convert_rascal
34
from RATapi.examples.domains.domains_custom_layers import domains_custom_layers
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""An example of using absorption in a RAT project."""

RATapi/examples/absorption/absorption.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
1+
"""An example for using absorption in RAT."""
2+
13
import pathlib
24

35
import numpy as np
46

57
import RATapi as RAT
68

79

8-
def absorption():
9-
"""Custom layers model including absorption"""
10+
def absorption() -> (RAT.Project, RAT.outputs.Results):
11+
"""Run a custom layers model including absorption.
12+
13+
RAT allows the use of an imaginary, as well as real part of the SLD.
14+
The effect of this is usually seen below the critical edge, and must sometimes be accounted for.
15+
16+
This is an example of a Custom Layers project using absorption. used here is Custom Layers.
17+
It analyses a bilayer sample on a permalloy / gold substrate,
18+
measured using polarised neutrons, against D2O and H2O, leading to 4 contrasts in total.
19+
Absorption (i.e. imaginary SLD) is defined for Gold and the Permalloy,
20+
to account for non-flat data below the critical edge.
21+
"""
1022
problem = RAT.Project(
1123
name="Absorption example",
1224
calculation="normal",

RATapi/examples/absorption/volume_thiol_bilayer.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Custom layer model file for the absorption example."""
2+
13
def volume_thiol_bilayer(params, bulk_in, bulk_out, contrast):
24
"""VolumeThiolBilayer RAT Custom Layer Model File.
35

RATapi/examples/bayes_benchmark/bayes_benchmark.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
"""This example compares three Bayesian posteriors for a low-dimensional
1+
"""An example script to compare different methods of Bayesian fitting.
2+
3+
This example compares three Bayesian posteriors for a low-dimensional
24
example: a posterior generated by DREAM, one generated by NS, and
35
one calculated directly.
46
@@ -33,6 +35,7 @@
3335
# this is the RasCAL-1 default project
3436
# it is a bare D2O substrate
3537
def get_project() -> RAT.Project:
38+
"""Create the project used as our example."""
3639
return RAT.Project(
3740
name="Bare D2O Substrate",
3841
calculation="normal",

RATapi/examples/convert_rascal_project/Model_IIb.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
"""A custom model file for a monolayer volume model."""
12
from math import cos, radians
23

34

45
def Model_IIb(params, bulk_in, bulk_out, contrast):
6+
"""Calculate layer parameters for a monolayer volume model at two deuterations."""
57
# converted from matlab file Model_IIb.m
68

79
Roughness, APM, thickHead, theta = params

0 commit comments

Comments
 (0)