Skip to content

Commit c92b7df

Browse files
Cleanup active plugins (#192)
* start help cleanup of active plugins * cleanup repo root folder * make style match CP templates * black format all active plugins --------- Co-authored-by: bethac07 <bcimini@broadinstitute.org>
1 parent e962b48 commit c92b7df

22 files changed

Lines changed: 2311 additions & 1572 deletions

active_plugins/calculatemoments.py

Lines changed: 217 additions & 175 deletions
Large diffs are not rendered by default.

active_plugins/callbarcodes.py

Lines changed: 77 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# coding=utf-8
2-
31
#################################
42
#
53
# Imports from useful Python libraries
@@ -40,35 +38,48 @@
4038
__doc__ = """\
4139
CallBarcodes
4240
============
43-
44-
**CallBarcodes** - This module calls barcodes.
45-
46-
|
47-
48-
============ ============ ===============
49-
Supports 2D? Supports 3D? Respects masks?
50-
============ ============ ===============
51-
YES Yes YES
52-
============ ============ ===============
53-
41+
**CallBarcodes** is used for assigning a barcode to an object based on the channel with the strongest intensity for a given number of cycles.
42+
It is used for optical sequencing by synthesis (SBS).
5443
5544
What do I need as input?
5645
^^^^^^^^^^^^^^^^^^^^^^^^
57-
To be added
46+
You need to input a .csv file that contains at least two columns.
47+
One column contains the known barcodes that you will be matching against.
48+
One column contains the corresponding gene/transcript names.
49+
All other columns in the .csv will be ignored.
50+
51+
Before running this module in your pipeline, you need to identify the objects in which you will be calling your barcodes and you will need to have measured the intensities of each object in four channels corresponding to nucleotides A,C,T, and G.
52+
If the background intensities of your four channels are not very well matched, you might want to run the **CompensateColors** module before measuring the object intensities.
5853
5954
What do I get as output?
6055
^^^^^^^^^^^^^^^^^^^^^^^^
6156
To be added
6257
6358
Measurements made by this module
6459
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
65-
To be added
60+
Within the InputObject.csv, this module outputs the following measurements:
61+
- BarcodeCalled is the n-cycle string of the barcode sequence that was read by the module
62+
- MatchedTo_Barcode is the known barcode that the module best matched to the called barcode
63+
- MatchedTo_ID is an ID number assigned to each known barcode
64+
- MatchedTo_GeneCode is the known gene/transcript name that corresponds to the known barcode
65+
- MatchedTo_Score is the quality of the called barcode to known barcode match, reported as (matching nucleotides)/(total nucleotides) where 1 is a perfect match
66+
67+
Note that CellProfiler cannot create a per-parent mean measurement of a string.
6668
6769
References
6870
^^^^^^^^^^
6971
Optical Pooled Screens in Human Cells.
7072
Feldman D, Singh A, Schmid-Burgk JL, Carlson RJ, Mezger A, Garrity AJ, Zhang F, Blainey PC.
7173
Cell. 2019 Oct 17;179(3):787-799.e17. doi: 10.1016/j.cell.2019.09.016.
74+
75+
|
76+
77+
============ ============ ===============
78+
Supports 2D? Supports 3D? Respects masks?
79+
============ ============ ===============
80+
YES YES YES
81+
============ ============ ===============
82+
7283
"""
7384

7485
C_CALL_BARCODES = "Barcode"
@@ -133,15 +144,15 @@ def set_directory_fn(path):
133144
"Select the column of barcodes to match against",
134145
["No CSV file"],
135146
choices_fn=self.get_choices,
136-
doc="""\
147+
doc="""\Select the column of barcodes to match against.
137148
""",
138149
)
139150

140151
self.metadata_field_tag = cellprofiler_core.setting.choice.Choice(
141152
"Select the column with gene/transcript barcode names",
142153
["No CSV file"],
143154
choices_fn=self.get_choices,
144-
doc="""\
155+
doc="""\Select the column with gene/transcript barcode names.
145156
""",
146157
)
147158

