Skip to content

Commit

Permalink
Merge branch 'release-1.1.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
castillohair committed May 5, 2017
2 parents cf42552 + 35f1b2d commit 31dc74c
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 35 deletions.
2 changes: 1 addition & 1 deletion FlowCal/__init__.py
Expand Up @@ -6,7 +6,7 @@
# Versions should comply with PEP440. For a discussion on single-sourcing
# the version across setup.py and the project code, see
# https://packaging.python.org/en/latest/single_source_version.html
__version__ = '1.1.2'
__version__ = '1.1.3'

import io
import excel_ui
Expand Down
70 changes: 46 additions & 24 deletions FlowCal/excel_ui.py
Expand Up @@ -380,14 +380,17 @@ def process_beads_table(beads_table,
beads_sample_gated,
channels=sc_channels)
# Density gating
beads_sample_gated, __, gate_contour = FlowCal.gate.density2d(
data=beads_sample_gated,
channels=sc_channels,
gate_fraction=beads_row['Gate Fraction'],
xscale='logicle',
yscale='logicle',
sigma=5.,
full_output=True)
try:
beads_sample_gated, __, gate_contour = FlowCal.gate.density2d(
data=beads_sample_gated,
channels=sc_channels,
gate_fraction=beads_row['Gate Fraction'],
xscale='logicle',
yscale='logicle',
sigma=5.,
full_output=True)
except ValueError as ve:
raise ExcelUIException(ve.message)

# Plot forward/side scatter density plot and fluorescence histograms
if plot:
Expand Down Expand Up @@ -782,13 +785,16 @@ def process_samples_table(samples_table,
sample_gated,
sc_channels + report_channels)
# Density gating
sample_gated, __, gate_contour = FlowCal.gate.density2d(
data=sample_gated,
channels=sc_channels,
gate_fraction=sample_row['Gate Fraction'],
xscale='logicle',
yscale='logicle',
full_output=True)
try:
sample_gated, __, gate_contour = FlowCal.gate.density2d(
data=sample_gated,
channels=sc_channels,
gate_fraction=sample_row['Gate Fraction'],
xscale='logicle',
yscale='logicle',
full_output=True)
except ValueError as ve:
raise ExcelUIException(ve.message)

# Plot forward/side scatter density plot and fluorescence histograms
if plot:
Expand Down Expand Up @@ -1311,7 +1317,11 @@ def show_open_file_dialog(filetypes):

return filename

def run(input_path=None, output_path=None, verbose=True, plot=True):
def run(input_path=None,
output_path=None,
verbose=True,
plot=True,
hist_sheet=False):
"""
Run the MS Excel User Interface.
Expand All @@ -1324,11 +1334,12 @@ def run(input_path=None, output_path=None, verbose=True, plot=True):
4. Generate statistics for each bead sample.
5. Process all the cell samples in the Samples table.
6. Generate statistics for each sample.
7. Generate a histogram table for each fluorescent channel specified
for each sample.
7. If requested, generate a histogram table for each fluorescent
channel specified for each sample.
8. Generate a table with run time, date, FlowCal version, among
others.
9. Save statistics and histograms in an output Excel file.
9. Save statistics and (if requested) histograms in an output Excel
file.
Parameters
----------
Expand All @@ -1344,6 +1355,9 @@ def run(input_path=None, output_path=None, verbose=True, plot=True):
plot : bool, optional
Whether to generate and save density/histogram plots of each
sample, and each beads sample.
hist_sheet : bool, optional
Whether to generate a sheet in the output Excel file specifying
histogram bin information.
"""

Expand Down Expand Up @@ -1406,9 +1420,10 @@ def run(input_path=None, output_path=None, verbose=True, plot=True):
add_samples_stats(samples_table, samples)

# Generate histograms
if verbose:
print("Generating histograms table...")
histograms_table = generate_histograms_table(samples_table, samples)
if hist_sheet:
if verbose:
print("Generating histograms table...")
histograms_table = generate_histograms_table(samples_table, samples)

# Generate about table
about_table = generate_about_table({'Input file path': input_path})
Expand All @@ -1418,7 +1433,8 @@ def run(input_path=None, output_path=None, verbose=True, plot=True):
table_list.append(('Instruments', instruments_table))
table_list.append(('Beads', beads_table))
table_list.append(('Samples', samples_table))
table_list.append(('Histograms', histograms_table))
if hist_sheet:
table_list.append(('Histograms', histograms_table))
table_list.append(('About Analysis', about_table))

