Skip to content

Commit

Permalink
Fix: use data from samples directly in samples reports
Browse files Browse the repository at this point in the history
This is a required change because after a transfer the sample <-> batch
relationship is severed. This is actually not a problem because the data
is already on the samples.
  • Loading branch information
ysbaddaden committed Jul 20, 2023
1 parent e391535 commit 39defaf
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 53 deletions.
26 changes: 13 additions & 13 deletions app/controllers/nih_tables_controller.rb
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
class NihTablesController < ApplicationController
def show
@samples_report = SamplesReport.find(params[:id])
@target_batch = @samples_report.target_batch
@samples_report = SamplesReport.preload(:samples => :box).find(params[:id])
return unless authorize_resource(@samples_report, READ_SAMPLES_REPORT)

zip_data = create_zip_file

@target_box = @samples_report.boxes.take
@target_sample = @samples_report.target_sample
zip_data = create_zip_file(@target_box.purpose)
send_data zip_data.read, type: 'application/zip', filename: "#{@samples_report.name}_nih_tables.zip"
end

private

def create_zip_file
purpose = @samples_report.samples[0].box.purpose

def create_zip_file(purpose)
zip_stream = Zip::OutputStream.write_buffer do |stream|
# Read public/templates/Instructions.txt contents and write to zip
# TODO: read public/templates/Instructions.txt contents and write to zip
stream.put_next_entry('Instructions.txt')
stream.write(File.read(Rails.root.join('public/templates/Instructions.txt')))

add_nih_table('samples', stream)
add_nih_table('results', stream)

if purpose == "LOD"
case purpose
when "LOD"
add_nih_table('lod', stream)
elsif purpose == "Challenge"
when "Challenge"
add_nih_table('challenge', stream)
end
end
Expand All @@ -33,6 +33,6 @@ def create_zip_file

def add_nih_table(table_name, stream)
stream.put_next_entry("#{@samples_report.name}_#{table_name}.csv")
stream.write(render_to_string('samples_reports/nih_'+table_name, formats: :csv))
stream.write(render_to_string("nih_#{table_name}", formats: :csv))
end
end
end
5 changes: 2 additions & 3 deletions app/controllers/samples_reports_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@ def index
@samples_reports = SamplesReport.where(institution: @navigation_context.institution)
@samples_reports = check_access(@samples_reports, READ_SAMPLES_REPORT).order('samples_reports.created_at DESC')

# Filter by search params

# filter by search params
@samples_reports = @samples_reports.partial_name(params[:name])
@samples_reports = @samples_reports.partial_sample_uuid(params[:sample_uuid])
@samples_reports = @samples_reports.partial_box_uuid(params[:box_uuid])
@samples_reports = @samples_reports.partial_batch_number(params[:batch_number])

#paginate samples report
# paginate samples report
@samples_reports = perform_pagination(@samples_reports)
end

Expand Down
3 changes: 2 additions & 1 deletion app/models/sample.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ def self.institution_is_required
has_many :sample_identifiers, inverse_of: :sample, dependent: :destroy
has_many :test_results, through: :sample_identifiers

has_many :samples_reports, through: :samples_report_sample
has_many :samples_reports, through: :samples_report_samples
has_many :samples_report_samples, dependent: :destroy

has_many :assay_attachments, dependent: :destroy
accepts_nested_attributes_for :assay_attachments, allow_destroy: true
Expand Down
32 changes: 19 additions & 13 deletions app/models/samples_report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class SamplesReport < ApplicationRecord

has_many :samples_report_samples, dependent: :destroy
has_many :samples, through: :samples_report_samples
has_many :boxes, through: :samples

def self.entity_scope
"samples_report"
Expand All @@ -30,19 +31,24 @@ def self.entity_scope
}