@@ -188,18 +199,23 @@ def set_directory_fn(path):
188199
)
189200

190201
self.has_empty_vector_barcode = cellprofiler_core.setting.Binary(
191-
"Do you have an empty vector barcode you would like to add to the barcode list?", False, doc="""\
202+
"Do you have an empty vector barcode you would like to add to the barcode list?",
203+
False,
204+
doc="""\
192205
Select "*{YES}*" to manually enter a sequence that should be added to the uploaded barcode
193206
list with the gene name of "EmptyVector". This can be helpful when there is a consistent
194-
backbone sequence to look out for in every barcoding set).""" .format(**{"YES": "Yes"
195-
}))
207+
backbone sequence to look out for in every barcoding set).""".format(
208+
**{"YES": "Yes"}
209+
),
210+
)
196211

197212
self.empty_vector_barcode_sequence = cellprofiler_core.setting.text.Text(
198-
"What is the empty vector sequence?", "AAAAAAAAAAAAAAA", doc="""\
199-
Enter the sequence that represents barcoding reads of an empty vector"""
213+
"What is the empty vector sequence?",
214+
"AAAAAAAAAAAAAAA",
215+
doc="""\
216+
Enter the sequence that represents barcoding reads of an empty vector""",
200217
)
201218

202-
203219
def settings(self):
204220
return [
205221
self.ncycles,
@@ -360,7 +376,11 @@ def run(self, workspace):
360376
listofmeasurements, self.ncycles.value, self.cycle1measure.value
361377
)
362378

363-
objectcount = len(measurements.get_current_measurement(self.input_object_name.value,listofmeasurements[0]))
379+
objectcount = len(
380+
measurements.get_current_measurement(
381+
self.input_object_name.value, listofmeasurements[0]
382+
)
383+
)
364384

365385
calledbarcodes, quality_scores = self.callonebarcode(
366386
measurements_for_calls,
@@ -378,14 +398,17 @@ def run(self, workspace):
378398

379399
workspace.measurements.add_measurement(
380400
self.input_object_name.value,
381-
"_".join([C_CALL_BARCODES,"MeanQualityScore"]),
382-
quality_scores)
401+
"_".join([C_CALL_BARCODES, "MeanQualityScore"]),
402+
quality_scores,
403+
)
383404

384405
barcodes = self.barcodeset(
385406
self.metadata_field_barcode.value, self.metadata_field_tag.value
386407
)
387408

388-
cropped_barcode_dict = {y[:self.ncycles.value]:y for y in list(barcodes.keys())}
409+
cropped_barcode_dict = {
410+
y[: self.ncycles.value]: y for y in list(barcodes.keys())
411+
}
389412

390413
scorelist = []
391414
matchedbarcode = []
@@ -417,16 +440,14 @@ def run(self, workspace):
417440
imagemeanscore = numpy.mean(scorelist)
418441

419442
workspace.measurements.add_measurement(
420-
"Image",
421-
"_".join([C_CALL_BARCODES,"MeanBarcodeScore"]),
422-
imagemeanscore)
443+
"Image", "_".join([C_CALL_BARCODES, "MeanBarcodeScore"]), imagemeanscore
444+
)
423445

424446
imagemeanquality = numpy.mean(quality_scores)
425447

426448
workspace.measurements.add_measurement(
427-
"Image",
428-
"_".join([C_CALL_BARCODES,"MeanQualityScore"]),
429-
imagemeanquality)
449+
"Image", "_".join([C_CALL_BARCODES, "MeanQualityScore"]), imagemeanquality
450+
)
430451

431452
workspace.measurements.add_measurement(
432453
self.input_object_name.value,
@@ -464,7 +485,10 @@ def run(self, workspace):
464485
)
465486

466487
if self.show_window:
467-
workspace.display_data.col_labels = ("Image Mean Score", "Image Mean Quality Score")
488+
workspace.display_data.col_labels = (
489+
"Image Mean Score",
490+
"Image Mean Quality Score",
491+
)
468492
workspace.display_data.statistics = [imagemeanscore, imagemeanquality]
469493

