Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 1.76.1 #2092

Merged
merged 19 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
4894b05
Restore customizing scatter plot colors
bistline Jul 22, 2024
fb0ff55
Safeguard against nil values in LabelSorter, move --Unspecified-- to …
bistline Jul 23, 2024
fde11c5
fixing test regression re: color order
bistline Jul 23, 2024
3a28094
Merge pull request #2086 from broadinstitute/jb-nan-color-map-fix
bistline Jul 24, 2024
75fb9a1
Merge pull request #2085 from broadinstitute/jb-cluster-custom-colors
bistline Jul 24, 2024
0ca70ea
Bump rexml from 3.2.8 to 3.3.2
dependabot[bot] Jul 24, 2024
f785f8e
Merge pull request #2087 from broadinstitute/dependabot/bundler/rexml…
eweitz Jul 25, 2024
db74d53
add larger machine types for AnnData ingest
jlchang Jul 30, 2024
f3db0e2
update test to show larger machine types are valid
jlchang Jul 30, 2024
08f88b2
add 40 and 80 machine types to GCE_MACHINE_TYPES
jlchang Jul 30, 2024
b7f7ac2
refining algorithm for EXTRACT_MACHINE_TYPES to remove overlap
bistline Jul 30, 2024
5edaa1a
update machine type map to scale faster
jlchang Jul 30, 2024
e800909
fix errors in comment
jlchang Jul 30, 2024
6ebc677
Merge pull request #2089 from broadinstitute/jlc_lg_adata_machines
jlchang Jul 30, 2024
fb37cc1
Omit subsampling options unless cluster is subsampled
bistline Jul 30, 2024
54796e6
fix tests after changing machine_type mappings
jlchang Jul 31, 2024
85b0209
fixing test regression
bistline Jul 31, 2024
aa8e400
Merge pull request #2090 from broadinstitute/jb-fix-subsample-selector
bistline Jul 31, 2024
37681a6
Merge pull request #2091 from broadinstitute/jlc_fix_adata_params_test
jlchang Jul 31, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,8 @@ GEM
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
retriable (3.1.2)
rexml (3.2.8)
strscan (>= 3.0.9)
rexml (3.3.2)
strscan
rubocop (1.36.0)
json (~> 2.3)
parallel (~> 1.10)
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/components/upload/upload-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const PROPERTIES_NOT_TO_SEND = [
]

const PROPERTIES_AS_JSON = ['custom_color_updates']
const DEEPLY_NESTED_PROPS = ['data_fragments']
const DEEPLY_NESTED_PROPS = ['custom_color_updates', 'data_fragments']