scope :partial_box_uuid, ->(box_uuid) {
joins("LEFT JOIN samples_report_samples ON samples_report_samples.samples_report_id = samples_reports.id
LEFT JOIN samples ON samples_report_samples.sample_id = samples.id
LEFT JOIN boxes ON boxes.id = samples.box_id")
.where("boxes.uuid LIKE ?", "%#{sanitize_sql_like(box_uuid)}%")
.group(:samples_report_id) unless box_uuid.blank?
unless box_uuid.blank?
where(id: SamplesReportSample
.select(:samples_report_id)
.joins(:sample => :box)
.where("boxes.uuid LIKE ?", "%#{sanitize_sql_like(box_uuid)}%"))
end
}

scope :partial_batch_number, ->(batch_number) {
joins("LEFT JOIN samples_report_samples ON samples_report_samples.samples_report_id = samples_reports.id
LEFT JOIN samples ON samples_report_samples.sample_id = samples.id
LEFT JOIN batches ON batches.id = samples.batch_id")
.where("batches.batch_number LIKE ?", "%#{sanitize_sql_like(batch_number)}%")
.group(:samples_report_id) unless batch_number.blank?
# after box transfer, the sample <-> batch relationship will be severed,
# hence the coalesce to match the old batch number (valid after transfer)
# then the original batch number (valid before transfer)
unless batch_number.blank?
where(id: SamplesReportSample
.select(:samples_report_id)
.left_joins(:sample => :batch)
.where("COALESCE(samples.old_batch_number, batches.batch_number) LIKE ?", "%#{sanitize_sql_like(batch_number)}%"))
end
}

def calculate_lod_and_lob
Expand All @@ -68,9 +74,9 @@ def calculate_lod_and_lob
self.save
end

def target_batch
# The target batch for this box is the batch of any sample which distractor is false or null
samples_report_samples.joins(:sample).find_by("samples.distractor IS NULL OR samples.distractor = 'false'").sample.batch
# Returns any sample that isn't a distractor.
def target_sample
samples.where.not(distractor: true).take!
end

private
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,16 @@ csv << [
'roc_y_values'
]

sample = @samples_report.samples[0]
csv << [
nil,
nil,
sample.box.uuid,
"#{sample.box.purpose}-panel",
@target_box.uuid,
"#{@target_box.purpose}-panel",
'inactivated virus',
'SARS-CoV-2',
@target_batch.target_organism_taxonomy_id,
@target_batch.pango_lineage,
@target_batch.who_label,
@target_sample.target_organism_taxonomy_id,
@target_sample.pango_lineage,
@target_sample.who_label,
@samples_report.threshold,
'copies/ml',
params[:true_positives],
Expand All @@ -51,4 +50,4 @@ csv << [
params[:auc],
params[:roc_x_values],
params[:roc_y_values]
]
]
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,24 @@ csv << [
'analytical_sensitivity_unit'
]

sample = @samples_report.samples[0]
csv << [
nil,
nil,
sample.box.uuid,
"#{sample.box.purpose}-panel",
@target_box.uuid,
"#{@target_box.purpose}-panel",
'inactivated virus',
'SARS-CoV-2',
@target_batch.target_organism_taxonomy_id,
@target_batch.pango_lineage,
@target_batch.who_label,
@target_sample.target_organism_taxonomy_id,
@target_sample.pango_lineage,
@target_sample.who_label,
@samples_report.lob,
nil,
@samples_report.lod,
@target_batch.reference_gene,
@target_sample.reference_gene,
nil,
nil,
"90",
'linear regression',
nil,
nil
]
]
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ csv << [
]

@samples_report.samples.each do |sample|
batch = Batch.find_by(batch_number: sample.batch_number)
csv << [
sample.id,
sample.id, # FIXME: UUID?
sample.box.uuid,
"#{sample.box.purpose}-panel",
nil,
Expand All @@ -31,14 +30,14 @@ csv << [
nil,
sample.concentration,
'copies/ml',
batch.reference_gene,
sample.id,
sample.reference_gene,
sample.id, # FIXME: ??
sample.batch_number,
'inactivated virus',
'SARS-CoV-2',
batch.target_organism_taxonomy_id,
batch.pango_lineage,
batch.who_label,
sample.target_organism_taxonomy_id,
sample.pango_lineage,
sample.who_label,
sample.inactivation_method
]
end
end

0 comments on commit 39defaf

Please sign in to comment.