microplate


Namemicroplate JSON
Version 1.6 PyPI version JSON
download
home_pageNone
SummaryA package for dealing with microtiter plates
upload_time2025-09-11 06:21:38
maintainerNone
docs_urlNone
authorNone
requires_pythonNone
licenseNone
keywords titer microtiter plate assay reader lab
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # microplate: A class for manipulating microtiter plate data

## Use Cases

The goal of microplate is to make working with microplate data in Python
more convenient. Well data storage/retrieval is done through standard
microtiter plate labels ('A1' or 'P5') rather than through array indices.

## Features

  - Import directly from files without any needed manipulation
  - Arbitrary plate sizes supported (any number of rows/columns)
  - Simplified storage/retrieval of microplate data by using traditional 
    well labels, rows/columns, or ranges.
  - Multiple data block support for assays with multiple reads.
  - Store arbitrary regions in plates to simplify calculating plate statistics.
  - Simple data normalization and statistic functions.
  - Iterator support to retrieve all data.
  - Easy view of plate data by printing the plate object.
  - Metadata storage by well for plate.
  - Hit cutoff and hit list retrieval based on microplate data.

## Source/Installation
The source code is currently hosted on GitHub at:
https://github.com/shumatejr/microplate

Binary installers for the latest released version are available at the [Python
Package Index (PyPI)](https://pypi.org/project/microplate/).

```sh
# PyPi
pip install microplate
```
Then just import the MTP class in your Python script.
```sh
from microplate import MTP
```

## Dependencies
- [NumPy](https://www.numpy.org)

## Example Usage
### Plate Creation
```sh
# Create an empty plate
plate_ratio = MTP(name = "Test Plate", rows=2, columns=3, blocks=3)

# Or define it from a file
# Multiple input files can be passed to add multiple data blocks to the plate.
# input_files input is in the format (filename, delimiter, file_row, file_column)
plate = MTP(
    name = "384-Well Test Plate", 
    rows = 16, 
    columns = 24,
    input_files = [ 
        ('test.txt',',',1,1),  # Comma delimited, Row 1, Column 1
        ('test.txt','\t',22,2), # Tab delimited, Row 22, Column 2
    ]
)

# View entire plate contents
print(plate)
```

### Well Manipulation/Retrieval
```sh
# Plate Access (empty string)
plate['']

# Well Access (well B3)
plate['B3'] = -1

# Row Access (row B)
plate['B']

# Column Access (column 3)
plate['3'] = 2

# Range Access
plate["A2:A3"] = -5

# If plates have multiple data blocks, add comma and value to specify block
plate['']    # Whole plate, implicitly data block 1
plate['',2]  # Whole plate, data block 2

plate["A2:A3",2] # Range from data block 2

# Values retrieved are numpy arrays, so 'matrix' math can be performed
# Make data block 3 a ratio of the other two data blocks
plate_ratio['',2] = 1
plate_ratio['',1] = 2

# Block 3 would store 2/1 in all wells
plate_ratio['',3] = plate_ratio['',2] / plate_ratio['',1]
```

### Regions
```sh
# Define regions
plate.set_region("high_ctrl", "A1:P1")
plate.set_region("low_ctrl", "A12:P12")
plate.set_region("full_plate", "A1:P12")

# Regions can be wells, ranges, or lists of any combination of the two
plate.set_region("corners", ["A1", "A12", "P1", "P12"])
plate.set_region("edges", ["A1:A12", "P1:P12"])
plate.set_region("A1+Right", ["A1", "A12:P12"])

# And then retrieve their values
plate.get_region("full_plate")
```

### Normalization
```sh
# Normalize entire plate by zscore (returns a copy)
plate = plate.normalize_zscore()

# Normalize to a percent basis based on high/low control
plate_normalized = plate.normalize_percent(
    region_high = 'high_ctrl', 
    region_low = 'low_ctrl',
    method = 'median'
)

# All data blocks are normalized unless specified
# Scales data block 2 from 0-100%
plate_normalized = plate.normalize_percent(
    region_high = 'full_plate', 
    region_low = 'full_plate',
    block = 2,
    method = 'minmax'
)
```

### Plate Calculations
```sh
# Calculate some basic plate statistics based on the defined regions
z_prime = plate.calc_z(region_high='high_ctrl', region_low='low_ctrl', block=1)
z = plate.calc_z(region_high='high_ctrl', region_low='sample',   block=1)
window = plate.calc_sw(region_high='high_ctrl', region_low='sample', block=1)
drift_row, drift_col = plate.calc_drift(region='sample', block=2)
```

### Cutoffs
```sh
# Calculate avg+3sd hit cutoffs, then return a list of hits
hit_cutoff = plate.calc_cutoff_sd('sample', block=1)
# calc_cutoff_excluded removes outliers from the hit cutoff calculation
hit_cutoff_excluded = plate.calc_cutoff_excluded(
    'sample', block=1, region_high='high_ctrl', region_low='low_ctrl'
)
hit_list = plate.get_hits(region="sample", cutoff=hit_cutoff_excluded, block=2)

# Print the hit information.
# The get_region method can be passed a well list to get the well results for a list of wells.
print(f"Hits: {hit_list}")
print(f"Raw: {plate.get_region(wells=hit_list, block=1)}")
print(f"Activity: {plate.get_region(wells=hit_list, block=2).round(2)}")
```

### Set Metadata
```sh
# Add a hit_flag key to the metadata dictionary indicating whether well is a hit
for well in plate.metadata:
    plate.metadata[well]['hit_flag'] = well in hit_list 
```

### Iterator Support
```sh
# Sequential acess of all wells through an iterator
for (label, row, column, value) in plate():
    print(f"Well:{label} Row:{row} Column:{column} Value:{value}")

# A specific block alone can be accessed if passed
for (label, row, column, value) in plate(block=2):
    print(f"Well:{label} Row:{row} Column:{column} Value:{value}")

```

## License
[MIT](LICENSE)

## Credits
Developed by Justin Shumate















            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "microplate",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "titer, microtiter, plate, assay, reader, lab",
    "author": null,
    "author_email": "Justin Shumate <shumatejr@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/fd/84/6451550cf6aca6a9a49bbf9ea621c317b7da6bda5e013dff33f5eb01d7d3/microplate-1.6.tar.gz",
    "platform": null,
    "description": "# microplate: A class for manipulating microtiter plate data\r\n\r\n## Use Cases\r\n\r\nThe goal of microplate is to make working with microplate data in Python\r\nmore convenient. Well data storage/retrieval is done through standard\r\nmicrotiter plate labels ('A1' or 'P5') rather than through array indices.\r\n\r\n## Features\r\n\r\n  - Import directly from files without any needed manipulation\r\n  - Arbitrary plate sizes supported (any number of rows/columns)\r\n  - Simplified storage/retrieval of microplate data by using traditional \r\n    well labels, rows/columns, or ranges.\r\n  - Multiple data block support for assays with multiple reads.\r\n  - Store arbitrary regions in plates to simplify calculating plate statistics.\r\n  - Simple data normalization and statistic functions.\r\n  - Iterator support to retrieve all data.\r\n  - Easy view of plate data by printing the plate object.\r\n  - Metadata storage by well for plate.\r\n  - Hit cutoff and hit list retrieval based on microplate data.\r\n\r\n## Source/Installation\r\nThe source code is currently hosted on GitHub at:\r\nhttps://github.com/shumatejr/microplate\r\n\r\nBinary installers for the latest released version are available at the [Python\r\nPackage Index (PyPI)](https://pypi.org/project/microplate/).\r\n\r\n```sh\r\n# PyPi\r\npip install microplate\r\n```\r\nThen just import the MTP class in your Python script.\r\n```sh\r\nfrom microplate import MTP\r\n```\r\n\r\n## Dependencies\r\n- [NumPy](https://www.numpy.org)\r\n\r\n## Example Usage\r\n### Plate Creation\r\n```sh\r\n# Create an empty plate\r\nplate_ratio = MTP(name = \"Test Plate\", rows=2, columns=3, blocks=3)\r\n\r\n# Or define it from a file\r\n# Multiple input files can be passed to add multiple data blocks to the plate.\r\n# input_files input is in the format (filename, delimiter, file_row, file_column)\r\nplate = MTP(\r\n    name = \"384-Well Test Plate\", \r\n    rows = 16, \r\n    columns = 24,\r\n    input_files = [ \r\n        ('test.txt',',',1,1),  # Comma delimited, Row 1, Column 1\r\n        ('test.txt','\\t',22,2), # Tab delimited, Row 22, Column 2\r\n    ]\r\n)\r\n\r\n# View entire plate contents\r\nprint(plate)\r\n```\r\n\r\n### Well Manipulation/Retrieval\r\n```sh\r\n# Plate Access (empty string)\r\nplate['']\r\n\r\n# Well Access (well B3)\r\nplate['B3'] = -1\r\n\r\n# Row Access (row B)\r\nplate['B']\r\n\r\n# Column Access (column 3)\r\nplate['3'] = 2\r\n\r\n# Range Access\r\nplate[\"A2:A3\"] = -5\r\n\r\n# If plates have multiple data blocks, add comma and value to specify block\r\nplate['']    # Whole plate, implicitly data block 1\r\nplate['',2]  # Whole plate, data block 2\r\n\r\nplate[\"A2:A3\",2] # Range from data block 2\r\n\r\n# Values retrieved are numpy arrays, so 'matrix' math can be performed\r\n# Make data block 3 a ratio of the other two data blocks\r\nplate_ratio['',2] = 1\r\nplate_ratio['',1] = 2\r\n\r\n# Block 3 would store 2/1 in all wells\r\nplate_ratio['',3] = plate_ratio['',2] / plate_ratio['',1]\r\n```\r\n\r\n### Regions\r\n```sh\r\n# Define regions\r\nplate.set_region(\"high_ctrl\", \"A1:P1\")\r\nplate.set_region(\"low_ctrl\", \"A12:P12\")\r\nplate.set_region(\"full_plate\", \"A1:P12\")\r\n\r\n# Regions can be wells, ranges, or lists of any combination of the two\r\nplate.set_region(\"corners\", [\"A1\", \"A12\", \"P1\", \"P12\"])\r\nplate.set_region(\"edges\", [\"A1:A12\", \"P1:P12\"])\r\nplate.set_region(\"A1+Right\", [\"A1\", \"A12:P12\"])\r\n\r\n# And then retrieve their values\r\nplate.get_region(\"full_plate\")\r\n```\r\n\r\n### Normalization\r\n```sh\r\n# Normalize entire plate by zscore (returns a copy)\r\nplate = plate.normalize_zscore()\r\n\r\n# Normalize to a percent basis based on high/low control\r\nplate_normalized = plate.normalize_percent(\r\n    region_high = 'high_ctrl', \r\n    region_low = 'low_ctrl',\r\n    method = 'median'\r\n)\r\n\r\n# All data blocks are normalized unless specified\r\n# Scales data block 2 from 0-100%\r\nplate_normalized = plate.normalize_percent(\r\n    region_high = 'full_plate', \r\n    region_low = 'full_plate',\r\n    block = 2,\r\n    method = 'minmax'\r\n)\r\n```\r\n\r\n### Plate Calculations\r\n```sh\r\n# Calculate some basic plate statistics based on the defined regions\r\nz_prime = plate.calc_z(region_high='high_ctrl', region_low='low_ctrl', block=1)\r\nz = plate.calc_z(region_high='high_ctrl', region_low='sample',   block=1)\r\nwindow = plate.calc_sw(region_high='high_ctrl', region_low='sample', block=1)\r\ndrift_row, drift_col = plate.calc_drift(region='sample', block=2)\r\n```\r\n\r\n### Cutoffs\r\n```sh\r\n# Calculate avg+3sd hit cutoffs, then return a list of hits\r\nhit_cutoff = plate.calc_cutoff_sd('sample', block=1)\r\n# calc_cutoff_excluded removes outliers from the hit cutoff calculation\r\nhit_cutoff_excluded = plate.calc_cutoff_excluded(\r\n    'sample', block=1, region_high='high_ctrl', region_low='low_ctrl'\r\n)\r\nhit_list = plate.get_hits(region=\"sample\", cutoff=hit_cutoff_excluded, block=2)\r\n\r\n# Print the hit information.\r\n# The get_region method can be passed a well list to get the well results for a list of wells.\r\nprint(f\"Hits: {hit_list}\")\r\nprint(f\"Raw: {plate.get_region(wells=hit_list, block=1)}\")\r\nprint(f\"Activity: {plate.get_region(wells=hit_list, block=2).round(2)}\")\r\n```\r\n\r\n### Set Metadata\r\n```sh\r\n# Add a hit_flag key to the metadata dictionary indicating whether well is a hit\r\nfor well in plate.metadata:\r\n    plate.metadata[well]['hit_flag'] = well in hit_list \r\n```\r\n\r\n### Iterator Support\r\n```sh\r\n# Sequential acess of all wells through an iterator\r\nfor (label, row, column, value) in plate():\r\n    print(f\"Well:{label} Row:{row} Column:{column} Value:{value}\")\r\n\r\n# A specific block alone can be accessed if passed\r\nfor (label, row, column, value) in plate(block=2):\r\n    print(f\"Well:{label} Row:{row} Column:{column} Value:{value}\")\r\n\r\n```\r\n\r\n## License\r\n[MIT](LICENSE)\r\n\r\n## Credits\r\nDeveloped by Justin Shumate\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A package for dealing with microtiter plates",
    "version": "1.6",
    "project_urls": {
        "Changelog": "https://github.com/shumatejr/microplate/blob/main/CHANGELOG.md",
        "Homepage": "https://github.com/shumatejr/microplate",
        "Issues": "https://github.com/shumatejr/microplate/issues"
    },
    "split_keywords": [
        "titer",
        " microtiter",
        " plate",
        " assay",
        " reader",
        " lab"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "06970b2937163ebbf4a18d7be31f436d7caad1758aa467178da9e1a913b36ae3",
                "md5": "9aa555c728ba8d95e5ccc07acc4830f9",
                "sha256": "c25076e1c048518308e426037cf9f4bd31436397b0b3147b62decf5386e91670"
            },
            "downloads": -1,
            "filename": "microplate-1.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "9aa555c728ba8d95e5ccc07acc4830f9",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 12040,
            "upload_time": "2025-09-11T06:21:38",
            "upload_time_iso_8601": "2025-09-11T06:21:38.119367Z",
            "url": "https://files.pythonhosted.org/packages/06/97/0b2937163ebbf4a18d7be31f436d7caad1758aa467178da9e1a913b36ae3/microplate-1.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "fd846451550cf6aca6a9a49bbf9ea621c317b7da6bda5e013dff33f5eb01d7d3",
                "md5": "9f3f46b328215e22e739638a0666a2bd",
                "sha256": "ee2497eb55bbc34158dedd353a762901b54321b86baa0c25bb1d6709e5cce764"
            },
            "downloads": -1,
            "filename": "microplate-1.6.tar.gz",
            "has_sig": false,
            "md5_digest": "9f3f46b328215e22e739638a0666a2bd",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 14039,
            "upload_time": "2025-09-11T06:21:38",
            "upload_time_iso_8601": "2025-09-11T06:21:38.924947Z",
            "url": "https://files.pythonhosted.org/packages/fd/84/6451550cf6aca6a9a49bbf9ea621c317b7da6bda5e013dff33f5eb01d7d3/microplate-1.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-11 06:21:38",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "shumatejr",
    "github_project": "microplate",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "microplate"
}
        
Elapsed time: 0.77312s