/** gets an object representing a new, empty study file. Does not communicate to server */
export function newStudyFileObj(studyId) {
Expand Down
2 changes: 1 addition & 1 deletion app/lib/cluster_viz_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def self.load_spatial_options(study)
# only options allowed are 1000, 10000, 20000, and 100000
# will only provide options if subsampling has completed for a cluster
def self.subsampling_options(cluster)
return [] if cluster.nil? || cluster.is_subsampling?
return [] if cluster.nil? || cluster.is_subsampling? || !cluster.subsampled

ClusterGroup::SUBSAMPLE_THRESHOLDS.select { |sample| sample < cluster.points }
end
Expand Down
17 changes: 11 additions & 6 deletions app/models/ann_data_ingest_parameters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,16 @@ class AnnDataIngestParameters
NON_ATTRIBUTE_PARAMS = %i[file_size machine_type].freeze

# GCE machine types and file size ranges for handling fragment extraction
# produces a hash with entries like { 'n2-highmem-4' => 0..4.gigabytes }
EXTRACT_MACHINE_TYPES = [4, 8, 16, 32].map.with_index do |cores, index|
floor = index == 0 ? 0 : (cores / 2).gigabytes
limit = (cores * 8).gigabytes
# produces a hash with entries like { 'n2-highmem-4' => 0..24.gigabytes }
# adjust (core * n) to n=4 for faster scaling (ie. n2-highmem-4 for 0 to 16G)
NUM_CORES = [4, 8, 16, 32, 48, 64, 80, 96].freeze
RAM_PER_CORE = NUM_CORES.map { |core| (core * 6).gigabytes }.freeze
EXTRACT_MACHINE_TYPES = NUM_CORES.map.with_index do |cores, index|
floor = index == 0 ? 0 : RAM_PER_CORE[index - 1]
limit = index == NUM_CORES.count - 1 ? RAM_PER_CORE[index] * 2 : RAM_PER_CORE[index]
# ranges that use '...' exclude the given end value.
{ "n2d-highmem-#{cores}" => floor...limit }
end.reduce({}, :merge)
end.reduce({}, :merge).freeze

attr_accessor(*PARAM_DEFAULTS.keys)

Expand All @@ -70,7 +73,9 @@ def initialize(attributes = nil)
# machine_type default is declared here to allow for autoscaling with optional override
# see https://ruby-doc.org/core-3.1.0/Range.html#method-i-3D-3D-3D for range detection doc
if @machine_type.nil?
self.machine_type = EXTRACT_MACHINE_TYPES.detect { |_, mem_range| mem_range === file_size }&.first || 'n2d-highmem-4'
self.machine_type = EXTRACT_MACHINE_TYPES.detect do |_, mem_range|
mem_range === file_size
end&.first || 'n2d-highmem-4'
end
end

Expand Down
2 changes: 1 addition & 1 deletion app/models/concerns/parameterizable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module Parameterizable
# https://cloud.google.com/compute/docs/general-purpose-machines
GCE_MACHINE_TYPES = %w[n2 n2d].map do |family|
%w[standard highmem highcpu].map do |series|
[2, 4, 8, 16, 32, 64, 96].map do |cores|
[2, 4, 8, 16, 32, 48, 64, 80, 96].map do |cores|
[family, series, cores].join('-')
end
end
Expand Down
11 changes: 8 additions & 3 deletions lib/label_sorter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ class LabelSorter
attr_reader :lowercase, :natural_types, :type_order

def initialize(str)
@str = str
@lowercase = str.downcase
@str = str.to_s # safeguard against nil or non-string values
@lowercase = @str.downcase
@natural_types = @lowercase.scan(/\d+|\D+/).map { |s| s =~ /\d/ ? s.to_i : s }
@type_order = @natural_types.map { |el| el.is_a?(Integer) ? :i : :s }.join
end
Expand All @@ -24,6 +24,11 @@ def to_s
end

def self.natural_sort(values)
values.map { |v| new(v) }.sort.map { |el| el.to_s }
sorted = values.map { |v| new(v) }.sort.map { |el| el.to_s }
# move any blank/Unspecified entries to the end to allow use of first color for actual label
if sorted.first.blank? || sorted.first == AnnotationVizService::MISSING_VALUE_LABEL
sorted << sorted.shift
end
sorted
end
end
3 changes: 1 addition & 2 deletions test/api/visualization/annotations_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,13 @@ class AnnotationsControllerTest < ActionDispatch::IntegrationTest
{
name: 'cell_type', type: 'group', scope: 'study', values: %w(big --Unspecified--),
identifier: 'cell_type--group--study',
color_map: { '--Unspecified--' => '#e41a1c', big: '#377eb8' }.with_indifferent_access
color_map: { big: '#e41a1c', '--Unspecified--' => '#377eb8' }.with_indifferent_access
},
{
name: 'nCount_RNA', type: 'numeric', scope: 'study', values: [],
identifier: 'nCount_RNA--numeric--study'
}
]
expected_annotations[2][:values][1] = '--Unspecified--'
assert_equal expected_annotations, annotations
assert_empty Api::V1::Visualization::AnnotationsController.get_facet_annotations(
@basic_study, cluster, 'does-not-exist--group--study'
Expand Down
10 changes: 10 additions & 0 deletions test/lib/label_sorter_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,14 @@ class LabelSorterTest < ActiveSupport::TestCase
assert_equal 1, last <=> first
assert_equal 1, last <=> middle
end

test 'should move blank or unspecified to the end' do
random = @labels.take(10).shuffle
blank_label = [''] + random
sorted = LabelSorter.natural_sort(blank_label)
assert sorted.last.blank?
unspecified = [AnnotationVizService::MISSING_VALUE_LABEL] + random
sorted = LabelSorter.natural_sort(unspecified)
assert_equal AnnotationVizService::MISSING_VALUE_LABEL, sorted.last
end
end
6 changes: 3 additions & 3 deletions test/models/ann_data_ingest_parameters_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class AnnDataIngestParametersTest < ActiveSupport::TestCase
cmd = '--ingest-anndata --anndata-file gs://bucket_id/test.h5ad --obsm-keys ["X_umap", "X_tsne"] --extract ' \
'["cluster", "metadata", "processed_expression"]'
assert_equal cmd, extraction.to_options_array.join(' ')
assert_equal 'n2d-highmem-16', extraction.machine_type
assert_equal 'n2d-highmem-32', extraction.machine_type
end

test 'should validate cluster params' do
Expand Down Expand Up @@ -98,8 +98,8 @@ class AnnDataIngestParametersTest < ActiveSupport::TestCase

test 'should set default machine type and allow override' do
params = AnnDataIngestParameters.new(@extract_params)
assert_equal 'n2d-highmem-16', params.machine_type
new_machine = 'n2d-highmem-32'
assert_equal 'n2d-highmem-32', params.machine_type
new_machine = 'n2d-highmem-80'
params.machine_type = new_machine
assert_equal new_machine, params.machine_type
assert params.valid?
Expand Down
1 change: 1 addition & 0 deletions test/services/cluster_viz_service_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class ClusterVizServiceTest < ActiveSupport::TestCase
cells: cells
})
cluster = @study.cluster_groups.by_name(cluster_name)
cluster.update(subsampled: true)
options = ClusterVizService.subsampling_options(cluster)
assert_equal [1000], options
end
Expand Down
4 changes: 2 additions & 2 deletions test/services/expression_viz_service_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,9 @@ def load_all_genes(study)
# cells A & B belong to 'bar', and cell C belongs to the blank label
expected_output = {
bar: {
y: [0.0, 3.0], cells: %w(A B), annotations: [], name: 'bar', color: @color_list[1]
y: [0.0, 3.0], cells: %w(A B), annotations: [], name: 'bar', color: @color_list[0]
}, "#{AnnotationVizService::MISSING_VALUE_LABEL}": {
y: [1.5], cells: %w(C), annotations: [], name: AnnotationVizService::MISSING_VALUE_LABEL, color: @color_list[0]
y: [1.5], cells: %w(C), annotations: [], name: AnnotationVizService::MISSING_VALUE_LABEL, color: @color_list[1]
}
}
assert_equal expected_output.with_indifferent_access, violin_data.with_indifferent_access
Expand Down
Loading
Loading