470494
def display(self, workspace, figure):
@@ -491,10 +515,12 @@ def getallbarcodemeasurements(self, measurements, ncycles, examplemeas):
491515
measurementdict[parsed_cycle].update({eachmeas: parsed_base})
492516
return measurementdict
493517

494-
def callonebarcode(self, measurementdict, measurements, object_name, ncycles, objectcount):
518+
def callonebarcode(
519+
self, measurementdict, measurements, object_name, ncycles, objectcount
520+
):
495521

496522
master_cycles = []
497-
score_array = numpy.zeros([ncycles,objectcount])
523+
score_array = numpy.zeros([ncycles, objectcount])
498524

499525
for eachcycle in range(1, ncycles + 1):
500526
cycles_measures_perobj = []
@@ -507,15 +533,15 @@ def callonebarcode(self, measurementdict, measurements, object_name, ncycles, ob
507533
)
508534
cyclecode.append(measurementdict[eachcycle][eachmeasure])
509535
cycle_measures_perobj = numpy.transpose(numpy.array(cycles_measures_perobj))
510-
argmax_per_obj = numpy.argmax(cycle_measures_perobj,1)
511-
max_per_obj = numpy.max(cycle_measures_perobj,1)
512-
sum_per_obj = numpy.sum(cycle_measures_perobj,1)
513-
score_per_obj = max_per_obj/sum_per_obj
536+
argmax_per_obj = numpy.argmax(cycle_measures_perobj, 1)
537+
max_per_obj = numpy.max(cycle_measures_perobj, 1)
538+
sum_per_obj = numpy.sum(cycle_measures_perobj, 1)
539+
score_per_obj = max_per_obj / sum_per_obj
514540
argmax_per_obj = list(argmax_per_obj)
515541
argmax_per_obj = [cyclecode[x] for x in argmax_per_obj]
516542

517543
master_cycles.append(list(argmax_per_obj))
518-
score_array[eachcycle-1] = score_per_obj
544+
score_array[eachcycle - 1] = score_per_obj
519545

520546
mean_per_object = score_array.mean(axis=0)
521547

@@ -532,15 +558,18 @@ def barcodeset(self, barcodecol, genecol):
532558
count += 1
533559
fd.close()
534560
if self.has_empty_vector_barcode:
535-
barcodeset[self.empty_vector_barcode_sequence.value]=(count,"EmptyVector")
561+
barcodeset[self.empty_vector_barcode_sequence.value] = (
562+
count,
563+
"EmptyVector",
564+
)
536565
return barcodeset
537566

538567
def queryall(self, cropped_barcode_dict, query):
539568

540569
cropped_barcode_list = list(cropped_barcode_dict.keys())
541570

542571
if query in cropped_barcode_list:
543-
#is a perfect match
572+
# is a perfect match
544573
return 1, cropped_barcode_dict[query]
545574

546575
else:
@@ -560,15 +589,15 @@ def get_measurement_columns(self, pipeline):
560589
result = [
561590
(
562591
"Image",
563-
"_".join([C_CALL_BARCODES,"MeanBarcodeScore"]),
564-
cellprofiler_core.constants.measurement.COLTYPE_FLOAT
592+
"_".join([C_CALL_BARCODES, "MeanBarcodeScore"]),
593+
cellprofiler_core.constants.measurement.COLTYPE_FLOAT,
565594
),
566595
(
567596
"Image",
568-
"_".join([C_CALL_BARCODES,"MeanQualityScore"]),
569-
cellprofiler_core.constants.measurement.COLTYPE_FLOAT
597+
"_".join([C_CALL_BARCODES, "MeanQualityScore"]),
598+
cellprofiler_core.constants.measurement.COLTYPE_FLOAT,
570599
),
571-
]
600+
]
572601

573602
result += [
574603
(

0 commit comments

Comments
 (0)