# Write output excel file
Expand Down Expand Up @@ -1459,10 +1475,16 @@ def run(input_path=None, output_path=None, verbose=True, plot=True):
"--plot",
action="store_true",
help="generate and save density plots/histograms of beads and samples")
parser.add_argument(
"-H",
"--histogram-sheet",
action="store_true",
help="generate sheet in output Excel file specifying histogram bins")
args = parser.parse_args()

# Run Excel UI
run(input_path=args.inputpath,
output_path=args.outputpath,
verbose=args.verbose,
plot=args.plot)
plot=args.plot,
hist_sheet=args.histogram_sheet)
9 changes: 7 additions & 2 deletions FlowCal/gate.py
Expand Up @@ -284,7 +284,8 @@ def density2d(data,
bin edges. Note that None is not allowed if ``data.hist_bins``
does not exist.
gate_fraction : float, optional
Fraction of events to retain after gating.
Fraction of events to retain after gating. Should be between 0 and
1, inclusive.
xscale : str, optional
Scale of the bins generated for the x axis, either ``linear``,
``log``, or ``logicle``. `xscale` is ignored in `bins` is an array
Expand Down Expand Up @@ -349,11 +350,15 @@ def density2d(data,

# Extract channels in which to gate
if len(channels) != 2:
raise ValueError('2 channels should be specified.')
raise ValueError('2 channels should be specified')
data_ch = data[:,channels]
if data_ch.ndim == 1:
data_ch = data_ch.reshape((-1,1))

# Check gating fraction
if gate_fraction < 0 or gate_fraction > 1:
raise ValueError('gate fraction should be between 0 and 1, inclusive')

# Check dimensions
if data_ch.ndim < 2:
raise ValueError('data should have at least 2 dimensions')
Expand Down
16 changes: 10 additions & 6 deletions FlowCal/plot.py
Expand Up @@ -751,12 +751,16 @@ def hist1d(data_list,
data_list = [data_list]

# Default colors
if histtype == 'stepfilled' and edgecolor is None and facecolor is None:
facecolor = [cmap_default(i)
for i in np.linspace(0, 1, len(data_list))]
elif histtype == 'step' and edgecolor is None and facecolor is None:
edgecolor = [cmap_default(i)
for i in np.linspace(0, 1, len(data_list))]
if histtype == 'stepfilled':
if facecolor is None:
facecolor = [cmap_default(i)
for i in np.linspace(0, 1, len(data_list))]
if edgecolor is None:
edgecolor = ['black']*len(data_list)
elif histtype == 'step':
if edgecolor is None:
edgecolor = [cmap_default(i)
for i in np.linspace(0, 1, len(data_list))]

# Convert colors to lists if necessary
if not isinstance(edgecolor, list):
Expand Down
2 changes: 1 addition & 1 deletion Run FlowCal (OSX)
Expand Up @@ -4,6 +4,6 @@
# This is necessary so that the open file dialog is shown properly
export MPLBACKEND="TkAgg"
# Run FlowCal
python -m FlowCal.excel_ui -v -p
python -m FlowCal.excel_ui -v -p -H
# Pause
read -p "Press [Enter] to finish..."
2 changes: 1 addition & 1 deletion Run FlowCal (Windows).bat
@@ -1,6 +1,6 @@
:: Not show commands
@echo off
:: Run FlowCal
python -m FlowCal.excel_ui -v -p
python -m FlowCal.excel_ui -v -p -H
:: Pause
set /p=Press [Enter] to finish...
24 changes: 24 additions & 0 deletions test/test_gate.py
Expand Up @@ -892,6 +892,30 @@ def test_gate_fraction_2_mask(self):
0,0,0,0,0,0], dtype=bool)
)

# Test error when gate_fraction outside [0,1]

def test_gate_fraction_2_error_negative_gate_fraction(self):
bins = [-0.5, 0.5, 1.5, 2.5, 3.5, 4.5]
self.assertRaises(
ValueError,
FlowCal.gate.density2d,
self.pyramid,
bins=bins,
gate_fraction=-0.1,
sigma=0.0,
)

def test_gate_fraction_2_error_large_gate_fraction(self):
bins = [-0.5, 0.5, 1.5, 2.5, 3.5, 4.5]
self.assertRaises(
ValueError,
FlowCal.gate.density2d,
self.pyramid,
bins=bins,
gate_fraction=1.1,
sigma=0.0,
)

# Test implicit gating (when values exist outside specified bins)
#
# The expected behavior is that density2d() should mimic
Expand Down

0 comments on commit 31dc74c

Please sign in to comment.