Skip to content

Commit

Permalink
Enh/waterlog (#23)
Browse files Browse the repository at this point in the history
* add waterlog result and water restriction models

* remove temp file

* improve behavior session docs

* formatting

* further doc improvements
  • Loading branch information
mochic authored Jul 24, 2024
1 parent dd5f362 commit e9ab523
Show file tree
Hide file tree
Showing 4 changed files with 242 additions and 31 deletions.
4 changes: 4 additions & 0 deletions src/aind_slims_api/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from aind_slims_api.models.mouse import SlimsMouseContent
from aind_slims_api.models.unit import SlimsUnit
from aind_slims_api.models.user import SlimsUser
from aind_slims_api.models.waterlog_result import SlimsWaterlogResult
from aind_slims_api.models.waterlog_water_restriction import SlimsWaterRestrictionEvent

__all__ = [
"SlimsAttachment",
Expand All @@ -16,4 +18,6 @@
"SlimsMouseContent",
"SlimsUnit",
"SlimsUser",
"SlimsWaterlogResult",
"SlimsWaterRestrictionEvent",
]
61 changes: 30 additions & 31 deletions src/aind_slims_api/models/behavior_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,44 +16,22 @@
class SlimsBehaviorSession(SlimsBaseModel):
"""Model for an instance of the Behavior Session ContentEvent
Properties
----------
mouse_pk : Optional[int]
The primary key of the mouse associated with this behavior session.
instrument_pk : Optional[int]
The primary key of the instrument associated with this behavior session.
trainer_pks : Optional[list[int]]
The primary keys of the trainers associated with this behavior session.
task : Optional[str]
Name of the task associated with the session.
task_stage : Optional[str]
Name of the stage associated with the session.
task_schema_version : Optional[str]
Version of the task schema.
is_curriculum_suggestion : Optional[bool]
Whether the session is a curriculum suggestion.
date : Optional[datetime]
Date of the suggestion.
notes : Optional[str]
Notes about the session.
Examples
--------
Read a session.
>>> from datetime import datetime
>>> from aind_slims_api import SlimsClient
>>> from aind_slims_api.models import SlimsMouseContent
>>> from aind_slims_api import models
>>> client = SlimsClient()
>>> mouse = client.fetch_model(SlimsMouseContent, barcode="00000000")
>>> mouse = client.fetch_model(models.SlimsMouseContent, barcode="00000000")
### Read
>>> behavior_sessions = client.fetch_models(SlimsBehaviorSession,
... mouse_pk=mouse.pk, sort=["date"])
>>> curriculum_attachments = client.fetch_attachments(behavior_sessions[0])
Write a new session.
>>> from aind_slims_api.models import SlimsInstrument, SlimsUser
>>> trainer = client.fetch_model(SlimsUser, username="LKim")
>>> instrument = client.fetch_model(SlimsInstrument, name="323_EPHYS1_OPTO")
### Write
>>> trainer = client.fetch_model(models.SlimsUser, username="LKim")
>>> instrument = client.fetch_model(models.SlimsInstrument, name="323_EPHYS1_OPTO")
>>> added = client.add_model(
... SlimsBehaviorSession(
... mouse_pk=mouse.pk,
Expand All @@ -68,14 +46,35 @@ class SlimsBehaviorSession(SlimsBaseModel):
... )
... )
Add a curriculum attachment to the session (Attachment content isn't
available immediately.)
### Add a curriculum attachment
Attachment content isn't available immediately.
>>> import json
>>> attachment_pk = client.add_attachment_content(
... added,
... "curriculum",
... json.dumps({"curriculum_key": "curriculum_value"}),
... )
Properties
----------
mouse_pk : Optional[int]
The primary key of the mouse associated with this behavior session.
instrument_pk : Optional[int]
The primary key of the instrument associated with this behavior session.
trainer_pks : Optional[list[int]]
The primary keys of the trainers associated with this behavior session.
task : Optional[str]
Name of the task associated with the session.
task_stage : Optional[str]
Name of the stage associated with the session.
task_schema_version : Optional[str]
Version of the task schema.
is_curriculum_suggestion : Optional[bool]
Whether the session is a curriculum suggestion.
date : Optional[datetime]
Date of the suggestion.
notes : Optional[str]
Notes about the session.
"""

pk: Optional[int] = Field(
Expand Down
125 changes: 125 additions & 0 deletions src/aind_slims_api/models/waterlog_result.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
"""Contains a model for a waterlog result stored in SLIMS."""

from datetime import datetime
from typing import Annotated, ClassVar, Optional

from pydantic import Field

from aind_slims_api import __version__
from aind_slims_api.models.base import SlimsBaseModel
from aind_slims_api.models.utils import UnitSpec


class SlimsWaterlogResult(SlimsBaseModel):
"""Model for a SLIMS Waterlog Result, the daily water/weight records
Examples
--------
>>> from aind_slims_api.core import SlimsClient
>>> from aind_slims_api import models
>>> client = SlimsClient()
>>> mouse = client.fetch_model(models.SlimsMouseContent, barcode="00000000")
>>> test_pk = client.fetch_pk("Test", test_name="test_waterlog")
Write waterlog result.
>>> waterlog_result = client.add_model(
... models.SlimsWaterlogResult(
... mouse_pk=mouse.pk,
... date=datetime(2021,1,1),
... weight_g=20.0,
... water_earned_ml=5.0,
... water_supplement_delivered_ml=5.0,
... water_supplement_recommended_ml=5.0,
... total_water_ml=10.0,
... comments="comments",
... workstation="aibs-computer-id",
... test_pk=test_pk,
... )
... )
Read a waterlog result.
>>> waterlog_results = client.fetch_models(
... models.SlimsWaterlogResult,
... mouse_pk=mouse.pk,
... sort=["date"],
... )
>>> waterlog_results[-1].weight_g
20.0
"""

date: datetime = Field(
datetime.now(),
serialization_alias="rslt_cf_datePerformed",
validation_alias="rslt_cf_datePerformed",
)
operator: Optional[str] = Field(
None,
serialization_alias="rslt_cf_waterlogOperator",
validation_alias="rslt_cf_waterlogOperator",
)
weight_g: Annotated[float | None, UnitSpec("g")] = Field(
None,
serialization_alias="rslt_cf_weight",
validation_alias="rslt_cf_weight",
)
water_earned_ml: Annotated[float | None, UnitSpec("ml")] = Field(
...,
serialization_alias="rslt_cf_waterEarned",
validation_alias="rslt_cf_waterEarned",
)
water_supplement_delivered_ml: Annotated[float | None, UnitSpec("ml")] = Field(
...,
serialization_alias="rslt_cf_waterSupplementDelivered",
validation_alias="rslt_cf_waterSupplementDelivered",
)
water_supplement_recommended_ml: Annotated[float | None, UnitSpec("ml")] = Field(
...,
serialization_alias="rslt_cf_waterSupplementRecommended",
validation_alias="rslt_cf_waterSupplementRecommended",
)
total_water_ml: Annotated[float | None, UnitSpec("ml")] = Field(
...,
serialization_alias="rslt_cf_totalWater",
validation_alias="rslt_cf_totalWater",
)
comments: Optional[str] = Field(
None,
serialization_alias="rslt_comments",
validation_alias="rslt_comments",
)
workstation: Optional[str] = Field(
None,
serialization_alias="rslt_cf_fk_workStation",
validation_alias="rslt_cf_fk_workStation",
)
sw_source: str = Field(
"aind-slims-api",
serialization_alias="rslt_cf_swSource",
validation_alias="rslt_cf_swSource",
)
sw_version: str = Field(
__version__,
serialization_alias="rslt_cf_swVersion",
validation_alias="rslt_cf_swVersion",
)
pk: Optional[int] = Field(
None,
serialization_alias="rslt_pk",
validation_alias="rslt_pk",
)
mouse_pk: Optional[int] = Field(
None,
serialization_alias="rslt_fk_content",
validation_alias="rslt_fk_content",
)
test_pk: Optional[int] = Field(
None,
serialization_alias="rslt_fk_test",
validation_alias="rslt_fk_test",
)

_slims_table = "Result"

_base_fetch_filters: ClassVar[dict[str, str]] = {
"test_name": "test_waterlog",
}
83 changes: 83 additions & 0 deletions src/aind_slims_api/models/waterlog_water_restriction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"""Contains a model for a waterlog water restriction event stored in SLIMS."""

from datetime import datetime
from typing import ClassVar, Optional

from pydantic import Field

from aind_slims_api.models.base import SlimsBaseModel

DEFAULT_WEIGHT_FRACTION = 0.85
MIN_WEIGHT_FRACTION = 0.75
MAX_WEIGHT_FRACTION = 1.0


class SlimsWaterRestrictionEvent(SlimsBaseModel):
"""Model for a Water Restriction Event
Examples
--------
>>> from aind_slims_api.core import SlimsClient
>>> from aind_slims_api import models
>>> client = SlimsClient()
>>> mouse = client.fetch_model(models.SlimsMouseContent, barcode="00000000")
### Write
>>> water_restriction_event = client.add_model(
... models.SlimsWaterRestrictionEvent(
... mouse_pk=mouse.pk,
... start_date=datetime(2021,1,1),
... end_date=datetime(2021,1,2),
... assigned_by="mochic",
... target_weight_fraction=0.90,
... )
... )
### Read
>>> water_restriction_events = client.fetch_models(
... models.SlimsWaterRestrictionEvent,
... mouse_pk=mouse.pk,
... sort=["start_date"],
... )
>>> water_restriction_events[-1].target_weight_fraction
0.9
"""

start_date: datetime = Field(
datetime.now(),
serialization_alias="cnvn_cf_startDate",
validation_alias="cnvn_cf_startDate",
)
end_date: Optional[datetime] = Field(
None,
serialization_alias="cnvn_cf_endDate",
validation_alias="cnvn_cf_endDate",
)
assigned_by: str = Field(
...,
serialization_alias="cnvn_cf_assignedBy",
validation_alias="cnvn_cf_assignedBy",
)
target_weight_fraction: float = Field(
default=DEFAULT_WEIGHT_FRACTION,
serialization_alias="cnvn_cf_targetWeightFraction",
validation_alias="cnvn_cf_targetWeightFraction",
gt=MIN_WEIGHT_FRACTION,
lt=MAX_WEIGHT_FRACTION,
)
pk: Optional[int] = Field(
None,
serialization_alias="cnvn_pk",
validation_alias="cnvn_pk",
)
mouse_pk: Optional[int] = Field(
None,
serialization_alias="cnvn_fk_content",
validation_alias="cnvn_fk_content",
)
cnvn_fk_contentEventType: int = 9 # pk of Water Restriction ContentEvent type

_slims_table = "ContentEvent"
_base_fetch_filters: ClassVar[dict[str, str]] = {
"cnvt_name": "Water Restriction",
}

0 comments on commit e9ab523

Please sign in to comment.