Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enh/waterlog #23

Merged
merged 5 commits into from
Jul 24, 2024
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
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",
}
Loading