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

Cheek Samples #597

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open

Cheek Samples #597

wants to merge 7 commits into from

Conversation

cassidysymons
Copy link
Collaborator

@cassidysymons cassidysymons commented Jan 13, 2025

This PR is intended to address the needs surrounding collecting skin samples from cheeks:

  1. It adds Cheek as a valid sample site and adds applicable constants to the metadata pulldown process.

  2. It adds the notion of "barcode metadata," which are fields that are strictly linked to samples, rather than implicitly linked to samples via sources (as all of the existing survey questions are).

From a UX perspective, the reason for this deviation is the temporal importance of the questions. While all metadata are temporally linked to samples, and we strive to close that gap as much as possible, these particular questions are directly related to preparation for the sample collection.

From a technical perspective, I opted to establish a new avenue of storage because neither existing method felt appropriate:

  • Utilizing the survey framework would be excessively heavy and would require a significant amount of hacking up code to expose three questions to the user interface.
  • Storing the data in the ag_kit_barcodes table would be far less than ideal given that they only apply to a small fraction of samples.

The middle ground I established is sufficient for the purpose - including data validation - and could be extended into a more robust framework if future use calls for it.

Corresponding microsetta-interface PR is biocore/microsetta-interface#334

@cassidysymons cassidysymons marked this pull request as ready for review January 13, 2025 16:45
Copy link
Collaborator

@AmandaBirmingham AmandaBirmingham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One question/future request re constant metadata values for cheek samples.

Copy link
Collaborator

@AmandaBirmingham AmandaBirmingham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing major

microsetta_private_api/repo/sample_repo.py Outdated Show resolved Hide resolved
microsetta_private_api/repo/sample_repo.py Outdated Show resolved Hide resolved
microsetta_private_api/repo/sample_repo.py Show resolved Hide resolved
microsetta_private_api/repo/sample_repo.py Outdated Show resolved Hide resolved
ag_kit_barcode_id UUID NOT NULL PRIMARY KEY,
sample_site_last_washed_date DATE,
sample_site_last_washed_time TIME,
sample_site_last_washed_product SAMPLE_SITE_LAST_WASHED_PRODUCT_TYPE,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this allowed to be null? Under what circumstances would that be the case?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, all three of the questions are (highly) encouraged but strictly optional. As such, we allow them to be nullable in the database.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok ... now I'm wondering what the meaningful difference is between (a) a completed cheek sample with no record in the ag_kit_barcodes_cheek table and (b) a completed cheek sample with a record in the ag_kit_barcodes_cheek table for which all fields except the foreign key back to the ag_kit_barcodes table are NULL. Do these two cases have two distinct meanings? What is signified by a completely empty (except for FK) record in the cheek table?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a metadata perspective, they do have a distinct meaning. NULL values would be reported as "not provided" while a cheek sample with no values for the questions (including NULL) would be reported as "not collected."

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, that's fascinating--I don't think I really understand what these differences mean in this context, but good to know!

microsetta_private_api/model/sample.py Show resolved Hide resolved
@cassidysymons
Copy link
Collaborator Author

@AmandaBirmingham I think this newest commit addresses the feedback that required changes, and I've added comments to notes that either don't seem to require change or were a strictly informational question. Please let me know if I missed anything or you have any further questions or concerns. Thanks!

@@ -87,7 +87,7 @@ def to_api(self):
# matches that of the association between a sample and a source
class SampleInfo:
def __init__(self, sample_id, datetime_collected, site, notes,
barcode_meta=None):
barcode_meta={}):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be reverted? There is an important unexpected edgecase with default objects:

>>> def foo(a, b, example={}):
...   example[a] = b
...   print(example)
... 
>>> foo(1, 2)
{1: 2}
>>> foo(3, 4)
{1: 2, 3: 4}
>>> foo(1, 10)
{1: 10, 3: 4}

In almost all cases, the intended behavior and recommended approach is:

>>> def foo(a, b, example=None):
...   if example is None:
...     example = {}
...   example[a] = b
...   print(example)
... 
>>> foo(1, 2)
{1: 2}
>>> foo(3, 4)
{3: 4}
>>> foo(1, 10)
{1: 10}

These should be caught by linters (see e.g. https://stackoverflow.com/a/73765790), which if not flagged here suggests we may need to revisit the linter configuration or linter used.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done - 6a31b02

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants