Class: SqedDepiction
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- SqedDepiction
- Includes:
- Housekeeping, Shared::Notes, Shared::Tags
- Defined in:
- app/models/sqed_depiction.rb
Overview
A SqedDepiction identifies a depiction as sqed (github.com/SpeciesFileGroup/sqed) parsable, and records the metadata required for parsing a stage image.
Instance Attribute Summary collapse
-
#boundary_color ⇒ Symbol
Color of the boundaries in the image, default/recommendation is green.
-
#boundary_finder ⇒ String
Name of the sqed BoundaryFinder class to use, e.g.
-
#has_border ⇒ Boolean
True if the stage image has a border than needs to be detected.
-
#layout ⇒ Symbol
The Sqed layout, like :cross, :equal_cross, :vertical_offset_cross, :internal_box etc.
-
#metadata_map ⇒ Hash
The sqed metadata map, e.g.
-
#rebuild ⇒ Object
Returns the value of attribute rebuild.
-
#result_boundaries ⇒ Hash
A cache for the result.
-
#result_ocr ⇒ Hash
A cache for the ocr result.
-
#specimen_coordinates ⇒ Hash
Not presently used, the specific coordinates bounding the specimen(s) only.
Class Method Summary collapse
- .clear_stale_progress(sqed_depiction = nil) ⇒ Object
- .last_without_data(project_id) ⇒ Object
-
.preprocess_empty(total = 10) ⇒ Integer
Caches section coordinates and ocr text for the first images that don't have such caches !! does not take into account project or user, just finds and processes.
- .with_collection_object_data ⇒ Object
- .without_collection_object_data ⇒ Object
Instance Method Summary collapse
-
#collecting_event_sections ⇒ Array of symbols
The (named) sections in this depiction that may have collecting event label metadata.
- #depiction_object ⇒ Object
- #extraction_metadata ⇒ Object
- #is_in_progress? ⇒ Boolean
- #nearby_sqed_depictions(before = 5, after = 5, progress = false) ⇒ Object
-
#next_collection_object ⇒ CollectionObject?
The next collection object, by :id, created from the addition of a SqedDepiction.
- #next_sqed_depiction ⇒ Object
-
#next_without_data(progress = false) ⇒ SqedDepiction
The next record in which the collection object has no buffered data.
- #preprocess(force = true) ⇒ Object
- #recalculate ⇒ Object
- #sqed_metadata_map ⇒ Object protected
Methods included from Shared::Notes
#concatenated_notes_string, #reject_notes
Methods included from Shared::Tags
#reject_tags, #tag_with, #tagged?, #tagged_with?
Methods included from Housekeeping
#has_polymorphic_relationship?
Methods inherited from ApplicationRecord
Instance Attribute Details
#boundary_color ⇒ Symbol
Color of the boundaries in the image, default/recommendation is green.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'app/models/sqed_depiction.rb', line 36 class SqedDepiction < ApplicationRecord include Housekeeping include Shared::Tags include Shared::Notes attr_accessor :rebuild belongs_to :depiction has_one :image, through: :depiction has_one :collection_object, through: :depiction, source_type: 'CollectionObject', source: :depiction_object validates_presence_of :depiction validates_presence_of :metadata_map, :boundary_color validates_inclusion_of :layout, in: SqedConfig::LAYOUTS.keys.map(&:to_s) validates_inclusion_of :boundary_finder, in: %w{Sqed::BoundaryFinder::ColorLineFinder Sqed::BoundaryFinder::Cross} validates_inclusion_of :has_border, in: [true, false] accepts_nested_attributes_for :depiction after_save :recalculate, if: -> { rebuild } def rebuild=(value) @rebuild = value end def recalculate preprocess(true) end def { boundary_color: boundary_color.to_sym, boundary_finder: boundary_finder&.constantize, has_border: has_border, layout: layout.to_sym, metadata_map: } end def depiction_object depiction.depiction_object end def self.with_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].not_eq(nil). or(t[:buffered_determinations].not_eq(nil)). or(t[:buffered_other_labels].not_eq(nil)) joins(:collection_object).where(q.to_sql) end def self.without_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].eq(nil). and(t[:buffered_determinations].eq(nil)). and(t[:buffered_other_labels].eq(nil)) joins(:collection_object).where(q.to_sql) end # @return [SqedDepiction] # the next record in which the collection object has no buffered data def next_without_data(progress = false) if progress SqedDepiction.clear_stale_progress(self) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(in_progress: false, project_id: project_id).order(:id).first : object else object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(:id).first : object end end def is_in_progress? in_progress && in_progress < 5.minutes.ago end def self.clear_stale_progress(sqed_depiction = nil) SqedDepiction.where('(in_progress < ?)', 5.minutes.ago) .update_all(in_progress: nil) if sqed_depiction SqedDepiction .where(updated_by_id: sqed_depiction.updated_by_id) .update_all(in_progress: nil) end true end def self.last_without_data(project_id) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(id: :asc).first : object end # @return [CollectionObject, nil] # the next collection object, by :id, created from the addition of a SqedDepiction def next_collection_object object = CollectionObject.joins(:sqed_depictions).where(project_id: project_id).where('sqed_depictions.id > ?', id).where('collection_objects.id <> ?', depiction_object.id).order(:id).first object = CollectionObject.joins(:sqed_depictions).order(:id).first if object.nil? object end # @return [Array of symbols] # the (named) sections in this depiction that may have collecting event label metadata def collecting_event_sections # !! master merge [:collecting_event_labels, :annotated_specimen] & [:metadata_map].values end def nearby_sqed_depictions(before = 5, after = 5, progress = false) q = SqedDepiction.where(project_id: project_id) if progress == true SqedDepiction.clear_stale_progress(self) q = q.where(in_progress: nil) end a = q.where('id > ?', id).order(:id).limit(after) b = q.where('id < ?', id).order('id DESC').limit(before) return { before: b, after: a} end def next_sqed_depiction sd = SqedDepiction.where(project_id: project_id).where('id > ?', id).order(:id).limit(1) sd.any? ? sd.first : SqedDepiction.where(project_id: project_id).first end def preprocess(force = true) return true if !File.exists?(depiction.image.image_file.path(:original)) # don't rebuild if not forced and one or both cache is empty if !force if !result_ocr.blank? || !result_boundary_coordinates.blank? return true end end # otherwise rebuild result = SqedToTaxonworks::Result.new(depiction_id: depiction.id) result.cache_all end # @return [Integer] # caches section coordinates and ocr text for the first images that don't have such caches !! does not take into account project or user, just finds and processes def self.preprocess_empty(total = 10) t = SqedDepiction.arel_table i = 0 while i < total r = SqedDepiction.where(t[:result_ocr].eq(nil).or(t[:result_boundary_coordinates].eq(nil)).to_sql).limit(1).first return i if r.nil? r.preprocess i = i + 1 end i end protected def .inject({}){|hsh, i| hsh.merge(i[0].to_i => i[1].to_sym)} end end |
#boundary_finder ⇒ String
Name of the sqed BoundaryFinder class to use, e.g. 'Sqed::BoundaryFinder::ColorLineFinder'
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'app/models/sqed_depiction.rb', line 36 class SqedDepiction < ApplicationRecord include Housekeeping include Shared::Tags include Shared::Notes attr_accessor :rebuild belongs_to :depiction has_one :image, through: :depiction has_one :collection_object, through: :depiction, source_type: 'CollectionObject', source: :depiction_object validates_presence_of :depiction validates_presence_of :metadata_map, :boundary_color validates_inclusion_of :layout, in: SqedConfig::LAYOUTS.keys.map(&:to_s) validates_inclusion_of :boundary_finder, in: %w{Sqed::BoundaryFinder::ColorLineFinder Sqed::BoundaryFinder::Cross} validates_inclusion_of :has_border, in: [true, false] accepts_nested_attributes_for :depiction after_save :recalculate, if: -> { rebuild } def rebuild=(value) @rebuild = value end def recalculate preprocess(true) end def { boundary_color: boundary_color.to_sym, boundary_finder: boundary_finder&.constantize, has_border: has_border, layout: layout.to_sym, metadata_map: } end def depiction_object depiction.depiction_object end def self.with_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].not_eq(nil). or(t[:buffered_determinations].not_eq(nil)). or(t[:buffered_other_labels].not_eq(nil)) joins(:collection_object).where(q.to_sql) end def self.without_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].eq(nil). and(t[:buffered_determinations].eq(nil)). and(t[:buffered_other_labels].eq(nil)) joins(:collection_object).where(q.to_sql) end # @return [SqedDepiction] # the next record in which the collection object has no buffered data def next_without_data(progress = false) if progress SqedDepiction.clear_stale_progress(self) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(in_progress: false, project_id: project_id).order(:id).first : object else object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(:id).first : object end end def is_in_progress? in_progress && in_progress < 5.minutes.ago end def self.clear_stale_progress(sqed_depiction = nil) SqedDepiction.where('(in_progress < ?)', 5.minutes.ago) .update_all(in_progress: nil) if sqed_depiction SqedDepiction .where(updated_by_id: sqed_depiction.updated_by_id) .update_all(in_progress: nil) end true end def self.last_without_data(project_id) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(id: :asc).first : object end # @return [CollectionObject, nil] # the next collection object, by :id, created from the addition of a SqedDepiction def next_collection_object object = CollectionObject.joins(:sqed_depictions).where(project_id: project_id).where('sqed_depictions.id > ?', id).where('collection_objects.id <> ?', depiction_object.id).order(:id).first object = CollectionObject.joins(:sqed_depictions).order(:id).first if object.nil? object end # @return [Array of symbols] # the (named) sections in this depiction that may have collecting event label metadata def collecting_event_sections # !! master merge [:collecting_event_labels, :annotated_specimen] & [:metadata_map].values end def nearby_sqed_depictions(before = 5, after = 5, progress = false) q = SqedDepiction.where(project_id: project_id) if progress == true SqedDepiction.clear_stale_progress(self) q = q.where(in_progress: nil) end a = q.where('id > ?', id).order(:id).limit(after) b = q.where('id < ?', id).order('id DESC').limit(before) return { before: b, after: a} end def next_sqed_depiction sd = SqedDepiction.where(project_id: project_id).where('id > ?', id).order(:id).limit(1) sd.any? ? sd.first : SqedDepiction.where(project_id: project_id).first end def preprocess(force = true) return true if !File.exists?(depiction.image.image_file.path(:original)) # don't rebuild if not forced and one or both cache is empty if !force if !result_ocr.blank? || !result_boundary_coordinates.blank? return true end end # otherwise rebuild result = SqedToTaxonworks::Result.new(depiction_id: depiction.id) result.cache_all end # @return [Integer] # caches section coordinates and ocr text for the first images that don't have such caches !! does not take into account project or user, just finds and processes def self.preprocess_empty(total = 10) t = SqedDepiction.arel_table i = 0 while i < total r = SqedDepiction.where(t[:result_ocr].eq(nil).or(t[:result_boundary_coordinates].eq(nil)).to_sql).limit(1).first return i if r.nil? r.preprocess i = i + 1 end i end protected def .inject({}){|hsh, i| hsh.merge(i[0].to_i => i[1].to_sym)} end end |
#has_border ⇒ Boolean
Returns True if the stage image has a border than needs to be detected.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'app/models/sqed_depiction.rb', line 36 class SqedDepiction < ApplicationRecord include Housekeeping include Shared::Tags include Shared::Notes attr_accessor :rebuild belongs_to :depiction has_one :image, through: :depiction has_one :collection_object, through: :depiction, source_type: 'CollectionObject', source: :depiction_object validates_presence_of :depiction validates_presence_of :metadata_map, :boundary_color validates_inclusion_of :layout, in: SqedConfig::LAYOUTS.keys.map(&:to_s) validates_inclusion_of :boundary_finder, in: %w{Sqed::BoundaryFinder::ColorLineFinder Sqed::BoundaryFinder::Cross} validates_inclusion_of :has_border, in: [true, false] accepts_nested_attributes_for :depiction after_save :recalculate, if: -> { rebuild } def rebuild=(value) @rebuild = value end def recalculate preprocess(true) end def { boundary_color: boundary_color.to_sym, boundary_finder: boundary_finder&.constantize, has_border: has_border, layout: layout.to_sym, metadata_map: } end def depiction_object depiction.depiction_object end def self.with_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].not_eq(nil). or(t[:buffered_determinations].not_eq(nil)). or(t[:buffered_other_labels].not_eq(nil)) joins(:collection_object).where(q.to_sql) end def self.without_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].eq(nil). and(t[:buffered_determinations].eq(nil)). and(t[:buffered_other_labels].eq(nil)) joins(:collection_object).where(q.to_sql) end # @return [SqedDepiction] # the next record in which the collection object has no buffered data def next_without_data(progress = false) if progress SqedDepiction.clear_stale_progress(self) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(in_progress: false, project_id: project_id).order(:id).first : object else object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(:id).first : object end end def is_in_progress? in_progress && in_progress < 5.minutes.ago end def self.clear_stale_progress(sqed_depiction = nil) SqedDepiction.where('(in_progress < ?)', 5.minutes.ago) .update_all(in_progress: nil) if sqed_depiction SqedDepiction .where(updated_by_id: sqed_depiction.updated_by_id) .update_all(in_progress: nil) end true end def self.last_without_data(project_id) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(id: :asc).first : object end # @return [CollectionObject, nil] # the next collection object, by :id, created from the addition of a SqedDepiction def next_collection_object object = CollectionObject.joins(:sqed_depictions).where(project_id: project_id).where('sqed_depictions.id > ?', id).where('collection_objects.id <> ?', depiction_object.id).order(:id).first object = CollectionObject.joins(:sqed_depictions).order(:id).first if object.nil? object end # @return [Array of symbols] # the (named) sections in this depiction that may have collecting event label metadata def collecting_event_sections # !! master merge [:collecting_event_labels, :annotated_specimen] & [:metadata_map].values end def nearby_sqed_depictions(before = 5, after = 5, progress = false) q = SqedDepiction.where(project_id: project_id) if progress == true SqedDepiction.clear_stale_progress(self) q = q.where(in_progress: nil) end a = q.where('id > ?', id).order(:id).limit(after) b = q.where('id < ?', id).order('id DESC').limit(before) return { before: b, after: a} end def next_sqed_depiction sd = SqedDepiction.where(project_id: project_id).where('id > ?', id).order(:id).limit(1) sd.any? ? sd.first : SqedDepiction.where(project_id: project_id).first end def preprocess(force = true) return true if !File.exists?(depiction.image.image_file.path(:original)) # don't rebuild if not forced and one or both cache is empty if !force if !result_ocr.blank? || !result_boundary_coordinates.blank? return true end end # otherwise rebuild result = SqedToTaxonworks::Result.new(depiction_id: depiction.id) result.cache_all end # @return [Integer] # caches section coordinates and ocr text for the first images that don't have such caches !! does not take into account project or user, just finds and processes def self.preprocess_empty(total = 10) t = SqedDepiction.arel_table i = 0 while i < total r = SqedDepiction.where(t[:result_ocr].eq(nil).or(t[:result_boundary_coordinates].eq(nil)).to_sql).limit(1).first return i if r.nil? r.preprocess i = i + 1 end i end protected def .inject({}){|hsh, i| hsh.merge(i[0].to_i => i[1].to_sym)} end end |
#layout ⇒ Symbol
The Sqed layout, like :cross, :equal_cross, :vertical_offset_cross, :internal_box etc.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'app/models/sqed_depiction.rb', line 36 class SqedDepiction < ApplicationRecord include Housekeeping include Shared::Tags include Shared::Notes attr_accessor :rebuild belongs_to :depiction has_one :image, through: :depiction has_one :collection_object, through: :depiction, source_type: 'CollectionObject', source: :depiction_object validates_presence_of :depiction validates_presence_of :metadata_map, :boundary_color validates_inclusion_of :layout, in: SqedConfig::LAYOUTS.keys.map(&:to_s) validates_inclusion_of :boundary_finder, in: %w{Sqed::BoundaryFinder::ColorLineFinder Sqed::BoundaryFinder::Cross} validates_inclusion_of :has_border, in: [true, false] accepts_nested_attributes_for :depiction after_save :recalculate, if: -> { rebuild } def rebuild=(value) @rebuild = value end def recalculate preprocess(true) end def { boundary_color: boundary_color.to_sym, boundary_finder: boundary_finder&.constantize, has_border: has_border, layout: layout.to_sym, metadata_map: } end def depiction_object depiction.depiction_object end def self.with_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].not_eq(nil). or(t[:buffered_determinations].not_eq(nil)). or(t[:buffered_other_labels].not_eq(nil)) joins(:collection_object).where(q.to_sql) end def self.without_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].eq(nil). and(t[:buffered_determinations].eq(nil)). and(t[:buffered_other_labels].eq(nil)) joins(:collection_object).where(q.to_sql) end # @return [SqedDepiction] # the next record in which the collection object has no buffered data def next_without_data(progress = false) if progress SqedDepiction.clear_stale_progress(self) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(in_progress: false, project_id: project_id).order(:id).first : object else object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(:id).first : object end end def is_in_progress? in_progress && in_progress < 5.minutes.ago end def self.clear_stale_progress(sqed_depiction = nil) SqedDepiction.where('(in_progress < ?)', 5.minutes.ago) .update_all(in_progress: nil) if sqed_depiction SqedDepiction .where(updated_by_id: sqed_depiction.updated_by_id) .update_all(in_progress: nil) end true end def self.last_without_data(project_id) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(id: :asc).first : object end # @return [CollectionObject, nil] # the next collection object, by :id, created from the addition of a SqedDepiction def next_collection_object object = CollectionObject.joins(:sqed_depictions).where(project_id: project_id).where('sqed_depictions.id > ?', id).where('collection_objects.id <> ?', depiction_object.id).order(:id).first object = CollectionObject.joins(:sqed_depictions).order(:id).first if object.nil? object end # @return [Array of symbols] # the (named) sections in this depiction that may have collecting event label metadata def collecting_event_sections # !! master merge [:collecting_event_labels, :annotated_specimen] & [:metadata_map].values end def nearby_sqed_depictions(before = 5, after = 5, progress = false) q = SqedDepiction.where(project_id: project_id) if progress == true SqedDepiction.clear_stale_progress(self) q = q.where(in_progress: nil) end a = q.where('id > ?', id).order(:id).limit(after) b = q.where('id < ?', id).order('id DESC').limit(before) return { before: b, after: a} end def next_sqed_depiction sd = SqedDepiction.where(project_id: project_id).where('id > ?', id).order(:id).limit(1) sd.any? ? sd.first : SqedDepiction.where(project_id: project_id).first end def preprocess(force = true) return true if !File.exists?(depiction.image.image_file.path(:original)) # don't rebuild if not forced and one or both cache is empty if !force if !result_ocr.blank? || !result_boundary_coordinates.blank? return true end end # otherwise rebuild result = SqedToTaxonworks::Result.new(depiction_id: depiction.id) result.cache_all end # @return [Integer] # caches section coordinates and ocr text for the first images that don't have such caches !! does not take into account project or user, just finds and processes def self.preprocess_empty(total = 10) t = SqedDepiction.arel_table i = 0 while i < total r = SqedDepiction.where(t[:result_ocr].eq(nil).or(t[:result_boundary_coordinates].eq(nil)).to_sql).limit(1).first return i if r.nil? r.preprocess i = i + 1 end i end protected def .inject({}){|hsh, i| hsh.merge(i[0].to_i => i[1].to_sym)} end end |
#metadata_map ⇒ Hash
The sqed metadata map, e.g. {0 => :curator_metadata, 1 => :identifier, 2 => :image_registration, 3 => :annotated_specimen }.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'app/models/sqed_depiction.rb', line 36 class SqedDepiction < ApplicationRecord include Housekeeping include Shared::Tags include Shared::Notes attr_accessor :rebuild belongs_to :depiction has_one :image, through: :depiction has_one :collection_object, through: :depiction, source_type: 'CollectionObject', source: :depiction_object validates_presence_of :depiction validates_presence_of :metadata_map, :boundary_color validates_inclusion_of :layout, in: SqedConfig::LAYOUTS.keys.map(&:to_s) validates_inclusion_of :boundary_finder, in: %w{Sqed::BoundaryFinder::ColorLineFinder Sqed::BoundaryFinder::Cross} validates_inclusion_of :has_border, in: [true, false] accepts_nested_attributes_for :depiction after_save :recalculate, if: -> { rebuild } def rebuild=(value) @rebuild = value end def recalculate preprocess(true) end def { boundary_color: boundary_color.to_sym, boundary_finder: boundary_finder&.constantize, has_border: has_border, layout: layout.to_sym, metadata_map: } end def depiction_object depiction.depiction_object end def self.with_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].not_eq(nil). or(t[:buffered_determinations].not_eq(nil)). or(t[:buffered_other_labels].not_eq(nil)) joins(:collection_object).where(q.to_sql) end def self.without_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].eq(nil). and(t[:buffered_determinations].eq(nil)). and(t[:buffered_other_labels].eq(nil)) joins(:collection_object).where(q.to_sql) end # @return [SqedDepiction] # the next record in which the collection object has no buffered data def next_without_data(progress = false) if progress SqedDepiction.clear_stale_progress(self) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(in_progress: false, project_id: project_id).order(:id).first : object else object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(:id).first : object end end def is_in_progress? in_progress && in_progress < 5.minutes.ago end def self.clear_stale_progress(sqed_depiction = nil) SqedDepiction.where('(in_progress < ?)', 5.minutes.ago) .update_all(in_progress: nil) if sqed_depiction SqedDepiction .where(updated_by_id: sqed_depiction.updated_by_id) .update_all(in_progress: nil) end true end def self.last_without_data(project_id) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(id: :asc).first : object end # @return [CollectionObject, nil] # the next collection object, by :id, created from the addition of a SqedDepiction def next_collection_object object = CollectionObject.joins(:sqed_depictions).where(project_id: project_id).where('sqed_depictions.id > ?', id).where('collection_objects.id <> ?', depiction_object.id).order(:id).first object = CollectionObject.joins(:sqed_depictions).order(:id).first if object.nil? object end # @return [Array of symbols] # the (named) sections in this depiction that may have collecting event label metadata def collecting_event_sections # !! master merge [:collecting_event_labels, :annotated_specimen] & [:metadata_map].values end def nearby_sqed_depictions(before = 5, after = 5, progress = false) q = SqedDepiction.where(project_id: project_id) if progress == true SqedDepiction.clear_stale_progress(self) q = q.where(in_progress: nil) end a = q.where('id > ?', id).order(:id).limit(after) b = q.where('id < ?', id).order('id DESC').limit(before) return { before: b, after: a} end def next_sqed_depiction sd = SqedDepiction.where(project_id: project_id).where('id > ?', id).order(:id).limit(1) sd.any? ? sd.first : SqedDepiction.where(project_id: project_id).first end def preprocess(force = true) return true if !File.exists?(depiction.image.image_file.path(:original)) # don't rebuild if not forced and one or both cache is empty if !force if !result_ocr.blank? || !result_boundary_coordinates.blank? return true end end # otherwise rebuild result = SqedToTaxonworks::Result.new(depiction_id: depiction.id) result.cache_all end # @return [Integer] # caches section coordinates and ocr text for the first images that don't have such caches !! does not take into account project or user, just finds and processes def self.preprocess_empty(total = 10) t = SqedDepiction.arel_table i = 0 while i < total r = SqedDepiction.where(t[:result_ocr].eq(nil).or(t[:result_boundary_coordinates].eq(nil)).to_sql).limit(1).first return i if r.nil? r.preprocess i = i + 1 end i end protected def .inject({}){|hsh, i| hsh.merge(i[0].to_i => i[1].to_sym)} end end |
#rebuild ⇒ Object
Returns the value of attribute rebuild.
41 42 43 |
# File 'app/models/sqed_depiction.rb', line 41 def rebuild @rebuild end |
#result_boundaries ⇒ Hash
Returns A cache for the result.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'app/models/sqed_depiction.rb', line 36 class SqedDepiction < ApplicationRecord include Housekeeping include Shared::Tags include Shared::Notes attr_accessor :rebuild belongs_to :depiction has_one :image, through: :depiction has_one :collection_object, through: :depiction, source_type: 'CollectionObject', source: :depiction_object validates_presence_of :depiction validates_presence_of :metadata_map, :boundary_color validates_inclusion_of :layout, in: SqedConfig::LAYOUTS.keys.map(&:to_s) validates_inclusion_of :boundary_finder, in: %w{Sqed::BoundaryFinder::ColorLineFinder Sqed::BoundaryFinder::Cross} validates_inclusion_of :has_border, in: [true, false] accepts_nested_attributes_for :depiction after_save :recalculate, if: -> { rebuild } def rebuild=(value) @rebuild = value end def recalculate preprocess(true) end def { boundary_color: boundary_color.to_sym, boundary_finder: boundary_finder&.constantize, has_border: has_border, layout: layout.to_sym, metadata_map: } end def depiction_object depiction.depiction_object end def self.with_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].not_eq(nil). or(t[:buffered_determinations].not_eq(nil)). or(t[:buffered_other_labels].not_eq(nil)) joins(:collection_object).where(q.to_sql) end def self.without_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].eq(nil). and(t[:buffered_determinations].eq(nil)). and(t[:buffered_other_labels].eq(nil)) joins(:collection_object).where(q.to_sql) end # @return [SqedDepiction] # the next record in which the collection object has no buffered data def next_without_data(progress = false) if progress SqedDepiction.clear_stale_progress(self) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(in_progress: false, project_id: project_id).order(:id).first : object else object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(:id).first : object end end def is_in_progress? in_progress && in_progress < 5.minutes.ago end def self.clear_stale_progress(sqed_depiction = nil) SqedDepiction.where('(in_progress < ?)', 5.minutes.ago) .update_all(in_progress: nil) if sqed_depiction SqedDepiction .where(updated_by_id: sqed_depiction.updated_by_id) .update_all(in_progress: nil) end true end def self.last_without_data(project_id) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(id: :asc).first : object end # @return [CollectionObject, nil] # the next collection object, by :id, created from the addition of a SqedDepiction def next_collection_object object = CollectionObject.joins(:sqed_depictions).where(project_id: project_id).where('sqed_depictions.id > ?', id).where('collection_objects.id <> ?', depiction_object.id).order(:id).first object = CollectionObject.joins(:sqed_depictions).order(:id).first if object.nil? object end # @return [Array of symbols] # the (named) sections in this depiction that may have collecting event label metadata def collecting_event_sections # !! master merge [:collecting_event_labels, :annotated_specimen] & [:metadata_map].values end def nearby_sqed_depictions(before = 5, after = 5, progress = false) q = SqedDepiction.where(project_id: project_id) if progress == true SqedDepiction.clear_stale_progress(self) q = q.where(in_progress: nil) end a = q.where('id > ?', id).order(:id).limit(after) b = q.where('id < ?', id).order('id DESC').limit(before) return { before: b, after: a} end def next_sqed_depiction sd = SqedDepiction.where(project_id: project_id).where('id > ?', id).order(:id).limit(1) sd.any? ? sd.first : SqedDepiction.where(project_id: project_id).first end def preprocess(force = true) return true if !File.exists?(depiction.image.image_file.path(:original)) # don't rebuild if not forced and one or both cache is empty if !force if !result_ocr.blank? || !result_boundary_coordinates.blank? return true end end # otherwise rebuild result = SqedToTaxonworks::Result.new(depiction_id: depiction.id) result.cache_all end # @return [Integer] # caches section coordinates and ocr text for the first images that don't have such caches !! does not take into account project or user, just finds and processes def self.preprocess_empty(total = 10) t = SqedDepiction.arel_table i = 0 while i < total r = SqedDepiction.where(t[:result_ocr].eq(nil).or(t[:result_boundary_coordinates].eq(nil)).to_sql).limit(1).first return i if r.nil? r.preprocess i = i + 1 end i end protected def .inject({}){|hsh, i| hsh.merge(i[0].to_i => i[1].to_sym)} end end |
#result_ocr ⇒ Hash
Returns A cache for the ocr result.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'app/models/sqed_depiction.rb', line 36 class SqedDepiction < ApplicationRecord include Housekeeping include Shared::Tags include Shared::Notes attr_accessor :rebuild belongs_to :depiction has_one :image, through: :depiction has_one :collection_object, through: :depiction, source_type: 'CollectionObject', source: :depiction_object validates_presence_of :depiction validates_presence_of :metadata_map, :boundary_color validates_inclusion_of :layout, in: SqedConfig::LAYOUTS.keys.map(&:to_s) validates_inclusion_of :boundary_finder, in: %w{Sqed::BoundaryFinder::ColorLineFinder Sqed::BoundaryFinder::Cross} validates_inclusion_of :has_border, in: [true, false] accepts_nested_attributes_for :depiction after_save :recalculate, if: -> { rebuild } def rebuild=(value) @rebuild = value end def recalculate preprocess(true) end def { boundary_color: boundary_color.to_sym, boundary_finder: boundary_finder&.constantize, has_border: has_border, layout: layout.to_sym, metadata_map: } end def depiction_object depiction.depiction_object end def self.with_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].not_eq(nil). or(t[:buffered_determinations].not_eq(nil)). or(t[:buffered_other_labels].not_eq(nil)) joins(:collection_object).where(q.to_sql) end def self.without_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].eq(nil). and(t[:buffered_determinations].eq(nil)). and(t[:buffered_other_labels].eq(nil)) joins(:collection_object).where(q.to_sql) end # @return [SqedDepiction] # the next record in which the collection object has no buffered data def next_without_data(progress = false) if progress SqedDepiction.clear_stale_progress(self) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(in_progress: false, project_id: project_id).order(:id).first : object else object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(:id).first : object end end def is_in_progress? in_progress && in_progress < 5.minutes.ago end def self.clear_stale_progress(sqed_depiction = nil) SqedDepiction.where('(in_progress < ?)', 5.minutes.ago) .update_all(in_progress: nil) if sqed_depiction SqedDepiction .where(updated_by_id: sqed_depiction.updated_by_id) .update_all(in_progress: nil) end true end def self.last_without_data(project_id) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(id: :asc).first : object end # @return [CollectionObject, nil] # the next collection object, by :id, created from the addition of a SqedDepiction def next_collection_object object = CollectionObject.joins(:sqed_depictions).where(project_id: project_id).where('sqed_depictions.id > ?', id).where('collection_objects.id <> ?', depiction_object.id).order(:id).first object = CollectionObject.joins(:sqed_depictions).order(:id).first if object.nil? object end # @return [Array of symbols] # the (named) sections in this depiction that may have collecting event label metadata def collecting_event_sections # !! master merge [:collecting_event_labels, :annotated_specimen] & [:metadata_map].values end def nearby_sqed_depictions(before = 5, after = 5, progress = false) q = SqedDepiction.where(project_id: project_id) if progress == true SqedDepiction.clear_stale_progress(self) q = q.where(in_progress: nil) end a = q.where('id > ?', id).order(:id).limit(after) b = q.where('id < ?', id).order('id DESC').limit(before) return { before: b, after: a} end def next_sqed_depiction sd = SqedDepiction.where(project_id: project_id).where('id > ?', id).order(:id).limit(1) sd.any? ? sd.first : SqedDepiction.where(project_id: project_id).first end def preprocess(force = true) return true if !File.exists?(depiction.image.image_file.path(:original)) # don't rebuild if not forced and one or both cache is empty if !force if !result_ocr.blank? || !result_boundary_coordinates.blank? return true end end # otherwise rebuild result = SqedToTaxonworks::Result.new(depiction_id: depiction.id) result.cache_all end # @return [Integer] # caches section coordinates and ocr text for the first images that don't have such caches !! does not take into account project or user, just finds and processes def self.preprocess_empty(total = 10) t = SqedDepiction.arel_table i = 0 while i < total r = SqedDepiction.where(t[:result_ocr].eq(nil).or(t[:result_boundary_coordinates].eq(nil)).to_sql).limit(1).first return i if r.nil? r.preprocess i = i + 1 end i end protected def .inject({}){|hsh, i| hsh.merge(i[0].to_i => i[1].to_sym)} end end |
#specimen_coordinates ⇒ Hash
Returns Not presently used, the specific coordinates bounding the specimen(s) only.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'app/models/sqed_depiction.rb', line 36 class SqedDepiction < ApplicationRecord include Housekeeping include Shared::Tags include Shared::Notes attr_accessor :rebuild belongs_to :depiction has_one :image, through: :depiction has_one :collection_object, through: :depiction, source_type: 'CollectionObject', source: :depiction_object validates_presence_of :depiction validates_presence_of :metadata_map, :boundary_color validates_inclusion_of :layout, in: SqedConfig::LAYOUTS.keys.map(&:to_s) validates_inclusion_of :boundary_finder, in: %w{Sqed::BoundaryFinder::ColorLineFinder Sqed::BoundaryFinder::Cross} validates_inclusion_of :has_border, in: [true, false] accepts_nested_attributes_for :depiction after_save :recalculate, if: -> { rebuild } def rebuild=(value) @rebuild = value end def recalculate preprocess(true) end def { boundary_color: boundary_color.to_sym, boundary_finder: boundary_finder&.constantize, has_border: has_border, layout: layout.to_sym, metadata_map: } end def depiction_object depiction.depiction_object end def self.with_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].not_eq(nil). or(t[:buffered_determinations].not_eq(nil)). or(t[:buffered_other_labels].not_eq(nil)) joins(:collection_object).where(q.to_sql) end def self.without_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].eq(nil). and(t[:buffered_determinations].eq(nil)). and(t[:buffered_other_labels].eq(nil)) joins(:collection_object).where(q.to_sql) end # @return [SqedDepiction] # the next record in which the collection object has no buffered data def next_without_data(progress = false) if progress SqedDepiction.clear_stale_progress(self) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(in_progress: false, project_id: project_id).order(:id).first : object else object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(:id).first : object end end def is_in_progress? in_progress && in_progress < 5.minutes.ago end def self.clear_stale_progress(sqed_depiction = nil) SqedDepiction.where('(in_progress < ?)', 5.minutes.ago) .update_all(in_progress: nil) if sqed_depiction SqedDepiction .where(updated_by_id: sqed_depiction.updated_by_id) .update_all(in_progress: nil) end true end def self.last_without_data(project_id) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(id: :asc).first : object end # @return [CollectionObject, nil] # the next collection object, by :id, created from the addition of a SqedDepiction def next_collection_object object = CollectionObject.joins(:sqed_depictions).where(project_id: project_id).where('sqed_depictions.id > ?', id).where('collection_objects.id <> ?', depiction_object.id).order(:id).first object = CollectionObject.joins(:sqed_depictions).order(:id).first if object.nil? object end # @return [Array of symbols] # the (named) sections in this depiction that may have collecting event label metadata def collecting_event_sections # !! master merge [:collecting_event_labels, :annotated_specimen] & [:metadata_map].values end def nearby_sqed_depictions(before = 5, after = 5, progress = false) q = SqedDepiction.where(project_id: project_id) if progress == true SqedDepiction.clear_stale_progress(self) q = q.where(in_progress: nil) end a = q.where('id > ?', id).order(:id).limit(after) b = q.where('id < ?', id).order('id DESC').limit(before) return { before: b, after: a} end def next_sqed_depiction sd = SqedDepiction.where(project_id: project_id).where('id > ?', id).order(:id).limit(1) sd.any? ? sd.first : SqedDepiction.where(project_id: project_id).first end def preprocess(force = true) return true if !File.exists?(depiction.image.image_file.path(:original)) # don't rebuild if not forced and one or both cache is empty if !force if !result_ocr.blank? || !result_boundary_coordinates.blank? return true end end # otherwise rebuild result = SqedToTaxonworks::Result.new(depiction_id: depiction.id) result.cache_all end # @return [Integer] # caches section coordinates and ocr text for the first images that don't have such caches !! does not take into account project or user, just finds and processes def self.preprocess_empty(total = 10) t = SqedDepiction.arel_table i = 0 while i < total r = SqedDepiction.where(t[:result_ocr].eq(nil).or(t[:result_boundary_coordinates].eq(nil)).to_sql).limit(1).first return i if r.nil? r.preprocess i = i + 1 end i end protected def .inject({}){|hsh, i| hsh.merge(i[0].to_i => i[1].to_sym)} end end |
Class Method Details
.clear_stale_progress(sqed_depiction = nil) ⇒ Object
115 116 117 118 119 120 121 122 123 124 |
# File 'app/models/sqed_depiction.rb', line 115 def self.clear_stale_progress(sqed_depiction = nil) SqedDepiction.where('(in_progress < ?)', 5.minutes.ago) .update_all(in_progress: nil) if sqed_depiction SqedDepiction .where(updated_by_id: sqed_depiction.updated_by_id) .update_all(in_progress: nil) end true end |
.last_without_data(project_id) ⇒ Object
126 127 128 129 |
# File 'app/models/sqed_depiction.rb', line 126 def self.last_without_data(project_id) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(id: :asc).first : object end |
.preprocess_empty(total = 10) ⇒ Integer
Returns caches section coordinates and ocr text for the first images that don't have such caches !! does not take into account project or user, just finds and processes.
181 182 183 184 185 186 187 188 189 190 191 |
# File 'app/models/sqed_depiction.rb', line 181 def self.preprocess_empty(total = 10) t = SqedDepiction.arel_table i = 0 while i < total r = SqedDepiction.where(t[:result_ocr].eq(nil).or(t[:result_boundary_coordinates].eq(nil)).to_sql).limit(1).first return i if r.nil? r.preprocess i = i + 1 end i end |
.with_collection_object_data ⇒ Object
80 81 82 83 84 85 86 87 |
# File 'app/models/sqed_depiction.rb', line 80 def self.with_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].not_eq(nil). or(t[:buffered_determinations].not_eq(nil)). or(t[:buffered_other_labels].not_eq(nil)) joins(:collection_object).where(q.to_sql) end |
.without_collection_object_data ⇒ Object
89 90 91 92 93 94 95 96 |
# File 'app/models/sqed_depiction.rb', line 89 def self.without_collection_object_data t = CollectionObject.arel_table q = t[:buffered_collecting_event].eq(nil). and(t[:buffered_determinations].eq(nil)). and(t[:buffered_other_labels].eq(nil)) joins(:collection_object).where(q.to_sql) end |
Instance Method Details
#collecting_event_sections ⇒ Array of symbols
Returns the (named) sections in this depiction that may have collecting event label metadata.
141 142 143 144 |
# File 'app/models/sqed_depiction.rb', line 141 def collecting_event_sections # !! master merge [:collecting_event_labels, :annotated_specimen] & [:metadata_map].values end |
#depiction_object ⇒ Object
76 77 78 |
# File 'app/models/sqed_depiction.rb', line 76 def depiction_object depiction.depiction_object end |
#extraction_metadata ⇒ Object
66 67 68 69 70 71 72 73 74 |
# File 'app/models/sqed_depiction.rb', line 66 def { boundary_color: boundary_color.to_sym, boundary_finder: boundary_finder&.constantize, has_border: has_border, layout: layout.to_sym, metadata_map: } end |
#is_in_progress? ⇒ Boolean
111 112 113 |
# File 'app/models/sqed_depiction.rb', line 111 def is_in_progress? in_progress && in_progress < 5.minutes.ago end |
#nearby_sqed_depictions(before = 5, after = 5, progress = false) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'app/models/sqed_depiction.rb', line 146 def nearby_sqed_depictions(before = 5, after = 5, progress = false) q = SqedDepiction.where(project_id: project_id) if progress == true SqedDepiction.clear_stale_progress(self) q = q.where(in_progress: nil) end a = q.where('id > ?', id).order(:id).limit(after) b = q.where('id < ?', id).order('id DESC').limit(before) return { before: b, after: a} end |
#next_collection_object ⇒ CollectionObject?
Returns the next collection object, by :id, created from the addition of a SqedDepiction.
133 134 135 136 137 |
# File 'app/models/sqed_depiction.rb', line 133 def next_collection_object object = CollectionObject.joins(:sqed_depictions).where(project_id: project_id).where('sqed_depictions.id > ?', id).where('collection_objects.id <> ?', depiction_object.id).order(:id).first object = CollectionObject.joins(:sqed_depictions).order(:id).first if object.nil? object end |
#next_sqed_depiction ⇒ Object
160 161 162 163 |
# File 'app/models/sqed_depiction.rb', line 160 def next_sqed_depiction sd = SqedDepiction.where(project_id: project_id).where('id > ?', id).order(:id).limit(1) sd.any? ? sd.first : SqedDepiction.where(project_id: project_id).first end |
#next_without_data(progress = false) ⇒ SqedDepiction
Returns the next record in which the collection object has no buffered data.
100 101 102 103 104 105 106 107 108 109 |
# File 'app/models/sqed_depiction.rb', line 100 def next_without_data(progress = false) if progress SqedDepiction.clear_stale_progress(self) object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(in_progress: false, project_id: project_id).order(:id).first : object else object = SqedDepiction.without_collection_object_data.with_project_id(project_id).where('collection_objects.id <> ?', depiction_object.id).where('sqed_depictions.id > ?', id).order(:id).first object.nil? ? SqedDepiction.where(project_id: project_id).order(:id).first : object end end |
#preprocess(force = true) ⇒ Object
165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'app/models/sqed_depiction.rb', line 165 def preprocess(force = true) return true if !File.exists?(depiction.image.image_file.path(:original)) # don't rebuild if not forced and one or both cache is empty if !force if !result_ocr.blank? || !result_boundary_coordinates.blank? return true end end # otherwise rebuild result = SqedToTaxonworks::Result.new(depiction_id: depiction.id) result.cache_all end |
#recalculate ⇒ Object
62 63 64 |
# File 'app/models/sqed_depiction.rb', line 62 def recalculate preprocess(true) end |
#sqed_metadata_map ⇒ Object (protected)
195 196 197 |
# File 'app/models/sqed_depiction.rb', line 195 def .inject({}){|hsh, i| hsh.merge(i[0].to_i => i[1].to_sym)} end |