1212png_dpi = 300
1313
1414COCHLEAE = {
15- "M_LR_000099_L" : {"seg_data" : "PV_SGN_v2" , "subtype" : ["Calb1" , "Lypd1" ], "intensity" : "ratio" },
16- "M_AMD_N180_L" : {"seg_data" : "SGN_merged" , "subtype" : ["CR" , "Lypd1" , "Ntng1" ], "intensity" : "absolute" },
17- "M_AMD_N180_R" : {"seg_data" : "SGN_merged" , "subtype" : ["CR" , "Ntng1" ], "intensity" : "absolute" },
1815 "M_LR_000098_L" : {"seg_data" : "SGN_v2" , "subtype" : ["CR" , "Ntng1" ], "intensity" : "ratio" },
16+ "M_LR_000099_L" : {"seg_data" : "PV_SGN_v2" , "subtype" : ["Calb1" , "Lypd1" ], "intensity" : "ratio" },
1917 "M_LR_000184_L" : {"seg_data" : "SGN_v2" , "subtype" : ["Prph" ], "output_seg" : "SGN_v2b" , "intensity" : "ratio" },
2018 "M_LR_000184_R" : {"seg_data" : "SGN_v2" , "subtype" : ["Prph" ], "output_seg" : "SGN_v2b" , "intensity" : "ratio" },
2119 "M_LR_000214_L" : {"seg_data" : "PV_SGN_v2" , "subtype" : ["Calb1" ], "intensity" : "ratio" },
2220 "M_LR_000260_L" : {"seg_data" : "SGN_v2" , "subtype" : ["Prph" , "Tuj1" ], "intensity" : "ratio" },
21+ "M_LR_N110_L" : {"seg_data" : "SGN_v2" , "subtype" : ["Calb1" , "Ntng1" ], "intensity" : "ratio" },
22+ "M_LR_N110_R" : {"seg_data" : "SGN_v2" , "subtype" : ["Calb1" , "Ntng1" ], "intensity" : "ratio" },
2323 "M_LR_N152_L" : {"seg_data" : "SGN_v2" , "subtype" : ["CR" , "Ntng1" ], "intensity" : "ratio" },
24+ "M_AMD_N180_L" : {"seg_data" : "SGN_merged" , "subtype" : ["CR" , "Lypd1" , "Ntng1" ], "intensity" : "absolute" },
25+ "M_AMD_N180_R" : {"seg_data" : "SGN_merged" , "subtype" : ["CR" , "Ntng1" ], "intensity" : "absolute" },
2426}
2527
28+ CUSTOM_THRESHOLDS = {
29+ "M_LR_000099_L" : {"Lypd1" : 0.65 },
30+ "M_LR_000184_L" : {"Prph" : 1 },
31+ "M_LR_000260_L" : {"Prph" : 0.7 },
32+ }
2633
2734def plot_intensity_thresholds (input_dir , output_dir , cochlea , plot = False ):
2835 """Plot histograms for positive and negative populations of subtype markers based on thresholding.
@@ -55,9 +62,15 @@ def plot_intensity_thresholds(input_dir, output_dir, cochlea, plot=False):
5562 table_measurement_path = f"{ cochlea } /tables/{ data_name } /{ stain } _{ seg_str } _object-measures.tsv"
5663 column = "median"
5764
58- rows = 1
59- columns = number_plots // rows
60- fig , ax = plt .subplots (rows , columns , figsize = (columns * 4 , rows * 4 ), sharex = True )
65+ # check for custom threshold
66+ if CUSTOM_THRESHOLDS .get (cochlea , {}).get (stain ) is not None :
67+ rows = 2
68+ else :
69+ rows = 1
70+
71+ columns = number_plots
72+ fig , axes = plt .subplots (rows , columns , figsize = (columns * 4 , rows * 4 ), sharex = True )
73+ ax = axes .flatten ()
6174 table_path_s3 , fs = get_s3_path (table_measurement_path )
6275 with fs .open (table_path_s3 , "r" ) as f :
6376 table_measurement = pd .read_csv (f , sep = "\t " )
@@ -72,8 +85,8 @@ def plot_intensity_thresholds(input_dir, output_dir, cochlea, plot=False):
7285 neg_values = list (subset_neg [column ])
7386 pos_values = list (subset_pos [column ])
7487
75- bins = np .linspace (min (min ( neg_values ), min ( pos_values ) ),
76- max (max ( neg_values ), max ( pos_values ) ), 30 )
88+ bins = np .linspace (min (neg_values + pos_values ),
89+ max (neg_values + pos_values ), 30 )
7790
7891 ax [num ].hist (pos_values , bins = bins , alpha = 0.6 , label = 'Positive' , color = 'tab:blue' )
7992 ax [num ].hist (neg_values , bins = bins , alpha = 0.6 , label = 'Negative' , color = 'tab:orange' )
@@ -82,6 +95,27 @@ def plot_intensity_thresholds(input_dir, output_dir, cochlea, plot=False):
8295 ax [num ].legend ()
8396 ax [num ].set_title (center_str )
8497
98+ if rows == 2 :
99+ for num , center_str in enumerate (center_strs ):
100+ seg_ids = param_dicts [center_str ]["seg_ids" ]
101+ threshold = CUSTOM_THRESHOLDS [cochlea ][stain ]
102+
103+ subset = table_measurement [table_measurement ["label_id" ].isin (seg_ids )]
104+ subset_neg = subset [(subset [column ] < threshold )]
105+ subset_pos = subset [(subset [column ] > threshold )]
106+ neg_values = list (subset_neg [column ])
107+ pos_values = list (subset_pos [column ])
108+
109+ bins = np .linspace (min (neg_values + pos_values ),
110+ max (neg_values + pos_values ), 30 )
111+
112+ ax [columns + num ].hist (pos_values , bins = bins , alpha = 0.6 , label = 'Positive (custom)' , color = 'tab:blue' )
113+ ax [columns + num ].hist (neg_values , bins = bins , alpha = 0.6 , label = 'Negative (custom)' , color = 'tab:orange' )
114+ ax [columns + num ].set_ylabel ('Count' )
115+ ax [columns + num ].set_xlabel ('Intensity' )
116+ ax [columns + num ].legend ()
117+ ax [columns + num ].set_title (center_str )
118+
85119 fig .suptitle (f"{ cochlea } - { stain } " , fontsize = 30 )
86120
87121 plt .tight_layout ()
@@ -101,14 +135,14 @@ def main():
101135 description = "Assign each segmentation instance a marker based on annotation thresholds."
102136 )
103137 parser .add_argument ("-c" , "--cochlea" , type = str , nargs = "+" , default = COCHLEAE , help = "Cochlea(e) to process." )
138+ parser .add_argument ("--figure_dir" , "-f" , type = str , required = True , help = "Output directory for plots." )
104139 parser .add_argument ("-i" , "--input_dir" , type = str ,
105- default = "/mnt/vast-nhr/projects/nim00007/data/moser/cochlea-lightsheet/mobie_project/cochlea-lightsheet/tables/Subtype_marker" , help = "Input directory." ) #noqa
106- parser .add_argument ("-o" , "--output_dir" , type = str ,
107- default = "/user/schilling40/u15000/plots/SGNsub_thresholds" , help = "Output directory." )
140+ default = "/mnt/vast-nhr/projects/nim00007/data/moser/cochlea-lightsheet/mobie_project/cochlea-lightsheet/tables/Subtype_marker" ,
141+ help = "Directory containing object measures of the cochleae." ) #noqa
108142
109143 args = parser .parse_args ()
110144 for cochlea in args .cochlea :
111- plot_intensity_thresholds (args .input_dir , args .output_dir , cochlea )
145+ plot_intensity_thresholds (args .input_dir , args .figure_dir , cochlea )
112146
113147
114148if __name__ == "__main__" :
0 commit comments