From 25c4bf63a4cd155502d37d5a319fa51b124d562c Mon Sep 17 00:00:00 2001 From: Philip W Fowler Date: Thu, 6 Jun 2024 16:44:06 +0100 Subject: [PATCH] added GB1ECSDP plate --- amygda/__init__.py | 3 +- bin/analyse-plate-with-amygda.py | 120 ++++++++++++++++++++-------- config/GB1ECSDP-conc-matrix.txt | 8 ++ config/GB1ECSDP-dilution-matrix.txt | 8 ++ config/GB1ECSDP-drug-matrix.txt | 8 ++ 5 files changed, 112 insertions(+), 35 deletions(-) create mode 100644 config/GB1ECSDP-conc-matrix.txt create mode 100644 config/GB1ECSDP-dilution-matrix.txt create mode 100644 config/GB1ECSDP-drug-matrix.txt diff --git a/amygda/__init__.py b/amygda/__init__.py index 7d0799c..e8b4e09 100755 --- a/amygda/__init__.py +++ b/amygda/__init__.py @@ -1,6 +1,7 @@ #! /usr/bin/env python from .core import PlateMeasurement + # from .statefiles import PlateMeasurementFile -__version__="1.3.1" +__version__ = "1.3.2" diff --git a/bin/analyse-plate-with-amygda.py b/bin/analyse-plate-with-amygda.py index f911c7d..a06f820 100755 --- a/bin/analyse-plate-with-amygda.py +++ b/bin/analyse-plate-with-amygda.py @@ -5,53 +5,96 @@ from scipy import stats parser = argparse.ArgumentParser() -parser.add_argument("--image",help="the path to the image") -parser.add_argument("--growth_pixel_threshold",default=130,type=int,help="the pixel threshold, below which a pixel is considered to be growth (0-255, default=130)") -parser.add_argument("--growth_percentage",default=2,type=float,help="if the central measured region in a well has more than this percentage of pixels labelled as growing, then the well is classified as growth (default=2).") -parser.add_argument("--measured_region",default=0.5,type=float,help="the radius of the central measured circle, as a decimal proportion of the whole well (default=0.5).") -parser.add_argument("--sensitivity",default=4,type=float,help="if the average growth in the control wells is more than (sensitivity x growth_percentage), then consider growth down to this sensitivity (default=4)") -parser.add_argument("--file_ending",default="-raw",type=str,help="the ending of the input file that is stripped. Default is '-raw' ") -parser.add_argument("--plate_design",default="UKMYC5",type=str,help="the name of the plate design. Must have a series of matching files in config/") +parser.add_argument("--image", help="the path to the image") +parser.add_argument( + "--growth_pixel_threshold", + default=130, + type=int, + help="the pixel threshold, below which a pixel is considered to be growth (0-255, default=130)", +) +parser.add_argument( + "--growth_percentage", + default=2, + type=float, + help="if the central measured region in a well has more than this percentage of pixels labelled as growing, then the well is classified as growth (default=2).", +) +parser.add_argument( + "--measured_region", + default=0.5, + type=float, + help="the radius of the central measured circle, as a decimal proportion of the whole well (default=0.5).", +) +parser.add_argument( + "--sensitivity", + default=4, + type=float, + help="if the average growth in the control wells is more than (sensitivity x growth_percentage), then consider growth down to this sensitivity (default=4)", +) +parser.add_argument( + "--file_ending", + default="-raw", + type=str, + help="the ending of the input file that is stripped. Default is '-raw' ", +) +parser.add_argument( + "--plate_design", + default="UKMYC5", + type=str, + help="the name of the plate design. Must have a series of matching files in config/", +) # parser.add_argument("--pixel_intensities",action="store_true",help="calculate and store the measured pixel intensities in the centre of each well? Default is False") options = parser.parse_args() # parse the path to the input image and work out its stem of -if '/' in options.image: - cols=options.image.split('/') - image_name=cols[-1].split(options.file_ending)[0] - image_path=cols[0]+"/" +if "/" in options.image: + cols = options.image.split("/") + image_name = cols[-1].split(options.file_ending)[0] + image_path = cols[0] + "/" for i in cols[1:-1]: - image_path+=i - image_path+="/" + image_path += i + image_path += "/" else: - image_path="." - image_name=options.image.split(options.file_ending)[0] - -assert options.plate_design in ['UKMYC5','UKMYC6','GPALL1F','CHNMCMM2','LeeLab'], "this plate design is not recognised" + image_path = "." + image_name = options.image.split(options.file_ending)[0] + +assert options.plate_design in [ + "UKMYC5", + "UKMYC6", + "GPALL1F", + "CHNMCMM2", + "LeeLab", + "GB1ECSDP", +], "this plate design is not recognised" # create a new measurement -plate=amygda.PlateMeasurement(image_path,categories={'ImageFileName':image_name},configuration_path="config/",pixel_intensities=False,plate_design=options.plate_design) +plate = amygda.PlateMeasurement( + image_path, + categories={"ImageFileName": image_name}, + configuration_path="config/", + pixel_intensities=False, + plate_design=options.plate_design, +) # create the path for the output images -plate_stem=plate.abspath+plate.image_name +plate_stem = plate.abspath + plate.image_name # define some colours for the output # the below are a contrasting set of colours taken from ColorBrewer 2 # http://colorbrewer2.org/#type=qualitative&scheme=Dark2&n=7 # you are, of course, free to make up your own! # Note these are (B,G,R) not (R,G,B) -pink=(138,41,231) -yellow=(51,255,255) -teal=(119,158,27) -green=(36,166,102) -black=(0,0,0) -white=(255,255,255) +pink = (138, 41, 231) +yellow = (51, 255, 255) +teal = (119, 158, 27) +green = (36, 166, 102) +black = (0, 0, 0) +white = (255, 255, 255) # load the raw image plate.load_image("-raw.png") # record that this image exists -plate.categories['IM_IMAGE_DOWNLOADED']=True +plate.categories["IM_IMAGE_DOWNLOADED"] = True # apply a mean shift filter to smooth the background colours plate.mean_shift_filter() @@ -69,30 +112,39 @@ plate.save_image("-filtered.jpg") # record that this image has been filtered -plate.categories['IM_IMAGE_FILTERED']=True +plate.categories["IM_IMAGE_FILTERED"] = True # load in the photo of the plate plate.load_image("-filtered.jpg") # attempt to segment the wells -if plate.identify_wells(hough_param1=20,hough_param2=25,radius_tolerance=0.005,verbose=False): +if plate.identify_wells( + hough_param1=20, hough_param2=25, radius_tolerance=0.005, verbose=False +): - plate.categories['IM_WELLS_IDENTIFIED']=True + plate.categories["IM_WELLS_IDENTIFIED"] = True - # measure growth - plate.measure_growth(region=options.measured_region,threshold_pixel=options.growth_pixel_threshold,threshold_percentage=options.growth_percentage,sensitivity=options.sensitivity) + # measure growth + plate.measure_growth( + region=options.measured_region, + threshold_pixel=options.growth_pixel_threshold, + threshold_percentage=options.growth_percentage, + sensitivity=options.sensitivity, + ) # save the numpy arrays containing the growth, positions of wells etc to disc plate.save_arrays("-arrays.npz") # draw circles around the wells - plate.annotate_well_circumference(color=pink,linewidth=2) + plate.annotate_well_circumference(color=pink, linewidth=2) # write the drug and concentration - plate.annotate_well_drugs_concs(color=black,fontsize=0.5) + plate.annotate_well_drugs_concs(color=black, fontsize=0.5) # add squares where the algorithm has detected growth - plate.annotate_well_analysed_region(growth_color=yellow,region=options.measured_region,thickness=3) + plate.annotate_well_analysed_region( + growth_color=yellow, region=options.measured_region, thickness=3 + ) # save the final image with wells with identified growth marked by red squares plate.save_image("-growth.jpg") diff --git a/config/GB1ECSDP-conc-matrix.txt b/config/GB1ECSDP-conc-matrix.txt new file mode 100644 index 0000000..13fd902 --- /dev/null +++ b/config/GB1ECSDP-conc-matrix.txt @@ -0,0 +1,8 @@ + 1, 2, 2, 1, 0.25, 0.12, 0.25, 2, 0.5, 0.25, 0.06, 0.5 + 2, 4, 4, 2, 0.5, 0.25, 0.5, 4, 1, 0.5, 0.12, 1 + 4, 8, 8, 4, 1, 0.5, 1, 8, 2, 1, 0.25, 2 + 8, 16, 16, 8, 2, 1, 2, 16, 4, 2, 0.5, 4 + 16, 32, 32, 16, 4, 2, 4, 32, 8, 4, 1, 8 + 32, 64, 64, 32, 8, 4, 8, 64, 16, 8, 2, 16 + 64, 128, 128, 64, 16, 8, 16, 128, 32, 16, 4, 32 + 0.25, 0.5, 1, 2, 4, 8, 16, 32, 0, 0, 0, 0 diff --git a/config/GB1ECSDP-dilution-matrix.txt b/config/GB1ECSDP-dilution-matrix.txt new file mode 100644 index 0000000..fd12a73 --- /dev/null +++ b/config/GB1ECSDP-dilution-matrix.txt @@ -0,0 +1,8 @@ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 + 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0 diff --git a/config/GB1ECSDP-drug-matrix.txt b/config/GB1ECSDP-drug-matrix.txt new file mode 100644 index 0000000..70a9076 --- /dev/null +++ b/config/GB1ECSDP-drug-matrix.txt @@ -0,0 +1,8 @@ +AMI,AUGC,AUG2,AZI,AZT,TGC,TAZ,CZA,C/T,AXO,CIP,GEN +AMI,AUGC,AUG2,AZI,AZT,TGC,TAZ,CZA,C/T,AXO,CIP,GEN +AMI,AUGC,AUG2,AZI,AZT,TGC,TAZ,CZA,C/T,AXO,CIP,GEN +AMI,AUGC,AUG2,AZI,AZT,TGC,TAZ,CZA,C/T,AXO,CIP,GEN +AMI,AUGC,AUG2,AZI,AZT,TGC,TAZ,CZA,C/T,AXO,CIP,GEN +AMI,AUGC,AUG2,AZI,AZT,TGC,TAZ,CZA,C/T,AXO,CIP,GEN +AMI,AUGC,AUG2,AZI,AZT,TGC,TAZ,CZA,C/T,AXO,CIP,GEN +AZA,AZA,AZA,AZA,AZA,AZA,AZA,AZA,POS,POS,POS,NEG