Class: Dphil::Character
- Inherits:
-
Object
- Object
- Dphil::Character
- Includes:
- LDOutput
- Defined in:
- lib/dphil/character.rb
Overview
Phylogenetic character for storing states and symbols.
Immutable.
Instance Attribute Summary collapse
-
#id ⇒ Integer
readonly
Character ID.
-
#state_list ⇒ Array<String>
readonly
Text-states.
-
#state_totals ⇒ Hash<String, Integer>
readonly
Character state totals by text-state.
-
#states ⇒ Hash<String, String>
readonly
Text-states by symbol.
-
#states_taxa ⇒ Hash<String, Integer>
readonly
Taxa IDs by text-state.
-
#symbol_list ⇒ Array<String>
readonly
Symbols.
-
#symbol_totals ⇒ Hash<String, Integer>
readonly
Character state totals by symbol.
-
#symbols ⇒ Hash<String, String>
readonly
Symbols by text-state.
-
#symbols_taxa ⇒ Hash<String, Integer>
readonly
Taxa IDs by symbol.
-
#taxa ⇒ Set<Integer>
readonly
Taxon IDs.
-
#taxa_states ⇒ Hash<Integer, String>
readonly
Text-states by taxon ID.
-
#taxa_symbols ⇒ Hash<Integer, String>
readonly
Symbols by taxon ID.
Instance Method Summary collapse
- #as_json(options = nil) ⇒ Object
-
#constant? ⇒ Boolean
Check if the character is invariant.
-
#get_state(symbol) ⇒ String?
Get state from symbol.
-
#get_state_taxon(taxon_id) ⇒ String?
Get state from taxon.
-
#get_symbol(state) ⇒ String?
Get symbol from state.
-
#get_symbol_taxon(taxon_id) ⇒ String?
Get symbol from taxon.
-
#get_taxa_state(state) ⇒ Array<Integer>
Get taxa from state.
-
#get_taxa_symbol(symbol) ⇒ Array<Integer>
Get taxa from symbol.
-
#informative? ⇒ Boolean
Check if character is parsimony-informative (At least 2 variants occurring in at least 2 places).
-
#initialize(id = nil, states = nil, **opts) ⇒ Character
constructor
Instantiates a new Character.
-
#inspect ⇒ String
(also: #to_s)
A string representation of the object.
-
#pretty_print(q) ⇒ Object
Pretty-print the object (used by Pry in particular).
- #to_h ⇒ Object
Methods included from LDOutput
Constructor Details
#initialize(id = nil, states = nil) ⇒ Character #initialize(**opts = {}) ⇒ Character
Instantiates a new Character
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/dphil/character.rb', line 20 def initialize(id = nil, states = nil, **opts) @id = (opts[:id] || id)&.to_s.to_i @taxa_states = (opts[:states] || states) .to_h.each_with_object({}) do |(taxon, state), acc| next if state.blank? taxon = taxon.to_s if taxon.is_a?(Symbol) acc[taxon.to_i] = normalize_text(state) end unique_states = weighted_uniq(@taxa_states.values) if unique_states.size > SYMBOL_ARRAY.size raise ArgumentError, "Too many states (found #{unique_states.size}, " \ "max #{SYMBOL_ARRAY.size})" end @states = {} @state_totals = unique_states unique_states.each_key.with_index do |state, index| @states[SYMBOL_ARRAY[index]] = state end instance_variables.each { |ivar| instance_variable_get(ivar).freeze } end |
Instance Attribute Details
#id ⇒ Integer (readonly)
Returns character ID.
46 47 48 |
# File 'lib/dphil/character.rb', line 46 def id @id end |
#state_list ⇒ Array<String> (readonly)
Returns text-states.
66 67 68 |
# File 'lib/dphil/character.rb', line 66 def state_list @state_list ||= states.values.freeze end |
#state_totals ⇒ Hash<String, Integer> (readonly)
Returns character state totals by text-state.
78 79 80 |
# File 'lib/dphil/character.rb', line 78 def state_totals @state_totals end |
#states ⇒ Hash<String, String> (readonly)
Returns text-states by symbol.
56 57 58 |
# File 'lib/dphil/character.rb', line 56 def states @states end |
#states_taxa ⇒ Hash<String, Integer> (readonly)
Returns taxa IDs by text-state.
98 99 100 101 102 |
# File 'lib/dphil/character.rb', line 98 def states_taxa @states_taxa ||= (states.each_value.each_with_object({}) do |state, acc| acc[state] = taxa_states.select { |_, tstate| state == tstate }.keys end).freeze end |
#symbol_list ⇒ Array<String> (readonly)
Returns symbols.
72 73 74 |
# File 'lib/dphil/character.rb', line 72 def symbol_list @symbol_list ||= states.keys.freeze end |
#symbol_totals ⇒ Hash<String, Integer> (readonly)
Returns character state totals by symbol.
82 83 84 |
# File 'lib/dphil/character.rb', line 82 def symbol_totals @symbol_totals ||= state_totals.transform_keys { |state| symbols[state] }.freeze end |
#symbols ⇒ Hash<String, String> (readonly)
Returns symbols by text-state.
60 61 62 |
# File 'lib/dphil/character.rb', line 60 def symbols @symbols ||= states.invert.freeze end |
#symbols_taxa ⇒ Hash<String, Integer> (readonly)
Returns taxa IDs by symbol.
106 107 108 |
# File 'lib/dphil/character.rb', line 106 def symbols_taxa @symbols_taxa ||= states_taxa.transform_keys { |state| symbols[state] }.freeze end |
#taxa ⇒ Set<Integer> (readonly)
Returns taxon IDs.
50 51 52 |
# File 'lib/dphil/character.rb', line 50 def taxa @taxa ||= Set.new(taxa_states.keys).freeze end |
#taxa_states ⇒ Hash<Integer, String> (readonly)
Returns text-states by taxon ID.
88 89 90 |
# File 'lib/dphil/character.rb', line 88 def taxa_states @taxa_states end |
#taxa_symbols ⇒ Hash<Integer, String> (readonly)
Returns symbols by taxon ID.
92 93 94 |
# File 'lib/dphil/character.rb', line 92 def taxa_symbols @taxa_symbols ||= taxa_states.transform_values { |state| symbols[state] }.freeze end |
Instance Method Details
#as_json(options = nil) ⇒ Object
178 179 180 |
# File 'lib/dphil/character.rb', line 178 def as_json( = nil) to_h.as_json() end |
#constant? ⇒ Boolean
Check if the character is invariant
161 162 163 |
# File 'lib/dphil/character.rb', line 161 def constant? @constant ||= states.size <= 1 end |
#get_state(symbol) ⇒ String?
Get state from symbol
113 114 115 |
# File 'lib/dphil/character.rb', line 113 def get_state(symbol) states[normalize_text(symbol)] end |
#get_state_taxon(taxon_id) ⇒ String?
Get state from taxon
141 142 143 |
# File 'lib/dphil/character.rb', line 141 def get_state_taxon(taxon_id) taxa_states[taxon_id.to_i] end |
#get_symbol(state) ⇒ String?
Get symbol from state
120 121 122 |
# File 'lib/dphil/character.rb', line 120 def get_symbol(state) symbols[normalize_text(state)] end |
#get_symbol_taxon(taxon_id) ⇒ String?
Get symbol from taxon
148 149 150 |
# File 'lib/dphil/character.rb', line 148 def get_symbol_taxon(taxon_id) taxa_symbols[taxon_id.to_i] end |
#get_taxa_state(state) ⇒ Array<Integer>
Get taxa from state
127 128 129 |
# File 'lib/dphil/character.rb', line 127 def get_taxa_state(state) states_taxa[normalize_text(state)] end |
#get_taxa_symbol(symbol) ⇒ Array<Integer>
Get taxa from symbol
134 135 136 |
# File 'lib/dphil/character.rb', line 134 def get_taxa_symbol(symbol) symbols_taxa[normalize_text(symbol)] end |
#informative? ⇒ Boolean
Check if character is parsimony-informative (At least 2 variants occurring in at least 2 places)
155 156 157 |
# File 'lib/dphil/character.rb', line 155 def informative? @informative ||= (states.size > 1 && states_taxa.count { |_, v| v.size > 1 } > 1) end |
#inspect ⇒ String Also known as: to_s
Returns a string representation of the object.
200 201 202 |
# File 'lib/dphil/character.rb', line 200 def inspect pretty_inspect.chomp end |
#pretty_print(q) ⇒ Object
Pretty-print the object (used by Pry in particular)
184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/dphil/character.rb', line 184 def pretty_print(q) q.object_group(self) do q.breakable q.group(1) do q.text "@id=#{id}" q.breakable q.group(1, "{", "}") do q.seplist(states) do |symbol, state| q.text "#{state.inspect}(#{symbol})=#{states_taxa[state]}" end end end end end |
#to_h ⇒ Object
165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/dphil/character.rb', line 165 def to_h { id: id, states: states, symbols: symbols, state_totals: state_totals, taxa_states: taxa_states, states_taxa: states_taxa, is_informative: informative?, is_constant: constant?, } end |