Class: Submission
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Submission
- Extended by:
- StateMachine
- Includes:
- ModelExtensions::Submission, DelayedJobBehaviour, Priorities, Uuid::Uuidable
- Defined in:
- app/models/submission.rb
Overview
A Submission collects multiple Orders together, to define a body of work. In the case of non-multiplexed requests the submission is largely redundant, but for multiplexed requests it usually helps define which assets will get pooled together at multiplexing. There are two Order subclasses which are important when it comes to submissions:
LinearSubmission: Most orders fall in this category. If the submission is multiplexed results in a single pool for the whole submissions.
FlexibleSubmission: Allows request types to specify their own pooling rules, which are used to define pools at the submission level.
While orders are mostly in charge of building their own requests, Submissions trigger this behaviour, and handle multiplexing between orders.
Defined Under Namespace
Modules: AssetGroupBehaviour, AssetSubmissionFinder, Crossable, DelayedJobBehaviour, FlexibleRequestGraph, LinearRequestGraph, Priorities, ProjectValidation, RequestOptionsBehaviour, ScrnaCoreCdnaPrepFeasibilityCalculator, ScrnaCoreCdnaPrepFeasibilityValidator, ScrnaCoreCdnaPrepPoolingPlanGenerator, StateMachine, ValidationsByTemplateName Classes: OrderPresenter, PresenterSkeleton, SubmissionCreator, SubmissionPresenter
Constant Summary collapse
- PER_ORDER_REQUEST_OPTIONS =
%w[pre_capture_plex_level gigabases_expected].freeze
- SCRNA_CORE_CDNA_PREP_GEM_X_5P =
'Limber-Htp - scRNA Core cDNA Prep GEM-X 5p'
Constants included from StateMachine
StateMachine::UNPROCESSED_STATES
Class Method Summary collapse
-
.render_class ⇒ Object
The class used to render warehouse messages.
Instance Method Summary collapse
-
#add_comment(description, user, title = nil) ⇒ Void
Adds the given comment to all requests in the submission.
-
#comments ⇒ Object
As mentioned above, comments are broken.
- #cross_project? ⇒ Boolean
- #cross_study? ⇒ Boolean
- #each_submission_warning {|store[:samples].uniq, store[:submissions].uniq| ... } ⇒ Object
- #friendly_name ⇒ Object
- #json_root ⇒ Object
- #multiplexed? ⇒ Boolean
-
#multiplexed_labware ⇒ Object
Attempts to find the multiplexed asset (usually a multiplexed library tube) associated with the submission.
-
#name ⇒ Object
rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity.
-
#next_requests_via_submission(request) ⇒ Array<Request>
You probably just want to call next_requests on request.
-
#not_ready_samples ⇒ Object
returns an array of samples, that potentially can not be included in submission.
- #not_ready_samples_names ⇒ Object
-
#order_request_type_ids ⇒ Object
Logged calls from: app/models/pre_capture_pool.rb:74.
-
#prevent_destruction_unless_building? ⇒ Boolean
Once submissions progress beyond building, destruction is a risky action and should be prevented.
-
#request_type_ids ⇒ Object
deprecated
Deprecated.
This is no longer valid. Orders may now have different request_types
- #requests_cancellable? ⇒ Boolean
- #scrna_core_cdna_prep_gem_x_5p_submission? ⇒ Boolean
- #study_names ⇒ Object
- #subject_type ⇒ Object
-
#used_tags ⇒ Array<String,String>
Used tags returns an array of unique [i7_oligo, i5_oligo] used as part of the submission.
Methods included from StateMachine
Methods included from Priorities
Methods included from DelayedJobBehaviour
#build_batch, #default_priority, #finalize_build!, #queue_submission_builder
Methods included from Uuid::Uuidable
included, #unsaved_uuid!, #uuid
Methods inherited from ApplicationRecord
alias_association, convert_labware_to_receptacle_for, find_by_id_or_name, find_by_id_or_name!
Methods included from Squishify
Class Method Details
.render_class ⇒ Object
The class used to render warehouse messages
83 84 85 |
# File 'app/models/submission.rb', line 83 def self.render_class Api::SubmissionIo end |
Instance Method Details
#add_comment(description, user, title = nil) ⇒ Void
Adds the given comment to all requests in the submission
105 106 107 |
# File 'app/models/submission.rb', line 105 def add_comment(description, user, title = nil) requests.each { |request| request.add_comment(description, user, title) } end |
#comments ⇒ Object
As mentioned above, comments are broken. Not quite sure why we're overriding it here
96 97 98 |
# File 'app/models/submission.rb', line 96 def comments orders.pluck(:comments).compact end |
#cross_project? ⇒ Boolean
236 237 238 |
# File 'app/models/submission.rb', line 236 def cross_project? multiplexed? && orders.map(&:project_id).uniq.size > 1 end |
#cross_study? ⇒ Boolean
240 241 242 |
# File 'app/models/submission.rb', line 240 def cross_study? multiplexed? && orders.map(&:study_id).uniq.size > 1 end |
#each_submission_warning {|store[:samples].uniq, store[:submissions].uniq| ... } ⇒ Object
141 142 143 144 145 146 147 148 149 150 |
# File 'app/models/submission.rb', line 141 def each_submission_warning store = { samples: [], submissions: [] } orders.each do |order| order.duplicates_within(1.month) do |samples, _orders, submissions| store[:samples].concat(samples) store[:submissions].concat(submissions) end end yield store[:samples].uniq, store[:submissions].uniq unless store[:samples].empty? end |
#friendly_name ⇒ Object
121 122 123 |
# File 'app/models/submission.rb', line 121 def friendly_name name end |
#json_root ⇒ Object
113 114 115 |
# File 'app/models/submission.rb', line 113 def json_root 'submission' end |
#multiplexed? ⇒ Boolean
125 126 127 |
# File 'app/models/submission.rb', line 125 def multiplexed? orders.any?(&:multiplexed?) end |
#multiplexed_labware ⇒ Object
Attempts to find the multiplexed asset (usually a multiplexed library tube) associated with the submission. Useful when trying to pool requests into a pre-existing tube at the end of the process.
136 137 138 139 |
# File 'app/models/submission.rb', line 136 def multiplexed_labware # All our multiplexed requests end up in a single asset, so we don't care which one we find. requests.joins(:request_type).find_by(request_types: { for_multiplexing: true })&.target_labware end |
#name ⇒ Object
rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
220 221 222 |
# File 'app/models/submission.rb', line 220 def name super.presence || "##{id} #{study_names.truncate(128)}" end |
#next_requests_via_submission(request) ⇒ Array<Request>
You probably just want to call next_requests on request.
Returns the next requests in the submission along from the one provides. Eg. Providing a library creation request will return multiplexing requests, and multiplexing requests return sequencing requests. You may get back more than one request. This makes certain assumptions about request number in submissions, and uses request offsets and request types to tie requests together. rubocop:todo Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/AbcSize
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'app/models/submission.rb', line 188 def next_requests_via_submission(request) # rubocop:todo Metrics/CyclomaticComplexity raise "Request #{request.id} is not part of submission #{id}" unless request.submission_id == id # Pick out the siblings of the request, so we can work out where it is in the list, and all of # the requests in the subsequent request type, so that we can tie them up. We order by ID # here so that the earliest requests, those created by the submission build, are always first; # any additional requests will have come from a sequencing batch being reset. all_requests = request_cache_for(request.request_type_id, request.next_request_type_id) sibling_requests = all_requests[request.request_type_id] next_possible_requests = all_requests[request.next_request_type_id] if request.for_multiplexing? # If we have no pooling behaviour specified, then we're pooling by submission. # We keep to the existing behaviour, to isolate risk return next_possible_requests if request.request_type.pooling_method.nil? # If we get here we've got custom pooling behaviour defined. index = request.request_type.pool_index_for_request(request) number_to_return = next_possible_requests.count / request.request_type.pool_count next_possible_requests.slice(index * number_to_return, number_to_return) else multiplier = multiplier_for(request.next_request_type_id) index = sibling_requests.select { |npr| npr.order_id.nil? || (npr.order_id == request.order_id) }.index(request) next_possible_requests.select { |npr| npr.order_id.nil? || (npr.order_id == request.order_id) }[ index * multiplier, multiplier ] end end |
#not_ready_samples ⇒ Object
returns an array of samples, that potentially can not be included in submission
153 154 155 |
# File 'app/models/submission.rb', line 153 def not_ready_samples @not_ready_samples ||= orders.map(&:not_ready_samples).flatten end |
#not_ready_samples_names ⇒ Object
157 158 159 |
# File 'app/models/submission.rb', line 157 def not_ready_samples_names @not_ready_samples_names ||= not_ready_samples.map(&:name).join(', ') end |
#order_request_type_ids ⇒ Object
Logged calls from: app/models/pre_capture_pool.rb:74
172 173 174 |
# File 'app/models/submission.rb', line 172 def order_request_type_ids orders.flat_map(&:request_types).uniq.compact end |
#prevent_destruction_unless_building? ⇒ Boolean
Once submissions progress beyond building, destruction is a risky action and should be prevented.
88 89 90 91 92 93 |
# File 'app/models/submission.rb', line 88 def prevent_destruction_unless_building? return false if destroyable? errors.add(:base, "can only be destroyed when in the 'building' stage. Later submissions should be cancelled.") throw :abort end |
#request_type_ids ⇒ Object
This is no longer valid. Orders may now have different request_types
162 163 164 165 166 |
# File 'app/models/submission.rb', line 162 def request_type_ids return [] if orders.blank? orders.first.request_types.map(&:to_i) end |
#requests_cancellable? ⇒ Boolean
109 110 111 |
# File 'app/models/submission.rb', line 109 def requests_cancellable? requests.all?(&:cancellable?) end |
#scrna_core_cdna_prep_gem_x_5p_submission? ⇒ Boolean
129 130 131 |
# File 'app/models/submission.rb', line 129 def scrna_core_cdna_prep_gem_x_5p_submission? orders.first.template_name == SCRNA_CORE_CDNA_PREP_GEM_X_5P end |
#study_names ⇒ Object
224 225 226 227 228 229 230 231 232 233 234 |
# File 'app/models/submission.rb', line 224 def study_names # TODO: Should probably be re-factored, although we'll only fall back to the intensive code in the case of cross # study re-requests orders .map { |o| o.study.try(:name) || o.assets.map { |a| a.studies.pluck(:name) } } .flatten .compact .sort .uniq .join('|') end |
#subject_type ⇒ Object
117 118 119 |
# File 'app/models/submission.rb', line 117 def subject_type 'submission' end |
#used_tags ⇒ Array<String,String>
Used tags returns an array of unique [i7_oligo, i5_oligo] used as part of the submission
248 249 250 |
# File 'app/models/submission.rb', line 248 def aliquots.includes(:tag, :tag2)..distinct.pluck('tags.oligo', 'tag2s_aliquots.oligo') end |